Repository: QuTech-Delft/libqasm (language: python)

Issue:
Release 0.6.6
- Update version.
- Update `CHANGELOG.md`.
- Remove `python/module/libQasm` folder.


Discussion / hints:

Fix patch:
diff --git a/.github/workflows/assets.yml b/.github/workflows/assets.yml
index c848b5002..696abadf4 100644
--- a/.github/workflows/assets.yml
+++ b/.github/workflows/assets.yml
@@ -10,8 +10,8 @@ on:
 
 jobs:
   macos-x64:
-    name: PyPI wheels for macOS
-    runs-on: macos-latest
+    name: PyPI wheels for macOS/x64
+    runs-on: macos-13  # x64
     strategy:
       matrix:
         python:
@@ -29,6 +29,7 @@ jobs:
       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip conan setuptools wheel
+          brew install swig
       - name: Build wheel
         run: python setup.py bdist_wheel
       - name: Wheel path
@@ -39,7 +40,50 @@ jobs:
           echo "WHEEL_NAME=$(ls *.whl)" >> $GITHUB_ENV
       - uses: actions/upload-artifact@v4
         with:
-          name: pypi-macos-py${{ matrix.python }}
+          name: pypi-macos-x64-py${{ matrix.python }}
+          path: pybuild/dist/${{ env.WHEEL_NAME }}
+      - uses: actions/upload-release-asset@v1
+        if: ${{ github.event_name == 'release' && github.event.action == 'created' }}
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          upload_url: ${{ github.event.release.upload_url }}
+          asset_path: pybuild/dist/${{ env.WHEEL_NAME }}
+          asset_name: ${{ env.WHEEL_NAME }}
+          asset_content_type: application/zip
+
+  macos-arm64:
+    name: PyPI wheels for macOS/arm64
+    runs-on: macos-14  # arm64
+    strategy:
+      matrix:
+        python:
+          - "3.8"
+          - "3.9"
+          - "3.10"
+          - "3.11"
+          - "3.12"
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+      - uses: actions/setup-python@v5
+        with:
+          python-version: ${{ matrix.python }}
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip conan setuptools wheel
+          brew install swig
+      - name: Build wheel
+        run: python setup.py bdist_wheel
+      - name: Wheel path
+        id: wheel
+        working-directory: pybuild/dist/
+        run: |
+          echo "WHEEL_NAME=$(ls *.whl)" >> $GITHUB_OUTPUT
+          echo "WHEEL_NAME=$(ls *.whl)" >> $GITHUB_ENV
+      - uses: actions/upload-artifact@v4
+        with:
+          name: pypi-macos-arm64-py${{ matrix.python }}
           path: pybuild/dist/${{ env.WHEEL_NAME }}
       - uses: actions/upload-release-asset@v1
         if: ${{ github.event_name == 'release' && github.event.action == 'created' }}
@@ -235,7 +279,7 @@ jobs:
         run: |
           conan profile detect --force
           conan remove -c "*/*"
-          conan build . -pr=conan/profiles/emscripten -pr:b=conan/profiles/release -b missing
+          conan build . -pr=conan/profiles/release-clang-emscripten-wasm -pr:b=conan/profiles/release -b missing
         shell: bash
       - name: Upload release asset
         uses: softprops/action-gh-release@v2
@@ -251,6 +295,7 @@ jobs:
     if: ${{ github.event_name == 'release' && github.event.action == 'created' }}
     needs:
       - macos-x64
+      - macos-arm64
       - manylinux-x64
       - manylinux-arm64
       - windows-x64
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4a800d921..3d7f4dd15 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,80 +3,91 @@
 All notable changes to this project will be documented in this file.
 This project adheres to [Semantic Versioning](http://semver.org/).
 
-## [ 0.6.5 ] - [ 2024-04-23 ]
+
+## [ 0.6.6 ] - [ 2024-05-14 ]
 
 ### Added
+- Allow multiple qubit/bit (register) definitions and mid-circuit measurements.
+- Python MacOS/arm64 jobs.
+- `python/test_libqasm.py` to test Python jobs.
 
 ### Changed
+- Fix Python MacOS/arm64 packages.
+- Fix `scripts/generate_antlr_parser.py`.
+- MacOS/x64 jobs now run in macos-13, and MacOS/arm64 jobs in macos-14, both GitHub runners.
+- Python module name from `libQasm` to `libqasm`.
+
+### Removed
+- `python/module/libQasm` folder.
+
+
+## [ 0.6.5 ] - [ 2024-04-23 ]
 
+### Added
+
+### Changed
 - Updated emscripten compilation flags.
 - Changed GitHub Actions `js-emscripten-wasm` job to work with `deno` instead of `node`.
 
 ### Removed
 
+
 ## [ 0.6.4 ] - [ 2024-04-15 ]
 
 ### Added
 
 ### Changed
-
 - Fixed CMake install.
 - `generate_antlr_parser.py` writes output include files in a given `include` folder. 
 
 ### Removed
 
+
 ## [ 0.6.3 ] - [ 2024-04-12 ]
 
 ### Added
-
 - `cpp-linux-x64-release-shared` test job.
 
 ### Changed
-
 - Allow multiple `measure` instructions at the end of a program.
 
 ### Removed
 
+
 ## [ 0.6.2 ] - [ 2024-04-09 ]
 
 ### Added
-
 - `.clang-format`.
 - `emscripten-wasm` assets job.
 
 ### Changed
-
 - Fix shared library build.
 
 ### Removed
-
 - `TREEN_GEN_BUILD_TESTS` option.
 
+
 ## [ 0.6.1 ] - [ 2024-04-08 ]
 
 ### Added
 
 ### Changed
-
 - Fix Python interface.
 - Update GitHub Actions versions.
 
 ### Removed
-
 - `m4` dependency.
 
+
 ## [ 0.6.0 ] - [ 2024-03-28 ]
 
 ### Added
-
 - cQasm 3.0 parser. MVP (Minimum Viable Product) implemented.
 - Conan as package manager.
 
 ### Changed
-
 - Different upgrades: C++20, CMake 3.12, Python 3.8 to 3.12.
 
 ### Removed
-
 - cQasm 1.x support.
 - Git submodules.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 50a80b7d0..9c5764722 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,9 +43,9 @@ option(LIBQASM_BUILD_PYTHON
 )
 mark_as_advanced(LIBQASM_BUILD_PYTHON)
 
-# Where the "libQasm" Python module should be built.
-set(LIBQASM_PYTHON_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/python/libQasm"
-    CACHE STRING "Where to install the libQasm Python module"
+# Where the 'libqasm' Python module should be built.
+set(LIBQASM_PYTHON_DIR "${CMAKE_INSTALL_FULL_LIBDIR}/python/libqasm"
+    CACHE STRING "Where to install the libqasm Python module"
 )
 mark_as_advanced(LIBQASM_PYTHON_DIR)
 
diff --git a/Dockerfile b/Dockerfile
index 926fe8b5c..059b6c352 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -34,7 +34,7 @@ WORKDIR /libqasm-copy
 
 # Build emscripten binaries
 RUN conan profile detect --force && \
-    conan build . -pr=conan/profiles/emscripten -pr:b=conan/profiles/release -b missing && \
+    conan build . -pr=conan/profiles/release-clang-emscripten-wasm -pr:b=conan/profiles/release -b missing && \
     ls -hl build/Release/emscripten
 
 # Rename cqasm_emscripten.js to cqasm_emscripten.mjs
@@ -42,5 +42,5 @@ RUN mv build/Release/emscripten/cqasm_emscripten.js build/Release/emscripten/cqa
 
 # Test emscripten binaries
 RUN cd emscripten && \
-    /root/.deno/bin/deno run -A test_cqasm.ts \
+    /root/.deno/bin/deno run -A test_libqasm.ts \
     cd /
diff --git a/README.md b/README.md
index 60f2636d9..5f10f21fa 100644
--- a/README.md
+++ b/README.md
@@ -64,28 +64,34 @@ in case it cannot find the binary packages for the current configuration (platfo
 
 ### Build profiles
 
-A group of predefined profiles is provided under the `conan/profiles` folder.
-They follow the `[tests-](debug|release)[-compat]` naming convention. For example:
-  - `release` is a Release build without tests and compatibility with the original API.
-  - `tests-debug-compat` is a Debug build with tests and compatibility enabled.
-
-All the profiles set the C++ standard to 20. All the `tests` profiles enable Address Sanitizer.
+A group of predefined profiles is provided under the `conan/profiles` folder.<br/>
+They follow the `[tests](-build_type)(-compiler)(-os)(-arch)[-shared]` naming convention:
+  - `tests`: if tests are being built.
+  - `build_type`: can be `debug` or `release`.
+  - `compiler`: `apple-clang`, `clang`, `gcc`, `msvc`.
+  - `os`: `emscripten`, `linux`, `macos`, `windows`.
+  - `arch`: `arm64`, `wasm`, `x64`.
+  - `shared`: if the library is being built in shared mode.
+
+All the profiles set the C++ standard to 20.<br/>
+All the `tests`, except for `linux-x64` profiles, enable Address Sanitizer.
 
 ### Build options
 
-Profiles are a shorthand for command line options. The command above could be written as well as: 
+Profiles are a shorthand for command line options. The command above could be written, similarly,  as: 
 
 ```
-conan build . -s:h compiler.cppstd=20 -s:h libqasm/*:build_type=Debug -o libqasm/*:build_tests=True -o libqasm/*:asan_enabled=True -b missing
+conan build . -s:a compiler.cppstd=20 -s:a libqasm/*:build_type=Debug -o libqasm/*:build_tests=True -o libqasm/*:asan_enabled=True -b missing
 ```
 
-These are the list of options that could be specified whether in a profile or in the command line:
+This is the list of options that could be specified either in a profile or in the command line:
 
 - `libqasm/*:asan_enabled={True,False}`: enables Address Sanitizer.
-- `libqasm/*:build_tests={True,False}`: builds tests or not.
 - `libqasm/*:build_type={Debug,Release}`: builds in debug or release mode.
 - `libqasm/*:shared={True,False}`: builds a shared object library instead of a static library, if applicable.
 
+Tests are enabled by default. To disable them, use `-c tools.build:skip_test=True`.
+
 ## Install
 
 ### From Python
@@ -107,7 +113,7 @@ python3 -m pytest
 The `CMakeLists.txt` file in the root directory includes install targets:
 
 ```
-conan create --version 0.5.2 . -pr=tests-debug -b missing
+conan create --version 0.6.6 . -pr:a=tests-debug -b missing
 ```
 
 You can test if it works by doing:
@@ -121,30 +127,49 @@ ctest -C Debug --output-on-failure
 
 ### From Python
 
-After installation, you should be able to use the bindings for the original API by just `import libQasm`.
-The new API doesn't have Python bindings yet.
+The `libqasm` module should provide access to the `V3xAnalyzer` API:
+- `parse_file`,
+- `parse_string`,
+- `analyze_file`, and
+- `analyzer_string`.
+
+The `cqasm.v3x` module is also available for a more fine-grained use of the library.
+
+```
+import cqasm.v3x.ast
+import cqasm.v3x.instruction
+import cqasm.v3x.primitives
+import cqasm.v3x.semantic
+import cqasm.v3x.types
+import cqasm.v3x.values
+```
 
 ### From C++
 
-The easiest way to use `libqasm` in a CMake project is to fetch the library and then link against it.
+`libqasm` can be requested as a Conan package from a `conanfile.py`.
+
+```
+def build_requirements(self):
+    self.tool_requires("libqasm/0.6.5")
+def requirements(self):
+    self.requires("libqasm/0.6.5")
+```
+
+And then linked against from a `CMakeLists.txt`: 
 
 ```
-include(FetchContent)
-FetchContent_Declare(cqasm
-    GIT_REPOSITORY https://github.com/QuTech-Delft/libqasm.git
-    GIT_TAG "<a given cqasm git tag>"
-)
-FetchContent_MakeAvailable(cqasm)
-target_include_directories(<your target> SYSTEM PRIVATE "${cqasm_SOURCE_DIR}/include")
-target_link_libraries(<your target> PUBLIC cqasm)
+target_link_libraries(<your target> PUBLIC libqasm::libqasm)
 ```
 
 Note that the following dependency is required for `libqasm` to build:
 
 * `Java JRE` >= 11
 
-The original API headers are *not* included by default.
-To enable those, pass <code><nobr>-o libqasm/*:compat=True</nobr></code> as a build option to Conan.
+The header file `cqasm.hpp` should provide access to the following API:
+- `cqasm::v3x::analyze_file`, and
+- `cqasm::v3x::analyze_string`.
+
+Again, other header files are available for a more fine-grained use of the library.
 
 ## Docker
 
@@ -154,7 +179,7 @@ This tests the library in a container with the bare minimum requirements for `li
 docker build .
 ```
 
-**Note for Windows users:** The above might fail on Windows to the autocrlf transformation that git does.
+**Note for Windows users:** The above might fail on Windows due to the `autocrlf` transformation that git does.
 If you are having trouble with this just create new clone of this repository using:
 
 ```
@@ -166,9 +191,18 @@ git clone --config core.autocrlf=input git@github.com:QuTech-Delft/libqasm.git
 The generation of emscripten binaries has been tested as a cross-compilation from an ubuntu/x64 platform.
 
 ```
-conan build . -pr=conan/profiles/emscripten -pr:b=conan/profiles/release -b missing
+conan build . -pr=conan/profiles/release-clang-emscripten-wasm -pr:b=conan/profiles/release -b missing
 ```
 
 The output of this build lives in `build/Release/emscripten`:
 - `cqasm_emscripten.js`.
 - `cqasm_emscripten.wasm`.
+
+Note that `cqasm_emscripten.js` is an ES6 module. An example of how to use it would be:
+
+```
+cd build/Release/emscripten
+mv cqasm_emscripten.js cqasm_emscripten.mjs
+cd ../../../emscripten
+deno run -A test_libqasm.ts
+```
\ No newline at end of file
diff --git a/conan/profiles/debug b/conan/profiles/debug
index 80299eee8..808a1a9d2 100644
--- a/conan/profiles/debug
+++ b/conan/profiles/debug
@@ -6,7 +6,9 @@ libqasm/*:build_type=Debug
 
 [options]
 libqasm/*:asan_enabled=False
-libqasm/*:build_tests=False
+
+[conf]
+tools.build:skip_test=True
 
 [replace_requires]
 nodejs/*: nodejs/16.20.2
diff --git a/conan/profiles/release b/conan/profiles/release
index d1e826bbd..bbb6c22f6 100644
--- a/conan/profiles/release
+++ b/conan/profiles/release
@@ -6,7 +6,9 @@ libqasm/*:build_type=Release
 
 [options]
 libqasm/*:asan_enabled=False
-libqasm/*:build_tests=False
+
+[conf]
+tools.build:skip_test=True
 
 [replace_requires]
 nodejs/*: nodejs/16.20.2
diff --git a/conan/profiles/emscripten b/conan/profiles/release-clang-emscripten-wasm
similarity index 100%
rename from conan/profiles/emscripten
rename to conan/profiles/release-clang-emscripten-wasm
diff --git a/conanfile.py b/conanfile.py
index 01899028e..016841e53 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -4,34 +4,33 @@
 
 from conan import ConanFile
 from conan.errors import ConanInvalidConfiguration
+from conan.tools.apple import fix_apple_shared_install_name
 from conan.tools.build import check_min_cppstd
 from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake
 from conan.tools.env import VirtualBuildEnv
-from conan.tools.files import copy
+from conan.tools.files import copy, rm
 from conan.tools.scm import Version
 
 from version import get_version
 
+required_conan_version = ">=1.60.0 <2 || >=2.0.6"
+
 
 class LibqasmConan(ConanFile):
     name = "libqasm"
     version = get_version()
-
-    # Optional metadata
     license = "Apache-2.0"
     homepage = "https://github.com/QuTech-Delft/libqasm"
     url = "https://github.com/conan-io/conan-center-index"
     description = "Library to parse cQASM files"
     topics = ("code generation", "parser", "compiler", "quantum compilation", "quantum simulation")
-
-    # Binary configuration
     settings = "os", "compiler", "build_type", "arch"
+    package_type = "library"
     options = {
         "shared": [True, False],
         "fPIC": [True, False],
         "asan_enabled": [True, False],
         "build_python": [True, False],
-        "build_tests": [True, False],
         "cqasm_python_dir": [None, "ANY"],
         "python_dir": [None, "ANY"],
         "python_ext": [None, "ANY"]
@@ -41,29 +40,30 @@ class LibqasmConan(ConanFile):
         "fPIC": True,
         "asan_enabled": False,
         "build_python": False,
-        "build_tests": False,
         "cqasm_python_dir": None,
         "python_dir": None,
         "python_ext": None
     }
-
     exports = "version.py", "include/version.hpp"
     exports_sources = "CMakeLists.txt", "include/*", "python/*", "res/*", "scripts/*", "src/*", "test/*"
 
-    def build_requirements(self):
-        self.tool_requires("tree-gen/1.0.7")
-        self.tool_requires("zulu-openjdk/21.0.1")
-        if self.settings.arch == "wasm":
-            self.tool_requires("emsdk/3.1.50")
-        if self.options.build_tests:
-            self.test_requires("gtest/1.14.0")
+    @property
+    def _should_build_test(self):
+        return not self.conf.get("tools.build:skip_test", default=True, check_type=bool)
 
-    def requirements(self):
-        self.requires("fmt/10.2.1")
-        self.requires("range-v3/0.12.0")
-        self.requires("tree-gen/1.0.7")
-        if not self.settings.arch == "wasm":
-            self.requires("antlr4-cppruntime/4.13.1")
+    @property
+    def _min_cppstd(self):
+        return "20"
+
+    @property
+    def _compilers_minimum_version(self):
+        return {
+            "gcc": "10",
+            "clang": "13",
+            "apple-clang": "14",
+            "Visual Studio": "16",
+            "msvc": "192"
+        }
 
     def config_options(self):
         if self.settings.os == "Windows":
@@ -72,6 +72,8 @@ def config_options(self):
     def configure(self):
         if self.options.shared:
             self.options.rm_safe("fPIC")
+        if self.settings.arch == "wasm":
+            self.options["antlr4-cppruntime"].shared = self.options.shared
 
     def layout(self):
         self.folders.source = "."
@@ -85,6 +87,33 @@ def layout(self):
         self.cpp.source.includedirs = ["include"]
         self.cpp.build.libdirs = ["."]
 
+    def build_requirements(self):
+        self.tool_requires("tree-gen/1.0.7")
+        if self.settings.arch != "armv8":
+            self.tool_requires("zulu-openjdk/21.0.1")
+        if self.settings.arch == "wasm":
+            self.tool_requires("emsdk/3.1.50")
+        if self._should_build_test:
+            self.test_requires("gtest/1.14.0")
+
+    def validate(self):
+        if self.settings.compiler.cppstd:
+            check_min_cppstd(self, self._min_cppstd)
+        minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False)
+        if minimum_version and Version(self.settings.compiler.version) < minimum_version:
+            raise ConanInvalidConfiguration(f"{self.ref} requires C++{self._min_cppstd},"
+                                            f"which your compiler does not support.")
+
+        if self.settings.arch != "wasm" and self.dependencies["antlr4-cppruntime"].options.shared != self.options.shared:
+            raise ConanInvalidConfiguration(f"{self.ref} requires antlr4-cppruntime to be built with the same shared option value.")
+
+    def requirements(self):
+        self.requires("fmt/10.2.1", transitive_headers=True)
+        self.requires("range-v3/0.12.0", transitive_headers=True)
+        self.requires("tree-gen/1.0.7", transitive_headers=True, transitive_libs=True)
+        if not self.settings.arch == "wasm":
+            self.requires("antlr4-cppruntime/4.13.1", transitive_headers=True)
+
     def generate(self):
         deps = CMakeDeps(self)
         deps.generate()
@@ -93,7 +122,7 @@ def generate(self):
         tc.variables["BUILD_SHARED_LIBS"] = self.options.shared
         tc.variables["LIBQASM_BUILD_EMSCRIPTEN"] = self.settings.arch == "wasm"
         tc.variables["LIBQASM_BUILD_PYTHON"] = self.options.build_python
-        tc.variables["LIBQASM_BUILD_TESTS"] = self.options.build_tests
+        tc.variables["LIBQASM_BUILD_TESTS"] = self._should_build_test
         tc.variables["LIBQASM_CQASM_PYTHON_DIR"] = self.options.cqasm_python_dir
         tc.variables["LIBQASM_PYTHON_DIR"] = self.options.python_dir
         tc.variables["LIBQASM_PYTHON_EXT"] = self.options.python_ext
@@ -107,30 +136,12 @@ def build(self):
         cmake.configure()
         cmake.build()
 
-    def validate(self):
-        compiler = self.settings.compiler
-        version = Version(self.settings.compiler.version)
-        if compiler == "apple-clang":
-            if version < "14":
-                raise ConanInvalidConfiguration("libqasm requires at least apple-clang++ 14")
-        elif compiler == "clang":
-            if version < "13":
-                raise ConanInvalidConfiguration("libqasm requires at least clang++ 13")
-        elif compiler == "gcc":
-            if version < "10.0":
-                raise ConanInvalidConfiguration("libqasm requires at least g++ 10.0")
-        elif compiler == "msvc":
-            if version < "19.29":
-                raise ConanInvalidConfiguration("libqasm requires at least msvc 19.29")
-        else:
-            raise ConanInvalidConfiguration("Unsupported compiler")
-        if compiler.get_safe("cppstd"):
-            check_min_cppstd(self, "20")
-
     def package(self):
         copy(self, "LICENSE.md", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
         cmake = CMake(self)
         cmake.install()
+        fix_apple_shared_install_name(self)
+        rm(self, "*.pdb", self.package_folder, recursive=True)
 
     def package_info(self):
         self.cpp_info.libs = ["cqasm"]
diff --git a/include/v3x/AnalyzeTreeGenAstVisitor.hpp b/include/v3x/AnalyzeTreeGenAstVisitor.hpp
index 393c43cc6..228c65928 100644
--- a/include/v3x/AnalyzeTreeGenAstVisitor.hpp
+++ b/include/v3x/AnalyzeTreeGenAstVisitor.hpp
@@ -96,9 +96,27 @@ class AnalyzeTreeGenAstVisitor : public ast::Visitor<std::any> {
         if (type_name == types::qubit_type_name) {
             return build_semantic_type<types::Qubit, types::QubitArray>(*type, types::qubit_type_name);
         }
+        if (type_name == types::bit_type_name) {
+            return build_semantic_type<types::Bit, types::BitArray>(*type, types::bit_type_name);
+        }
         throw error::AnalysisError("unknown type \"" + type_name + "\"");
     }
 
+    /**
+     * Convenience function for visiting a global or a local block
+     */
+    template <typename Block>
+    void visit_block(Block &block) {
+        for (const auto &statement_ast : block.statements) {
+            try {
+                statement_ast->visit(*this);
+            } catch (error::AnalysisError &err) {
+                err.context(block);
+                result_.errors.push_back(std::move(err));
+            }
+        }
+    }
+
     /**
      * Convenience function for visiting a function call given the function's name and arguments
      */
diff --git a/include/v3x/BuildTreeGenAstVisitor.hpp b/include/v3x/BuildTreeGenAstVisitor.hpp
index 031e00059..7d315b908 100644
--- a/include/v3x/BuildTreeGenAstVisitor.hpp
+++ b/include/v3x/BuildTreeGenAstVisitor.hpp
@@ -59,20 +59,17 @@ class BuildTreeGenAstVisitor : public BuildCustomAstVisitor {
 public:
     std::any visitProgram(CqasmParser::ProgramContext *context) override;
     std::any visitVersionSection(CqasmParser::VersionSectionContext *context) override;
-    std::any visitBodySection(CqasmParser::BodySectionContext *context) override;
-    std::any visitVariableDeclarationSection(CqasmParser::VariableDeclarationSectionContext *context) override;
-    std::any visitInstructionsSection(CqasmParser::InstructionsSectionContext *context) override;
-    std::any visitGatesSection(CqasmParser::GatesSectionContext *context) override;
-    std::any visitMeasureInstructionsSection(CqasmParser::MeasureInstructionsSectionContext *context) override;
+    std::any visitGlobalBlockSection(CqasmParser::GlobalBlockSectionContext *context) override;
     std::any visitEofSection(CqasmParser::EofSectionContext *context) override;
     std::any visitStatementSeparator(CqasmParser::StatementSeparatorContext *context) override;
     std::any visitVersion(CqasmParser::VersionContext *context) override;
-    std::any visitVariableDeclaration(CqasmParser::VariableDeclarationContext *context) override;
+    std::any visitGlobalBlockStatement(CqasmParser::GlobalBlockStatementContext *context) override;
     std::any visitVariableDefinition(CqasmParser::VariableDefinitionContext *context) override;
-    std::any visitGate(CqasmParser::GateContext *context) override;
     std::any visitMeasureInstruction(CqasmParser::MeasureInstructionContext *context) override;
+    std::any visitGate(CqasmParser::GateContext *context) override;
     std::any visitType(CqasmParser::TypeContext *context) override;
     std::any visitQubitType(CqasmParser::QubitTypeContext *context) override;
+    std::any visitBitType(CqasmParser::BitTypeContext *context) override;
     std::any visitArraySizeDeclaration(CqasmParser::ArraySizeDeclarationContext *context) override;
     std::any visitExpressionList(CqasmParser::ExpressionListContext *context) override;
     std::any visitIndexList(CqasmParser::IndexListContext *context) override;
diff --git a/include/v3x/cqasm-types.hpp b/include/v3x/cqasm-types.hpp
index 33615cbbf..58bf1ee94 100644
--- a/include/v3x/cqasm-types.hpp
+++ b/include/v3x/cqasm-types.hpp
@@ -16,10 +16,12 @@
 namespace cqasm::v3x::types {
 
 constexpr const char *qubit_type_name = "qubit";
+constexpr const char *bit_type_name = "bit";
 constexpr const char *bool_type_name = "bool";
 constexpr const char *integer_type_name = "int";
 constexpr const char *float_type_name = "float";
 constexpr const char *qubit_array_type_name = "qubit array";
+constexpr const char *bit_array_type_name = "bit array";
 
 /**
  * A cQASM type.
diff --git a/include/version.hpp b/include/version.hpp
index 3c5f21e46..78ec363b3 100644
--- a/include/version.hpp
+++ b/include/version.hpp
@@ -2,7 +2,7 @@
 
 namespace cqasm {
 
-static const char *version{ "0.6.5" };
+static const char *version{ "0.6.6" };
 static const char *release_year{ "2024" };
 
 [[nodiscard]] [[maybe_unused]] static const char *get_version() {
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index ca422c5b9..ff0f237b4 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -95,7 +95,7 @@ set(CMAKE_CXX_EXTENSIONS OFF)
 
 # Configure SWIG.
 set(SWIG_FILE
-    "${CMAKE_CURRENT_SOURCE_DIR}/libQasm.i"
+    "${CMAKE_CURRENT_SOURCE_DIR}/libqasm.i"
 )
 
 set_source_files_properties("${SWIG_FILE}" PROPERTIES
@@ -108,7 +108,7 @@ set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}")
 
 # Run SWIG to generated the C++ source file and Python wrapper module.
 swig_add_library(
-    libQasm
+    libqasm
     TYPE MODULE
     LANGUAGE python
     SOURCES "${SWIG_FILE}"
@@ -116,14 +116,14 @@ swig_add_library(
 
 # Compile the C++ source file and link it against the cqasm library.
 if(WIN32)
-    swig_link_libraries(libQasm "${PYTHON_LIBRARIES}" cqasm)
+    swig_link_libraries(libqasm "${PYTHON_LIBRARIES}" cqasm)
 else()
-    swig_link_libraries(libQasm cqasm)
+    swig_link_libraries(libqasm cqasm)
 endif()
 if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
-    set_target_properties(_libQasm PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
+    set_target_properties(_libqasm PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
 endif()
-target_include_directories(_libQasm PRIVATE "${PYTHON_INCLUDE_DIRS}")
+target_include_directories(_libqasm PRIVATE "${PYTHON_INCLUDE_DIRS}")
 
 
 #=============================================================================#
@@ -133,12 +133,12 @@ target_include_directories(_libQasm PRIVATE "${PYTHON_INCLUDE_DIRS}")
 # Install the shared object (*.pyd on Windows).
 if("${LIBQASM_PYTHON_EXT}" STREQUAL "")
     install(
-        TARGETS _libQasm
+        TARGETS _libqasm
         LIBRARY DESTINATION "${LIBQASM_PYTHON_DIR}"
     )
 else()
     install(
-        FILES "$<TARGET_FILE:_libQasm>"
+        FILES "$<TARGET_FILE:_libqasm>"
         DESTINATION "${LIBQASM_PYTHON_DIR}"
         RENAME "${LIBQASM_PYTHON_EXT}"
     )
@@ -146,7 +146,7 @@ endif()
 
 # Install the generated files.
 install(
-    FILES "${CMAKE_SWIG_OUTDIR}/libQasm.py"
+    FILES "${CMAKE_SWIG_OUTDIR}/libqasm.py"
     DESTINATION "${LIBQASM_PYTHON_DIR}"
 )
 install(
diff --git a/python/README.md b/python/README.md
index 61f077657..e7d1693d6 100644
--- a/python/README.md
+++ b/python/README.md
@@ -7,8 +7,8 @@ File/directory list:
  - `CMakeLists.txt`: SWIG and the Python extension build are handled by CMake, so it can link everything together properly.
    Don't use this file directly. It is intended to be added by the root `CMakeLists.txt`, and only when the build is orchestrated by `setup.py`.
 
- - `libQasm`: represents the Python module excluding the extension. Any Python files in here will be included in the Python install.
+ - `libqasm`: represents the Python module excluding the extension. Any Python files in here will be included in the Python install.
 
- - `libQasm.i`: SWIG directives for the bindings.
+ - `libqasm.i`: SWIG directives for the bindings.
 
  - `python_lib.py`: helper script for CMake to find the Python library to link against, because `FindPYTHON` often picks the wrong one, especially in virtual environments.
\ No newline at end of file
diff --git a/python/libQasm.i b/python/libqasm.i
similarity index 94%
rename from python/libQasm.i
rename to python/libqasm.i
index 9475e86e2..957c66ebc 100644
--- a/python/libQasm.i
+++ b/python/libqasm.i
@@ -1,5 +1,5 @@
-/* libQasm_swig.i */
-%module libQasm
+/* libqasm.i */
+%module libqasm
 
 %begin %{
 #ifdef _MSC_VER
diff --git a/python/module/cqasm/v3x/__init__.py b/python/module/cqasm/v3x/__init__.py
index 7cbfe6b02..7891e5552 100644
--- a/python/module/cqasm/v3x/__init__.py
+++ b/python/module/cqasm/v3x/__init__.py
@@ -1,9 +1,9 @@
 import cqasm.v3x.ast as ast
 import cqasm.v3x.semantic as semantic
-import libQasm
+import libqasm
 
 
-class Analyzer(libQasm.V3xAnalyzer):
+class Analyzer(libqasm.V3xAnalyzer):
     # parse_file and parse_string are static methods because they do not change the status of the analyzer
     # Instead, they just invoke free functions that create a temporary instance of a parser
     # analyze_file and analyze_string are not static methods because they change the status of the analyzer
@@ -14,7 +14,7 @@ class Analyzer(libQasm.V3xAnalyzer):
 
     @staticmethod
     def parse_file(*args):
-        ret = libQasm.V3xAnalyzer.parse_file(*args)
+        ret = libqasm.V3xAnalyzer.parse_file(*args)
         if len(ret) == 1:
             serialized_ast_str = str(ret[0])
             serialized_ast_bytes = serialized_ast_str.encode(encoding='utf-8', errors="surrogateescape")
@@ -24,7 +24,7 @@ def parse_file(*args):
 
     @staticmethod
     def parse_string(*args):
-        ret = libQasm.V3xAnalyzer.parse_string(*args)
+        ret = libqasm.V3xAnalyzer.parse_string(*args)
         if len(ret) == 1:
             serialized_ast_str = str(ret[0])
             serialized_ast_bytes = serialized_ast_str.encode(encoding='utf-8', errors="surrogateescape")
@@ -52,11 +52,11 @@ def analyze_string(self, *args):
 
     @staticmethod
     def parse_file_to_json(*args):
-        return libQasm.V3xAnalyzer.parse_file_to_json(*args)
+        return libqasm.V3xAnalyzer.parse_file_to_json(*args)
 
     @staticmethod
     def parse_string_to_json(*args):
-        return libQasm.V3xAnalyzer.parse_string_to_json(*args)
+        return libqasm.V3xAnalyzer.parse_string_to_json(*args)
 
     def analyze_file_to_json(self, *args):
         return super().analyze_file_to_json(*args)
diff --git a/python/module/libQasm/__init__.py b/python/module/libqasm/__init__.py
similarity index 96%
rename from python/module/libQasm/__init__.py
rename to python/module/libqasm/__init__.py
index 328c53af0..e9ecb8fca 100644
--- a/python/module/libQasm/__init__.py
+++ b/python/module/libqasm/__init__.py
@@ -20,6 +20,6 @@
 del version_info
 
 # Import the SWIG-generated module.
-from .libQasm import *
+from .libqasm import *
 
 # __all__ = [ init, schedule, compile ]
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_0_b/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_0_b/ast.golden.txt
new file mode 100644
index 000000000..7af64613f
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_0_b/ast.golden.txt
@@ -0,0 +1,37 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 0
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/measure_q/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_0_b/input.cq
similarity index 52%
rename from res/v3x/parsing/measure_instruction/measure_q/input.cq
rename to res/v3x/parsing/bit_array_definition/bit_array_of_0_b/input.cq
index e35adeb5f..efec0fc4d 100644
--- a/res/v3x/parsing/measure_instruction/measure_q/input.cq
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_0_b/input.cq
@@ -1,3 +1,3 @@
 version 3
 
-measure q
+bit[0] b
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_0_b/semantic.3.0.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_0_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..727b7c702
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_0_b/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:8..9: found bit array of size <= 0
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_123abc/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_123abc/ast.golden.txt
new file mode 100644
index 000000000..3a53d2e81
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_123abc/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:8..11: extraneous input 'abc' expecting ']'
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_123abc/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_123abc/input.cq
new file mode 100644
index 000000000..50601b9ef
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_123abc/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[123abc]
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17/ast.golden.txt
new file mode 100644
index 000000000..99ed747f6
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:8..9: missing IDENTIFIER at '\n'
diff --git a/res/v3x/parsing/measure_instruction/measure_42/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_17/input.cq
similarity index 50%
rename from res/v3x/parsing/measure_instruction/measure_42/input.cq
rename to res/v3x/parsing/bit_array_definition/bit_array_of_17/input.cq
index 05a79ebd5..072e0f1d8 100644
--- a/res/v3x/parsing/measure_instruction/measure_42/input.cq
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17/input.cq
@@ -1,3 +1,3 @@
 version 3
 
-measure 42
+bit[17]
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_1/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_1/ast.golden.txt
new file mode 100644
index 000000000..66696ca45
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_1/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:9..10: mismatched input '1' expecting IDENTIFIER
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_1/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_17_1/input.cq
new file mode 100644
index 000000000..247545713
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_1/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[17] 1
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_3.14/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_3.14/ast.golden.txt
new file mode 100644
index 000000000..30d1795d0
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_3.14/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:9..13: mismatched input '3.14' expecting IDENTIFIER
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_3.14/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_17_3.14/input.cq
new file mode 100644
index 000000000..5f609c86d
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_3.14/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[17] 3.14
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b/ast.golden.txt
new file mode 100644
index 000000000..df2dc224c
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b/ast.golden.txt
@@ -0,0 +1,37 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:9..10
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..8
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 17
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b/input.cq
new file mode 100644
index 000000000..916390411
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[17] b
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b/semantic.3.0.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..033e79eba
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b/semantic.3.0.golden.txt
@@ -0,0 +1,26 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: [
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 17
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_b1/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_b1/ast.golden.txt
new file mode 100644
index 000000000..7c889b57b
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_b1/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:12..14: extraneous input 'b1' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_b1/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_b1/input.cq
new file mode 100644
index 000000000..7ecf09e0d
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_b1/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[17] b0 b1
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_comma_b1/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_comma_b1/ast.golden.txt
new file mode 100644
index 000000000..d629f4176
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_comma_b1/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:11..12: mismatched input ',' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_comma_b1/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_comma_b1/input.cq
new file mode 100644
index 000000000..69eab3828
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b0_comma_b1/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[17] b0, b1
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/ast.golden.txt
new file mode 100644
index 000000000..5205a2906
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/ast.golden.txt
@@ -0,0 +1,59 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:9..10
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..8
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 17
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:9..10
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..8
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 17
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/input.cq
new file mode 100644
index 000000000..fbe7f1a9e
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/input.cq
@@ -0,0 +1,4 @@
+version 3
+
+bit[17] b
+bit[17] b
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/semantic.3.0.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..aef0a6d4b
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b__bit_array_of_17_b/semantic.3.0.golden.txt
@@ -0,0 +1,35 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: [
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 17
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 17
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b_at_0/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b_at_0/ast.golden.txt
new file mode 100644
index 000000000..c915727b3
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b_at_0/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:10..11: mismatched input '[' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_b_at_0/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b_at_0/input.cq
new file mode 100644
index 000000000..ddcad7800
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_b_at_0/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[17] b[0]
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_equal/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_17_equal/ast.golden.txt
new file mode 100644
index 000000000..a0feee839
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_equal/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:9..10: mismatched input '=' expecting IDENTIFIER
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_17_equal/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_17_equal/input.cq
new file mode 100644
index 000000000..98ace8b44
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_17_equal/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[17] =
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_3.14/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_3.14/ast.golden.txt
new file mode 100644
index 000000000..a7bcdba54
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_3.14/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:5..9: mismatched input '3.14' expecting INTEGER_LITERAL
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_3.14/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_3.14/input.cq
new file mode 100644
index 000000000..48ca531f4
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_3.14/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[3.14]
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_b/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_b/ast.golden.txt
new file mode 100644
index 000000000..f20eb2410
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_b/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:5..6: mismatched input 'b' expecting INTEGER_LITERAL
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_b/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_b/input.cq
new file mode 100644
index 000000000..78126cf5e
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_b/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[b]
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_equal/ast.golden.txt b/res/v3x/parsing/bit_array_definition/bit_array_of_equal/ast.golden.txt
new file mode 100644
index 000000000..8baf9b3dc
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_equal/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:5..6: mismatched input '=' expecting INTEGER_LITERAL
diff --git a/res/v3x/parsing/bit_array_definition/bit_array_of_equal/input.cq b/res/v3x/parsing/bit_array_definition/bit_array_of_equal/input.cq
new file mode 100644
index 000000000..f614b18db
--- /dev/null
+++ b/res/v3x/parsing/bit_array_definition/bit_array_of_equal/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit[=]
diff --git a/res/v3x/parsing/bit_definition/bbit_b/ast.golden.txt b/res/v3x/parsing/bit_definition/bbit_b/ast.golden.txt
new file mode 100644
index 000000000..ca1fd75d9
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bbit_b/ast.golden.txt
@@ -0,0 +1,32 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Gate( # input.cq:3:1..4
+          name: <
+            Identifier(
+              name: Bit
+            )
+          >
+          operands: <
+            ExpressionList(
+              items: [
+                Identifier( # input.cq:3:5..6
+                  name: b
+                )
+              ]
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/bit_definition/bbit_b/input.cq b/res/v3x/parsing/bit_definition/bbit_b/input.cq
new file mode 100644
index 000000000..4334239f7
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bbit_b/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+Bit b
diff --git a/res/v3x/parsing/bit_definition/bbit_b/semantic.3.0.golden.txt b/res/v3x/parsing/bit_definition/bbit_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..69d4fae00
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bbit_b/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:5..6: failed to resolve variable 'b'
diff --git a/res/v3x/parsing/bit_definition/bit/ast.golden.txt b/res/v3x/parsing/bit_definition/bit/ast.golden.txt
new file mode 100644
index 000000000..ee42cb07c
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:4..5: missing IDENTIFIER at '\n'
diff --git a/res/v3x/parsing/bit_definition/bit/input.cq b/res/v3x/parsing/bit_definition/bit/input.cq
new file mode 100644
index 000000000..4d4e341bb
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit
diff --git a/res/v3x/parsing/bit_definition/bit_1/ast.golden.txt b/res/v3x/parsing/bit_definition/bit_1/ast.golden.txt
new file mode 100644
index 000000000..8ce02f5fc
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_1/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:5..6: mismatched input '1' expecting IDENTIFIER
diff --git a/res/v3x/parsing/bit_definition/bit_1/input.cq b/res/v3x/parsing/bit_definition/bit_1/input.cq
new file mode 100644
index 000000000..cc390266f
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_1/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit 1
diff --git a/res/v3x/parsing/bit_definition/bit_123abc/ast.golden.txt b/res/v3x/parsing/bit_definition/bit_123abc/ast.golden.txt
new file mode 100644
index 000000000..b3c60bc43
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_123abc/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:5..8: extraneous input '123' expecting IDENTIFIER
diff --git a/res/v3x/parsing/bit_definition/bit_123abc/input.cq b/res/v3x/parsing/bit_definition/bit_123abc/input.cq
new file mode 100644
index 000000000..e085516c0
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_123abc/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit 123abc
diff --git a/res/v3x/parsing/bit_definition/bit_3.14/ast.golden.txt b/res/v3x/parsing/bit_definition/bit_3.14/ast.golden.txt
new file mode 100644
index 000000000..29447b5fe
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_3.14/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:5..9: mismatched input '3.14' expecting IDENTIFIER
diff --git a/res/v3x/parsing/bit_definition/bit_3.14/input.cq b/res/v3x/parsing/bit_definition/bit_3.14/input.cq
new file mode 100644
index 000000000..85e83f412
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_3.14/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit 3.14
diff --git a/res/v3x/parsing/bit_definition/bit_b/ast.golden.txt b/res/v3x/parsing/bit_definition/bit_b/ast.golden.txt
new file mode 100644
index 000000000..a84c383dc
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b/ast.golden.txt
@@ -0,0 +1,33 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:5..6
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..4
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/bit_definition/bit_b/input.cq b/res/v3x/parsing/bit_definition/bit_b/input.cq
new file mode 100644
index 000000000..065390b90
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit b
diff --git a/res/v3x/parsing/bit_definition/bit_b/semantic.3.0.golden.txt b/res/v3x/parsing/bit_definition/bit_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..7d8452f14
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b/semantic.3.0.golden.txt
@@ -0,0 +1,26 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: [
+    Variable(
+      name: b
+      typ: <
+        Bit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/bit_definition/bit_b0_b1/ast.golden.txt b/res/v3x/parsing/bit_definition/bit_b0_b1/ast.golden.txt
new file mode 100644
index 000000000..d74446c54
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b0_b1/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:8..10: extraneous input 'b1' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/bit_definition/bit_b0_b1/input.cq b/res/v3x/parsing/bit_definition/bit_b0_b1/input.cq
new file mode 100644
index 000000000..20b2cca5a
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b0_b1/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit b0 b1
diff --git a/res/v3x/parsing/bit_definition/bit_b0_comma_b1/ast.golden.txt b/res/v3x/parsing/bit_definition/bit_b0_comma_b1/ast.golden.txt
new file mode 100644
index 000000000..1373c5159
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b0_comma_b1/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:7..8: mismatched input ',' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/bit_definition/bit_b0_comma_b1/input.cq b/res/v3x/parsing/bit_definition/bit_b0_comma_b1/input.cq
new file mode 100644
index 000000000..cb4bd2aaa
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b0_comma_b1/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit b0, b1
diff --git a/res/v3x/parsing/bit_definition/bit_b__bit_b/ast.golden.txt b/res/v3x/parsing/bit_definition/bit_b__bit_b/ast.golden.txt
new file mode 100644
index 000000000..17c4a971d
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b__bit_b/ast.golden.txt
@@ -0,0 +1,51 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:5..6
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..4
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:5..6
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..4
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/bit_definition/bit_b__bit_b/input.cq b/res/v3x/parsing/bit_definition/bit_b__bit_b/input.cq
new file mode 100644
index 000000000..c8e3b1e7b
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b__bit_b/input.cq
@@ -0,0 +1,4 @@
+version 3
+
+bit b
+bit b
diff --git a/res/v3x/parsing/bit_definition/bit_b__bit_b/semantic.3.0.golden.txt b/res/v3x/parsing/bit_definition/bit_b__bit_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..32f860fd9
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b__bit_b/semantic.3.0.golden.txt
@@ -0,0 +1,35 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: [
+    Variable(
+      name: b
+      typ: <
+        Bit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        Bit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/bit_definition/bit_b_at_0/ast.golden.txt b/res/v3x/parsing/bit_definition/bit_b_at_0/ast.golden.txt
new file mode 100644
index 000000000..25c34cbab
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b_at_0/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:6..7: mismatched input '[' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/bit_definition/bit_b_at_0/input.cq b/res/v3x/parsing/bit_definition/bit_b_at_0/input.cq
new file mode 100644
index 000000000..f00d79a56
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_b_at_0/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit b[0]
diff --git a/res/v3x/parsing/bit_definition/bit_equal/ast.golden.txt b/res/v3x/parsing/bit_definition/bit_equal/ast.golden.txt
new file mode 100644
index 000000000..bdafdaccf
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_equal/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:5..6: mismatched input '=' expecting IDENTIFIER
diff --git a/res/v3x/parsing/bit_definition/bit_equal/input.cq b/res/v3x/parsing/bit_definition/bit_equal/input.cq
new file mode 100644
index 000000000..410fea496
--- /dev/null
+++ b/res/v3x/parsing/bit_definition/bit_equal/input.cq
@@ -0,0 +1,3 @@
+version 3
+
+bit =
diff --git a/res/v3x/parsing/case_sensitiveness/eu_uppercase/ast.golden.txt b/res/v3x/parsing/case_sensitiveness/eu_uppercase/ast.golden.txt
index c55994d6a..815279ab6 100644
--- a/res/v3x/parsing/case_sensitiveness/eu_uppercase/ast.golden.txt
+++ b/res/v3x/parsing/case_sensitiveness/eu_uppercase/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..3
           name: <
             Identifier(
@@ -49,7 +47,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/case_sensitiveness/pi_uppercase/ast.golden.txt b/res/v3x/parsing/case_sensitiveness/pi_uppercase/ast.golden.txt
index 4bc6425af..0d1894080 100644
--- a/res/v3x/parsing/case_sensitiveness/pi_uppercase/ast.golden.txt
+++ b/res/v3x/parsing/case_sensitiveness/pi_uppercase/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..3
           name: <
             Identifier(
@@ -49,7 +47,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/case_sensitiveness/q_uppercase/ast.golden.txt b/res/v3x/parsing/case_sensitiveness/q_uppercase/ast.golden.txt
index 6e74ef2ec..7eca5f98a 100644
--- a/res/v3x/parsing/case_sensitiveness/q_uppercase/ast.golden.txt
+++ b/res/v3x/parsing/case_sensitiveness/q_uppercase/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..2
           name: <
             Identifier(
@@ -46,7 +44,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/case_sensitiveness/qubit_all_uppercase/ast.golden.txt b/res/v3x/parsing/case_sensitiveness/qubit_all_uppercase/ast.golden.txt
index 1faae6e60..332b2f049 100644
--- a/res/v3x/parsing/case_sensitiveness/qubit_all_uppercase/ast.golden.txt
+++ b/res/v3x/parsing/case_sensitiveness/qubit_all_uppercase/ast.golden.txt
@@ -1,2 +1,32 @@
-ERROR
-Error at input.cq:3:1..6: no viable alternative at input '\n\nQUBIT'
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Gate( # input.cq:3:1..6
+          name: <
+            Identifier(
+              name: QUBIT
+            )
+          >
+          operands: <
+            ExpressionList(
+              items: [
+                Identifier( # input.cq:3:7..8
+                  name: q
+                )
+              ]
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/case_sensitiveness/qubit_camel_case/ast.golden.txt b/res/v3x/parsing/case_sensitiveness/qubit_camel_case/ast.golden.txt
index 7b3568bc4..33c35bdb3 100644
--- a/res/v3x/parsing/case_sensitiveness/qubit_camel_case/ast.golden.txt
+++ b/res/v3x/parsing/case_sensitiveness/qubit_camel_case/ast.golden.txt
@@ -1,2 +1,32 @@
-ERROR
-Error at input.cq:3:1..6: no viable alternative at input '\n\nQubit'
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Gate( # input.cq:3:1..6
+          name: <
+            Identifier(
+              name: Qubit
+            )
+          >
+          operands: <
+            ExpressionList(
+              items: [
+                Identifier( # input.cq:3:7..8
+                  name: q
+                )
+              ]
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/case_sensitiveness/tau_uppercase/ast.golden.txt b/res/v3x/parsing/case_sensitiveness/tau_uppercase/ast.golden.txt
index f542e8f9c..7a3a2ed1d 100644
--- a/res/v3x/parsing/case_sensitiveness/tau_uppercase/ast.golden.txt
+++ b/res/v3x/parsing/case_sensitiveness/tau_uppercase/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..3
           name: <
             Identifier(
@@ -49,7 +47,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/case_sensitiveness/x_lowercase/ast.golden.txt b/res/v3x/parsing/case_sensitiveness/x_lowercase/ast.golden.txt
index e35ed0539..48d39ae0a 100644
--- a/res/v3x/parsing/case_sensitiveness/x_lowercase/ast.golden.txt
+++ b/res/v3x/parsing/case_sensitiveness/x_lowercase/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..2
           name: <
             Identifier(
@@ -46,7 +44,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/comments/multi_line/ast.golden.txt b/res/v3x/parsing/comments/multi_line/ast.golden.txt
index 48331a4b4..9062b4184 100644
--- a/res/v3x/parsing/comments/multi_line/ast.golden.txt
+++ b/res/v3x/parsing/comments/multi_line/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/comments/multi_line/semantic.3.0.golden.txt b/res/v3x/parsing/comments/multi_line/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/comments/multi_line/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/comments/multi_line/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/comments/multi_line_then_error/ast.golden.txt b/res/v3x/parsing/comments/multi_line_then_error/ast.golden.txt
index e54561605..23c26d878 100644
--- a/res/v3x/parsing/comments/multi_line_then_error/ast.golden.txt
+++ b/res/v3x/parsing/comments/multi_line_then_error/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:5:1..5: no viable alternative at input '\n\n\nblah'
+Error at input.cq:5:5..6: no viable alternative at input 'blah\n'
diff --git a/res/v3x/parsing/comments/multi_line_within_single_line/ast.golden.txt b/res/v3x/parsing/comments/multi_line_within_single_line/ast.golden.txt
index 48331a4b4..9062b4184 100644
--- a/res/v3x/parsing/comments/multi_line_within_single_line/ast.golden.txt
+++ b/res/v3x/parsing/comments/multi_line_within_single_line/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/comments/multi_line_within_single_line/semantic.3.0.golden.txt b/res/v3x/parsing/comments/multi_line_within_single_line/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/comments/multi_line_within_single_line/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/comments/multi_line_within_single_line/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/comments/open_multi_line_within_single_line/ast.golden.txt b/res/v3x/parsing/comments/open_multi_line_within_single_line/ast.golden.txt
index 48331a4b4..9062b4184 100644
--- a/res/v3x/parsing/comments/open_multi_line_within_single_line/ast.golden.txt
+++ b/res/v3x/parsing/comments/open_multi_line_within_single_line/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/comments/open_multi_line_within_single_line/semantic.3.0.golden.txt b/res/v3x/parsing/comments/open_multi_line_within_single_line/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/comments/open_multi_line_within_single_line/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/comments/open_multi_line_within_single_line/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/comments/single_line/ast.golden.txt b/res/v3x/parsing/comments/single_line/ast.golden.txt
index 48331a4b4..9062b4184 100644
--- a/res/v3x/parsing/comments/single_line/ast.golden.txt
+++ b/res/v3x/parsing/comments/single_line/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/comments/single_line/semantic.3.0.golden.txt b/res/v3x/parsing/comments/single_line/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/comments/single_line/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/comments/single_line/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/comments/single_line_and_multi_line_before_version/ast.golden.txt b/res/v3x/parsing/comments/single_line_and_multi_line_before_version/ast.golden.txt
index f36b4f959..e11173c0f 100644
--- a/res/v3x/parsing/comments/single_line_and_multi_line_before_version/ast.golden.txt
+++ b/res/v3x/parsing/comments/single_line_and_multi_line_before_version/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/comments/single_line_and_multi_line_before_version/semantic.3.0.golden.txt b/res/v3x/parsing/comments/single_line_and_multi_line_before_version/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/comments/single_line_and_multi_line_before_version/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/comments/single_line_and_multi_line_before_version/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/comments/single_line_then_error/ast.golden.txt b/res/v3x/parsing/comments/single_line_then_error/ast.golden.txt
index 1a7b84de5..b5090eb1f 100644
--- a/res/v3x/parsing/comments/single_line_then_error/ast.golden.txt
+++ b/res/v3x/parsing/comments/single_line_then_error/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:4:1..5: no viable alternative at input '\n\n\nblah'
+Error at input.cq:4:5: no viable alternative at input 'blah'
diff --git a/res/v3x/parsing/comments/single_line_within_multi_line/ast.golden.txt b/res/v3x/parsing/comments/single_line_within_multi_line/ast.golden.txt
index 48331a4b4..9062b4184 100644
--- a/res/v3x/parsing/comments/single_line_within_multi_line/ast.golden.txt
+++ b/res/v3x/parsing/comments/single_line_within_multi_line/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/comments/single_line_within_multi_line/semantic.3.0.golden.txt b/res/v3x/parsing/comments/single_line_within_multi_line/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/comments/single_line_within_multi_line/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/comments/single_line_within_multi_line/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_eu_q/ast.golden.txt b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_eu_q/ast.golden.txt
index 65f5037fb..4a07c1f66 100644
--- a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_eu_q/ast.golden.txt
+++ b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_eu_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..3
           name: <
             Identifier(
@@ -49,7 +47,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_eu_q/semantic.3.0.golden.txt b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_eu_q/semantic.3.0.golden.txt
index 9138b637f..cf028725c 100644
--- a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_eu_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_eu_q/semantic.3.0.golden.txt
@@ -6,17 +6,6 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        Qubit(
-          size: 1
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
@@ -46,5 +35,16 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_pi_q/ast.golden.txt b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_pi_q/ast.golden.txt
index a2c8cfb5b..82c3760df 100644
--- a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_pi_q/ast.golden.txt
+++ b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_pi_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..3
           name: <
             Identifier(
@@ -49,7 +47,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_pi_q/semantic.3.0.golden.txt b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_pi_q/semantic.3.0.golden.txt
index 1fc6e616e..460d8b3d9 100644
--- a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_pi_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_pi_q/semantic.3.0.golden.txt
@@ -6,17 +6,6 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        Qubit(
-          size: 1
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
@@ -46,5 +35,16 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_tau_q/ast.golden.txt b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_tau_q/ast.golden.txt
index f2d4d317a..ef7b32872 100644
--- a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_tau_q/ast.golden.txt
+++ b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_tau_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..3
           name: <
             Identifier(
@@ -49,7 +47,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_tau_q/semantic.3.0.golden.txt b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_tau_q/semantic.3.0.golden.txt
index d4a338d9f..d23d68789 100644
--- a/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_tau_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/eu_pi_tau/qubit_q__Rx_tau_q/semantic.3.0.golden.txt
@@ -6,17 +6,6 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        Qubit(
-          size: 1
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
@@ -46,5 +35,16 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/expression/out_of_bounds_index/ast.golden.txt b/res/v3x/parsing/expression/out_of_bounds_index/ast.golden.txt
index 483d57ec5..cefc76f56 100644
--- a/res/v3x/parsing/expression/out_of_bounds_index/ast.golden.txt
+++ b/res/v3x/parsing/expression/out_of_bounds_index/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:10..11
           name: <
             Identifier(
@@ -30,8 +30,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..2
           name: <
             Identifier(
@@ -67,7 +65,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/expression/out_of_range_float_literal/ast.golden.txt b/res/v3x/parsing/expression/out_of_range_float_literal/ast.golden.txt
index f9fea0bf7..8b75c1137 100644
--- a/res/v3x/parsing/expression/out_of_range_float_literal/ast.golden.txt
+++ b/res/v3x/parsing/expression/out_of_range_float_literal/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:1..2: no viable alternative at input '\n\nX'
+Error at input.cq:3:3: value '1.79769313486231570e+309' is out of the FLOAT_LITERAL range
diff --git a/res/v3x/parsing/expression/out_of_range_integer_literal/ast.golden.txt b/res/v3x/parsing/expression/out_of_range_integer_literal/ast.golden.txt
index f9fea0bf7..1f9c434d6 100644
--- a/res/v3x/parsing/expression/out_of_range_integer_literal/ast.golden.txt
+++ b/res/v3x/parsing/expression/out_of_range_integer_literal/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:1..2: no viable alternative at input '\n\nX'
+Error at input.cq:3:3: value '18446744073709551616' is out of the INTEGER_LITERAL range
diff --git a/res/v3x/parsing/expression_list/bad_first_part/ast.golden.txt b/res/v3x/parsing/expression_list/bad_first_part/ast.golden.txt
index df9d2e68e..1b6507387 100644
--- a/res/v3x/parsing/expression_list/bad_first_part/ast.golden.txt
+++ b/res/v3x/parsing/expression_list/bad_first_part/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:7:12..13: extraneous input ',' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}
+Error at input.cq:7:9..12: mismatched input 'abc' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/expression_list/bad_second_part/ast.golden.txt b/res/v3x/parsing/expression_list/bad_second_part/ast.golden.txt
index 5de0e2b2f..83d745692 100644
--- a/res/v3x/parsing/expression_list/bad_second_part/ast.golden.txt
+++ b/res/v3x/parsing/expression_list/bad_second_part/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:7:18..19: mismatched input '\n' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}
+Error at input.cq:7:15..18: extraneous input 'abc' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/instruction/X/ast.golden.txt b/res/v3x/parsing/instruction/X/ast.golden.txt
index f9fea0bf7..3e48a794f 100644
--- a/res/v3x/parsing/instruction/X/ast.golden.txt
+++ b/res/v3x/parsing/instruction/X/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:1..2: no viable alternative at input '\n\nX'
+Error at input.cq:3:2..3: no viable alternative at input 'X\n'
diff --git a/res/v3x/parsing/instruction/X_1/ast.golden.txt b/res/v3x/parsing/instruction/X_1/ast.golden.txt
index f9fea0bf7..af7f7e349 100644
--- a/res/v3x/parsing/instruction/X_1/ast.golden.txt
+++ b/res/v3x/parsing/instruction/X_1/ast.golden.txt
@@ -1,2 +1,32 @@
-ERROR
-Error at input.cq:3:1..2: no viable alternative at input '\n\nX'
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Gate( # input.cq:3:1..2
+          name: <
+            Identifier(
+              name: X
+            )
+          >
+          operands: <
+            ExpressionList(
+              items: [
+                IntegerLiteral( # input.cq:3:3..4
+                  value: 1
+                )
+              ]
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/instruction/X_1/semantic.3.0.golden.txt b/res/v3x/parsing/instruction/X_1/semantic.3.0.golden.txt
index d69e99a9e..85dbeb2af 100644
--- a/res/v3x/parsing/instruction/X_1/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/instruction/X_1/semantic.3.0.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:1..2: failed to resolve instruction 'x' with argument pack (int)
+Error at input.cq:3:1..2: failed to resolve instruction 'X' with argument pack (int)
diff --git a/res/v3x/parsing/instruction/X_123abc/ast.golden.txt b/res/v3x/parsing/instruction/X_123abc/ast.golden.txt
index f9fea0bf7..460fdb33e 100644
--- a/res/v3x/parsing/instruction/X_123abc/ast.golden.txt
+++ b/res/v3x/parsing/instruction/X_123abc/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:1..2: no viable alternative at input '\n\nX'
+Error at input.cq:3:6..9: extraneous input 'abc' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/instruction/X_3.14/ast.golden.txt b/res/v3x/parsing/instruction/X_3.14/ast.golden.txt
index f9fea0bf7..3461541b4 100644
--- a/res/v3x/parsing/instruction/X_3.14/ast.golden.txt
+++ b/res/v3x/parsing/instruction/X_3.14/ast.golden.txt
@@ -1,2 +1,32 @@
-ERROR
-Error at input.cq:3:1..2: no viable alternative at input '\n\nX'
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Gate( # input.cq:3:1..2
+          name: <
+            Identifier(
+              name: X
+            )
+          >
+          operands: <
+            ExpressionList(
+              items: [
+                FloatLiteral( # input.cq:3:3..7
+                  value: 3.14
+                )
+              ]
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/instruction/X_3.14/semantic.3.0.golden.txt b/res/v3x/parsing/instruction/X_3.14/semantic.3.0.golden.txt
new file mode 100644
index 000000000..9cf2e3231
--- /dev/null
+++ b/res/v3x/parsing/instruction/X_3.14/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:3:1..2: failed to resolve instruction 'X' with argument pack (float)
diff --git a/res/v3x/parsing/instruction/X_q0/ast.golden.txt b/res/v3x/parsing/instruction/X_q0/ast.golden.txt
index f9fea0bf7..c3f013f1c 100644
--- a/res/v3x/parsing/instruction/X_q0/ast.golden.txt
+++ b/res/v3x/parsing/instruction/X_q0/ast.golden.txt
@@ -1,2 +1,49 @@
-ERROR
-Error at input.cq:3:1..2: no viable alternative at input '\n\nX'
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Gate( # input.cq:3:1..2
+          name: <
+            Identifier(
+              name: X
+            )
+          >
+          operands: <
+            ExpressionList(
+              items: [
+                Index( # input.cq:3:3..4
+                  expr: <
+                    Identifier(
+                      name: q
+                    )
+                  >
+                  indices: <
+                    IndexList(
+                      items: [
+                        IndexItem(
+                          index: <
+                            IntegerLiteral( # input.cq:3:5..6
+                              value: 0
+                            )
+                          >
+                        )
+                      ]
+                    )
+                  >
+                )
+              ]
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/instruction/X_v/ast.golden.txt b/res/v3x/parsing/instruction/X_v/ast.golden.txt
index f9fea0bf7..78d1570f0 100644
--- a/res/v3x/parsing/instruction/X_v/ast.golden.txt
+++ b/res/v3x/parsing/instruction/X_v/ast.golden.txt
@@ -1,2 +1,32 @@
-ERROR
-Error at input.cq:3:1..2: no viable alternative at input '\n\nX'
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Gate( # input.cq:3:1..2
+          name: <
+            Identifier(
+              name: X
+            )
+          >
+          operands: <
+            ExpressionList(
+              items: [
+                Identifier( # input.cq:3:3..4
+                  name: v
+                )
+              ]
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/instruction/qubit_2__H_q_0__H_q_1__CNOT_q_0_q_1/ast.golden.txt b/res/v3x/parsing/instruction/qubit_2__H_q_0__H_q_1__CNOT_q_0_q_1/ast.golden.txt
index 9949af5c8..b254163d1 100644
--- a/res/v3x/parsing/instruction/qubit_2__H_q_0__H_q_1__CNOT_q_0_q_1/ast.golden.txt
+++ b/res/v3x/parsing/instruction/qubit_2__H_q_0__H_q_1__CNOT_q_0_q_1/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:10..11
           name: <
             Identifier(
@@ -30,8 +30,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:5:1..2
           name: <
             Identifier(
@@ -155,7 +153,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/instruction/qubit_2__H_q_0__H_q_1__CNOT_q_0_q_1/semantic.3.0.golden.txt b/res/v3x/parsing/instruction/qubit_2__H_q_0__H_q_1__CNOT_q_0_q_1/semantic.3.0.golden.txt
index 03048f6ef..3df9db668 100644
--- a/res/v3x/parsing/instruction/qubit_2__H_q_0__H_q_1__CNOT_q_0_q_1/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/instruction/qubit_2__H_q_0__H_q_1__CNOT_q_0_q_1/semantic.3.0.golden.txt
@@ -6,17 +6,6 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        QubitArray(
-          size: 2
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
@@ -116,5 +105,16 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 2
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/instruction/qubit_q__X_q/ast.golden.txt b/res/v3x/parsing/instruction/qubit_q__X_q/ast.golden.txt
index 04451300f..fdd3cc896 100644
--- a/res/v3x/parsing/instruction/qubit_q__X_q/ast.golden.txt
+++ b/res/v3x/parsing/instruction/qubit_q__X_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:5:1..2
           name: <
             Identifier(
@@ -46,7 +44,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/instruction/qubit_q__X_q/semantic.3.0.golden.txt b/res/v3x/parsing/instruction/qubit_q__X_q/semantic.3.0.golden.txt
index d1bcfab89..75869d063 100644
--- a/res/v3x/parsing/instruction/qubit_q__X_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/instruction/qubit_q__X_q/semantic.3.0.golden.txt
@@ -6,17 +6,6 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        Qubit(
-          size: 1
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
@@ -43,5 +32,16 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/instruction/v_1/ast.golden.txt b/res/v3x/parsing/instruction/v_1/ast.golden.txt
index 58c4ef806..4d658a6d3 100644
--- a/res/v3x/parsing/instruction/v_1/ast.golden.txt
+++ b/res/v3x/parsing/instruction/v_1/ast.golden.txt
@@ -1,2 +1,32 @@
-ERROR
-Error at input.cq:3:1..2: no viable alternative at input '\n\nv'
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Gate( # input.cq:3:1..2
+          name: <
+            Identifier(
+              name: v
+            )
+          >
+          operands: <
+            ExpressionList(
+              items: [
+                IntegerLiteral( # input.cq:3:3..4
+                  value: 1
+                )
+              ]
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_3_q_to_b0/ast.golden.txt b/res/v3x/parsing/measure_instruction/array_of_3_q_to_b0/ast.golden.txt
new file mode 100644
index 000000000..caac5e48d
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_3_q_to_b0/ast.golden.txt
@@ -0,0 +1,73 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 3
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:5..7
+          name: <
+            Identifier(
+              name: b0
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..4
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:6..13
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:6:1..3
+              name: b0
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:14..15
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_3_q_to_b0/input.cq b/res/v3x/parsing/measure_instruction/array_of_3_q_to_b0/input.cq
new file mode 100644
index 000000000..d890b828c
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_3_q_to_b0/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[3] q
+bit b0
+
+b0 = measure q
diff --git a/res/v3x/parsing/measure_instruction/array_of_3_q_to_b0/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/array_of_3_q_to_b0/semantic.3.0.golden.txt
new file mode 100644
index 000000000..839ddfa8c
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_3_q_to_b0/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:6:6..13: qubit and bit indices have different sizes
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_5_b/ast.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_5_b/ast.golden.txt
new file mode 100644
index 000000000..a7666dd5e
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_5_b/ast.golden.txt
@@ -0,0 +1,77 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:13..14
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_5_b/input.cq b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_5_b/input.cq
new file mode 100644
index 000000000..e3d9ccdff
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_5_b/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[5] q
+bit[5] b
+
+b = measure q
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_5_b/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_5_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..91cd08af0
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_5_b/semantic.3.0.golden.txt
@@ -0,0 +1,69 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: [
+        Instruction(
+          instruction_ref: measure(bit array, qubit array)
+          name: measure
+          operands: [
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    BitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: q
+                  typ: <
+                    QubitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
+          ]
+          annotations: []
+        )
+      ]
+    )
+  >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_9_b/ast.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_9_b/ast.golden.txt
new file mode 100644
index 000000000..be97db2d2
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_9_b/ast.golden.txt
@@ -0,0 +1,77 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 9
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:13..14
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_9_b/input.cq b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_9_b/input.cq
new file mode 100644
index 000000000..683942f3d
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_9_b/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[5] q
+bit[9] b
+
+b = measure q
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_9_b/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_9_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..628e3d7ec
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_array_of_9_b/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:6:5..12: qubit and bit indices have different sizes
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_0_4/ast.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_0_4/ast.golden.txt
new file mode 100644
index 000000000..e136dc334
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_0_4/ast.golden.txt
@@ -0,0 +1,99 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 9
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:10..17
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Index( # input.cq:6:1..2
+              expr: <
+                Identifier(
+                  name: b
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:3..4
+                          value: 0
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:5..6
+                          value: 4
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:18..19
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_0_4/input.cq b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_0_4/input.cq
new file mode 100644
index 000000000..73d9467fe
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_0_4/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[5] q
+bit[9] b
+
+b[0:4] = measure q
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_0_4/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_0_4/semantic.3.0.golden.txt
new file mode 100644
index 000000000..f001937e4
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_0_4/semantic.3.0.golden.txt
@@ -0,0 +1,86 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: [
+        Instruction(
+          instruction_ref: measure(bit array, qubit array)
+          name: measure
+          operands: [
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    BitArray(
+                      size: 9
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 0
+                )
+                ConstInt(
+                  value: 1
+                )
+                ConstInt(
+                  value: 2
+                )
+                ConstInt(
+                  value: 3
+                )
+                ConstInt(
+                  value: 4
+                )
+              ]
+            )
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: q
+                  typ: <
+                    QubitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
+          ]
+          annotations: []
+        )
+      ]
+    )
+  >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 9
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_2_6/ast.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_2_6/ast.golden.txt
new file mode 100644
index 000000000..bcacc4cc5
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_2_6/ast.golden.txt
@@ -0,0 +1,99 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 9
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:10..17
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Index( # input.cq:6:1..2
+              expr: <
+                Identifier(
+                  name: b
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:3..4
+                          value: 2
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:5..6
+                          value: 6
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:18..19
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_2_6/input.cq b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_2_6/input.cq
new file mode 100644
index 000000000..75069d878
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_2_6/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[5] q
+bit[9] b
+
+b[2:6] = measure q
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_2_6/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_2_6/semantic.3.0.golden.txt
new file mode 100644
index 000000000..378c7561a
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_b_range_2_6/semantic.3.0.golden.txt
@@ -0,0 +1,86 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: [
+        Instruction(
+          instruction_ref: measure(bit array, qubit array)
+          name: measure
+          operands: [
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    BitArray(
+                      size: 9
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 2
+                )
+                ConstInt(
+                  value: 3
+                )
+                ConstInt(
+                  value: 4
+                )
+                ConstInt(
+                  value: 5
+                )
+                ConstInt(
+                  value: 6
+                )
+              ]
+            )
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: q
+                  typ: <
+                    QubitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
+          ]
+          annotations: []
+        )
+      ]
+    )
+  >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 9
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_range_b_0_4/ast.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_range_b_0_4/ast.golden.txt
new file mode 100644
index 000000000..e87d8fdec
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_range_b_0_4/ast.golden.txt
@@ -0,0 +1,92 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  statements: <
+    StatementList(
+      items: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Keyword(
+              name: qubit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 5
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Keyword(
+              name: bit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 9
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:10..17
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          condition: -
+          lhs: <
+            Index( # input.cq:6:1..2
+              expr: <
+                Identifier(
+                  name: b
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:3..4
+                          value: 0
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:5..6
+                          value: 4
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:18..19
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_5_q_to_range_b_2_6/ast.golden.txt b/res/v3x/parsing/measure_instruction/array_of_5_q_to_range_b_2_6/ast.golden.txt
new file mode 100644
index 000000000..e97476700
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_5_q_to_range_b_2_6/ast.golden.txt
@@ -0,0 +1,92 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  statements: <
+    StatementList(
+      items: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Keyword(
+              name: qubit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 5
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Keyword(
+              name: bit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 9
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:10..17
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          condition: -
+          lhs: <
+            Index( # input.cq:6:1..2
+              expr: <
+                Identifier(
+                  name: b
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:3..4
+                          value: 2
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:5..6
+                          value: 6
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:18..19
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_9_q_to_array_of_5_b/ast.golden.txt b/res/v3x/parsing/measure_instruction/array_of_9_q_to_array_of_5_b/ast.golden.txt
new file mode 100644
index 000000000..be97db2d2
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_9_q_to_array_of_5_b/ast.golden.txt
@@ -0,0 +1,77 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 9
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:13..14
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/array_of_9_q_to_array_of_5_b/input.cq b/res/v3x/parsing/measure_instruction/array_of_9_q_to_array_of_5_b/input.cq
new file mode 100644
index 000000000..683942f3d
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_9_q_to_array_of_5_b/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[5] q
+bit[9] b
+
+b = measure q
diff --git a/res/v3x/parsing/measure_instruction/array_of_9_q_to_array_of_5_b/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/array_of_9_q_to_array_of_5_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..628e3d7ec
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/array_of_9_q_to_array_of_5_b/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:6:5..12: qubit and bit indices have different sizes
diff --git a/res/v3x/parsing/measure_instruction/b_to_b/ast.golden.txt b/res/v3x/parsing/measure_instruction/b_to_b/ast.golden.txt
new file mode 100644
index 000000000..65ff9d579
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/b_to_b/ast.golden.txt
@@ -0,0 +1,51 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:5..6
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..4
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:5:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:5:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:5:13..14
+              name: b
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/b_to_b/input.cq b/res/v3x/parsing/measure_instruction/b_to_b/input.cq
new file mode 100644
index 000000000..5a9a3222a
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/b_to_b/input.cq
@@ -0,0 +1,5 @@
+version 3
+
+bit b
+
+b = measure b
diff --git a/res/v3x/parsing/measure_instruction/b_to_b/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/b_to_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..1ba2367ba
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/b_to_b/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:5:5..12: failed to resolve instruction 'measure' with argument pack (bit, bit)
diff --git a/res/v3x/parsing/measure_instruction/b_to_q/ast.golden.txt b/res/v3x/parsing/measure_instruction/b_to_q/ast.golden.txt
new file mode 100644
index 000000000..7d8667293
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/b_to_q/ast.golden.txt
@@ -0,0 +1,69 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:7..8
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..6
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:5..6
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..4
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: q
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:13..14
+              name: b
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/b_to_q/input.cq b/res/v3x/parsing/measure_instruction/b_to_q/input.cq
new file mode 100644
index 000000000..706a8caa3
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/b_to_q/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit q
+bit b
+
+q = measure b
diff --git a/res/v3x/parsing/measure_instruction/b_to_q/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/b_to_q/semantic.3.0.golden.txt
new file mode 100644
index 000000000..d41cbf097
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/b_to_q/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:6:5..12: failed to resolve instruction 'measure' with argument pack (qubit, bit)
diff --git a/res/v3x/parsing/measure_instruction/bit_and_qubit/ast.golden.txt b/res/v3x/parsing/measure_instruction/bit_and_qubit/ast.golden.txt
new file mode 100644
index 000000000..c4464593b
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/bit_and_qubit/ast.golden.txt
@@ -0,0 +1,69 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:7..8
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..6
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:5..6
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..4
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:13..14
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/bit_and_qubit/input.cq b/res/v3x/parsing/measure_instruction/bit_and_qubit/input.cq
new file mode 100644
index 000000000..ca19ca122
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/bit_and_qubit/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit q
+bit b
+
+b = measure q
diff --git a/res/v3x/parsing/measure_instruction/qubit_q__measure_q/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/bit_and_qubit/semantic.3.0.golden.txt
similarity index 58%
rename from res/v3x/parsing/measure_instruction/qubit_q__measure_q/semantic.3.0.golden.txt
rename to res/v3x/parsing/measure_instruction/bit_and_qubit/semantic.3.0.golden.txt
index dc5ae20b4..7a74ae0ab 100644
--- a/res/v3x/parsing/measure_instruction/qubit_q__measure_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/measure_instruction/bit_and_qubit/semantic.3.0.golden.txt
@@ -6,24 +6,26 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        Qubit(
-          size: 1
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
         Instruction(
-          instruction_ref: measure(qubit)
+          instruction_ref: measure(bit, qubit)
           name: measure
           operands: [
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    Bit(
+                      size: 1
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
             VariableRef(
               variable --> <
                 Variable(
@@ -43,5 +45,25 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        Bit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/measure_instruction/measure_42/ast.golden.txt b/res/v3x/parsing/measure_instruction/measure_42/ast.golden.txt
deleted file mode 100644
index dc5c82a8d..000000000
--- a/res/v3x/parsing/measure_instruction/measure_42/ast.golden.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-ERROR
-Error at input.cq:3:1..8: no viable alternative at input '\n\nmeasure'
diff --git a/res/v3x/parsing/measure_instruction/measure_q/ast.golden.txt b/res/v3x/parsing/measure_instruction/measure_q/ast.golden.txt
deleted file mode 100644
index dc5c82a8d..000000000
--- a/res/v3x/parsing/measure_instruction/measure_q/ast.golden.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-ERROR
-Error at input.cq:3:1..8: no viable alternative at input '\n\nmeasure'
diff --git a/res/v3x/parsing/measure_instruction/no_bit/ast.golden.txt b/res/v3x/parsing/measure_instruction/no_bit/ast.golden.txt
new file mode 100644
index 000000000..16d8e3330
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/no_bit/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:4:1..8: extraneous input 'measure' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/measure_instruction/qubit_q__measure_q/input.cq b/res/v3x/parsing/measure_instruction/no_bit/input.cq
similarity index 100%
rename from res/v3x/parsing/measure_instruction/qubit_q__measure_q/input.cq
rename to res/v3x/parsing/measure_instruction/no_bit/input.cq
diff --git a/res/v3x/parsing/measure_instruction/measure/ast.golden.txt b/res/v3x/parsing/measure_instruction/no_bit_no_qubit/ast.golden.txt
similarity index 100%
rename from res/v3x/parsing/measure_instruction/measure/ast.golden.txt
rename to res/v3x/parsing/measure_instruction/no_bit_no_qubit/ast.golden.txt
diff --git a/res/v3x/parsing/measure_instruction/measure/input.cq b/res/v3x/parsing/measure_instruction/no_bit_no_qubit/input.cq
similarity index 100%
rename from res/v3x/parsing/measure_instruction/measure/input.cq
rename to res/v3x/parsing/measure_instruction/no_bit_no_qubit/input.cq
diff --git a/res/v3x/parsing/measure_instruction/no_qubit/ast.golden.txt b/res/v3x/parsing/measure_instruction/no_qubit/ast.golden.txt
new file mode 100644
index 000000000..b2de12d20
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/no_qubit/ast.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:5:12..13: mismatched input '\n' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}
diff --git a/res/v3x/parsing/measure_instruction/no_qubit/input.cq b/res/v3x/parsing/measure_instruction/no_qubit/input.cq
new file mode 100644
index 000000000..011880740
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/no_qubit/input.cq
@@ -0,0 +1,5 @@
+version 3
+
+bit b
+
+b = measure
diff --git a/res/v3x/parsing/measure_instruction/q0_to_array_of_3_b/ast.golden.txt b/res/v3x/parsing/measure_instruction/q0_to_array_of_3_b/ast.golden.txt
new file mode 100644
index 000000000..684a5fe48
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q0_to_array_of_3_b/ast.golden.txt
@@ -0,0 +1,73 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:7..9
+          name: <
+            Identifier(
+              name: q0
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..6
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 3
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:13..15
+              name: q0
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q0_to_array_of_3_b/input.cq b/res/v3x/parsing/measure_instruction/q0_to_array_of_3_b/input.cq
new file mode 100644
index 000000000..1e642ded7
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q0_to_array_of_3_b/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit q0
+bit[3] b
+
+b = measure q0
diff --git a/res/v3x/parsing/measure_instruction/q0_to_array_of_3_b/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q0_to_array_of_3_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..628e3d7ec
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q0_to_array_of_3_b/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:6:5..12: qubit and bit indices have different sizes
diff --git a/res/v3x/parsing/measure_instruction/q0_to_b_0/ast.golden.txt b/res/v3x/parsing/measure_instruction/q0_to_b_0/ast.golden.txt
new file mode 100644
index 000000000..12b8c8746
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q0_to_b_0/ast.golden.txt
@@ -0,0 +1,90 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:7..9
+          name: <
+            Identifier(
+              name: q0
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..6
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 3
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:8..15
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Index( # input.cq:6:1..2
+              expr: <
+                Identifier(
+                  name: b
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:3..4
+                          value: 0
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:6:16..18
+              name: q0
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q0_to_b_0/input.cq b/res/v3x/parsing/measure_instruction/q0_to_b_0/input.cq
new file mode 100644
index 000000000..9d659128f
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q0_to_b_0/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit q0
+bit[3] b
+
+b[0] = measure q0
diff --git a/res/v3x/parsing/measure_instruction/q0_to_b_0/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q0_to_b_0/semantic.3.0.golden.txt
new file mode 100644
index 000000000..1adf77b83
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q0_to_b_0/semantic.3.0.golden.txt
@@ -0,0 +1,74 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: [
+        Instruction(
+          instruction_ref: measure(bit, qubit)
+          name: measure
+          operands: [
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    BitArray(
+                      size: 3
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 0
+                )
+              ]
+            )
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: q0
+                  typ: <
+                    Qubit(
+                      size: 1
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
+          ]
+          annotations: []
+        )
+      ]
+    )
+  >
+  variables: [
+    Variable(
+      name: q0
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 3
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/measure_instruction/qubit_array_of_5__measure_q_at_0_2_4/ast.golden.txt b/res/v3x/parsing/measure_instruction/q_0_to_b0/ast.golden.txt
similarity index 60%
rename from res/v3x/parsing/measure_instruction/qubit_array_of_5__measure_q_at_0_2_4/ast.golden.txt
rename to res/v3x/parsing/measure_instruction/q_0_to_b0/ast.golden.txt
index e53de413f..4c5332d4f 100644
--- a/res/v3x/parsing/measure_instruction/qubit_array_of_5__measure_q_at_0_2_4/ast.golden.txt
+++ b/res/v3x/parsing/measure_instruction/q_0_to_b0/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:10..11
           name: <
             Identifier(
@@ -23,24 +23,44 @@ Program(
               >
               size: <
                 IntegerLiteral(
-                  value: 5
+                  value: 3
                 )
               >
             )
           >
           annotations: []
         )
-      >
-      gates: []
-      measure_instructions: [
-        MeasureInstruction( # input.cq:4:1..8
+        Variable( # input.cq:4:5..7
+          name: <
+            Identifier(
+              name: b0
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..4
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:6..13
           name: <
             Identifier(
               name: measure
             )
           >
-          operand: <
-            Index( # input.cq:4:9..10
+          lhs: <
+            Identifier( # input.cq:6:1..3
+              name: b0
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:14..15
               expr: <
                 Identifier(
                   name: q
@@ -51,25 +71,11 @@ Program(
                   items: [
                     IndexItem(
                       index: <
-                        IntegerLiteral( # input.cq:4:11..12
+                        IntegerLiteral( # input.cq:6:16..17
                           value: 0
                         )
                       >
                     )
-                    IndexItem(
-                      index: <
-                        IntegerLiteral( # input.cq:4:13..14
-                          value: 2
-                        )
-                      >
-                    )
-                    IndexItem(
-                      index: <
-                        IntegerLiteral( # input.cq:4:15..16
-                          value: 4
-                        )
-                      >
-                    )
                   ]
                 )
               >
diff --git a/res/v3x/parsing/measure_instruction/q_0_to_b0/input.cq b/res/v3x/parsing/measure_instruction/q_0_to_b0/input.cq
new file mode 100644
index 000000000..e4570e40e
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_0_to_b0/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[3] q
+bit b0
+
+b0 = measure q[0]
diff --git a/res/v3x/parsing/measure_instruction/qubit_array_of_5__measure_q_at_0_2_4/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q_0_to_b0/semantic.3.0.golden.txt
similarity index 59%
rename from res/v3x/parsing/measure_instruction/qubit_array_of_5__measure_q_at_0_2_4/semantic.3.0.golden.txt
rename to res/v3x/parsing/measure_instruction/q_0_to_b0/semantic.3.0.golden.txt
index 0eb354093..f99a00894 100644
--- a/res/v3x/parsing/measure_instruction/qubit_array_of_5__measure_q_at_0_2_4/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/measure_instruction/q_0_to_b0/semantic.3.0.golden.txt
@@ -6,31 +6,33 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        QubitArray(
-          size: 5
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
         Instruction(
-          instruction_ref: measure(qubit array)
+          instruction_ref: measure(bit, qubit)
           name: measure
           operands: [
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: b0
+                  typ: <
+                    Bit(
+                      size: 1
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
             IndexRef(
               variable --> <
                 Variable(
                   name: q
                   typ: <
                     QubitArray(
-                      size: 5
+                      size: 3
                     )
                   >
                   annotations: []
@@ -40,12 +42,6 @@ Program(
                 ConstInt(
                   value: 0
                 )
-                ConstInt(
-                  value: 2
-                )
-                ConstInt(
-                  value: 4
-                )
               ]
             )
           ]
@@ -54,5 +50,25 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 3
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b0
+      typ: <
+        Bit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/measure_instruction/q_1_3_4_5_7_to_array_of_5_b/ast.golden.txt b/res/v3x/parsing/measure_instruction/q_1_3_4_5_7_to_array_of_5_b/ast.golden.txt
new file mode 100644
index 000000000..4ae6af684
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_1_3_4_5_7_to_array_of_5_b/ast.golden.txt
@@ -0,0 +1,122 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 9
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:13..14
+              expr: <
+                Identifier(
+                  name: q
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:15..16
+                          value: 1
+                        )
+                      >
+                    )
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:18..19
+                          value: 3
+                        )
+                      >
+                    )
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:21..22
+                          value: 4
+                        )
+                      >
+                    )
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:24..25
+                          value: 5
+                        )
+                      >
+                    )
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:27..28
+                          value: 7
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_1_3_4_5_7_to_array_of_5_b/input.cq b/res/v3x/parsing/measure_instruction/q_1_3_4_5_7_to_array_of_5_b/input.cq
new file mode 100644
index 000000000..8215918df
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_1_3_4_5_7_to_array_of_5_b/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[9] q
+bit[5] b
+
+b = measure q[1, 3, 4, 5, 7]
diff --git a/res/v3x/parsing/measure_instruction/q_1_3_4_5_7_to_array_of_5_b/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q_1_3_4_5_7_to_array_of_5_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..959feb632
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_1_3_4_5_7_to_array_of_5_b/semantic.3.0.golden.txt
@@ -0,0 +1,86 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: [
+        Instruction(
+          instruction_ref: measure(bit array, qubit array)
+          name: measure
+          operands: [
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    BitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: q
+                  typ: <
+                    QubitArray(
+                      size: 9
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 1
+                )
+                ConstInt(
+                  value: 3
+                )
+                ConstInt(
+                  value: 4
+                )
+                ConstInt(
+                  value: 5
+                )
+                ConstInt(
+                  value: 7
+                )
+              ]
+            )
+          ]
+          annotations: []
+        )
+      ]
+    )
+  >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 9
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_2_4_to_b_1_3/ast.golden.txt b/res/v3x/parsing/measure_instruction/q_2_4_to_b_1_3/ast.golden.txt
new file mode 100644
index 000000000..1c3b72531
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_2_4_to_b_1_3/ast.golden.txt
@@ -0,0 +1,125 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:11..18
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Index( # input.cq:6:1..2
+              expr: <
+                Identifier(
+                  name: b
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:3..4
+                          value: 1
+                        )
+                      >
+                    )
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:6..7
+                          value: 3
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:19..20
+              expr: <
+                Identifier(
+                  name: q
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:21..22
+                          value: 2
+                        )
+                      >
+                    )
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:24..25
+                          value: 4
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_2_4_to_b_1_3/input.cq b/res/v3x/parsing/measure_instruction/q_2_4_to_b_1_3/input.cq
new file mode 100644
index 000000000..132ec6498
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_2_4_to_b_1_3/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[5] q
+bit[5] b
+
+b[1, 3] = measure q[2, 4]
diff --git a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0__measure_q_at_1/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q_2_4_to_b_1_3/semantic.3.0.golden.txt
similarity index 68%
rename from res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0__measure_q_at_1/semantic.3.0.golden.txt
rename to res/v3x/parsing/measure_instruction/q_2_4_to_b_1_3/semantic.3.0.golden.txt
index 3e503a8c0..9f3c2b079 100644
--- a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0__measure_q_at_1/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/measure_instruction/q_2_4_to_b_1_3/semantic.3.0.golden.txt
@@ -6,31 +6,20 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        QubitArray(
-          size: 2
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
         Instruction(
-          instruction_ref: measure(qubit)
+          instruction_ref: measure(bit array, qubit array)
           name: measure
           operands: [
             IndexRef(
               variable --> <
                 Variable(
-                  name: q
+                  name: b
                   typ: <
-                    QubitArray(
-                      size: 2
+                    BitArray(
+                      size: 5
                     )
                   >
                   annotations: []
@@ -38,24 +27,20 @@ Program(
               >
               indices: [
                 ConstInt(
-                  value: 0
+                  value: 1
+                )
+                ConstInt(
+                  value: 3
                 )
               ]
             )
-          ]
-          annotations: []
-        )
-        Instruction(
-          instruction_ref: measure(qubit)
-          name: measure
-          operands: [
             IndexRef(
               variable --> <
                 Variable(
                   name: q
                   typ: <
                     QubitArray(
-                      size: 2
+                      size: 5
                     )
                   >
                   annotations: []
@@ -63,7 +48,10 @@ Program(
               >
               indices: [
                 ConstInt(
-                  value: 1
+                  value: 2
+                )
+                ConstInt(
+                  value: 4
                 )
               ]
             )
@@ -73,5 +61,25 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/measure_instruction/q_2_4_to_b_range_1_2/ast.golden.txt b/res/v3x/parsing/measure_instruction/q_2_4_to_b_range_1_2/ast.golden.txt
new file mode 100644
index 000000000..892df8bec
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_2_4_to_b_range_1_2/ast.golden.txt
@@ -0,0 +1,123 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:10..17
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Index( # input.cq:6:1..2
+              expr: <
+                Identifier(
+                  name: b
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:3..4
+                          value: 1
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:5..6
+                          value: 2
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:18..19
+              expr: <
+                Identifier(
+                  name: q
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:20..21
+                          value: 2
+                        )
+                      >
+                    )
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:23..24
+                          value: 4
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_2_4_to_b_range_1_2/input.cq b/res/v3x/parsing/measure_instruction/q_2_4_to_b_range_1_2/input.cq
new file mode 100644
index 000000000..b6e1126a7
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_2_4_to_b_range_1_2/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[5] q
+bit[5] b
+
+b[1:2] = measure q[2, 4]
diff --git a/res/v3x/parsing/measure_instruction/q_2_4_to_b_range_1_2/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q_2_4_to_b_range_1_2/semantic.3.0.golden.txt
new file mode 100644
index 000000000..55f69ea3e
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_2_4_to_b_range_1_2/semantic.3.0.golden.txt
@@ -0,0 +1,85 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: [
+        Instruction(
+          instruction_ref: measure(bit array, qubit array)
+          name: measure
+          operands: [
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    BitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 1
+                )
+                ConstInt(
+                  value: 2
+                )
+              ]
+            )
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: q
+                  typ: <
+                    QubitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 2
+                )
+                ConstInt(
+                  value: 4
+                )
+              ]
+            )
+          ]
+          annotations: []
+        )
+      ]
+    )
+  >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0__measure_q_at_1/ast.golden.txt b/res/v3x/parsing/measure_instruction/q_range_0_4_to_array_of_5_b/ast.golden.txt
similarity index 61%
rename from res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0__measure_q_at_1/ast.golden.txt
rename to res/v3x/parsing/measure_instruction/q_range_0_4_to_array_of_5_b/ast.golden.txt
index abc01245b..dd96ab461 100644
--- a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0__measure_q_at_1/ast.golden.txt
+++ b/res/v3x/parsing/measure_instruction/q_range_0_4_to_array_of_5_b/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:10..11
           name: <
             Identifier(
@@ -23,54 +23,48 @@ Program(
               >
               size: <
                 IntegerLiteral(
-                  value: 2
+                  value: 9
                 )
               >
             )
           >
           annotations: []
         )
-      >
-      gates: []
-      measure_instructions: [
-        MeasureInstruction( # input.cq:4:1..8
+        Variable( # input.cq:4:8..9
           name: <
             Identifier(
-              name: measure
+              name: b
             )
           >
-          operand: <
-            Index( # input.cq:4:9..10
-              expr: <
-                Identifier(
-                  name: q
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
                 )
               >
-              indices: <
-                IndexList(
-                  items: [
-                    IndexItem(
-                      index: <
-                        IntegerLiteral( # input.cq:4:11..12
-                          value: 0
-                        )
-                      >
-                    )
-                  ]
+              size: <
+                IntegerLiteral(
+                  value: 5
                 )
               >
             )
           >
           annotations: []
         )
-        MeasureInstruction( # input.cq:5:1..8
+        MeasureInstruction( # input.cq:6:5..12
           name: <
             Identifier(
               name: measure
             )
           >
-          operand: <
-            Index( # input.cq:5:9..10
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:13..14
               expr: <
                 Identifier(
                   name: q
@@ -79,10 +73,15 @@ Program(
               indices: <
                 IndexList(
                   items: [
-                    IndexItem(
-                      index: <
-                        IntegerLiteral( # input.cq:5:11..12
-                          value: 1
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:15..16
+                          value: 0
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:17..18
+                          value: 4
                         )
                       >
                     )
diff --git a/res/v3x/parsing/measure_instruction/q_range_0_4_to_array_of_5_b/input.cq b/res/v3x/parsing/measure_instruction/q_range_0_4_to_array_of_5_b/input.cq
new file mode 100644
index 000000000..fa9764302
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_range_0_4_to_array_of_5_b/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[9] q
+bit[5] b
+
+b = measure q[0:4]
diff --git a/res/v3x/parsing/measure_instruction/q_range_0_4_to_array_of_5_b/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q_range_0_4_to_array_of_5_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..56523e286
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_range_0_4_to_array_of_5_b/semantic.3.0.golden.txt
@@ -0,0 +1,86 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: [
+        Instruction(
+          instruction_ref: measure(bit array, qubit array)
+          name: measure
+          operands: [
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    BitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: q
+                  typ: <
+                    QubitArray(
+                      size: 9
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 0
+                )
+                ConstInt(
+                  value: 1
+                )
+                ConstInt(
+                  value: 2
+                )
+                ConstInt(
+                  value: 3
+                )
+                ConstInt(
+                  value: 4
+                )
+              ]
+            )
+          ]
+          annotations: []
+        )
+      ]
+    )
+  >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 9
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_range_2_6_to_array_of_5_b/ast.golden.txt b/res/v3x/parsing/measure_instruction/q_range_2_6_to_array_of_5_b/ast.golden.txt
new file mode 100644
index 000000000..5e5752249
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_range_2_6_to_array_of_5_b/ast.golden.txt
@@ -0,0 +1,99 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 9
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:13..14
+              expr: <
+                Identifier(
+                  name: q
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:15..16
+                          value: 2
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:17..18
+                          value: 6
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_range_2_6_to_array_of_5_b/input.cq b/res/v3x/parsing/measure_instruction/q_range_2_6_to_array_of_5_b/input.cq
new file mode 100644
index 000000000..67f36a4e2
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_range_2_6_to_array_of_5_b/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[9] q
+bit[5] b
+
+b = measure q[2:6]
diff --git a/res/v3x/parsing/measure_instruction/q_range_2_6_to_array_of_5_b/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q_range_2_6_to_array_of_5_b/semantic.3.0.golden.txt
new file mode 100644
index 000000000..f2afacb22
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_range_2_6_to_array_of_5_b/semantic.3.0.golden.txt
@@ -0,0 +1,86 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: [
+        Instruction(
+          instruction_ref: measure(bit array, qubit array)
+          name: measure
+          operands: [
+            VariableRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    BitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+            )
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: q
+                  typ: <
+                    QubitArray(
+                      size: 9
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 2
+                )
+                ConstInt(
+                  value: 3
+                )
+                ConstInt(
+                  value: 4
+                )
+                ConstInt(
+                  value: 5
+                )
+                ConstInt(
+                  value: 6
+                )
+              ]
+            )
+          ]
+          annotations: []
+        )
+      ]
+    )
+  >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 9
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_range_3_4_to_b_1_3/ast.golden.txt b/res/v3x/parsing/measure_instruction/q_range_3_4_to_b_1_3/ast.golden.txt
new file mode 100644
index 000000000..38f974b88
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_range_3_4_to_b_1_3/ast.golden.txt
@@ -0,0 +1,123 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..9
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..7
+              name: <
+                Keyword(
+                  name: bit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 5
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:11..18
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            Index( # input.cq:6:1..2
+              expr: <
+                Identifier(
+                  name: b
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:3..4
+                          value: 1
+                        )
+                      >
+                    )
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:6..7
+                          value: 3
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:19..20
+              expr: <
+                Identifier(
+                  name: q
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:21..22
+                          value: 3
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:23..24
+                          value: 4
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_range_3_4_to_b_1_3/input.cq b/res/v3x/parsing/measure_instruction/q_range_3_4_to_b_1_3/input.cq
new file mode 100644
index 000000000..de862a63c
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_range_3_4_to_b_1_3/input.cq
@@ -0,0 +1,6 @@
+version 3
+
+qubit[5] q
+bit[5] b
+
+b[1, 3] = measure q[3:4]
diff --git a/res/v3x/parsing/measure_instruction/q_range_3_4_to_b_1_3/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q_range_3_4_to_b_1_3/semantic.3.0.golden.txt
new file mode 100644
index 000000000..123116c0a
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_range_3_4_to_b_1_3/semantic.3.0.golden.txt
@@ -0,0 +1,85 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: [
+        Instruction(
+          instruction_ref: measure(bit array, qubit array)
+          name: measure
+          operands: [
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: b
+                  typ: <
+                    BitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 1
+                )
+                ConstInt(
+                  value: 3
+                )
+              ]
+            )
+            IndexRef(
+              variable --> <
+                Variable(
+                  name: q
+                  typ: <
+                    QubitArray(
+                      size: 5
+                    )
+                  >
+                  annotations: []
+                )
+              >
+              indices: [
+                ConstInt(
+                  value: 3
+                )
+                ConstInt(
+                  value: 4
+                )
+              ]
+            )
+          ]
+          annotations: []
+        )
+      ]
+    )
+  >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: b
+      typ: <
+        BitArray(
+          size: 5
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_to_5/ast.golden.txt b/res/v3x/parsing/measure_instruction/q_to_5/ast.golden.txt
new file mode 100644
index 000000000..5d8293088
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_to_5/ast.golden.txt
@@ -0,0 +1,51 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:7..8
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..6
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:5:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          lhs: <
+            IntegerLiteral( # input.cq:5:1..2
+              value: 5
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:5:13..14
+              name: q
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/q_to_5/input.cq b/res/v3x/parsing/measure_instruction/q_to_5/input.cq
new file mode 100644
index 000000000..018859427
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_to_5/input.cq
@@ -0,0 +1,5 @@
+version 3
+
+qubit q
+
+5 = measure q
diff --git a/res/v3x/parsing/measure_instruction/q_to_5/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q_to_5/semantic.3.0.golden.txt
new file mode 100644
index 000000000..79d884b4d
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_to_5/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:5:5..12: failed to resolve instruction 'measure' with argument pack (int, qubit)
diff --git a/res/v3x/parsing/measure_instruction/qubit_q__measure_q/ast.golden.txt b/res/v3x/parsing/measure_instruction/q_to_q/ast.golden.txt
similarity index 74%
rename from res/v3x/parsing/measure_instruction/qubit_q__measure_q/ast.golden.txt
rename to res/v3x/parsing/measure_instruction/q_to_q/ast.golden.txt
index 64cec9bc6..01806b5f8 100644
--- a/res/v3x/parsing/measure_instruction/qubit_q__measure_q/ast.golden.txt
+++ b/res/v3x/parsing/measure_instruction/q_to_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,17 +26,19 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: []
-      measure_instructions: [
-        MeasureInstruction( # input.cq:4:1..8
+        MeasureInstruction( # input.cq:5:5..12
           name: <
             Identifier(
               name: measure
             )
           >
-          operand: <
-            Identifier( # input.cq:4:9..10
+          lhs: <
+            Identifier( # input.cq:5:1..2
+              name: q
+            )
+          >
+          rhs: <
+            Identifier( # input.cq:5:13..14
               name: q
             )
           >
diff --git a/res/v3x/parsing/measure_instruction/q_to_q/input.cq b/res/v3x/parsing/measure_instruction/q_to_q/input.cq
new file mode 100644
index 000000000..96fa2d665
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_to_q/input.cq
@@ -0,0 +1,5 @@
+version 3
+
+qubit q
+
+q = measure q
diff --git a/res/v3x/parsing/measure_instruction/q_to_q/semantic.3.0.golden.txt b/res/v3x/parsing/measure_instruction/q_to_q/semantic.3.0.golden.txt
new file mode 100644
index 000000000..f48b30b3c
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/q_to_q/semantic.3.0.golden.txt
@@ -0,0 +1,2 @@
+ERROR
+Error at input.cq:5:5..12: failed to resolve instruction 'measure' with argument pack (qubit, qubit)
diff --git a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0__measure_q_at_1/input.cq b/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0__measure_q_at_1/input.cq
deleted file mode 100644
index 2897599b4..000000000
--- a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0__measure_q_at_1/input.cq
+++ /dev/null
@@ -1,5 +0,0 @@
-version 3
-
-qubit[2] q
-measure q[0]
-measure q[1]
diff --git a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0_q_at_1/ast.golden.txt b/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0_q_at_1/ast.golden.txt
deleted file mode 100644
index 9cb5bb1ef..000000000
--- a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0_q_at_1/ast.golden.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-ERROR
-Error at input.cq:4:13..14: mismatched input ',' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0_q_at_1/input.cq b/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0_q_at_1/input.cq
deleted file mode 100644
index 4ec7b3f27..000000000
--- a/res/v3x/parsing/measure_instruction/qubit_array_of_2_q__measure_q_at_0_q_at_1/input.cq
+++ /dev/null
@@ -1,4 +0,0 @@
-version 3
-
-qubit[2] q
-measure q[0], q[1]
diff --git a/res/v3x/parsing/measure_instruction/qubit_array_of_5__measure_q_at_0_2_4/input.cq b/res/v3x/parsing/measure_instruction/qubit_array_of_5__measure_q_at_0_2_4/input.cq
deleted file mode 100644
index 78901f659..000000000
--- a/res/v3x/parsing/measure_instruction/qubit_array_of_5__measure_q_at_0_2_4/input.cq
+++ /dev/null
@@ -1,4 +0,0 @@
-version 3
-
-qubit[5] q
-measure q[0,2,4]
diff --git a/res/v3x/parsing/measure_instruction/range_q_0_4_to_array_of_5_b/ast.golden.txt b/res/v3x/parsing/measure_instruction/range_q_0_4_to_array_of_5_b/ast.golden.txt
new file mode 100644
index 000000000..ddd7657c7
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/range_q_0_4_to_array_of_5_b/ast.golden.txt
@@ -0,0 +1,92 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  statements: <
+    StatementList(
+      items: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Keyword(
+              name: qubit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 9
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Keyword(
+              name: bit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 5
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          condition: -
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:13..14
+              expr: <
+                Identifier(
+                  name: q
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:15..16
+                          value: 0
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:17..18
+                          value: 4
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/range_q_2_6_to_array_of_5_b/ast.golden.txt b/res/v3x/parsing/measure_instruction/range_q_2_6_to_array_of_5_b/ast.golden.txt
new file mode 100644
index 000000000..203d08cbe
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/range_q_2_6_to_array_of_5_b/ast.golden.txt
@@ -0,0 +1,92 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  statements: <
+    StatementList(
+      items: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Keyword(
+              name: qubit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 9
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Keyword(
+              name: bit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 5
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:5..12
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          condition: -
+          lhs: <
+            Identifier( # input.cq:6:1..2
+              name: b
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:13..14
+              expr: <
+                Identifier(
+                  name: q
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:15..16
+                          value: 2
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:17..18
+                          value: 6
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/measure_instruction/range_q_3_4_to_b_1_3/ast.golden.txt b/res/v3x/parsing/measure_instruction/range_q_3_4_to_b_1_3/ast.golden.txt
new file mode 100644
index 000000000..7416253b5
--- /dev/null
+++ b/res/v3x/parsing/measure_instruction/range_q_3_4_to_b_1_3/ast.golden.txt
@@ -0,0 +1,116 @@
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  statements: <
+    StatementList(
+      items: [
+        Variable( # input.cq:3:10..11
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Keyword(
+              name: qubit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 5
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:8..9
+          name: <
+            Identifier(
+              name: b
+            )
+          >
+          typ: <
+            Keyword(
+              name: bit
+            )
+          >
+          size: <
+            IntegerLiteral(
+              value: 5
+            )
+          >
+          annotations: []
+        )
+        MeasureInstruction( # input.cq:6:11..18
+          name: <
+            Identifier(
+              name: measure
+            )
+          >
+          condition: -
+          lhs: <
+            Index( # input.cq:6:1..2
+              expr: <
+                Identifier(
+                  name: b
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:3..4
+                          value: 1
+                        )
+                      >
+                    )
+                    IndexItem(
+                      index: <
+                        IntegerLiteral( # input.cq:6:6..7
+                          value: 3
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          rhs: <
+            Index( # input.cq:6:19..20
+              expr: <
+                Identifier(
+                  name: q
+                )
+              >
+              indices: <
+                IndexList(
+                  items: [
+                    IndexRange(
+                      first: <
+                        IntegerLiteral( # input.cq:6:21..22
+                          value: 3
+                        )
+                      >
+                      last: <
+                        IntegerLiteral( # input.cq:6:23..24
+                          value: 4
+                        )
+                      >
+                    )
+                  ]
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/newline_or_semicolon/version_3_newline_qubit_q/ast.golden.txt b/res/v3x/parsing/newline_or_semicolon/version_3_newline_qubit_q/ast.golden.txt
index a39d37f0c..2dc90a8b3 100644
--- a/res/v3x/parsing/newline_or_semicolon/version_3_newline_qubit_q/ast.golden.txt
+++ b/res/v3x/parsing/newline_or_semicolon/version_3_newline_qubit_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,9 +26,7 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: []
-      measure_instructions: []
+      ]
     )
   >
 )
diff --git a/res/v3x/parsing/newline_or_semicolon/version_3_newline_qubit_q/semantic.3.0.golden.txt b/res/v3x/parsing/newline_or_semicolon/version_3_newline_qubit_q/semantic.3.0.golden.txt
index 8ce6c39e3..ce1766976 100644
--- a/res/v3x/parsing/newline_or_semicolon/version_3_newline_qubit_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/newline_or_semicolon/version_3_newline_qubit_q/semantic.3.0.golden.txt
@@ -6,7 +6,12 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: [
     Variable(
       name: q
       typ: <
@@ -16,11 +21,6 @@ Program(
       >
       annotations: []
     )
-  >
-  block: <
-    Block(
-      statements: []
-    )
-  >
+  ]
 )
 
diff --git a/res/v3x/parsing/newline_or_semicolon/version_3_semicolon_qubit_q/ast.golden.txt b/res/v3x/parsing/newline_or_semicolon/version_3_semicolon_qubit_q/ast.golden.txt
index b6d69be15..5453b5983 100644
--- a/res/v3x/parsing/newline_or_semicolon/version_3_semicolon_qubit_q/ast.golden.txt
+++ b/res/v3x/parsing/newline_or_semicolon/version_3_semicolon_qubit_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:1:18..19
           name: <
             Identifier(
@@ -26,9 +26,7 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: []
-      measure_instructions: []
+      ]
     )
   >
 )
diff --git a/res/v3x/parsing/newline_or_semicolon/version_3_semicolon_qubit_q/semantic.3.0.golden.txt b/res/v3x/parsing/newline_or_semicolon/version_3_semicolon_qubit_q/semantic.3.0.golden.txt
index 8ce6c39e3..ce1766976 100644
--- a/res/v3x/parsing/newline_or_semicolon/version_3_semicolon_qubit_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/newline_or_semicolon/version_3_semicolon_qubit_q/semantic.3.0.golden.txt
@@ -6,7 +6,12 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: [
     Variable(
       name: q
       typ: <
@@ -16,11 +21,6 @@ Program(
       >
       annotations: []
     )
-  >
-  block: <
-    Block(
-      statements: []
-    )
-  >
+  ]
 )
 
diff --git a/res/v3x/parsing/program/bad_token_after_version/ast.golden.txt b/res/v3x/parsing/program/bad_token_after_version/ast.golden.txt
index 873ff23cc..09b5f7465 100644
--- a/res/v3x/parsing/program/bad_token_after_version/ast.golden.txt
+++ b/res/v3x/parsing/program/bad_token_after_version/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:1..4: no viable alternative at input '\n\n123'
+Error at input.cq:3:4..7: mismatched input 'abc' expecting '='
diff --git a/res/v3x/parsing/program/newlines_before_version/ast.golden.txt b/res/v3x/parsing/program/newlines_before_version/ast.golden.txt
index d963d53c7..be3758d1a 100644
--- a/res/v3x/parsing/program/newlines_before_version/ast.golden.txt
+++ b/res/v3x/parsing/program/newlines_before_version/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/program/newlines_before_version/semantic.3.0.golden.txt b/res/v3x/parsing/program/newlines_before_version/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/program/newlines_before_version/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/program/newlines_before_version/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/program/no_statement_separators_after_last_statement/ast.golden.txt b/res/v3x/parsing/program/no_statement_separators_after_last_statement/ast.golden.txt
index 59b6677ab..7e82c99b9 100644
--- a/res/v3x/parsing/program/no_statement_separators_after_last_statement/ast.golden.txt
+++ b/res/v3x/parsing/program/no_statement_separators_after_last_statement/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:2:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:3:1..2
           name: <
             Identifier(
@@ -46,7 +44,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/program/no_statement_separators_after_last_statement/semantic.3.0.golden.txt b/res/v3x/parsing/program/no_statement_separators_after_last_statement/semantic.3.0.golden.txt
index 31a0998bb..c1e59b817 100644
--- a/res/v3x/parsing/program/no_statement_separators_after_last_statement/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/program/no_statement_separators_after_last_statement/semantic.3.0.golden.txt
@@ -6,17 +6,6 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        Qubit(
-          size: 1
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
@@ -43,5 +32,16 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/program/no_statement_separators_after_version/ast.golden.txt b/res/v3x/parsing/program/no_statement_separators_after_version/ast.golden.txt
index 48331a4b4..9062b4184 100644
--- a/res/v3x/parsing/program/no_statement_separators_after_version/ast.golden.txt
+++ b/res/v3x/parsing/program/no_statement_separators_after_version/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/program/no_statement_separators_after_version/semantic.3.0.golden.txt b/res/v3x/parsing/program/no_statement_separators_after_version/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/program/no_statement_separators_after_version/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/program/no_statement_separators_after_version/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/program/statement_separators_after_statements/ast.golden.txt b/res/v3x/parsing/program/statement_separators_after_statements/ast.golden.txt
index 59b6677ab..7e82c99b9 100644
--- a/res/v3x/parsing/program/statement_separators_after_statements/ast.golden.txt
+++ b/res/v3x/parsing/program/statement_separators_after_statements/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:2:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:3:1..2
           name: <
             Identifier(
@@ -46,7 +44,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/program/statement_separators_after_statements/semantic.3.0.golden.txt b/res/v3x/parsing/program/statement_separators_after_statements/semantic.3.0.golden.txt
index 31a0998bb..c1e59b817 100644
--- a/res/v3x/parsing/program/statement_separators_after_statements/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/program/statement_separators_after_statements/semantic.3.0.golden.txt
@@ -6,17 +6,6 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        Qubit(
-          size: 1
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
@@ -43,5 +32,16 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/program/statement_separators_before_eof/ast.golden.txt b/res/v3x/parsing/program/statement_separators_before_eof/ast.golden.txt
index 48331a4b4..9062b4184 100644
--- a/res/v3x/parsing/program/statement_separators_before_eof/ast.golden.txt
+++ b/res/v3x/parsing/program/statement_separators_before_eof/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/program/statement_separators_before_eof/semantic.3.0.golden.txt b/res/v3x/parsing/program/statement_separators_before_eof/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/program/statement_separators_before_eof/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/program/statement_separators_before_eof/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/program/statement_separators_between_statements/ast.golden.txt b/res/v3x/parsing/program/statement_separators_between_statements/ast.golden.txt
index 7cd672c4a..5fce185b3 100644
--- a/res/v3x/parsing/program/statement_separators_between_statements/ast.golden.txt
+++ b/res/v3x/parsing/program/statement_separators_between_statements/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:2:7..8
           name: <
             Identifier(
@@ -26,8 +26,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:4:1..2
           name: <
             Identifier(
@@ -46,7 +44,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/program/statement_separators_between_statements/semantic.3.0.golden.txt b/res/v3x/parsing/program/statement_separators_between_statements/semantic.3.0.golden.txt
index 31a0998bb..c1e59b817 100644
--- a/res/v3x/parsing/program/statement_separators_between_statements/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/program/statement_separators_between_statements/semantic.3.0.golden.txt
@@ -6,17 +6,6 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        Qubit(
-          size: 1
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
@@ -43,5 +32,16 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/qubit_array_definition/qubit_array_of_0_q/ast.golden.txt b/res/v3x/parsing/qubit_array_definition/qubit_array_of_0_q/ast.golden.txt
index ef5067f0f..3e862d5b1 100644
--- a/res/v3x/parsing/qubit_array_definition/qubit_array_of_0_q/ast.golden.txt
+++ b/res/v3x/parsing/qubit_array_definition/qubit_array_of_0_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:10..11
           name: <
             Identifier(
@@ -30,9 +30,7 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: []
-      measure_instructions: []
+      ]
     )
   >
 )
diff --git a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_equal/ast.golden.txt b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_equal/ast.golden.txt
index 6394fa98a..d2c8de678 100644
--- a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_equal/ast.golden.txt
+++ b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_equal/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:11: token recognition error at: '=\n'
+Error at input.cq:3:11..12: mismatched input '=' expecting IDENTIFIER
diff --git a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q/ast.golden.txt b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q/ast.golden.txt
index 79f861012..cb5d2eb5c 100644
--- a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q/ast.golden.txt
+++ b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:11..12
           name: <
             Identifier(
@@ -30,9 +30,7 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: []
-      measure_instructions: []
+      ]
     )
   >
 )
diff --git a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q/semantic.3.0.golden.txt b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q/semantic.3.0.golden.txt
index 84377b207..74e36d847 100644
--- a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q/semantic.3.0.golden.txt
@@ -6,7 +6,12 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: [
     Variable(
       name: q
       typ: <
@@ -16,11 +21,6 @@ Program(
       >
       annotations: []
     )
-  >
-  block: <
-    Block(
-      statements: []
-    )
-  >
+  ]
 )
 
diff --git a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q0_q1/ast.golden.txt b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q0_q1/ast.golden.txt
index 9fd93a570..40e958ecd 100644
--- a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q0_q1/ast.golden.txt
+++ b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q0_q1/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:16..17: mismatched input '\n' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}
+Error at input.cq:3:14..16: extraneous input 'q1' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/ast.golden.txt b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/ast.golden.txt
index bcc7eda36..bf9c02152 100644
--- a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/ast.golden.txt
+++ b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/ast.golden.txt
@@ -1,2 +1,59 @@
-ERROR
-Error at input.cq:4:1..6: extraneous input 'qubit' expecting {<EOF>, NEW_LINE, ';'}
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:11..12
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..10
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 17
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:11..12
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..10
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: <
+                IntegerLiteral(
+                  value: 17
+                )
+              >
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/semantic.3.0.golden.txt b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/semantic.3.0.golden.txt
index 89d3fa675..66db44e5b 100644
--- a/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/qubit_array_definition/qubit_array_of_17_q__qubit_array_of_17_q/semantic.3.0.golden.txt
@@ -11,7 +11,6 @@ Program(
       statements: []
     )
   >
-  functions: []
   variables: [
     Variable(
       name: q
diff --git a/res/v3x/parsing/qubit_array_definition/qubit_array_of_equal/ast.golden.txt b/res/v3x/parsing/qubit_array_definition/qubit_array_of_equal/ast.golden.txt
index e25340875..16b4ec8e5 100644
--- a/res/v3x/parsing/qubit_array_definition/qubit_array_of_equal/ast.golden.txt
+++ b/res/v3x/parsing/qubit_array_definition/qubit_array_of_equal/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:7: token recognition error at: '=]'
+Error at input.cq:3:7..8: mismatched input '=' expecting INTEGER_LITERAL
diff --git a/res/v3x/parsing/qubit_definition/qqubit_q/ast.golden.txt b/res/v3x/parsing/qubit_definition/qqubit_q/ast.golden.txt
index 7b3568bc4..33c35bdb3 100644
--- a/res/v3x/parsing/qubit_definition/qqubit_q/ast.golden.txt
+++ b/res/v3x/parsing/qubit_definition/qqubit_q/ast.golden.txt
@@ -1,2 +1,32 @@
-ERROR
-Error at input.cq:3:1..6: no viable alternative at input '\n\nQubit'
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Gate( # input.cq:3:1..6
+          name: <
+            Identifier(
+              name: Qubit
+            )
+          >
+          operands: <
+            ExpressionList(
+              items: [
+                Identifier( # input.cq:3:7..8
+                  name: q
+                )
+              ]
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/qubit_definition/qubit_equal/ast.golden.txt b/res/v3x/parsing/qubit_definition/qubit_equal/ast.golden.txt
index 02893bffc..997a4f267 100644
--- a/res/v3x/parsing/qubit_definition/qubit_equal/ast.golden.txt
+++ b/res/v3x/parsing/qubit_definition/qubit_equal/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:7: token recognition error at: '=\n'
+Error at input.cq:3:7..8: mismatched input '=' expecting IDENTIFIER
diff --git a/res/v3x/parsing/qubit_definition/qubit_q/ast.golden.txt b/res/v3x/parsing/qubit_definition/qubit_q/ast.golden.txt
index a39d37f0c..2dc90a8b3 100644
--- a/res/v3x/parsing/qubit_definition/qubit_q/ast.golden.txt
+++ b/res/v3x/parsing/qubit_definition/qubit_q/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:7..8
           name: <
             Identifier(
@@ -26,9 +26,7 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: []
-      measure_instructions: []
+      ]
     )
   >
 )
diff --git a/res/v3x/parsing/qubit_definition/qubit_q/semantic.3.0.golden.txt b/res/v3x/parsing/qubit_definition/qubit_q/semantic.3.0.golden.txt
index 8ce6c39e3..ce1766976 100644
--- a/res/v3x/parsing/qubit_definition/qubit_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/qubit_definition/qubit_q/semantic.3.0.golden.txt
@@ -6,7 +6,12 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: [
     Variable(
       name: q
       typ: <
@@ -16,11 +21,6 @@ Program(
       >
       annotations: []
     )
-  >
-  block: <
-    Block(
-      statements: []
-    )
-  >
+  ]
 )
 
diff --git a/res/v3x/parsing/qubit_definition/qubit_q0_q1/ast.golden.txt b/res/v3x/parsing/qubit_definition/qubit_q0_q1/ast.golden.txt
index 101192879..58747bdca 100644
--- a/res/v3x/parsing/qubit_definition/qubit_q0_q1/ast.golden.txt
+++ b/res/v3x/parsing/qubit_definition/qubit_q0_q1/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:3:12..13: mismatched input '\n' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}
+Error at input.cq:3:10..12: extraneous input 'q1' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/qubit_definition/qubit_q1__qubit_q2/ast.golden.txt b/res/v3x/parsing/qubit_definition/qubit_q1__qubit_q2/ast.golden.txt
index bcc7eda36..636e5a1bf 100644
--- a/res/v3x/parsing/qubit_definition/qubit_q1__qubit_q2/ast.golden.txt
+++ b/res/v3x/parsing/qubit_definition/qubit_q1__qubit_q2/ast.golden.txt
@@ -1,2 +1,51 @@
-ERROR
-Error at input.cq:4:1..6: extraneous input 'qubit' expecting {<EOF>, NEW_LINE, ';'}
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:7..9
+          name: <
+            Identifier(
+              name: q1
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..6
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:7..9
+          name: <
+            Identifier(
+              name: q2
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..6
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/qubit_definition/qubit_q1__qubit_q2/semantic.3.0.golden.txt b/res/v3x/parsing/qubit_definition/qubit_q1__qubit_q2/semantic.3.0.golden.txt
new file mode 100644
index 000000000..a26322187
--- /dev/null
+++ b/res/v3x/parsing/qubit_definition/qubit_q1__qubit_q2/semantic.3.0.golden.txt
@@ -0,0 +1,35 @@
+SUCCESS
+Program(
+  api_version: 3.0
+  version: <
+    Version(
+      items: 3
+    )
+  >
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: [
+    Variable(
+      name: q1
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+    Variable(
+      name: q2
+      typ: <
+        Qubit(
+          size: 1
+        )
+      >
+      annotations: []
+    )
+  ]
+)
+
diff --git a/res/v3x/parsing/qubit_definition/qubit_q__qubit_q/ast.golden.txt b/res/v3x/parsing/qubit_definition/qubit_q__qubit_q/ast.golden.txt
index bcc7eda36..94ac15dad 100644
--- a/res/v3x/parsing/qubit_definition/qubit_q__qubit_q/ast.golden.txt
+++ b/res/v3x/parsing/qubit_definition/qubit_q__qubit_q/ast.golden.txt
@@ -1,2 +1,51 @@
-ERROR
-Error at input.cq:4:1..6: extraneous input 'qubit' expecting {<EOF>, NEW_LINE, ';'}
+SUCCESS
+Program(
+  version: <
+    Version( # input.cq:1:9..10
+      items: 3
+    )
+  >
+  block: <
+    GlobalBlock(
+      statements: [
+        Variable( # input.cq:3:7..8
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:3:1..6
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+        Variable( # input.cq:4:7..8
+          name: <
+            Identifier(
+              name: q
+            )
+          >
+          typ: <
+            Type( # input.cq:4:1..6
+              name: <
+                Keyword(
+                  name: qubit
+                )
+              >
+              size: -
+            )
+          >
+          annotations: []
+        )
+      ]
+    )
+  >
+)
+
diff --git a/res/v3x/parsing/qubit_definition/qubit_q__qubit_q/semantic.3.0.golden.txt b/res/v3x/parsing/qubit_definition/qubit_q__qubit_q/semantic.3.0.golden.txt
index 7a18a6aee..6e5ea893f 100644
--- a/res/v3x/parsing/qubit_definition/qubit_q__qubit_q/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/qubit_definition/qubit_q__qubit_q/semantic.3.0.golden.txt
@@ -11,7 +11,6 @@ Program(
       statements: []
     )
   >
-  functions: []
   variables: [
     Variable(
       name: q
diff --git a/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/ast.golden.json b/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/ast.golden.json
index 8384c0642..d90fbabed 100644
--- a/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/ast.golden.json
+++ b/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/ast.golden.json
@@ -1,1 +1,1 @@
-{"Program":{"version":{"Version":{"items":"3","source_location":"input.cq:1:9..10"}},"block":{"GlobalBlock":{"qubit_variable_declaration":{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"4"}},"source_location":"input.cq:3:1..9"}},"annotations":"[]","source_location":"input.cq:3:10..11"}},"gates":[{"Gate":{"name":{"Identifier":{"name":"CNOT"}},"operands":{"ExpressionList":{"items":[{"Index":{"expr":{"Identifier":{"name":"q"}},"indices":{"IndexList":{"items":[{"IndexItem":{"index":{"IntegerLiteral":{"value":"0","source_location":"input.cq:5:8..9"}}}},{"IndexItem":{"index":{"IntegerLiteral":{"value":"1","source_location":"input.cq:5:11..12"}}}}]}},"source_location":"input.cq:5:6..7"}},{"Index":{"expr":{"Identifier":{"name":"q"}},"indices":{"IndexList":{"items":[{"IndexItem":{"index":{"IntegerLiteral":{"value":"3","source_location":"input.cq:5:17..18"}}}},{"IndexItem":{"index":{"IntegerLiteral":{"value":"2","source_location":"input.cq:5:20..21"}}}}]}},"source_location":"input.cq:5:15..16"}}]}},"annotations":"[]","source_location":"input.cq:5:1..5"}}],"measure_instructions":"[]"}}}}
\ No newline at end of file
+{"Program":{"version":{"Version":{"items":"3","source_location":"input.cq:1:9..10"}},"block":{"GlobalBlock":{"statements":[{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"4"}},"source_location":"input.cq:3:1..9"}},"annotations":"[]","source_location":"input.cq:3:10..11"}},{"Gate":{"name":{"Identifier":{"name":"CNOT"}},"operands":{"ExpressionList":{"items":[{"Index":{"expr":{"Identifier":{"name":"q"}},"indices":{"IndexList":{"items":[{"IndexItem":{"index":{"IntegerLiteral":{"value":"0","source_location":"input.cq:5:8..9"}}}},{"IndexItem":{"index":{"IntegerLiteral":{"value":"1","source_location":"input.cq:5:11..12"}}}}]}},"source_location":"input.cq:5:6..7"}},{"Index":{"expr":{"Identifier":{"name":"q"}},"indices":{"IndexList":{"items":[{"IndexItem":{"index":{"IntegerLiteral":{"value":"3","source_location":"input.cq:5:17..18"}}}},{"IndexItem":{"index":{"IntegerLiteral":{"value":"2","source_location":"input.cq:5:20..21"}}}}]}},"source_location":"input.cq:5:15..16"}}]}},"annotations":"[]","source_location":"input.cq:5:1..5"}}]}}}}
\ No newline at end of file
diff --git a/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/ast.golden.txt b/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/ast.golden.txt
index 9bfef0470..bec25619b 100644
--- a/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/ast.golden.txt
+++ b/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/ast.golden.txt
@@ -7,7 +7,7 @@ Program(
   >
   block: <
     GlobalBlock(
-      qubit_variable_declaration: <
+      statements: [
         Variable( # input.cq:3:10..11
           name: <
             Identifier(
@@ -30,8 +30,6 @@ Program(
           >
           annotations: []
         )
-      >
-      gates: [
         Gate( # input.cq:5:1..5
           name: <
             Identifier(
@@ -101,7 +99,6 @@ Program(
           annotations: []
         )
       ]
-      measure_instructions: []
     )
   >
 )
diff --git a/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/semantic.3.0.golden.json b/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/semantic.3.0.golden.json
index b3d0d45a5..b3c8f15a5 100644
--- a/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/semantic.3.0.golden.json
+++ b/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/semantic.3.0.golden.json
@@ -1,1 +1,1 @@
-{"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"qubit_variable_declaration":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"4"}},"annotations":"[]"}},"block":{"Block":{"statements":[{"Instruction":{"instruction_ref":"CNOT(qubit array, qubit array)","name":"CNOT","operands":[{"IndexRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"4"}},"annotations":"[]"}},"indices":[{"ConstInt":{"value":"0"}},{"ConstInt":{"value":"1"}}]}},{"IndexRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"4"}},"annotations":"[]"}},"indices":[{"ConstInt":{"value":"3"}},{"ConstInt":{"value":"2"}}]}}],"annotations":"[]"}}]}}}}
\ No newline at end of file
+{"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"block":{"Block":{"statements":[{"Instruction":{"instruction_ref":"CNOT(qubit array, qubit array)","name":"CNOT","operands":[{"IndexRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"4"}},"annotations":"[]"}},"indices":[{"ConstInt":{"value":"0"}},{"ConstInt":{"value":"1"}}]}},{"IndexRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"4"}},"annotations":"[]"}},"indices":[{"ConstInt":{"value":"3"}},{"ConstInt":{"value":"2"}}]}}],"annotations":"[]"}}]}},"variables":[{"Variable":{"name":"q","typ":{"QubitArray":{"size":"4"}},"annotations":"[]"}}]}}
\ No newline at end of file
diff --git a/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/semantic.3.0.golden.txt b/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/semantic.3.0.golden.txt
index df75927d6..49f3ed4c7 100644
--- a/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/sgmq/cnot_q_0_1_q_3_2/semantic.3.0.golden.txt
@@ -6,17 +6,6 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: <
-    Variable(
-      name: q
-      typ: <
-        QubitArray(
-          size: 4
-        )
-      >
-      annotations: []
-    )
-  >
   block: <
     Block(
       statements: [
@@ -72,5 +61,16 @@ Program(
       ]
     )
   >
+  variables: [
+    Variable(
+      name: q
+      typ: <
+        QubitArray(
+          size: 4
+        )
+      >
+      annotations: []
+    )
+  ]
 )
 
diff --git a/res/v3x/parsing/version/version_1.0/ast.golden.txt b/res/v3x/parsing/version/version_1.0/ast.golden.txt
index 565cfe4bd..19612f51a 100644
--- a/res/v3x/parsing/version/version_1.0/ast.golden.txt
+++ b/res/v3x/parsing/version/version_1.0/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 1.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/version/version_2.0/ast.golden.txt b/res/v3x/parsing/version/version_2.0/ast.golden.txt
index 538a685a0..2f6863b70 100644
--- a/res/v3x/parsing/version/version_2.0/ast.golden.txt
+++ b/res/v3x/parsing/version/version_2.0/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 2.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/version/version_3.0/ast.golden.txt b/res/v3x/parsing/version/version_3.0/ast.golden.txt
index 48331a4b4..9062b4184 100644
--- a/res/v3x/parsing/version/version_3.0/ast.golden.txt
+++ b/res/v3x/parsing/version/version_3.0/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3.0
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/version/version_3.0/semantic.3.0.golden.txt b/res/v3x/parsing/version/version_3.0/semantic.3.0.golden.txt
index f6874cf18..7545500ec 100644
--- a/res/v3x/parsing/version/version_3.0/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/version/version_3.0/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3.0
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/version/version_3.2.1/ast.golden.txt b/res/v3x/parsing/version/version_3.2.1/ast.golden.txt
index 72f911cdf..afc53802e 100644
--- a/res/v3x/parsing/version/version_3.2.1/ast.golden.txt
+++ b/res/v3x/parsing/version/version_3.2.1/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:1:12..14: extraneous input '.1' expecting {<EOF>, NEW_LINE, ';', 'qubit'}
+Error at input.cq:1:12..14: extraneous input '.1' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/res/v3x/parsing/version/version_3/ast.golden.txt b/res/v3x/parsing/version/version_3/ast.golden.txt
index 864a5bcac..fb5958a39 100644
--- a/res/v3x/parsing/version/version_3/ast.golden.txt
+++ b/res/v3x/parsing/version/version_3/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 3
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/version/version_3/semantic.3.0.golden.txt b/res/v3x/parsing/version/version_3/semantic.3.0.golden.txt
index 5a8798024..12a646c0b 100644
--- a/res/v3x/parsing/version/version_3/semantic.3.0.golden.txt
+++ b/res/v3x/parsing/version/version_3/semantic.3.0.golden.txt
@@ -6,7 +6,11 @@ Program(
       items: 3
     )
   >
-  qubit_variable_declaration: -
-  block: -
+  block: <
+    Block(
+      statements: []
+    )
+  >
+  variables: []
 )
 
diff --git a/res/v3x/parsing/version/version_30.20/ast.golden.txt b/res/v3x/parsing/version/version_30.20/ast.golden.txt
index 9a23f9c4e..b317b9c17 100644
--- a/res/v3x/parsing/version/version_30.20/ast.golden.txt
+++ b/res/v3x/parsing/version/version_30.20/ast.golden.txt
@@ -5,6 +5,10 @@ Program(
       items: 30.20
     )
   >
-  block: -
+  block: <
+    GlobalBlock(
+      statements: []
+    )
+  >
 )
 
diff --git a/res/v3x/parsing/version/version_3_dot/ast.golden.txt b/res/v3x/parsing/version/version_3_dot/ast.golden.txt
index f8f80e585..bab1c6206 100644
--- a/res/v3x/parsing/version/version_3_dot/ast.golden.txt
+++ b/res/v3x/parsing/version/version_3_dot/ast.golden.txt
@@ -1,2 +1,2 @@
 ERROR
-Error at input.cq:1:10..11: extraneous input '.' expecting {<EOF>, NEW_LINE, ';', 'qubit'}
+Error at input.cq:1:10..11: extraneous input '.' expecting {<EOF>, NEW_LINE, ';'}
diff --git a/scripts/generate_antlr_parser.py b/scripts/generate_antlr_parser.py
index 2e5f32fe2..d46de138c 100644
--- a/scripts/generate_antlr_parser.py
+++ b/scripts/generate_antlr_parser.py
@@ -75,7 +75,8 @@ def generate_antlr_parser(input_folder, output_source_folder, output_include_fol
         for output_file in output_files:
             if output_file.endswith(".h"):
                 print(f"\t{output_file}")
-                shutil.move(os.path.join(output_source_folder, output_file), output_include_folder)
+                shutil.move(os.path.join(output_source_folder, output_file),
+                            os.path.join(output_include_folder, output_file))
     except FileNotFoundError as err:
         print("Error running java: {}".format(err.strerror))
         exit(4)
diff --git a/setup.py b/setup.py
index 85b4c4e28..979f96e59 100755
--- a/setup.py
+++ b/setup.py
@@ -27,8 +27,8 @@
 dist_dir = target_dir + os.sep + 'dist'  # wheel output directory
 cbuild_dir = target_dir + os.sep + 'cbuild'  # cmake build directory
 prefix_dir = target_dir + os.sep + 'prefix'  # cmake install prefix
-srcmod_dir = pysrc_dir + os.sep + 'module'  # libQasm Python module directory, source files only
-module_dir = target_dir + os.sep + 'module'  # libQasm Python module directory, including generated file(s)
+srcmod_dir = pysrc_dir + os.sep + 'module'  # libqasm Python module directory, source files only
+module_dir = target_dir + os.sep + 'module'  # libqasm Python module directory, including generated file(s)
 
 # Copy the handwritten Python sources into the module directory that we're telling setuptools is our source directory,
 # because setuptools insists on spamming output files into that directory.
@@ -73,7 +73,7 @@ def run(self):
 
         # Figure out how setuptools wants to name the extension file and where it wants to place it
         cqasm_target = os.path.abspath(self.get_ext_fullpath('cqasm._cqasm'))
-        target = os.path.abspath(self.get_ext_fullpath('libQasm._libQasm'))
+        target = os.path.abspath(self.get_ext_fullpath('libqasm._libqasm'))
 
         # Build the Python extension and install it where setuptools expects it
         if not os.path.exists(cbuild_dir):
@@ -96,7 +96,6 @@ def run(self):
                 ['-s:b']['libqasm/*:build_type=' + build_type]
 
                 ['-o']['libqasm/*:build_python=True']
-                ['-o']['libqasm/*:build_tests=' + build_tests]
                 # The Python library needs the compatibility headers
                 ['-o']['libqasm/*:cqasm_python_dir=' + re.escape(os.path.dirname(cqasm_target))]
                 ['-o']['libqasm/*:python_dir=' + re.escape(os.path.dirname(target))]
@@ -108,6 +107,8 @@ def run(self):
                 ['-b']['missing']
                 ['-tf']['']
             )
+            if not build_tests:
+                cmd = cmd['-c']['tools.build:skip_test=True']
             if platform.system() == "Darwin":
                 cmd = cmd['-c']['tools.build:defines=["_LIBCPP_DISABLE_AVAILABILITY"]']
             cmd & FG
@@ -161,7 +162,7 @@ def initialize_options(self):
 setup(
     name='libqasm',
     version=get_version(),
-    description='libQasm Python Package',
+    description='libqasm Python Package',
     long_description=read('README.md'),
     long_description_content_type='text/markdown',
     author='QuTech, TU Delft',
@@ -174,12 +175,12 @@ def initialize_options(self):
         'Programming Language :: Python :: 3 :: Only',
         'Topic :: Scientific/Engineering'
     ],
-    packages=['libQasm', 'cqasm', 'cqasm.v3x'],
+    packages=['libqasm', 'cqasm', 'cqasm.v3x'],
     package_dir={'': 'pybuild/module'},
     # NOTE: the library build process is completely overridden to let CMake handle it.
     # setuptools implementation is horribly broken.
     # This is here just to have the rest of setuptools understand that this is a Python module with an extension in it.
-    ext_modules=[Extension('libQasm._libQasm', [])],
+    ext_modules=[Extension('libqasm._libqasm', [])],
     cmdclass={
         'bdist': bdist,
         'bdist_wheel': bdist_wheel,
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bab211f16..22951f7b2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
 
-project(libcqasm C CXX)
+project(libqasm C CXX)
 
 #-------------------------------------------------------------------------------
 # Configuration
diff --git a/src/v3x/AnalyzeTreeGenAstVisitor.cpp b/src/v3x/AnalyzeTreeGenAstVisitor.cpp
index d47e6d0d0..03ac7f7c5 100644
--- a/src/v3x/AnalyzeTreeGenAstVisitor.cpp
+++ b/src/v3x/AnalyzeTreeGenAstVisitor.cpp
@@ -23,13 +23,9 @@ std::any AnalyzeTreeGenAstVisitor::visit_program(ast::Program &program_ast) {
     result_.root = tree::make<semantic::Program>();
     result_.root->api_version = analyzer_.api_version;
     result_.root->version = std::any_cast<tree::One<semantic::Version>>(visit_version(*program_ast.version));
-    if (!program_ast.block.empty()) {
-        auto [block, variables] = std::any_cast<GlobalBlockReturnT>(visit_global_block(*program_ast.block));
-        result_.root->block = std::move(block);
-        if (!variables.empty()) {
-            result_.root->qubit_variable_declaration = tree::Maybe<semantic::Variable>{ variables[0].get_ptr() };
-        }
-    }
+    auto [block, variables] = std::any_cast<GlobalBlockReturnT>(visit_global_block(*program_ast.block));
+    result_.root->block = std::move(block);
+    result_.root->variables = variables;
     return result_;
 }
 
@@ -62,26 +58,7 @@ std::any AnalyzeTreeGenAstVisitor::visit_version(ast::Version &node) {
 }
 
 std::any AnalyzeTreeGenAstVisitor::visit_global_block(ast::GlobalBlock &node) {
-    visit_variable(*node.qubit_variable_declaration);
-
-    for (const auto &gate_ast : node.gates) {
-        try {
-            visit_gate(*gate_ast);
-        } catch (error::AnalysisError &err) {
-            err.context(node);
-            result_.errors.push_back(std::move(err));
-        }
-    }
-
-    for (const auto &measure_instruction_ast : node.measure_instructions) {
-        try {
-            visit_measure_instruction(*measure_instruction_ast);
-        } catch (error::AnalysisError &err) {
-            err.context(node);
-            result_.errors.push_back(std::move(err));
-        }
-    }
-
+    visit_block(node);
     return GlobalBlockReturnT{ analyzer_.current_block(), analyzer_.current_variables() };
 }
 
@@ -190,17 +167,57 @@ std::any AnalyzeTreeGenAstVisitor::visit_gate(ast::Gate &node) {
     return ret;
 }
 
+bool check_qubit_and_bit_indices_have_same_size(const values::Values &operands) {
+    size_t qubit_indices_size{};
+    size_t bit_indices_size{};
+    // Instruction operands can be, whether variables references or index references
+    // Variables can be of type qubit, bit, qubit array, or bit array
+    // Qubits and bits have a single index, arrays have a size
+    // Index references point to a qubit array or bit array
+    for (const auto &operand : operands) {
+        if (auto variable_ref = operand->as_variable_ref()) {
+            const auto &variable = *variable_ref->variable;
+            if (variable.typ->as_qubit()) {
+                qubit_indices_size += 1;
+            } else if (auto qubit_array = variable.typ->as_qubit_array()) {
+                qubit_indices_size += qubit_array->size;
+            } else if (variable.typ->as_bit()) {
+                bit_indices_size += 1;
+            } else if (auto bit_array = variable.typ->as_bit_array()) {
+                bit_indices_size += bit_array->size;
+            }
+        } else if (auto index_ref = operand->as_index_ref()) {
+            const auto &variable = *index_ref->variable;
+            if (variable.typ->as_qubit() || variable.typ->as_qubit_array()) {
+                qubit_indices_size += index_ref->indices.size();
+            } else if (variable.typ->as_bit() || variable.typ->as_bit_array()) {
+                bit_indices_size += index_ref->indices.size();
+            }
+        }
+    }
+    return qubit_indices_size == bit_indices_size;
+}
+
 std::any AnalyzeTreeGenAstVisitor::visit_measure_instruction(ast::MeasureInstruction &node) {
     auto ret = tree::Maybe<semantic::Instruction>();
     try {
         // Set operand
         // Notice operands have to be added in this order
         // Otherwise instruction resolution would fail
-        auto operands = values::Values{ std::any_cast<values::Value>(visit_expression(*node.operand)) };
+        auto operands = values::Values();
+        operands.add(std::any_cast<values::Value>(visit_expression(*node.lhs)));
+        operands.add(std::any_cast<values::Value>(visit_expression(*node.rhs)));
 
         // Resolve the instruction
         ret.set(analyzer_.resolve_instruction(node.name->name, operands));
 
+        // Check qubit and bit indices have the same size
+        if (!ret->instruction_ref.empty()) {
+            if (!check_qubit_and_bit_indices_have_same_size(operands)) {
+                throw error::AnalysisError{ "qubit and bit indices have different sizes" };
+            }
+        }
+
         // Copy annotation data
         ret->annotations = std::any_cast<tree::Any<semantic::AnnotationData>>(visit_annotated(*node.as_annotated()));
         ret->copy_annotation<parser::SourceLocation>(node);
@@ -393,7 +410,7 @@ std::any AnalyzeTreeGenAstVisitor::visit_index(ast::Index &node) {
         auto variable_ref_ptr = expression->as_variable_ref();
         const auto variable_link = variable_ref_ptr->variable;
         const auto variable_type = variable_link->typ;
-        if (variable_type->as_qubit_array()) {
+        if (variable_type->as_qubit_array() || variable_type->as_bit_array()) {
             auto indices = std::any_cast<IndexListT>(visit_index_list(*node.indices));
             check_out_of_range(indices, types::size_of(variable_type));
             auto ret = tree::make<values::IndexRef>(variable_link, indices);
diff --git a/src/v3x/BuildTreeGenAstVisitor.cpp b/src/v3x/BuildTreeGenAstVisitor.cpp
index 7eb69e7e5..9a867b958 100644
--- a/src/v3x/BuildTreeGenAstVisitor.cpp
+++ b/src/v3x/BuildTreeGenAstVisitor.cpp
@@ -100,9 +100,9 @@ double BuildTreeGenAstVisitor::get_float_value(antlr4::tree::TerminalNode *node)
 std::any BuildTreeGenAstVisitor::visitProgram(CqasmParser::ProgramContext *context) {
     auto ret = tree::make<Program>();
     ret->version = std::any_cast<One<Version>>(visitVersionSection(context->versionSection()));
-    if (context->bodySection()) {
-        ret->block = std::any_cast<One<GlobalBlock>>(visitBodySection(context->bodySection())).get_ptr();
-    }
+    ret->block = context->globalBlockSection()
+        ? std::any_cast<One<GlobalBlock>>(visitGlobalBlockSection(context->globalBlockSection()))
+        : tree::make<GlobalBlock>();
     return ret;
 }
 
@@ -110,14 +110,12 @@ std::any BuildTreeGenAstVisitor::visitVersionSection(CqasmParser::VersionSection
     return visitVersion(context->version());
 }
 
-std::any BuildTreeGenAstVisitor::visitBodySection(CqasmParser::BodySectionContext *context) {
+std::any BuildTreeGenAstVisitor::visitGlobalBlockSection(CqasmParser::GlobalBlockSectionContext *context) {
     auto ret = tree::make<GlobalBlock>();
-    ret->qubit_variable_declaration =
-        std::any_cast<One<Variable>>(visitVariableDeclarationSection(context->variableDeclarationSection()));
-    auto [gates, measure_instructions] =
-        std::any_cast<InstructionsSectionT>(visitInstructionsSection(context->instructionsSection()));
-    ret->gates = std::move(gates);
-    ret->measure_instructions = std::move(measure_instructions);
+    const auto &statements = context->globalBlockStatement();
+    std::for_each(statements.begin(), statements.end(), [this, &ret](const auto &statement_ctx) {
+        ret->statements.add(std::any_cast<One<Statement>>(statement_ctx->accept(this)));
+    });
     return ret;
 }
 
@@ -125,44 +123,6 @@ std::any BuildTreeGenAstVisitor::visitEofSection(CqasmParser::EofSectionContext
     return {};
 }
 
-std::any BuildTreeGenAstVisitor::visitVariableDeclarationSection(
-    CqasmParser::VariableDeclarationSectionContext *context) {
-    return visitVariableDeclaration(context->variableDeclaration());
-}
-
-std::any BuildTreeGenAstVisitor::visitInstructionsSection(CqasmParser::InstructionsSectionContext *context) {
-    auto gates = Any<Gate>{};
-    if (context->gatesSection()) {
-        gates = std::any_cast<Any<Gate>>(visitGatesSection(context->gatesSection()));
-    }
-    auto measure_instructions = Any<MeasureInstruction>{};
-    if (context->measureInstructionsSection()) {
-        measure_instructions = std::any_cast<Any<MeasureInstruction>>(
-            visitMeasureInstructionsSection(context->measureInstructionsSection()));
-    }
-    return InstructionsSectionT{ std::move(gates), std::move(measure_instructions) };
-}
-
-std::any BuildTreeGenAstVisitor::visitGatesSection(CqasmParser::GatesSectionContext *context) {
-    auto ret = Any<Gate>{};
-    const auto &gates = context->gate();
-    std::for_each(gates.begin(), gates.end(), [this, &ret](const auto &gate_ctx) {
-        ret.add(std::any_cast<One<Gate>>(gate_ctx->accept(this)));
-    });
-    return ret;
-}
-
-std::any BuildTreeGenAstVisitor::visitMeasureInstructionsSection(
-    CqasmParser::MeasureInstructionsSectionContext *context) {
-    auto ret = Any<MeasureInstruction>{};
-    const auto &measure_instructions = context->measureInstruction();
-    std::for_each(measure_instructions.begin(), measure_instructions.end(),
-        [this, &ret](const auto &measure_instruction_ctx) {
-    ret.add(std::any_cast<One<MeasureInstruction>>(measure_instruction_ctx->accept(this)));
-    });
-    return ret;
-}
-
 std::any BuildTreeGenAstVisitor::visitStatementSeparator(CqasmParser::StatementSeparatorContext *) {
     return {};
 }
@@ -183,12 +143,26 @@ std::any BuildTreeGenAstVisitor::visitVersion(CqasmParser::VersionContext *conte
     return ret;
 }
 
-std::any BuildTreeGenAstVisitor::visitVariableDeclaration(CqasmParser::VariableDeclarationContext *context) {
-    return visitVariableDefinition(context->variableDefinition());
+std::any BuildTreeGenAstVisitor::visitGlobalBlockStatement(CqasmParser::GlobalBlockStatementContext *context) {
+    if (auto variable_definition_ctx = context->variableDefinition(); variable_definition_ctx) {
+        return variable_definition_ctx->accept(this);
+    } else if (auto instruction_ctx = context->instruction(); instruction_ctx) {
+        return instruction_ctx->accept(this);
+    }
+    throw error::AnalysisError{ "unknown local block statement type" };
 }
 
 std::any BuildTreeGenAstVisitor::visitVariableDefinition(CqasmParser::VariableDefinitionContext *context) {
-    return visitVariable(context);
+    return One<Statement>{ visitVariable(context) };
+}
+
+std::any BuildTreeGenAstVisitor::visitMeasureInstruction(CqasmParser::MeasureInstructionContext *context) {
+    auto ret = tree::make<MeasureInstruction>();
+    ret->name = tree::make<Identifier>(context->MEASURE()->getText());
+    ret->lhs = std::any_cast<One<Expression>>(context->expression(0)->accept(this));
+    ret->rhs = std::any_cast<One<Expression>>(context->expression(1)->accept(this));
+    setNodeAnnotation(ret, context->MEASURE()->getSymbol());
+    return One<Statement>{ ret };
 }
 
 std::any BuildTreeGenAstVisitor::visitGate(CqasmParser::GateContext *context) {
@@ -199,15 +173,7 @@ std::any BuildTreeGenAstVisitor::visitGate(CqasmParser::GateContext *context) {
         ret->operands->items.add(std::any_cast<One<Expression>>(context->expression()->accept(this)));
     }
     setNodeAnnotation(ret, context->IDENTIFIER()->getSymbol());
-    return ret;
-}
-
-std::any BuildTreeGenAstVisitor::visitMeasureInstruction(CqasmParser::MeasureInstructionContext *context) {
-    auto ret = tree::make<MeasureInstruction>();
-    ret->name = tree::make<Identifier>(context->MEASURE()->getText());
-    ret->operand = std::any_cast<One<Expression>>(context->expression()->accept(this));
-    setNodeAnnotation(ret, context->MEASURE()->getSymbol());
-    return ret;
+    return One<Statement>{ ret };
 }
 
 std::any BuildTreeGenAstVisitor::visitType(CqasmParser::TypeContext *context) {
@@ -224,6 +190,16 @@ std::any BuildTreeGenAstVisitor::visitQubitType(CqasmParser::QubitTypeContext *c
     return ret;
 }
 
+std::any BuildTreeGenAstVisitor::visitBitType(CqasmParser::BitTypeContext *context) {
+    auto ret =
+        tree::make<Type>(tree::make<Keyword>(types::bit_type_name), getArraySize(context->arraySizeDeclaration()));
+    setNodeAnnotation(ret, context->BIT_TYPE()->getSymbol());
+    if (context->arraySizeDeclaration()) {
+        expandNodeAnnotation(ret, context->arraySizeDeclaration()->CLOSE_BRACKET()->getSymbol());
+    }
+    return ret;
+}
+
 Maybe<IntegerLiteral> BuildTreeGenAstVisitor::getArraySize(CqasmParser::ArraySizeDeclarationContext *context) {
     return (context) ? Maybe<IntegerLiteral>{ std::any_cast<One<IntegerLiteral>>(context->accept(this)).get_ptr() }
                      : Maybe<IntegerLiteral>{};
diff --git a/src/v3x/CqasmLexer.g4 b/src/v3x/CqasmLexer.g4
index 1a6adc867..15991622e 100644
--- a/src/v3x/CqasmLexer.g4
+++ b/src/v3x/CqasmLexer.g4
@@ -11,6 +11,7 @@ SEMICOLON: ';';
 COLON: ':';
 COMMA: ',';
 DOT: '.';
+EQUALS: '=';
 OPEN_BRACKET: '[';
 CLOSE_BRACKET: ']';
 OPEN_PARENS: '(';
@@ -49,6 +50,7 @@ TERNARY_CONDITIONAL_OP: '?';
 VERSION: 'version' -> pushMode(VERSION_STATEMENT);
 MEASURE: 'measure';
 QUBIT_TYPE: 'qubit';
+BIT_TYPE: 'bit';
 
 // Numeric literals
 BOOLEAN_LITERAL: 'true' | 'false';
diff --git a/src/v3x/CqasmParser.g4 b/src/v3x/CqasmParser.g4
index 293d77509..397b53922 100644
--- a/src/v3x/CqasmParser.g4
+++ b/src/v3x/CqasmParser.g4
@@ -11,46 +11,41 @@ options {
 // by removing the need to implement some methods,
 // which would otherwise contain boilerplate code (e.g. 'statement' and 'expression')
 
-program: versionSection bodySection? eofSection;
+program: versionSection globalBlockSection? eofSection;
+
 versionSection: statementSeparator* version;
-bodySection: variableDeclarationSection instructionsSection;
-variableDeclarationSection: statementSeparator* variableDeclaration;
-instructionsSection: gatesSection? measureInstructionsSection?;
-gatesSection: (statementSeparator* gate)+;
-measureInstructionsSection: (statementSeparator* measureInstruction)+;
+
+globalBlockSection: (statementSeparator+ globalBlockStatement)+;
+
 eofSection: statementSeparator* EOF;
 
 statementSeparator: NEW_LINE | SEMICOLON;
 
 version: VERSION VERSION_NUMBER;
 
-variableDeclaration: variableDefinition;
-
-gate: IDENTIFIER (OPEN_PARENS expression CLOSE_PARENS)? expressionList;
-
-measureInstruction: MEASURE expression;
+globalBlockStatement:
+    variableDefinition
+    | instruction
+    ;
 
 variableDefinition: type IDENTIFIER;
 
+instruction:
+    expression EQUALS MEASURE expression  # measureInstruction
+    | IDENTIFIER (OPEN_PARENS expression CLOSE_PARENS)? expressionList  # gate
+    ;
+
 type: quantumType;
 
 quantumType:
     QUBIT_TYPE arraySizeDeclaration?  # qubitType
+    | BIT_TYPE arraySizeDeclaration?  # bitType
     ;
 
 arraySizeDeclaration: OPEN_BRACKET INTEGER_LITERAL CLOSE_BRACKET;
 
 expressionList: expression (COMMA expression)*;
 
-indexList: indexEntry (COMMA indexEntry)*;
-
-// Current implementation of the semantic parser will expect constant integers
-// both for the expression in indexItem and the two expressions in indexRange
-indexEntry:
-    expression  # indexItem
-    | expression COLON expression  # indexRange
-    ;
-
 // Current implementation of the semantic parser will expect constants
 // for all the expressions of the arithmetic operators
 expression:
@@ -78,3 +73,12 @@ expression:
     | INTEGER_LITERAL  # integerLiteral
     | FLOAT_LITERAL  # floatLiteral
     ;
+
+indexList: indexEntry (COMMA indexEntry)*;
+
+// Current implementation of the semantic parser will expect constant integers
+// both for the expression in indexItem and the two expressions in indexRange
+indexEntry:
+    expression  # indexItem
+    | expression COLON expression  # indexRange
+    ;
diff --git a/src/v3x/cqasm-ast.tree b/src/v3x/cqasm-ast.tree
index b79042259..1d5d130f9 100644
--- a/src/v3x/cqasm-ast.tree
+++ b/src/v3x/cqasm-ast.tree
@@ -177,9 +177,14 @@ annotated {
                     operands: One<expression_list>;
                 }
 
+                # For some instructions, like the measure instruction,
+                # we want to differentiate between left hand side and right and side operands.
+                # For a measure instruction, the right hand side operand should be a qubit,
+                # and the left hand side operand a bit.
                 measure_instruction {
                     name: One<identifier>;
-                    operand: One<expression>;
+                    lhs: One<expression>;
+                    rhs: One<expression>;
                 }
             }
         }
@@ -192,15 +197,13 @@ version {
 
 block {
     global_block {
-        qubit_variable_declaration: One<variable>;
-        gates: Any<gate>;
-        measure_instructions: Any<measure_instruction>;
+        statements: Any<statement>;
     }
 }
 
 root {
     program {
         version: One<version>;
-        block: Maybe<global_block>;
+        block: One<global_block>;
     }
 }
diff --git a/src/v3x/cqasm-semantic.tree b/src/v3x/cqasm-semantic.tree
index 16ab037b8..f4b88aaf0 100644
--- a/src/v3x/cqasm-semantic.tree
+++ b/src/v3x/cqasm-semantic.tree
@@ -76,9 +76,9 @@ program {
     # File version.
     version: One<version>;
 
-    # Qubit variable.
-    qubit_variable_declaration: Maybe<variable>;
-
     # Global scope block.
-    block: Maybe<block>;
+    block: One<block>;
+
+    # The list of variables.
+    variables: Any<variable>;
 }
diff --git a/src/v3x/cqasm-types.cpp b/src/v3x/cqasm-types.cpp
index db53522ad..d1c65094a 100644
--- a/src/v3x/cqasm-types.cpp
+++ b/src/v3x/cqasm-types.cpp
@@ -13,18 +13,22 @@ namespace cqasm::v3x::types {
  * In it, each character represents one type. The supported characters are as follows:
  *
  *  - Q = qubit
+ *  - B = bit (measurement register)
  *  - b = bool
  *  - i = int
  *  - f = float
  *  - V = qubit array
+  *  - W = bit array
  */
 Type from_spec(const char c) {
     switch (c) {
         case 'Q': return tree::make<types::Qubit>();
+        case 'B': return tree::make<types::Bit>();
         case 'b': return tree::make<types::Bool>();
         case 'i': return tree::make<types::Int>();
         case 'f': return tree::make<types::Float>();
         case 'V': return tree::make<types::QubitArray>();
+        case 'W': return tree::make<types::BitArray>();
         default: throw std::invalid_argument("unknown type code encountered");
     }
 }
@@ -59,6 +63,8 @@ std::ostream &operator<<(std::ostream &os, const Type &type) {
         os << "!EMPTY";
     } else if (type->as_qubit()) {
         os << types::qubit_type_name;
+    } else if (type->as_bit()) {
+        os << types::bit_type_name;
     } else if (type->as_bool()) {
         os << types::bool_type_name;
     } else if (type->as_int()) {
@@ -67,6 +73,8 @@ std::ostream &operator<<(std::ostream &os, const Type &type) {
         os << types::float_type_name;
     } else if (type->as_qubit_array()) {
         os << types::qubit_array_type_name;
+    } else if (type->as_bit_array()) {
+        os << types::bit_array_type_name;
     } else {
         // Fallback when no friendly repr is known
         os << *type;
diff --git a/src/v3x/cqasm-types.tree b/src/v3x/cqasm-types.tree
index 436d98167..8d1a4f598 100644
--- a/src/v3x/cqasm-types.tree
+++ b/src/v3x/cqasm-types.tree
@@ -34,7 +34,9 @@ type_base {
     # Type of a float number (IEEE double).
     float {}
 
+    bit {}
     qubit {}
 
+    bit_array {}
     qubit_array {}
 }
diff --git a/src/v3x/cqasm-values.cpp b/src/v3x/cqasm-values.cpp
index 82313332a..f973acd79 100644
--- a/src/v3x/cqasm-values.cpp
+++ b/src/v3x/cqasm-values.cpp
@@ -84,6 +84,8 @@ bool check_promote(const types::Type &from_type, const types::Type &to_type) {
 types::Type element_type_of(const types::Type &type) {
     if (types::type_check(type, tree::make<types::QubitArray>())) {
         return tree::make<types::Qubit>();
+    } else if (types::type_check(type, tree::make<types::BitArray>())) {
+        return tree::make<types::Bit>();
     } else {
         throw std::runtime_error{ fmt::format("type ({}) is not of array type", type) };
     }
diff --git a/src/v3x/register-instructions.cpp b/src/v3x/register-instructions.cpp
index a7c351171..75860a9c0 100644
--- a/src/v3x/register-instructions.cpp
+++ b/src/v3x/register-instructions.cpp
@@ -30,8 +30,10 @@ void register_instructions(analyzer::Analyzer *analyzer) {
     analyzer->register_instruction("H", "V");
     analyzer->register_instruction("I", "Q");
     analyzer->register_instruction("I", "V");
-    analyzer->register_instruction("measure", "Q");
-    analyzer->register_instruction("measure", "V");
+    analyzer->register_instruction("measure", "BQ");
+    analyzer->register_instruction("measure", "WV");
+    analyzer->register_instruction("measure", "BV");
+    analyzer->register_instruction("measure", "WQ");
     analyzer->register_instruction("mX90", "Q");
     analyzer->register_instruction("mX90", "V");
     analyzer->register_instruction("mY90", "Q");


Test patch:
diff --git a/.github/actions/python-tests/action.yaml b/.github/actions/python-tests/action.yaml
index 7a0469695..9e517785a 100644
--- a/.github/actions/python-tests/action.yaml
+++ b/.github/actions/python-tests/action.yaml
@@ -20,6 +20,11 @@ runs:
     - name: Build
       run: python -m pip install --verbose .
       shell: ${{ inputs.shell }}
-    - name: Test
+    - name: Run unit tests
       run: python -m pytest
       shell: ${{ inputs.shell }}
+    - name: Test libqasm
+      working-directory: python
+      run: |
+        python test_libqasm.py
+      shell: bash
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index cb6862bb0..8b568ff68 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -8,20 +8,6 @@ on:
   pull_request:
 
 jobs:
-  cpp-shared:
-    name: "C++ tests (shared)"
-    runs-on: ubuntu-latest
-    strategy:
-      fail-fast: false
-    steps:
-      - name: Checkout
-        uses: actions/checkout@v4
-      - uses: ./.github/actions/cpp-tests
-        with:
-          build_type: Release
-          conan_profile_host: conan/profiles/release-gcc-linux-x64-shared
-          shell: bash
-
   cpp-linux-x64:
     name: "C++ tests (gcc-clang/Linux/x64)"
     runs-on: ubuntu-latest
@@ -43,9 +29,10 @@ jobs:
           conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-${{ matrix.compiler }}-linux-x64
           shell: bash
 
-  cpp-macos-x64:
-    name: "C++ tests (clang/MacOS/x64)"
-    runs-on: macos-latest
+  cpp-linux-arm64:
+    name: "C++ tests (gcc/Linux/ARM64)"
+    runs-on: [self-hosted, ARM64, Linux]
+    container: python:3.11
     strategy:
       fail-fast: false
       matrix:
@@ -55,15 +42,26 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v4
+        # We are having problems when using zulu-opendjk Conan package on an armv8 architecture.
+        # zulu-openjdk provides the Java JRE required by the ANTLR generator.
+        # So, for the time being, we are installing Java manually for this platform
+      - name: Install dependencies
+        run: |
+          apt-get update
+          apt-get install -y default-jre pipx
+        # Add Conan to path (even before it is installed)
+      - name: Add Conan to path
+        run: |
+          echo "${HOME}/.local/bin" >> $GITHUB_PATH
       - uses: ./.github/actions/cpp-tests
         with:
           build_type: ${{ matrix.build_type }}
-          conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-apple_clang-macos-x64
+          conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-gcc-linux-arm64
           shell: bash
 
-  cpp-windows-x64:
-    name: "C++ tests (msvc/Windows/x64)"
-    runs-on: windows-latest
+  cpp-macos-x64:
+    name: "C++ tests (clang/MacOS/x64)"
+    runs-on: macos-13  # x64
     strategy:
       fail-fast: false
       matrix:
@@ -76,14 +74,12 @@ jobs:
       - uses: ./.github/actions/cpp-tests
         with:
           build_type: ${{ matrix.build_type }}
-          conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-msvc-windows-x64
-          conan_profile_build: conan/profiles/tests-${{ matrix.build_type }}-msvc-windows-x64
+          conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-apple_clang-macos-x64
           shell: bash
 
-  cpp-linux-arm64:
-    name: "C++ tests (gcc/Linux/ARM64)"
-    runs-on: [self-hosted, ARM64, Linux]
-    container: python:3.11
+  cpp-macos-arm64:
+    name: "C++ tests (clang/macos/ARM64)"
+    runs-on: macos-14  # arm64
     strategy:
       fail-fast: false
       matrix:
@@ -98,21 +94,18 @@ jobs:
         # So, for the time being, we are installing Java manually for this platform
       - name: Install dependencies
         run: |
-          apt-get update
-          apt-get install -y default-jre pipx
-        # Add Conan to path (even before it is installed)
-      - name: Add Conan to path
-        run: |
-          echo "${HOME}/.local/bin" >> $GITHUB_PATH
+          brew install java
+          echo "$(brew --prefix java)/bin" >> $GITHUB_PATH
+        shell: bash
       - uses: ./.github/actions/cpp-tests
         with:
           build_type: ${{ matrix.build_type }}
-          conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-gcc-linux-arm64
+          conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-apple_clang-macos-arm64
           shell: bash
 
-  cpp-macos-arm64:
-    name: "C++ tests (clang/macos/ARM64)"
-    runs-on: [self-hosted, ARM64, macOS]
+  cpp-windows-x64:
+    name: "C++ tests (msvc/Windows/x64)"
+    runs-on: windows-latest
     strategy:
       fail-fast: false
       matrix:
@@ -122,22 +115,29 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v4
-        # We are having problems when using zulu-opendjk Conan package on an armv8 architecture.
-        # zulu-openjdk provides the Java JRE required by the ANTLR generator.
-        # So, for the time being, we are installing Java manually for this platform
-      - name: Install dependencies
-        run: |
-          brew install java
-          echo "$(brew --prefix java)/bin" >> $GITHUB_PATH
-        shell: bash
       - uses: ./.github/actions/cpp-tests
         with:
           build_type: ${{ matrix.build_type }}
-          conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-apple_clang-macos-arm64
+          conan_profile_host: conan/profiles/tests-${{ matrix.build_type }}-msvc-windows-x64
+          conan_profile_build: conan/profiles/tests-${{ matrix.build_type }}-msvc-windows-x64
           shell: bash
 
-  js-emscripten-wasm:
-    name: "JS tests (em++/emscripten/wasm)"
+  cpp-shared:
+    name: "C++ tests (shared)"
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+      - uses: ./.github/actions/cpp-tests
+        with:
+          build_type: Release
+          conan_profile_host: conan/profiles/release-gcc-linux-x64-shared
+          shell: bash
+
+  ts-emscripten-wasm:
+    name: "TS tests (clang/emscripten/wasm)"
     runs-on: ubuntu-latest
     strategy:
       fail-fast: false
@@ -164,7 +164,7 @@ jobs:
         run: |
           conan profile detect --force
           conan remove -c "*/*"
-          conan build . -pr=conan/profiles/emscripten -pr:b=conan/profiles/release -b missing
+          conan build . -pr=conan/profiles/release-clang-emscripten-wasm -pr:b=conan/profiles/release -b missing
         shell: bash
       - name: Rename cqasm_emscripten.js to cqasm_emscripten.mjs
         working-directory: build/Release/emscripten
@@ -178,7 +178,7 @@ jobs:
       - name: Test
         working-directory: emscripten
         run: |
-          deno run -A test_cqasm.ts
+          deno run -A test_libqasm.ts
         shell: bash
 
   python-linux-x64:
@@ -201,7 +201,7 @@ jobs:
 
   python-macos-x64:
     name: "Python tests (macOS/x64)"
-    runs-on: macos-latest
+    runs-on: macos-13
     steps:
       - name: Checkout
         uses: actions/checkout@v4
@@ -217,6 +217,25 @@ jobs:
         with:
           shell: bash
 
+  python-macos-arm64:
+    name: "Python tests (macOS/arm64)"
+    runs-on: macos-14
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+      - name: Install dependencies
+        run: |
+          brew install java swig
+          echo "$(brew --prefix java)/bin" >> $GITHUB_PATH
+        shell: bash
+      - name: Export LIBQASM_BUILD_TYPE
+        run: |
+          echo "LIBQASM_BUILD_TYPE=Debug" >> $GITHUB_ENV
+        shell: bash
+      - uses: ./.github/actions/python-tests
+        with:
+          shell: bash
+
   python-windows-x64:
     name: "Python tests (Windows/x64)"
     runs-on: windows-latest
@@ -255,7 +274,7 @@ jobs:
       - cpp-windows-x64
       - cpp-linux-arm64
       - cpp-macos-arm64
-      - js-emscripten-wasm
+      - ts-emscripten-wasm
       - python-linux-x64
       - python-macos-x64
       - python-windows-x64
diff --git a/conan/profiles/tests-debug b/conan/profiles/tests-debug
index f382889b8..cc5c85edc 100644
--- a/conan/profiles/tests-debug
+++ b/conan/profiles/tests-debug
@@ -6,4 +6,3 @@ libqasm/*:build_type=Debug
 
 [options]
 libqasm/*:asan_enabled=True
-libqasm/*:build_tests=True
diff --git a/conan/profiles/tests-release b/conan/profiles/tests-release
index 19ec2aab2..8bb289fcb 100644
--- a/conan/profiles/tests-release
+++ b/conan/profiles/tests-release
@@ -6,4 +6,3 @@ libqasm/*:build_type=Release
 
 [options]
 libqasm/*:asan_enabled=True
-libqasm/*:build_tests=True
diff --git a/emscripten/test_cqasm.js b/emscripten/test_cqasm.js
deleted file mode 100644
index bd0089392..000000000
--- a/emscripten/test_cqasm.js
+++ /dev/null
@@ -1,77 +0,0 @@
-wrapper = require("../build/Release/emscripten/cqasm_emscripten.js");
-
-process.on("unhandledRejection", error => {
-    console.error("unhandledRejection", error, "\n");
-});
-
-wrapper().then(function(result) {
-    var cqasm = new result["EmscriptenWrapper"]()
-    var ret_code = 0
-
-    console.log("Hola from JavaScript!")
-
-    try {
-        var output = cqasm.get_version()
-        var expected_output = "0.6.4"
-        console.log("\nThe version of libqasm compiled with emscripten is:", output);
-        if (output !== expected_output) {
-            console.log("\tExpected output:", expected_output)
-            ret_code |= 1
-        }
-    } catch (e) { console.log(e.stack); }
-
-    try {
-        var program_1 = "version 3;qubit[5] q;h q[0:4"
-        output = cqasm.parse_string_to_json(program_1, "shor.cq")
-        expected_output = String.raw`{"errors":[{"range":{"start":{"line":1,"character":29},"end":{"line":1,"character":29}},"message":"missing ']' at '<EOF>'","severity":1,"relatedInformation":[{"location":{"uri":"file:///shor.cq","range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}}},"message":"<unknown error message>"}]}]}`
-        console.log( "\nExample 1:", program_1, "\n\tCalling parse_string_to_json...", "\n\tOutput:", output)
-        if (output !== expected_output) {
-            console.log("\tExpected output:", expected_output)
-            ret_code |= 2
-        }
-    } catch (e) { console.log(e.stack); }
-
-    try {
-        var program_2 = "version 3;qubit[5] q;h q[0:4];measure q"
-        output = cqasm.parse_string_to_json(program_2, "<unknown>")
-        expected_output = String.raw`{"Program":{"version":{"Version":{"items":"3","source_location":"<unknown>:1:9..10"}},"block":{"GlobalBlock":{"qubit_variable_declaration":{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"5"}},"source_location":"<unknown>:1:11..19"}},"annotations":"[]","source_location":"<unknown>:1:20..21"}},"gates":[{"Gate":{"name":{"Identifier":{"name":"h"}},"operands":{"ExpressionList":{"items":[{"Index":{"expr":{"Identifier":{"name":"q"}},"indices":{"IndexList":{"items":[{"IndexRange":{"first":{"IntegerLiteral":{"value":"0","source_location":"<unknown>:1:26..27"}},"last":{"IntegerLiteral":{"value":"4","source_location":"<unknown>:1:28..29"}}}}]}},"source_location":"<unknown>:1:24..25"}}]}},"annotations":"[]","source_location":"<unknown>:1:22..23"}}],"measure_instructions":[{"MeasureInstruction":{"name":{"Identifier":{"name":"measure"}},"operand":{"Identifier":{"name":"q","source_location":"<unknown>:1:39..40"}},"annotations":"[]","source_location":"<unknown>:1:31..38"}}]}}}}`
-        console.log("\nExample 2:", program_2, "\n\tCalling parse_string_to_json...", "\n\tOutput:", output)
-        if (output !== expected_output) {
-            console.log("\tExpected output:", expected_output)
-            ret_code |= 4
-        }
-    } catch (e) {
-        console.log(e.stack);
-    }
-
-    try {
-        var program_3 = "version 3;qubit[3] q;X q[3]"
-        output = cqasm.analyze_string_to_json(program_3, "q_gym.cq")
-        expected_output = String.raw`{"errors":[{"range":{"start":{"line":1,"character":24},"end":{"line":1,"character":25}},"message":"index 3 out of range (size 3)","severity":1,"relatedInformation":[{"location":{"uri":"file:///q_gym.cq","range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}}},"message":"<unknown error message>"}]}]}`
-        console.log("\nExample 3:", program_3, "\n\tCalling analyze_string_to_json...", "\n\tOutput:", output)
-        if (output !== expected_output) {
-            console.log("\tExpected output:", expected_output)
-            ret_code |= 8
-        }
-    } catch (e) { console.log(e.stack); }
-
-    try {
-        var program_4 = "version 3;qubit[5] q;H q[0:4];measure q"
-        output = cqasm.analyze_string_to_json(program_4, "spin_q.cq")
-        expected_output = String.raw`{"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"qubit_variable_declaration":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}},"block":{"Block":{"statements":[{"Instruction":{"instruction_ref":"H(qubit array)","name":"H","operands":[{"IndexRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}},"indices":[{"ConstInt":{"value":"0"}},{"ConstInt":{"value":"1"}},{"ConstInt":{"value":"2"}},{"ConstInt":{"value":"3"}},{"ConstInt":{"value":"4"}}]}}],"annotations":"[]"}},{"Instruction":{"instruction_ref":"measure(qubit array)","name":"measure","operands":[{"VariableRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}}}}],"annotations":"[]"}}]}}}}`
-        console.log("\nExample 4:", program_4, "\n\tCalling analyze_string_to_json...", "\n\tOutput:", output)
-        if (output !== expected_output) {
-            console.log("\tExpected output:", expected_output)
-            ret_code |= 16
-        }
-    } catch (e) { console.log(e.stack); }
-
-    cqasm.delete()
-
-    if (ret_code === 0) {
-        console.log("\nOK\n")
-    } else {
-        console.log("\nError: returning", ret_code.toString(16), "\n")
-    }
-    return process.exit(ret_code)
-});
diff --git a/emscripten/test_cqasm.ts b/emscripten/test_libqasm.ts
similarity index 57%
rename from emscripten/test_cqasm.ts
rename to emscripten/test_libqasm.ts
index 29f0968a8..4cff743ef 100644
--- a/emscripten/test_cqasm.ts
+++ b/emscripten/test_libqasm.ts
@@ -8,7 +8,7 @@ wrapper().then(function(result: any) {
 
     try {
         let output = cqasm.get_version()
-        let expected_output = "0.6.5"
+        let expected_output = "0.6.6"
         console.log("\nThe version of libqasm compiled with emscripten is:", output);
         if (output !== expected_output) {
             console.log("\tExpected output:", expected_output)
@@ -19,9 +19,9 @@ wrapper().then(function(result: any) {
     }
 
     try {
-        let program_1 = "version 3;qubit[5] q;H q[0:4];measure"
+        let program_1 = "version 3;qubit[5] q;bit[5] b;H q[0:4];b = measure"
         let output = cqasm.parse_string_to_json(program_1, "shor.cq")
-        let expected_output = String.raw`{"errors":[{"range":{"start":{"line":1,"character":38},"end":{"line":1,"character":38}},"message":"mismatched input '<EOF>' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}","severity":1,"relatedInformation":[{"location":{"uri":"file:///shor.cq","range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}}},"message":"<unknown error message>"}]}]}`
+        let expected_output = String.raw`{"errors":[{"range":{"start":{"line":1,"character":51},"end":{"line":1,"character":51}},"message":"mismatched input '<EOF>' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}","severity":1,"relatedInformation":[{"location":{"uri":"file:///shor.cq","range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}}},"message":"<unknown error message>"}]}]}`
         console.log( "\nExample 1:", program_1, "\n\tCalling parse_string_to_json...", "\n\tOutput:", output)
         if (output !== expected_output) {
             console.log("\tExpected output:", expected_output)
@@ -30,9 +30,9 @@ wrapper().then(function(result: any) {
     } catch (e) { console.log(e.stack); }
 
     try {
-        let program_2 = "version 3;qubit[5] q;H q[0:4];measure q"
+        let program_2 = "version 3;qubit[5] q;bit[5] b;H q[0:4];b = measure q"
         let output = cqasm.parse_string_to_json(program_2, "<unknown>")
-        let expected_output = String.raw`{"Program":{"version":{"Version":{"items":"3","source_location":"<unknown>:1:9..10"}},"block":{"GlobalBlock":{"qubit_variable_declaration":{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"5"}},"source_location":"<unknown>:1:11..19"}},"annotations":"[]","source_location":"<unknown>:1:20..21"}},"gates":[{"Gate":{"name":{"Identifier":{"name":"H"}},"operands":{"ExpressionList":{"items":[{"Index":{"expr":{"Identifier":{"name":"q"}},"indices":{"IndexList":{"items":[{"IndexRange":{"first":{"IntegerLiteral":{"value":"0","source_location":"<unknown>:1:26..27"}},"last":{"IntegerLiteral":{"value":"4","source_location":"<unknown>:1:28..29"}}}}]}},"source_location":"<unknown>:1:24..25"}}]}},"annotations":"[]","source_location":"<unknown>:1:22..23"}}],"measure_instructions":[{"MeasureInstruction":{"name":{"Identifier":{"name":"measure"}},"operand":{"Identifier":{"name":"q","source_location":"<unknown>:1:39..40"}},"annotations":"[]","source_location":"<unknown>:1:31..38"}}]}}}}`
+        let expected_output = String.raw`{"Program":{"version":{"Version":{"items":"3","source_location":"<unknown>:1:9..10"}},"block":{"GlobalBlock":{"statements":[{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"5"}},"source_location":"<unknown>:1:11..19"}},"annotations":"[]","source_location":"<unknown>:1:20..21"}},{"Variable":{"name":{"Identifier":{"name":"b"}},"typ":{"Type":{"name":{"Keyword":{"name":"bit"}},"size":{"IntegerLiteral":{"value":"5"}},"source_location":"<unknown>:1:22..28"}},"annotations":"[]","source_location":"<unknown>:1:29..30"}},{"Gate":{"name":{"Identifier":{"name":"H"}},"operands":{"ExpressionList":{"items":[{"Index":{"expr":{"Identifier":{"name":"q"}},"indices":{"IndexList":{"items":[{"IndexRange":{"first":{"IntegerLiteral":{"value":"0","source_location":"<unknown>:1:35..36"}},"last":{"IntegerLiteral":{"value":"4","source_location":"<unknown>:1:37..38"}}}}]}},"source_location":"<unknown>:1:33..34"}}]}},"annotations":"[]","source_location":"<unknown>:1:31..32"}},{"MeasureInstruction":{"name":{"Identifier":{"name":"measure"}},"lhs":{"Identifier":{"name":"b","source_location":"<unknown>:1:40..41"}},"rhs":{"Identifier":{"name":"q","source_location":"<unknown>:1:52..53"}},"annotations":"[]","source_location":"<unknown>:1:44..51"}}]}}}}`
         console.log("\nExample 2:", program_2, "\n\tCalling parse_string_to_json...", "\n\tOutput:", output)
         if (output !== expected_output) {
             console.log("\tExpected output:", expected_output)
@@ -54,9 +54,9 @@ wrapper().then(function(result: any) {
     } catch (e) { console.log(e.stack); }
 
     try {
-        let program_4 = "version 3;qubit[5] q;H q[0:4];measure q"
+        let program_4 = "version 3;qubit[5] q;bit[5] b;H q[0:4];b = measure q"
         let output = cqasm.analyze_string_to_json(program_4, "spin_q.cq")
-        let expected_output = String.raw`{"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"qubit_variable_declaration":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}},"block":{"Block":{"statements":[{"Instruction":{"instruction_ref":"H(qubit array)","name":"H","operands":[{"IndexRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}},"indices":[{"ConstInt":{"value":"0"}},{"ConstInt":{"value":"1"}},{"ConstInt":{"value":"2"}},{"ConstInt":{"value":"3"}},{"ConstInt":{"value":"4"}}]}}],"annotations":"[]"}},{"Instruction":{"instruction_ref":"measure(qubit array)","name":"measure","operands":[{"VariableRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}}}}],"annotations":"[]"}}]}}}}`
+        let expected_output = String.raw`{"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"block":{"Block":{"statements":[{"Instruction":{"instruction_ref":"H(qubit array)","name":"H","operands":[{"IndexRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}},"indices":[{"ConstInt":{"value":"0"}},{"ConstInt":{"value":"1"}},{"ConstInt":{"value":"2"}},{"ConstInt":{"value":"3"}},{"ConstInt":{"value":"4"}}]}}],"annotations":"[]"}},{"Instruction":{"instruction_ref":"measure(bit array, qubit array)","name":"measure","operands":[{"VariableRef":{"variable":{"Variable":{"name":"b","typ":{"BitArray":{"size":"5"}},"annotations":"[]"}}}},{"VariableRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}}}}],"annotations":"[]"}}]}},"variables":[{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}},{"Variable":{"name":"b","typ":{"BitArray":{"size":"5"}},"annotations":"[]"}}]}}`
         console.log("\nExample 4:", program_4, "\n\tCalling analyze_string_to_json...", "\n\tOutput:", output)
         if (output !== expected_output) {
             console.log("\tExpected output:", expected_output)
diff --git a/python/test_libqasm.py b/python/test_libqasm.py
new file mode 100644
index 000000000..a157c9cce
--- /dev/null
+++ b/python/test_libqasm.py
@@ -0,0 +1,61 @@
+import sys
+
+import cqasm.v3x as cqasm
+
+
+class TestDataEntry:
+    def __init__(self, file_name: str, program: str, analyzer_api_name: str, expected_output: str):
+        self.file_name = file_name
+        self.program = program
+        self.analyzer_api_name = analyzer_api_name
+        self.expected_output = expected_output
+
+
+test_data_entries = [
+    TestDataEntry(
+        "shor.cq",
+        "version 3;qubit[5] q;bit[5] b;H q[0:4];b = measure",
+        "parse_string_to_json",
+        '''{"errors":[{"range":{"start":{"line":1,"character":51},"end":{"line":1,"character":51}},"message":"mismatched input '<EOF>' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}","severity":1,"relatedInformation":[{"location":{"uri":"file:///shor.cq","range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}}},"message":"<unknown error message>"}]}]}'''
+    ),
+    TestDataEntry(
+        "<unknown>",
+        "version 3;qubit[5] q;bit[5] b;H q[0:4];b = measure q",
+        "parse_string_to_json",
+        '''{"Program":{"version":{"Version":{"items":"3","source_location":"<unknown>:1:9..10"}},"block":{"GlobalBlock":{"statements":[{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"5"}},"source_location":"<unknown>:1:11..19"}},"annotations":"[]","source_location":"<unknown>:1:20..21"}},{"Variable":{"name":{"Identifier":{"name":"b"}},"typ":{"Type":{"name":{"Keyword":{"name":"bit"}},"size":{"IntegerLiteral":{"value":"5"}},"source_location":"<unknown>:1:22..28"}},"annotations":"[]","source_location":"<unknown>:1:29..30"}},{"Gate":{"name":{"Identifier":{"name":"H"}},"operands":{"ExpressionList":{"items":[{"Index":{"expr":{"Identifier":{"name":"q"}},"indices":{"IndexList":{"items":[{"IndexRange":{"first":{"IntegerLiteral":{"value":"0","source_location":"<unknown>:1:35..36"}},"last":{"IntegerLiteral":{"value":"4","source_location":"<unknown>:1:37..38"}}}}]}},"source_location":"<unknown>:1:33..34"}}]}},"annotations":"[]","source_location":"<unknown>:1:31..32"}},{"MeasureInstruction":{"name":{"Identifier":{"name":"measure"}},"lhs":{"Identifier":{"name":"b","source_location":"<unknown>:1:40..41"}},"rhs":{"Identifier":{"name":"q","source_location":"<unknown>:1:52..53"}},"annotations":"[]","source_location":"<unknown>:1:44..51"}}]}}}}'''
+    ),
+    TestDataEntry(
+        "q_gym.cq",
+        "version 3;qubit[3] q;X q[3]",
+        "analyze_string_to_json",
+        '''{"errors":[{"range":{"start":{"line":1,"character":24},"end":{"line":1,"character":25}},"message":"index 3 out of range (size 3)","severity":1,"relatedInformation":[{"location":{"uri":"file:///q_gym.cq","range":{"start":{"line":0,"character":0},"end":{"line":0,"character":0}}},"message":"<unknown error message>"}]}]}'''
+    ),
+    TestDataEntry(
+        "spin_q.cq",
+        "version 3;qubit[5] q;bit[5] b;H q[0:4];b = measure q",
+        "analyze_string_to_json",
+        '''{"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"block":{"Block":{"statements":[{"Instruction":{"instruction_ref":"H(qubit array)","name":"H","operands":[{"IndexRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}},"indices":[{"ConstInt":{"value":"0"}},{"ConstInt":{"value":"1"}},{"ConstInt":{"value":"2"}},{"ConstInt":{"value":"3"}},{"ConstInt":{"value":"4"}}]}}],"annotations":"[]"}},{"Instruction":{"instruction_ref":"measure(bit array, qubit array)","name":"measure","operands":[{"VariableRef":{"variable":{"Variable":{"name":"b","typ":{"BitArray":{"size":"5"}},"annotations":"[]"}}}},{"VariableRef":{"variable":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}}}}],"annotations":"[]"}}]}},"variables":[{"Variable":{"name":"q","typ":{"QubitArray":{"size":"5"}},"annotations":"[]"}},{"Variable":{"name":"b","typ":{"BitArray":{"size":"5"}},"annotations":"[]"}}]}}'''
+    )
+]
+
+
+def main():
+    ret_code = 0
+    for i, entry in enumerate(test_data_entries):
+        analyzer = cqasm.Analyzer()
+        print(f"\nExample {i+1}: {entry.program}\n\tCalling {entry.analyzer_api_name}...\n")
+        analyzer_api = getattr(analyzer, entry.analyzer_api_name)
+        output = analyzer_api(entry.program, entry.file_name)
+        print(f"\tOutput: {output}")
+        if output != entry.expected_output:
+            print(f"\tExpected output: {entry.expected_output}\n")
+            ret_code |= i*2
+    if ret_code == 0:
+        print("\nOK\n")
+    else:
+        print(f"\nError: returning {ret_code:04b}b\n")
+        sys.exit(ret_code)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/test/cqasm-result.cpp b/test/cqasm-result.cpp
index b8e55fcbd..a7c74c24a 100644
--- a/test/cqasm-result.cpp
+++ b/test/cqasm-result.cpp
@@ -26,7 +26,7 @@ TEST(to_json, v3x_parser_ast) {
     auto ast_result = cqasm::v3x::parser::parse_file(input_file_path.generic_string(), std::nullopt);
     auto json_result = to_json(ast_result);
     auto expected_json_result = std::string{
-        R"delim({"Program":{"version":{"Version":{"items":"3","source_location":"<unknown file name>:1:9..10"}},"block":{"GlobalBlock":{"qubit_variable_declaration":{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"0"}},"source_location":"<unknown file name>:3:1..9"}},"annotations":"[]","source_location":"<unknown file name>:3:10..11"}},"gates":"[]","measure_instructions":"[]"}}}})delim"
+        R"delim({"Program":{"version":{"Version":{"items":"3","source_location":"<unknown file name>:1:9..10"}},"block":{"GlobalBlock":{"statements":[{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"0"}},"source_location":"<unknown file name>:3:1..9"}},"annotations":"[]","source_location":"<unknown file name>:3:10..11"}}]}}}})delim"
     };
     EXPECT_EQ(json_result, expected_json_result);
 }
@@ -46,7 +46,7 @@ TEST(to_json, v3x_analyzer_ast) {
     auto semantic_ast_result = cqasm::v3x::default_analyzer().analyze_file(input_file_path.generic_string());
     auto json_result = to_json(semantic_ast_result);
     auto expected_json_result = std::string{
-        R"delim({"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"qubit_variable_declaration":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"17"}},"annotations":"[]"}},"block":{"Block":{"statements":"[]"}}}})delim"
+        R"delim({"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"block":{"Block":{"statements":"[]"}},"variables":[{"Variable":{"name":"q","typ":{"QubitArray":{"size":"17"}},"annotations":"[]"}}]}})delim"
     };
     EXPECT_EQ(json_result, expected_json_result);
 }
diff --git a/test/v3x/cpp/cqasm-analyzer.cpp b/test/v3x/cpp/cqasm-analyzer.cpp
index fb591b428..c9d394b4c 100644
--- a/test/v3x/cpp/cqasm-analyzer.cpp
+++ b/test/v3x/cpp/cqasm-analyzer.cpp
@@ -26,7 +26,7 @@ class AnalyzerAnalyzeTest : public ::testing::Test {
     version::Version version_3_0 = "3.0";
 
     tree::One<ast::Version> version = tree::make<ast::Version>(version_3_0);
-    tree::Maybe<ast::GlobalBlock> global_block{};
+    tree::One<ast::GlobalBlock> global_block = tree::make<ast::GlobalBlock>();
     tree::One<ast::Program> program = tree::make<ast::Program>(version, global_block);
     parser::ParseResult parse_result_ok = parser::ParseResult{ program, error::ParseErrors{} };
 
diff --git a/test/v3x/cpp/cqasm-parse-helper.cpp b/test/v3x/cpp/cqasm-parse-helper.cpp
index 69ed52011..ec5d8980a 100644
--- a/test/v3x/cpp/cqasm-parse-helper.cpp
+++ b/test/v3x/cpp/cqasm-parse-helper.cpp
@@ -38,8 +38,8 @@ class ParseHelperParseTest : public ::testing::Test {
     }
     void ExpectScannerParseReturnsWellFormedRoot() {
         auto one_version = tree::make<ast::Version>(version_3_0);
-        auto maybe_global_block = tree::Maybe<ast::GlobalBlock>{};
-        auto one_program = tree::make<ast::Program>(one_version, maybe_global_block);
+        auto one_global_block = tree::make<ast::GlobalBlock>();
+        auto one_program = tree::make<ast::Program>(one_version, one_global_block);
         auto parse_result = ParseResult{ one_program, error::ParseErrors{} };
         EXPECT_CALL(*scanner_up, parse()).WillOnce(::testing::Return(parse_result));
     }
diff --git a/test/v3x/python/test_analysis_result.py b/test/v3x/python/test_analysis_result.py
index 9d9504603..d1e9dcf66 100644
--- a/test/v3x/python/test_analysis_result.py
+++ b/test/v3x/python/test_analysis_result.py
@@ -17,5 +17,5 @@ def test_to_json_with_analyzer_ast(self):
         program_str = "version 3; qubit[17] q"
         v3x_analyzer = cq.Analyzer()
         actual_ast_json = v3x_analyzer.analyze_string_to_json(program_str)
-        expected_ast_json = '''{"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"qubit_variable_declaration":{"Variable":{"name":"q","typ":{"QubitArray":{"size":"17"}},"annotations":"[]"}},"block":{"Block":{"statements":"[]"}}}}'''
+        expected_ast_json = '''{"Program":{"api_version":"3.0","version":{"Version":{"items":"3"}},"block":{"Block":{"statements":"[]"}},"variables":[{"Variable":{"name":"q","typ":{"QubitArray":{"size":"17"}},"annotations":"[]"}}]}}'''
         self.assertEqual(actual_ast_json, expected_ast_json)
diff --git a/test/v3x/python/test_parse_result.py b/test/v3x/python/test_parse_result.py
index ac35acf07..8d5cb7f7c 100644
--- a/test/v3x/python/test_parse_result.py
+++ b/test/v3x/python/test_parse_result.py
@@ -17,5 +17,5 @@ def test_to_json_with_parser_ast(self):
         program_str = "version 3; qubit[0] q"
         v3x_analyzer = cq.Analyzer()
         actual_ast_json = v3x_analyzer.parse_string_to_json(program_str)
-        expected_ast_json = '''{"Program":{"version":{"Version":{"items":"3","source_location":"<unknown file name>:1:9..10"}},"block":{"GlobalBlock":{"qubit_variable_declaration":{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"0"}},"source_location":"<unknown file name>:1:12..20"}},"annotations":"[]","source_location":"<unknown file name>:1:21..22"}},"gates":"[]","measure_instructions":"[]"}}}}'''
+        expected_ast_json = '''{"Program":{"version":{"Version":{"items":"3","source_location":"<unknown file name>:1:9..10"}},"block":{"GlobalBlock":{"statements":[{"Variable":{"name":{"Identifier":{"name":"q"}},"typ":{"Type":{"name":{"Keyword":{"name":"qubit"}},"size":{"IntegerLiteral":{"value":"0"}},"source_location":"<unknown file name>:1:12..20"}},"annotations":"[]","source_location":"<unknown file name>:1:21..22"}}]}}}}'''
         self.assertEqual(actual_ast_json, expected_ast_json)
diff --git a/test/v3x/python/test_v3x_analyzer.py b/test/v3x/python/test_v3x_analyzer.py
index 4d84adaaf..46a795eb6 100644
--- a/test/v3x/python/test_v3x_analyzer.py
+++ b/test/v3x/python/test_v3x_analyzer.py
@@ -5,37 +5,44 @@
 
 class TestV3xAnalyzer(unittest.TestCase):
     def test_parse_string_returning_ast(self):
-        program_str = "version 3;qubit[5] q;H q[0:4];measure q"
+        program_str = "version 3;qubit[5] q;bit[5] b;H q[0:4];b = measure q"
         v3x_analyzer = cq.Analyzer()
         ast = v3x_analyzer.parse_string(program_str)
 
         self.assertEqual(ast.version.items[0], 3)
-        
-        qubit_array = ast.block.qubit_variable_declaration
+
+        qubit_array = ast.block.statements[0]
         self.assertEqual(qubit_array.name.name, "b'q'")
         self.assertEqual(qubit_array.typ.name.name, "b'qubit'")
         self.assertEqual(qubit_array.typ.size.value, 5)
-        
-        h_instruction = ast.block.gates[0]
+
+        bit_array = ast.block.statements[1]
+        self.assertEqual(bit_array.name.name, "b'b'")
+        self.assertEqual(bit_array.typ.name.name, "b'bit'")
+        self.assertEqual(bit_array.typ.size.value, 5)
+
+        h_instruction = ast.block.statements[2]
         self.assertEqual(h_instruction.name.name, "b'H'")
         h_operand = h_instruction.operands.items[0]
         self.assertEqual(h_operand.expr.name, "b'q'")
         self.assertEqual(h_operand.indices.items[0].first.value, 0)
         self.assertEqual(h_operand.indices.items[0].last.value, 4)
 
-        measure_instruction = ast.block.measure_instructions[0]
+        measure_instruction = ast.block.statements[3]
         self.assertEqual(measure_instruction.name.name, "b'measure'")
-        self.assertEqual(measure_instruction.operand.name, "b'q'")
+        self.assertEqual(measure_instruction.lhs.name, "b'b'")
+        self.assertEqual(measure_instruction.rhs.name, "b'q'")
 
     def test_parse_string_returning_errors(self):
-        program_str = "version 3;qubit[5] q;H q[0:4];measure"
+        program_str = "version 3;qubit[5] q;bit[5] b;H q[0:4];b = measure"
         v3x_analyzer = cq.Analyzer()
         errors = v3x_analyzer.parse_string(program_str)
-        expected_errors = ["Error at <unknown file name>:1:38: mismatched input '<EOF>' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}"]
+        print(errors)
+        expected_errors = ["Error at <unknown file name>:1:51: mismatched input '<EOF>' expecting {'(', '+', '-', '~', '!', BOOLEAN_LITERAL, INTEGER_LITERAL, FLOAT_LITERAL, IDENTIFIER}"]
         self.assertEqual(errors, expected_errors)
 
     def test_analyze_string_returning_ast(self):
-        program_str = "version 3;qubit[5] q;H q[0:4];measure q"
+        program_str = "version 3;qubit[5] q;bit[5] b;H q[0:4];b = measure q"
         v3x_analyzer = cq.Analyzer()
         ast = v3x_analyzer.analyze_string(program_str)
 
@@ -55,14 +62,21 @@ def test_analyze_string_returning_ast(self):
 
         measure_instruction = ast.block.statements[1]
         self.assertEqual(measure_instruction.name, "b'measure'")
-        measure_qubit_operand = measure_instruction.operands[0]
+        measure_bit_operand = measure_instruction.operands[0]
+        self.assertEqual(measure_bit_operand.variable.name, "b'b'")
+        self.assertIsInstance(measure_bit_operand.variable.typ, cq.types.BitArray)
+        self.assertEqual(measure_bit_operand.variable.typ.size, 5)
+        measure_qubit_operand = measure_instruction.operands[1]
         self.assertEqual(measure_qubit_operand.variable.name, "b'q'")
         self.assertIsInstance(measure_qubit_operand.variable.typ, cq.types.QubitArray)
         self.assertEqual(measure_qubit_operand.variable.typ.size, 5)
 
-        qubit_array = ast.qubit_variable_declaration
+        qubit_array = ast.variables[0]
         self.assertEqual(qubit_array.name, "b'q'")
         self.assertIsInstance(qubit_array.typ, cq.types.QubitArray)
+        bit_array = ast.variables[1]
+        self.assertEqual(bit_array.name, "b'b'")
+        self.assertIsInstance(bit_array.typ, cq.types.BitArray)
 
     def test_analyze_string_returning_errors(self):
         program_str = "version 3;qubit[3] q;X q[3]"