diff --git a/.clang-format b/.clang-format
new file mode 100644
index 0000000000..96e93e796a
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,20 @@
+---
+# This section defines defaults for all languages. Currently we derive ANTLR style from LLVM.
+BasedOnStyle: LLVM
+# Only use clang-format for C++ for now.
+DisableFormat: true
+
+---
+# This section configures C++ formatting.
+Language: Cpp
+DisableFormat: false
+Standard: c++17
+# Prevent clang-format from attempting to pick the alignment and always use right alignment.
+DerivePointerAlignment: false
+# ANTLR existing style is to right align pointers and references.
+PointerAlignment: Right
+ReferenceAlignment: Right
+# Some of ANTLR existing code is longer than the default 80, so use 100 for now.
+ColumnLimit: 100
+# Historically ANTLR has used indentation within namespaces, so replicate it.
+NamespaceIndentation: Inner
diff --git a/.editorconfig b/.editorconfig
index daa6da0fb6..1c32f7d661 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -8,3 +8,11 @@ charset = utf-8
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
+ij_java_else_on_new_line = true
+
+[*.{h,cpp}]
+charset = utf-8
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = space
+indent_size = 2
diff --git a/.gitattributes b/.gitattributes
index 5edc9289fe..3bacbd399f 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,2 +1,2 @@
# This rule applies to all files which don't match another line below
-* text=auto
+* text=auto
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index 30d0c32aa6..820db5243d 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,8 +1,15 @@
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 8ac81421f4..686759a7a9 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,5 +1,23 @@
\ No newline at end of file
+(Please make sure your PR is in a branch other than dev or master
+ and also make sure that you derive this branch from dev.)
+
+As of 4.10, ANTLR uses the Linux Foundation's Developer
+Certificate of Origin, DCO, version 1.1. See either
+https://developercertificate.org/ or file
+contributors-cert-of-origin.txt in the main directory.
+
+Each commit requires a "signature", which is simple as
+using `-s` (not `-S`) to the git commit command:
+
+git commit -s -m 'This is my commit message'
+
+Github's pull request process enforces the sig and gives
+instructions on how to fix any commits that lack the sig.
+See https://github.com/apps/dco for more info.
+
+No signature is required in this file (unlike the
+previous ANTLR contributor's certificate of origin.)
+-->
diff --git a/.github/workflows/hosted.yml b/.github/workflows/hosted.yml
new file mode 100644
index 0000000000..43a2e0f985
--- /dev/null
+++ b/.github/workflows/hosted.yml
@@ -0,0 +1,342 @@
+name: antlr4
+
+concurrency:
+ group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+on:
+ push:
+ branches: [ master, dev, hostedci ]
+ pull_request:
+ branches: [ master, dev ]
+
+permissions:
+ contents: read
+
+jobs:
+ cpp-lib-build:
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [
+ macos-15,
+ ubuntu-22.04,
+ windows-2022
+ ]
+ compiler: [ clang, gcc ]
+ unity_build: [ ON, OFF ]
+ exclude:
+ - os: windows-2022
+ compiler: gcc
+ include:
+ - os: windows-2022
+ compiler: cl
+
+ steps:
+ - name: Install dependencies (Ubuntu)
+ if: startswith(matrix.os, 'ubuntu')
+ run: |
+ sudo apt-get update -qq
+ sudo apt install -y ninja-build
+
+ - name: Install dependencies (MacOS)
+ if: startswith(matrix.os, 'macos')
+ run: brew install ninja
+
+ - name: Setup Clang
+ if: (matrix.compiler == 'clang') && !startswith(matrix.os, 'macos')
+ uses: egor-tensin/setup-clang@v1
+ with:
+ version: 13
+ platform: x64
+ cygwin: 0
+
+ - name: Check out code
+ uses: actions/checkout@v3
+
+ - name: Use ccache
+ if: startswith(matrix.os, 'macos') || startswith(matrix.os, 'ubuntu')
+ uses: hendrikmuhs/ccache-action@v1.2
+ with:
+ key: ${{ matrix.os }}-${{ matrix.compiler }}
+
+ - name: Configure shell (Ubuntu)
+ if: startswith(matrix.os, 'ubuntu')
+ run: echo 'PATH=/usr/lib/ccache:'"$PATH" >> $GITHUB_ENV
+
+ - name: Configure shell (MacOS)
+ if: startswith(matrix.os, 'macos')
+ run: echo "PATH=$(brew --prefix)/opt/ccache/libexec:$PATH" >> $GITHUB_ENV
+
+ - name: Build (Windows)
+ if: startswith(matrix.os, 'windows')
+ shell: cmd
+ run: |
+ call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+
+ if "${{ matrix.compiler }}" EQU "cl" (
+ set CC=cl
+ set CXX=cl
+ echo 'CC=cl' >> $GITHUB_ENV
+ echo 'CXX=cl' >> $GITHUB_ENV
+ ) else (
+ set CC=clang
+ set CXX=clang++
+ echo 'CC=clang' >> $GITHUB_ENV
+ echo 'CXX=clang++' >> $GITHUB_ENV
+ )
+
+ set
+ where cmake && cmake --version
+ where ninja && ninja --version
+ where %CC% && %CC% -version
+ where %CXX% && %CXX% -version
+
+ cd runtime/Cpp
+
+ cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DANTLR_BUILD_CPP_TESTS=OFF -DCMAKE_UNITY_BUILD=${{ matrix.unity_build }} -DCMAKE_UNITY_BUILD_BATCH_SIZE=20 -S . -B out/Debug
+ if %errorlevel% neq 0 exit /b %errorlevel%
+
+ cmake --build out/Debug -j %NUMBER_OF_PROCESSORS%
+ if %errorlevel% neq 0 exit /b %errorlevel%
+
+ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DANTLR_BUILD_CPP_TESTS=OFF -S . -B out/Release
+ if %errorlevel% neq 0 exit /b %errorlevel%
+
+ cmake --build out/Release -j %NUMBER_OF_PROCESSORS%
+ if %errorlevel% neq 0 exit /b %errorlevel%
+
+ - name: Build (non-Windows)
+ if: startswith(matrix.os, 'macos') || startswith(matrix.os, 'ubuntu')
+ run: |
+ if [ "${{matrix.compiler}}" == "clang" ]; then
+ export CC=clang
+ export CXX=clang++
+ echo 'CC=clang' >> $GITHUB_ENV
+ echo 'CXX=clang++' >> $GITHUB_ENV
+ else
+ export CC=gcc
+ export CXX=g++
+ echo 'CC=gcc' >> $GITHUB_ENV
+ echo 'CXX=g++' >> $GITHUB_ENV
+ fi
+
+ env
+ which cmake && cmake --version
+ which ninja && ninja --version
+ which $CC && $CC --version
+ which $CXX && $CXX --version
+
+ cd runtime/Cpp
+
+ cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug -DANTLR_BUILD_CPP_TESTS=OFF -DCMAKE_UNITY_BUILD=${{ matrix.unity_build }} -DCMAKE_UNITY_BUILD_BATCH_SIZE=20 -S . -B out/Debug
+ cmake --build out/Debug --parallel
+
+ cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DANTLR_BUILD_CPP_TESTS=OFF -S . -B out/Release
+ cmake --build out/Release --parallel
+
+ - name: Prepare artifacts
+ if: always()
+ run: |
+ cd ${{ github.workspace }}/..
+ tar czfp antlr_${{ matrix.os }}_${{ matrix.compiler }}.tgz --exclude='.git' antlr4
+ mv antlr_${{ matrix.os }}_${{ matrix.compiler }}.tgz ${{ github.workspace }}/.
+
+ - name: Archive artifacts
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@v4
+ with:
+ name: antlr_${{ matrix.os }}_${{ matrix.compiler }}
+ path: antlr_${{ matrix.os }}_${{ matrix.compiler }}.tgz
+
+
+ build:
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [
+ macos-15,
+ ubuntu-22.04,
+ windows-2022
+ ]
+ target: [
+ tool,
+ cpp,
+ csharp,
+ dart,
+ go,
+ java,
+ javascript,
+ typescript,
+ php,
+ python3,
+ # swift,
+ ]
+ exclude:
+ - os: windows-2022
+ target: swift
+
+ steps:
+ # Check out the code before setting the environment since some
+ # of the actions actually parse the files to figure out the
+ # dependencies, for instance, the setup-java actually parses
+ # **/pom.xml files to decide what to cache.
+ - name: Check out code
+ uses: actions/checkout@v3
+
+ - name: Checkout antlr PHP runtime
+ if: matrix.target == 'php'
+ uses: actions/checkout@v3
+ with:
+ repository: antlr/antlr-php-runtime
+ path: runtime/PHP
+
+ - name: Setup PHP 8.2
+ if: matrix.target == 'php'
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: '8.3'
+ extensions: mbstring
+ tools: composer
+
+ - name: Install dependencies
+ env:
+ COMPOSER_CACHE_DIR: ${{ github.workspace }}/.cache
+ if: matrix.target == 'php'
+ run: |-
+ cd runtime/PHP
+ composer install --no-progress --no-interaction --prefer-dist --optimize-autoloader
+
+ - name: Install dependencies (Ubuntu)
+ if: startswith(matrix.os, 'ubuntu')
+ run: |
+ sudo apt-get update -qq
+ sudo apt install -y ninja-build
+
+ - name: Install dependencies (MacOS)
+ if: startswith(matrix.os, 'macos')
+ run: brew install ninja
+
+ - name: Set up JDK 11
+ id: setup-java
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'zulu'
+ java-version: 11
+ cache: 'maven'
+
+ - name: Set up Maven
+ if: steps.setup-java.outputs.cache-hit != 'true'
+ uses: stCarolas/setup-maven@v4.5
+ with:
+ maven-version: 3.8.5
+
+ - name: Add msbuild to PATH
+ if: startswith(matrix.os, 'windows') && (matrix.target == 'cpp')
+ uses: microsoft/setup-msbuild@v1.1
+
+ - name: Set up Python 3
+ if: matrix.target == 'python3'
+ uses: actions/setup-python@v4
+ with:
+ python-version: '3.x'
+ architecture: 'x64'
+
+ - name: Set up Node 16
+ if: (matrix.target == 'javascript') || (matrix.target == 'typescript')
+ uses: actions/setup-node@v3.6.0
+ with:
+ node-version: '16'
+
+ - name: Setup Dotnet
+ if: matrix.target == 'csharp'
+ uses: actions/setup-dotnet@v3.0.3
+ with:
+ dotnet-version: '7.0.x'
+
+ - name: Setup Dart 2.12.1
+ if: matrix.target == 'dart'
+ uses: dart-lang/setup-dart@v1.3
+ with:
+ sdk: 2.12.1
+
+ - name: Setup Go 1.19
+ if: matrix.target == 'go'
+ uses: actions/setup-go@v3.3.1
+ with:
+ go-version: '^1.19'
+
+ - name: Setup Swift
+ if: matrix.target == 'swift'
+ uses: swift-actions/setup-swift@v1.19.0
+ with:
+ swift-version: '5.2'
+
+ - name: Use ccache
+ if: (startswith(matrix.os, 'macos') || startswith(matrix.os, 'ubuntu')) && (matrix.target == 'cpp')
+ uses: hendrikmuhs/ccache-action@v1.2
+ with:
+ key: ${{ matrix.os }}-${{ matrix.target }}
+
+ - name: Configure shell (Ubuntu)
+ if: startswith(matrix.os, 'ubuntu') && (matrix.target == 'cpp')
+ run: echo 'PATH=/usr/lib/ccache:'"$PATH" >> $GITHUB_ENV
+
+ - name: Configure shell (MacOS)
+ if: startswith(matrix.os, 'macos') && (matrix.target == 'cpp')
+ run: echo "PATH=$(brew --prefix)/opt/ccache/libexec:$PATH" >> $GITHUB_ENV
+
+ - name: Build ANTLR with Maven
+ run: mvn install -DskipTests=true -Darguments="-Dmaven.javadoc.skip=true" -B -V
+
+ - name: Test tool
+ if: matrix.target == 'tool'
+ run: |
+ cd tool-testsuite
+ mvn test
+
+ - name: Test runtime (Windows)
+ if: startsWith(matrix.os, 'windows') && (matrix.target != 'tool')
+ run: |
+ gci env:* | sort-object name
+
+ cd runtime-testsuite
+ switch ("${{ matrix.target }}")
+ {
+ python3 { mvn -X '-Dantlr-python3-exec="${{ env.pythonLocation }}\python.exe"' '-Dtest=python3.**' test }
+ default { mvn -X '-Dtest=${{ matrix.target }}.**' test }
+ }
+
+ env:
+ CMAKE_GENERATOR: Ninja
+
+ - name: Test runtime (non-Windows)
+ if: (startsWith(matrix.os, 'ubuntu') || startsWith(matrix.os, 'macos')) && (matrix.target != 'tool')
+ run: |
+ env
+
+ cd runtime-testsuite
+ case ${{ matrix.target }} in
+ python3) mvn -X '-Dantlr-python3-exec=${{ env.pythonLocation }}/bin/python' '-Dtest=python3.**' test ;;
+ *) mvn -X '-Dtest=${{ matrix.target }}.**' test ;;
+ esac
+
+ - name: Prepare artifacts
+ if: always()
+ run: |
+ cd ${{ github.workspace }}/..
+ tar czfp antlr_${{ matrix.os }}_${{ matrix.target }}.tgz --exclude='.git' antlr4
+ mv antlr_${{ matrix.os }}_${{ matrix.target }}.tgz ${{ github.workspace }}/.
+
+ - name: Archive artifacts
+ if: always()
+ continue-on-error: true
+ uses: actions/upload-artifact@v4
+ with:
+ name: antlr_${{ matrix.os }}_${{ matrix.target }}
+ path: antlr_${{ matrix.os }}_${{ matrix.target }}.tgz
diff --git a/.gitignore b/.gitignore
index adc8e5163d..b6ea50bc29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,6 @@
+# Nuget packages
+*.nupkg
+
# Maven build folders
target/
# ... but not code generation targets
@@ -21,6 +24,8 @@ user.build.properties
__pycache__/
*.py[cod]
*$py.class
+# Build results
+*.egg-info/
## CSharp and VisualStudio, selected lines from https://raw.githubusercontent.com/github/gitignore/master/VisualStudio.gitignore
# User-specific files
@@ -29,9 +34,8 @@ __pycache__/
*.userosscache
*.sln.docstates
-# User-specific files (MonoDevelop/Xamarin Studio)
+# User-specific files (MonoDevelop/Xamarin Studio/Visual Studio)
*.userprefs
-*.user
.vs/
project.lock.json
@@ -47,9 +51,6 @@ bld/
[Oo]bj/
[Ll]og/
-# Visual Studio 2015 cache/options directory
-.vs/
-
# NetBeans user configuration files
nbactions*.xml
/nbproject/private/
@@ -82,6 +83,9 @@ nbactions*.xml
/gen4/
/tool/playground/
tmp/
+**/generatedCode/*.interp
+**/generatedCode/*.tokens
+**/generatedCode/*.bak
# Configurable build files
bilder.py
@@ -97,4 +101,41 @@ xcuserdata
# VSCode Java plugin temporary files
javac-services.0.log
javac-services.0.log.lck
-test/
+
+# Don't ignore python tests
+!runtime/Python3/test/
+Antlr4.sln
+runtime/PHP
+
+# Swift binaries
+.build/
+
+# Code coverage reports
+coverage/
+
+# Cpp generated build files
+runtime/Cpp/CMakeCache.txt
+runtime/Cpp/CMakeFiles/
+runtime/Cpp/CPackConfig.cmake
+runtime/Cpp/CPackSourceConfig.cmake
+runtime/Cpp/CTestTestfile.cmake
+runtime/Cpp/Makefile
+runtime/Cpp/_deps/
+runtime/Cpp/cmake_install.cmake
+runtime/Cpp/runtime/CMakeFiles/
+runtime/Cpp/runtime/CTestTestfile.cmake
+runtime/Cpp/runtime/Makefile
+runtime/Cpp/runtime/antlr4_tests
+runtime/Cpp/runtime/antlr4_tests\[1]_include.cmake
+runtime/Cpp/runtime/antlr4_tests\[1]_tests.cmake
+runtime/Cpp/runtime/cmake_install.cmake
+runtime/Cpp/runtime/libantlr4-runtime.4.10.1.dylib
+runtime/Cpp/runtime/libantlr4-runtime.a
+runtime/Cpp/runtime/libantlr4-runtime.dylib
+/runtime/Cpp/runtime/libantlr4-runtime.4.12.0.dylib
+/runtime/Cpp/runtime/libantlr4-runtime.4.13.0.dylib
+
+# Go test and performance trace files
+**/*.pprof
+*.interp
+*.tokens
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 7944e8e32f..0000000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "runtime/PHP"]
- path = runtime/PHP
- url = https://github.com/antlr/antlr-php-runtime.git
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index aac274bebb..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,246 +0,0 @@
-sudo: true
-
-language: java
-
-branches:
- only:
- - rust-target
-
-before_cache:
- - rm -rf $HOME/.m2/repository/org/antlr
-cache:
- timeout: 600
- directories:
- - $HOME/.m2
- - $HOME/Library/Caches/Antlr4
- - $HOME/Library/Caches/Homebrew
- cargo: true
-
-stages:
- - smoke-test
- # - main-test
- # - extended-test
- - deploy
-
-jobs:
- include:
- - os: linux
- dist: trusty
- jdk: openjdk8
- cache: cargo
- env: TARGET=rust
- stage: smoke-test
- - script: skip
- before_install: skip
- stage: deploy
- deploy:
- provider: releases
- token: $GITHUB_TOKEN
- repo: rrevenantt/antlr4rust
- file: tool/target/antlr4-4.8-2-SNAPSHOT-complete.jar
- tag_name: antlr4-4.8-2-Rust-0.2
- overwrite: true
- cleanup: false
- prerelease: false
- edge: true
- on:
- tags: false
- branch: rust-target
- # - os: linux
- # dist: trusty
- # compiler: clang
- # jdk: openjdk8
- # env:
- # - TARGET=cpp
- # - CXX=g++-5
- # - GROUP=LEXER
- # stage: main-test
- # addons:
- # apt:
- # sources:
- # - ubuntu-toolchain-r-test
- # - llvm-toolchain-precise-3.7
- # packages:
- # - g++-5
- # - uuid-dev
- # - clang-3.7
- # - os: linux
- # dist: trusty
- # compiler: clang
- # jdk: openjdk8
- # env:
- # - TARGET=cpp
- # - CXX=g++-5
- # - GROUP=PARSER
- # stage: main-test
- # addons:
- # apt:
- # sources:
- # - ubuntu-toolchain-r-test
- # - llvm-toolchain-precise-3.7
- # packages:
- # - g++-5
- # - uuid-dev
- # - clang-3.7
- # - os: linux
- # dist: trusty
- # compiler: clang
- # jdk: openjdk8
- # env:
- # - TARGET=cpp
- # - CXX=g++-5
- # - GROUP=RECURSION
- # stage: main-test
- # addons:
- # apt:
- # sources:
- # - ubuntu-toolchain-r-test
- # - llvm-toolchain-precise-3.7
- # packages:
- # - g++-5
- # - uuid-dev
- # - clang-3.7
- # - os: osx
- # compiler: clang
- # osx_image: xcode10.2
- # env:
- # - TARGET=cpp
- # - GROUP=LEXER
- # stage: extended-test
- # - os: osx
- # compiler: clang
- # osx_image: xcode10.2
- # env:
- # - TARGET=cpp
- # - GROUP=PARSER
- # stage: extended-test
- # - os: osx
- # compiler: clang
- # osx_image: xcode10.2
- # env:
- # - TARGET=cpp
- # - GROUP=RECURSION
- # stage: extended-test
- # - os: osx
- # compiler: clang
- # osx_image: xcode10.2
- # env:
- # - TARGET=swift
- # - GROUP=LEXER
- # stage: main-test
- # - os: osx
- # compiler: clang
- # osx_image: xcode10.2
- # env:
- # - TARGET=swift
- # - GROUP=PARSER
- # stage: main-test
- # - os: osx
- # compiler: clang
- # osx_image: xcode10.2
- # env:
- # - TARGET=swift
- # - GROUP=RECURSION
- # stage: main-test
- # - os: linux
- # dist: xenial
- # compiler: clang
- # env:
- # - TARGET=swift
- # - GROUP=ALL
- # stage: extended-test
- # - os: osx
- # osx_image: xcode10.2
- # env:
- # - TARGET=dotnet
- # - GROUP=LEXER
- # stage: extended-test
- # - os: osx
- # osx_image: xcode10.2
- # env:
- # - TARGET=dotnet
- # - GROUP=PARSER
- # stage: extended-test
- # - os: osx
- # osx_image: xcode10.2
- # env:
- # - TARGET=dotnet
- # - GROUP=RECURSION
- # stage: extended-test
- # - os: linux
- # dist: trusty
- # jdk: openjdk7
- # env: TARGET=java
- # stage: extended-test
- - os: linux
- jdk: openjdk8
- env: TARGET=java
- stage: smoke-test
- # - os: linux
- # jdk: openjdk8
- # env: TARGET=csharp
- # stage: main-test
- # - os: linux
- # language: php
- # php:
- # - 7.2
- # jdk: openjdk8
- # env: TARGET=php
- # stage: main-test
- # - os: linux
- # jdk: openjdk8
- # dist: trusty
- # env:
- # - TARGET=dotnet
- # - GROUP=LEXER
- # stage: extended-test
- # - os: linux
- # jdk: openjdk8
- # dist: trusty
- # env:
- # - TARGET=dotnet
- # - GROUP=PARSER
- # stage: extended-test
- # - os: linux
- # jdk: openjdk8
- # dist: trusty
- # env:
- # - TARGET=dotnet
- # - GROUP=RECURSION
- # stage: extended-test
-# - os: linux
-# jdk: openjdk8
-# env: TARGET=python2
-# stage: main-test
-# - os: linux
-# jdk: openjdk8
-# env: TARGET=python3
-# addons:
-# apt:
-# sources:
-# - deadsnakes # source required so it finds the package definition below
-# packages:
-# - python3.7
-# stage: main-test
-# - os: linux
-# dist: trusty
-# jdk: openjdk8
-# env: TARGET=javascript
-# stage: main-test
-# - os: linux
-# dist: trusty
-# jdk: openjdk8
-# env: TARGET=go
-# stage: smoke-test
-
-before_install:
- - f="./.travis/before-install-$TRAVIS_OS_NAME-$TARGET.sh"; ! [ -x "$f" ] || "$f"
-
-script:
- - |
- cd runtime-testsuite;
- travis_wait 40 ../.travis/run-tests-$TARGET.sh;
- rc=$?;
- cat target/surefire-reports/*.dumpstream || true;
- exit $rc
-
diff --git a/.travis/before-install-linux-csharp.sh b/.travis/before-install-linux-csharp.sh
deleted file mode 100755
index 0872a4635e..0000000000
--- a/.travis/before-install-linux-csharp.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-echo "deb http://download.mono-project.com/repo/debian xenial main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
-sudo apt-get update -qq
-sudo apt-get install -qq mono-complete
diff --git a/.travis/before-install-linux-dotnet.sh b/.travis/before-install-linux-dotnet.sh
deleted file mode 100755
index 816044f40b..0000000000
--- a/.travis/before-install-linux-dotnet.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-# install dotnet
-sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
-sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
-sudo apt-get update
-sudo apt-get --allow-unauthenticated install dotnet-dev-1.0.4
-
diff --git a/.travis/before-install-linux-go.sh b/.travis/before-install-linux-go.sh
deleted file mode 100755
index 16c8281801..0000000000
--- a/.travis/before-install-linux-go.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-eval "$(sudo gimme 1.7.3)"
-( go version ; go env ) || true
diff --git a/.travis/before-install-linux-javascript.sh b/.travis/before-install-linux-javascript.sh
deleted file mode 100755
index 23fc8c1da9..0000000000
--- a/.travis/before-install-linux-javascript.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-sudo apt-get update -qq
-curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
-sudo apt-get install -qq nodejs
-node --version
diff --git a/.travis/before-install-linux-php.sh b/.travis/before-install-linux-php.sh
deleted file mode 100755
index b95e3b31d5..0000000000
--- a/.travis/before-install-linux-php.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-sudo apt-get update -qq
-
-php -v
-
-mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
\ No newline at end of file
diff --git a/.travis/before-install-linux-swift.sh b/.travis/before-install-linux-swift.sh
deleted file mode 100755
index 1a2b2a5550..0000000000
--- a/.travis/before-install-linux-swift.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-set -euo pipefail
-
-# install dependencies
-# some packages below will be update, swift assumes newer versions
-# of, for example, sqlite3 and libicu, without the update some
-# tools will not work
-sudo apt-get update
-sudo apt-get install clang-3.6 libxml2
-sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100
-
-# This would fix a know linker issue mentioned in:
-# https://bugs.swift.org/browse/SR-2299
-sudo ln -sf ld.gold /usr/bin/ld
diff --git a/.travis/before-install-osx-dotnet.sh b/.travis/before-install-osx-dotnet.sh
deleted file mode 100755
index a4b187709d..0000000000
--- a/.travis/before-install-osx-dotnet.sh
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-cache_dir="$HOME/Library/Caches/Antlr4"
-dotnet_url='https://download.microsoft.com/download/F/4/F/F4FCB6EC-5F05-4DF8-822C-FF013DF1B17F/dotnet-dev-osx-x64.1.1.4.pkg'
-dotnet_file=$(basename "$dotnet_url")
-dotnet_shasum='dc46d93716db8bea8cc3c668088cc9e39384b5a4'
-
-thisdir=$(dirname "$0")
-
-# OpenSSL setup for dotnet core
-mkdir -p /usr/local/lib
-ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/
-ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
-
-# download dotnet core
-mkdir -p "$cache_dir"
-(cd "$cache_dir"
- if [ -f "$dotnet_file" ]
- then
- if ! shasum -s -c <<<"$dotnet_shasum $dotnet_file"
- then
- rm -f "$dotnet_file"
- fi
- fi
- if ! [ -f "$dotnet_file" ]
- then
- curl "$dotnet_url" -o "$dotnet_file"
- fi
-)
-
-# install dotnet core
-sudo installer -pkg "$cache_dir/$dotnet_file" -target /
-
-# make the link
-ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/
diff --git a/.travis/run-tests-cpp.sh b/.travis/run-tests-cpp.sh
deleted file mode 100755
index e95dc8922d..0000000000
--- a/.travis/run-tests-cpp.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-if [ $GROUP == "LEXER" ]; then
- mvn -q -Dgroups="org.antlr.v4.test.runtime.category.LexerTests" -Dtest=cpp.* test
-elif [ $GROUP == "PARSER" ]; then
- mvn -q -Dgroups="org.antlr.v4.test.runtime.category.ParserTests" -Dtest=cpp.* test
-elif [ $GROUP == "RECURSION" ]; then
- mvn -q -Dgroups="org.antlr.v4.test.runtime.category.LeftRecursionTests" -Dtest=cpp.* test
-else
- mvn -q -Dtest=cpp.* test
-fi
-
diff --git a/.travis/run-tests-csharp.sh b/.travis/run-tests-csharp.sh
deleted file mode 100755
index 7f2c275249..0000000000
--- a/.travis/run-tests-csharp.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=csharp.* test
diff --git a/.travis/run-tests-dotnet.sh b/.travis/run-tests-dotnet.sh
deleted file mode 100755
index 4488056641..0000000000
--- a/.travis/run-tests-dotnet.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-# we need to build the runtime before test run, since we used "--no-dependencies"
-# when we call dotnet cli for restore and build, in order to speed up
-
-dotnet restore ../runtime/CSharp/runtime/CSharp/Antlr4.Runtime/Antlr4.Runtime.dotnet.csproj
-dotnet build -c Release -f netstandard1.3 ../runtime/CSharp/runtime/CSharp/Antlr4.Runtime/Antlr4.Runtime.dotnet.csproj
-
-# call test
-
-if [ $GROUP == "LEXER" ]; then
- mvn -q -Dgroups="org.antlr.v4.test.runtime.category.LexerTests" -Dparallel=classes -DthreadCount=4 -Dtest=csharp.* -Dantlr-csharp-netstandard=true test
-elif [ $GROUP == "PARSER" ]; then
- mvn -q -Dgroups="org.antlr.v4.test.runtime.category.ParserTests" -Dparallel=classes -DthreadCount=4 -Dtest=csharp.* -Dantlr-csharp-netstandard=true test
-elif [ $GROUP == "RECURSION" ]; then
- mvn -q -Dgroups="org.antlr.v4.test.runtime.category.LeftRecursionTests" -Dparallel=classes -DthreadCount=4 -Dtest=csharp.* -Dantlr-csharp-netstandard=true test
-else
- mvn -q -Dparallel=classes -DthreadCount=4 -Dtest=csharp.* -Dantlr-csharp-netstandard=true test
-fi
diff --git a/.travis/run-tests-go.sh b/.travis/run-tests-go.sh
deleted file mode 100755
index 1a127ce864..0000000000
--- a/.travis/run-tests-go.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=go.* test
diff --git a/.travis/run-tests-java.sh b/.travis/run-tests-java.sh
deleted file mode 100755
index b2fde3660d..0000000000
--- a/.travis/run-tests-java.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=java.* test
-cd ../tool-testsuite
-mvn test
diff --git a/.travis/run-tests-javascript.sh b/.travis/run-tests-javascript.sh
deleted file mode 100755
index 013321870b..0000000000
--- a/.travis/run-tests-javascript.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=node.* test
diff --git a/.travis/run-tests-php.sh b/.travis/run-tests-php.sh
deleted file mode 100755
index 853efbd86a..0000000000
--- a/.travis/run-tests-php.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-php_path=$(which php)
-
-composer install -d ../runtime/PHP
-
-mvn -q -DPHP_PATH="${php_path}" -Dparallel=methods -DthreadCount=4 -Dtest=php.* test
diff --git a/.travis/run-tests-python2.sh b/.travis/run-tests-python2.sh
deleted file mode 100755
index c5cd0ca998..0000000000
--- a/.travis/run-tests-python2.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-python --version
-
-mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=python2.* test
-
-cd ../runtime/Python2/tests
-
-python run.py
diff --git a/.travis/run-tests-python3.sh b/.travis/run-tests-python3.sh
deleted file mode 100755
index 8b74928c5c..0000000000
--- a/.travis/run-tests-python3.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-python3 --version
-
-mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=python3.* test
-
-cd ../runtime/Python3/test
-
-python3 run.py
diff --git a/.travis/run-tests-swift.sh b/.travis/run-tests-swift.sh
deleted file mode 100755
index 677f356b2c..0000000000
--- a/.travis/run-tests-swift.sh
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-# linux specific setup, those setup have to be
-# here since environment variables doesn't pass
-# across scripts
-if [ $TRAVIS_OS_NAME == "linux" ]; then
- export SWIFT_VERSION=swift-5.0.1
- export SWIFT_HOME=$(pwd)/swift/$SWIFT_VERSION-RELEASE-ubuntu16.04/usr/bin/
- export PATH=$SWIFT_HOME:$PATH
-
- # download swift
- mkdir swift
- curl https://swift.org/builds/$SWIFT_VERSION-release/ubuntu1604/$SWIFT_VERSION-RELEASE/$SWIFT_VERSION-RELEASE-ubuntu16.04.tar.gz -s | tar xz -C swift &> /dev/null
-fi
-
-if [ -z "${JAVA_HOME-}" ]
-then
- export JAVA_HOME="$(java -XshowSettings:properties -version 2>&1 |
- grep 'java\.home' | awk '{ print $3 }')"
- echo "export JAVA_HOME=$JAVA_HOME"
-fi
-
-# check swift
-swift --version
-swift build --version
-
-pushd ../runtime/Swift
-./boot.py --test
-popd
-
-if [ $GROUP == "LEXER" ]; then
- mvn -q -Dgroups="org.antlr.v4.test.runtime.category.LexerTests" -Dtest=swift.* test
-elif [ $GROUP == "PARSER" ]; then
- mvn -q -Dgroups="org.antlr.v4.test.runtime.category.ParserTests" -Dtest=swift.* test
-elif [ $GROUP == "RECURSION" ]; then
- mvn -q -Dgroups="org.antlr.v4.test.runtime.category.LeftRecursionTests" -Dtest=swift.* test
-else
- mvn -q -Dtest=swift.* test
-fi
diff --git a/ANTLR-HOUSE-RULES.md b/ANTLR-HOUSE-RULES.md
new file mode 100644
index 0000000000..4fe89e9486
--- /dev/null
+++ b/ANTLR-HOUSE-RULES.md
@@ -0,0 +1,28 @@
+# ANTLR HOUSE RULES
+
+*Last updated: Sept 10, 2022*
+
+This brief document describes best practices for us to all get along and for the benefit of the project. Collaborating on this project poses a number of difficulties:
+
+* different native languages
+* different time zones
+* lack of common company or other organization as social glue
+* we are just github userids without personal connection to most other contributors
+* those developers able to contribute to such a complex project typically have a lot of experience and, consequently, strong opinions
+
+Effective communication is difficult under the circumstances and civil discourse is a requirement to keep the project on track. Over 35 years, in-fighting between contributors has made parrt's job as supreme dictator for life much more difficult.
+
+Rules
+
+1. Assume good intentions of the other party.
+2. Try to be welcoming and respectful of differing viewpoints experiences.
+2. No personal attacks, meaning ideas can be bad in your comments but not people. Replace "You are ..." with "Your idea is ...".
+3. Control your anger please. No hate speech, racism, sexism, or ethnocentrism. No trolling or insulting. See rule #1.
+2. Be tolerant and understanding of non-native English speakers' word choice and phrasing. This is a huge source of misunderstandings; see rule #1. For example, to a native English speaker "I cannot *approve* this" makes it sound like the writer has control over the readers contribution. Instead, the writer likely meant "I cannot *support* this." See rule #1.
+3. Soften word choice to use conditional tenses and helper words. For example, use phrases such as "I'm not sure this is a good idea because ..." or "I wonder if you'd consider this other possibility: ..." etc...
+
+Supreme dictator for life parrt has final say. His decisions will not always be correct nor to your liking, but he has a difficult cost-benefit equation to solve for every bug fix, feature, and PR.
+
+Any text contrary to these house rules will likely be edited and replaced with an admonishment by parrt.
+
+Send concerns to parrt@antlr.org.
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 989acfe550..0a2317bab3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,10 +1,22 @@
# Contributing to ANTLR 4
-1. [Fork](https://help.github.com/articles/fork-a-repo) the [antlr/antlr4 repo](https://github.com/antlr/antlr4)
-2. Install and configure [EditorConfig](http://editorconfig.org/) so your text editor or IDE uses the ANTLR 4 coding style
-3. [Build ANTLR 4](doc/building-antlr.md)
-4. [Run the ANTLR project unit tests](doc/antlr-project-testing.md)
-5. Create a [pull request](https://help.github.com/articles/using-pull-requests/) including your change
+1. [Fork](https://help.github.com/articles/fork-a-repo) the [antlr/antlr4 repo](https://github.com/antlr/antlr4), which will give you both key branches, `master` and `dev`
+2. Make sure to `git checkout dev` in your fork so that you are working from the latest development branch
+3. Create and work from a branch derived from `dev` such as `git checkout -b your-branch-name`
+4. Install and configure [EditorConfig](http://editorconfig.org/) so your text editor or IDE uses the ANTLR 4 coding style
+5. [Build ANTLR 4](doc/building-antlr.md)
+6. [Run the ANTLR project unit tests](doc/antlr-project-testing.md)
+7. Create a [pull request](https://help.github.com/articles/using-pull-requests/) with your changes and make sure you're comparing your `dev`-derived branch in your fork to the `dev` branch from the `antlr/antlr4` repo:
+
-**Note:** You must sign the `contributors.txt` certificate of origin with your pull request if you've not done so before.
+**Note:** Each commit requires a "signature", which is simple as using `-s` (not
+`-S`) to the git commit command:
+
+```
+git commit -s -m 'This is my commit message'
+```
+
+Github's pull request process enforces the sig and gives instructions on how to
+fix any commits that lack the sig. See [Github DCO app](https://github.com/apps/dco)
+for more info.
diff --git a/LICENSE.txt b/LICENSE.txt
index 2042d1bda6..5d27694155 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,52 +1,28 @@
-[The "BSD 3-clause license"]
-Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+Copyright (c) 2012-2022 The ANTLR Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- 3. Neither the name of the copyright holder nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-=====
-
-MIT License for codepointat.js from https://git.io/codepointat
-MIT License for fromcodepoint.js from https://git.io/vDW1m
-
-Copyright Mathias Bynens
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+3. Neither name of copyright holders nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Package.swift b/Package.swift
new file mode 100644
index 0000000000..9d212615c1
--- /dev/null
+++ b/Package.swift
@@ -0,0 +1,38 @@
+// swift-tools-version:5.6
+
+import PackageDescription
+
+let package = Package(
+ name: "Antlr4",
+ products: [
+ .library(
+ name: "Antlr4",
+ targets: ["Antlr4"]),
+ .library(
+ name: "Antlr4Static",
+ type: .static,
+ targets: ["Antlr4"]),
+ .library(
+ name: "Antlr4Dynamic",
+ type: .dynamic,
+ targets: ["Antlr4"]),
+ ],
+ targets: [
+ .target(
+ name: "Antlr4",
+ dependencies: [],
+ path: "./runtime/Swift/Sources/Antlr4"),
+ .testTarget(
+ name: "Antlr4Tests",
+ dependencies: ["Antlr4"],
+ path: "./runtime/Swift/Tests/Antlr4Tests",
+ exclude: [
+ "./runtime/Swift/Tests/VisitorBasic.g4",
+ "./runtime/Swift/Tests/VisitorCalc.g4",
+ "./runtime/Swift/Tests/LexerA.g4",
+ "./runtime/Swift/Tests/LexerB.g4",
+ "./runtime/Swift/Tests/Threading.g4"
+ ]
+ )
+ ]
+)
diff --git a/README.md b/README.md
index ec5c21c627..206491addc 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,60 @@
# ANTLR v4
-[](https://travis-ci.org/antlr/antlr4) [](https://ci.appveyor.com/project/parrt/antlr4) [](http://java.oracle.com) [](https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt)
+[](http://java.oracle.com)
+[](https://raw.githubusercontent.com/antlr/antlr4/master/LICENSE.txt)
**ANTLR** (ANother Tool for Language Recognition) is a powerful parser generator for reading, processing, executing, or translating structured text or binary files. It's widely used to build languages, tools, and frameworks. From a grammar, ANTLR generates a parser that can build parse trees and also generates a listener interface (or visitor) that makes it easy to respond to the recognition of phrases of interest.
-*Given day-job constraints, my time working on this project is limited so I'll have to focus first on fixing bugs rather than changing/improving the feature set. Likely I'll do it in bursts every few months. Please do not be offended if your bug or pull request does not yield a response! --parrt*
+**Dev branch build status**
-[](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=BF92STRXT8F8Q)
+[](https://github.com/antlr/antlr4/actions/workflows/hosted.yml) (github actions)
+
+
+
+
+## Versioning
+
+ANTLR 4 supports 10 target languages
+(Cpp, CSharp, Dart, Java, JavaScript, PHP, Python3, Swift, TypeScript, Go),
+and ensuring consistency across these targets is a unique and highly valuable feature.
+To ensure proper support of this feature, each release of ANTLR is a complete release of the tool and the 10 runtimes, all with the same version.
+As such, ANTLR versioning does not strictly follow semver semantics:
+
+* a component may be released with the latest version number even though nothing has changed within that component since the previous release
+* major version is bumped only when ANTLR is rewritten for a totally new "generation", such as ANTLR3 -> ANTLR4 (LL(\*) -> ALL(\*) parsing)
+* minor version updates may include minor breaking changes, the policy is to regenerate parsers with every release (4.11 -> 4.12)
+* backwards compatibility is only guaranteed for patch version bumps (4.11.1 -> 4.11.2)
+
+If you use a semver verifier in your CI, you probably want to apply special rules for ANTLR, such as treating minor change as a major change.
+
+## Repo branch structure
+
+The default branch for this repo is [`master`](https://github.com/antlr/antlr4/tree/master), which is the latest stable release and has tags for the various releases; e.g., see release tag [4.9.3](https://github.com/antlr/antlr4/tree/4.9.3). Branch [`dev`](https://github.com/antlr/antlr4/tree/dev) is where development occurs between releases and all pull requests should be derived from that branch. The `dev` branch is merged back into `master` to cut a release and the release state is tagged (e.g., with `4.10-rc1` or `4.10`.) Visually our process looks roughly like this:
+
+
+
+The Go target now has its own dedicated repo:
+
+```bash
+$ go get github.com/antlr4-go/antlr
+```
+**Note**
+The dedicated Go repo is for `go get` and `import` only. Go runtime development is still performed in the main `antlr/antlr4` repo.
## Authors and major contributors
* [Terence Parr](http://www.cs.usfca.edu/~parrt/), parrt@cs.usfca.edu
ANTLR project lead and supreme dictator for life
[University of San Francisco](http://www.usfca.edu/)
-* [Sam Harwell](http://tunnelvisionlabs.com/) (Tool co-author, Java and C# target)
-* Eric Vergnaud (Javascript, Python2, Python3 targets and significant work on C# target)
+* [Sam Harwell](http://tunnelvisionlabs.com/) (Tool co-author, Java and original C# target)
+* [Eric Vergnaud](https://github.com/ericvergnaud) (Javascript, TypeScript, Python2, Python3 targets and maintenance of C# target)
* [Peter Boyer](https://github.com/pboyer) (Go target)
* [Mike Lischke](http://www.soft-gems.net/) (C++ completed target)
* Dan McLaughlin (C++ initial target)
@@ -23,6 +63,12 @@ ANTLR project lead and supreme dictator for life
* [Ewan Mellor](https://github.com/ewanmellor), [Hanzhou Shi](https://github.com/hanjoes) (Swift target merging)
* [Ben Hamilton](https://github.com/bhamiltoncx) (Full Unicode support in serialized ATN and all languages' runtimes for code points > U+FFFF)
* [Marcos Passos](https://github.com/marcospassos) (PHP target)
+* [Lingyu Li](https://github.com/lingyv-li) (Dart target)
+* [Ivan Kochurkin](https://github.com/KvanTTT) has made major contributions to overall quality, error handling, and Target performance.
+* [Justin King](https://github.com/jcking) has done a huge amount of work across multiple targets, but especially for C++.
+* [Ken Domino](https://github.com/kaby76) has a knack for finding bugs/issues and analysis; also a major contributor on the [grammars-v4 repo](https://github.com/antlr/grammars-v4).
+* [Jim Idle](https://github.com/jimidle) has contributed to previous versions of ANTLR and recently jumped back in to solve a major problem with the Go target.
+
## Useful information
@@ -31,7 +77,12 @@ ANTLR project lead and supreme dictator for life
* [Official site](http://www.antlr.org/)
* [Documentation](https://github.com/antlr/antlr4/blob/master/doc/index.md)
* [FAQ](https://github.com/antlr/antlr4/blob/master/doc/faq/index.md)
-* [ANTLR code generation targets](https://github.com/antlr/antlr4/blob/master/doc/targets.md) (Currently: Java, C#, Python2|3, JavaScript, Go, C++, Swift)
+* [ANTLR code generation targets](https://github.com/antlr/antlr4/blob/master/doc/targets.md) (Currently: Java, C#, Python3, JavaScript, TypeScript, Go, C++, Swift, Dart, PHP)
+* _Note: As of version 4.14, we are dropping support for Python 2. We love the Python
+community, but Python 2 support was officially halted in Jan 2020. More recently,
+GiHub also dropped support for Python 2, which has made it impossible for us to
+maintain a consistent level of quality across targets (we use GitHub for our CI).
+Long live Python 3!_
* [Java API](http://www.antlr.org/api/Java/index.html)
* [ANTLR v3](http://www.antlr3.org/)
* [v3 to v4 Migration, differences](https://github.com/antlr/antlr4/blob/master/doc/faq/general.md)
@@ -45,7 +96,7 @@ You might also find the following pages useful, particularly if you want to mess
Programmers run into parsing problems all the time. Whether it’s a data format like JSON, a network protocol like SMTP, a server configuration file for Apache, a PostScript/PDF file, or a simple spreadsheet macro language—ANTLR v4 and this book will demystify the process. ANTLR v4 has been rewritten from scratch to make it easier than ever to build parsers and the language applications built on top. This completely rewritten new edition of the bestselling Definitive ANTLR Reference shows you how to take advantage of these new features.
-You can buy the book [The Definitive ANTLR 4 Reference](http://amzn.com/1934356999) at amazon or an [electronic version at the publisher's site](https://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference).
+You can buy the book [The Definitive ANTLR 4 Reference](http://amzn.com/dp/1934356999) at amazon or an [electronic version at the publisher's site](https://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference).
You will find the [Book source code](http://pragprog.com/titles/tpantlr2/source_code) useful.
diff --git a/antlr4-maven-plugin/pom.xml b/antlr4-maven-plugin/pom.xml
index 76e9bd37f3..be4fb698f2 100644
--- a/antlr4-maven-plugin/pom.xml
+++ b/antlr4-maven-plugin/pom.xml
@@ -8,23 +8,18 @@
org.antlr
antlr4-master
- 4.8-2-SNAPSHOT
+ 4.13.3-SNAPSHOT
antlr4-maven-plugin
maven-plugin
ANTLR 4 Maven plugin
Maven plugin for ANTLR 4 grammars
-
- 3.0
-
-
-
+
2009
- 3.3.9
- 1.11.12
+ 3.8.5
@@ -39,13 +34,13 @@
org.apache.maven
maven-plugin-api
- 3.0.5
- compile
+ ${mavenVersion}
+ provided
org.codehaus.plexus
plexus-compiler-api
- 2.2
+ 2.12.1
org.sonatype.plexus
@@ -64,26 +59,26 @@
junit
junit
- 4.12
+ 4.13.2
test
org.apache.maven.plugin-tools
maven-plugin-annotations
- 3.2
+ 3.6.4
provided
io.takari.maven.plugins
takari-plugin-testing
- 2.9.0
+ 3.0.0
test
org.apache.maven
maven-core
${mavenVersion}
- test
+ provided
org.apache.maven
@@ -94,14 +89,19 @@
org.codehaus.plexus
plexus-utils
- 3.0.15
+ 3.4.2
provided
-
- org.apache.maven
- maven-project
- 2.2.1
-
+
+ org.slf4j
+ slf4j-api
+ 2.0.0
+
+
+ org.slf4j
+ slf4j-simple
+ 2.0.0
+
@@ -120,7 +120,7 @@
org.apache.maven.plugins
maven-plugin-plugin
- 3.3
+ 3.6.2
true
@@ -143,7 +143,7 @@
io.takari.maven.plugins
takari-lifecycle-plugin
- ${takariLifecycleVersion}
+ 2.0.7
true
@@ -155,29 +155,26 @@
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+
+
-
- org.apache.maven.plugins
- maven-plugin-plugin
- 3.3
-
org.apache.maven.plugins
maven-javadoc-plugin
- 2.10.4
+ 3.3.1
true
-
- org.apache.maven.plugins
- maven-jxr-plugin
- 2.5
-
diff --git a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java
index c0926fe6c8..3fb37a8e0e 100644
--- a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java
+++ b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java
@@ -55,7 +55,7 @@
name = "antlr4",
defaultPhase = LifecyclePhase.GENERATE_SOURCES,
requiresDependencyResolution = ResolutionScope.COMPILE,
- requiresProject = true)
+ requiresProject = true, threadSafe = true)
public class Antlr4Mojo extends AbstractMojo {
// First, let's deal with the options that the ANTLR tool itself
@@ -276,7 +276,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
for (List args : argumentSets) {
try {
// Create an instance of the ANTLR 4 build tool
- tool = new CustomTool(args.toArray(new String[args.size()]));
+ tool = new CustomTool(args.toArray(new String[0]));
} catch (Exception e) {
log.error("The attempt to create the ANTLR 4 build tool failed, see exception report for details", e);
throw new MojoFailureException("Error creating an instanceof the ANTLR tool.", e);
diff --git a/antlr4-maven-plugin/src/test/projects/dependencyRemoved/pom.xml b/antlr4-maven-plugin/src/test/projects/dependencyRemoved/pom.xml
index 35be7219ba..e778e9206d 100644
--- a/antlr4-maven-plugin/src/test/projects/dependencyRemoved/pom.xml
+++ b/antlr4-maven-plugin/src/test/projects/dependencyRemoved/pom.xml
@@ -17,7 +17,7 @@
junit
junit
- 4.11
+ 4.13.1
test
diff --git a/antlr4-maven-plugin/src/test/projects/importTokens/pom.xml b/antlr4-maven-plugin/src/test/projects/importTokens/pom.xml
index 7f8c6570db..99c88cb09b 100644
--- a/antlr4-maven-plugin/src/test/projects/importTokens/pom.xml
+++ b/antlr4-maven-plugin/src/test/projects/importTokens/pom.xml
@@ -17,7 +17,7 @@
junit
junit
- 4.11
+ 4.13.1
test
diff --git a/antlr4-maven-plugin/src/test/projects/importsCustom/pom.xml b/antlr4-maven-plugin/src/test/projects/importsCustom/pom.xml
index 4ab0de8f20..bd2a6d26a5 100644
--- a/antlr4-maven-plugin/src/test/projects/importsCustom/pom.xml
+++ b/antlr4-maven-plugin/src/test/projects/importsCustom/pom.xml
@@ -17,7 +17,7 @@
junit
junit
- 4.11
+ 4.13.1
test
diff --git a/antlr4-maven-plugin/src/test/projects/importsStandard/pom.xml b/antlr4-maven-plugin/src/test/projects/importsStandard/pom.xml
index 77dcf00381..2a6efd2522 100644
--- a/antlr4-maven-plugin/src/test/projects/importsStandard/pom.xml
+++ b/antlr4-maven-plugin/src/test/projects/importsStandard/pom.xml
@@ -17,7 +17,7 @@
junit
junit
- 4.11
+ 4.13.1
test
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 5788acadf3..0000000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-version: '4.7.1-SNAPSHOT+AppVeyor.{build}'
-cache:
- - '%USERPROFILE%\.m2'
- - '%USERPROFILE%\.nuget\packages -> **\project.json'
-image: Visual Studio 2017
-build: off
-install:
- - git submodule update --init --recursive
- - cinst -y php --params "/InstallDir:C:\tools\php"
- - cinst -y composer
-build_script:
- - mvn -DskipTests install --batch-mode
- - msbuild /target:restore /target:rebuild /property:Configuration=Release /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /verbosity:detailed runtime/CSharp/runtime/CSharp/Antlr4.dotnet.sln
- - msbuild ./runtime-testsuite/target/classes/CSharp/runtime/CSharp/Antlr4.vs2013.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /verbosity:detailed
-after_build:
- - msbuild /target:pack /property:Configuration=Release /verbosity:detailed runtime/CSharp/runtime/CSharp/Antlr4.dotnet.sln
-test_script:
- - mvn install -Dantlr-php-php="C:\tools\php\php.exe" -Dantlr-python2-python="C:\Python27\python.exe" -Dantlr-python3-python="C:\Python35\python.exe" -Dantlr-javascript-nodejs="C:\Program Files (x86)\nodejs\node.exe" --batch-mode
-artifacts:
-- path: 'runtime\**\*.nupkg'
- name: NuGet
\ No newline at end of file
diff --git a/build/Antlr4.Runtime.nuspec b/build/Antlr4.Runtime.nuspec
deleted file mode 100644
index f629ba1fe1..0000000000
--- a/build/Antlr4.Runtime.nuspec
+++ /dev/null
@@ -1,64 +0,0 @@
-
-
-
- Antlr4.Runtime
- 0.0.0
- Sam Harwell, Terence Parr
- Sam Harwell
- The runtime library for parsers generated by the C# target of ANTLR 4. This package supports projects targeting .NET 2.0 or newer, and built using Visual Studio 2008 or newer.
- en-us
- https://github.com/sharwell/antlr4cs
- https://raw.github.com/sharwell/antlr4cs/master/LICENSE.txt
- https://raw.github.com/antlr/website-antlr4/master/images/icons/antlr.png
- Copyright © Sam Harwell 2014
- https://github.com/sharwell/antlr4cs/releases/v$version$
- true
- antlr antlr4 parsing
- ANTLR 4 Runtime
- The runtime library for parsers generated by the C# target of ANTLR 4.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/build/Antlr4.VS2008.nuspec b/build/Antlr4.VS2008.nuspec
deleted file mode 100644
index 36ffe7ec9a..0000000000
--- a/build/Antlr4.VS2008.nuspec
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
- Antlr4.VS2008
- 0.0.0
- Sam Harwell, Terence Parr
- Sam Harwell
- The C# target of the ANTLR 4 parser generator for Visual Studio 2008 projects. This package supports projects targeting .NET 2.0 or newer, and built using Visual Studio 2008.
- en-us
- https://github.com/sharwell/antlr4cs
- https://raw.github.com/sharwell/antlr4cs/master/LICENSE.txt
- https://raw.github.com/antlr/website-antlr4/master/images/icons/antlr.png
- Copyright © Sam Harwell 2014
- https://github.com/sharwell/antlr4cs/releases/v$version$
- true
- true
- antlr antlr4 parsing
- ANTLR 4 (Visual Studio 2008)
- The C# target of the ANTLR 4 parser generator for Visual Studio 2008 projects.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/build/Antlr4.nuspec b/build/Antlr4.nuspec
deleted file mode 100644
index 9dc4e4754c..0000000000
--- a/build/Antlr4.nuspec
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
- Antlr4
- 0.0.0
- Sam Harwell, Terence Parr
- Sam Harwell
- The C# target of the ANTLR 4 parser generator for Visual Studio 2010+ projects. This package supports projects targeting .NET 2.0 or newer, and built using Visual Studio 2010 or newer.
- en-us
- https://github.com/sharwell/antlr4cs
- https://raw.github.com/sharwell/antlr4cs/master/LICENSE.txt
- https://raw.github.com/antlr/website-antlr4/master/images/icons/antlr.png
- Copyright © Sam Harwell 2014
- https://github.com/sharwell/antlr4cs/releases/v$version$
- true
- true
- antlr antlr4 parsing
- ANTLR 4
- The C# target of the ANTLR 4 parser generator for Visual Studio 2010+ projects.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/build/build.ps1 b/build/build.ps1
deleted file mode 100644
index 5dcc5e6071..0000000000
--- a/build/build.ps1
+++ /dev/null
@@ -1,139 +0,0 @@
-param (
- [switch]$Debug,
- [string]$VisualStudioVersion = "12.0",
- [switch]$NoClean,
- [string]$Java6Home,
- [string]$MavenHome,
- [string]$MavenRepo = "$($env:USERPROFILE)\.m2",
- [switch]$SkipMaven,
- [switch]$SkipKeyCheck
-)
-
-# build the solutions
-$SolutionPath = "..\Runtime\CSharp\Antlr4.sln"
-$CF35SolutionPath = "..\Runtime\CSharp\Antlr4.VS2008.sln"
-
-# make sure the script was run from the expected path
-if (!(Test-Path $SolutionPath)) {
- echo "The script was run from an invalid working directory."
- exit 1
-}
-
-. .\version.ps1
-
-If ($Debug) {
- $BuildConfig = 'Debug'
-} Else {
- $BuildConfig = 'Release'
-}
-
-If ($NoClean) {
- $Target = 'build'
-} Else {
- $Target = 'rebuild'
-}
-
-If (-not $MavenHome) {
- $MavenHome = $env:M2_HOME
-}
-
-$Java6RegKey = 'HKLM:\SOFTWARE\JavaSoft\Java Runtime Environment\1.6'
-$Java6RegValue = 'JavaHome'
-If (-not $Java6Home -and (Test-Path $Java6RegKey)) {
- $JavaHomeKey = Get-Item -LiteralPath $Java6RegKey
- If ($JavaHomeKey.GetValue($Java6RegValue, $null) -ne $null) {
- $JavaHomeProperty = Get-ItemProperty $Java6RegKey $Java6RegValue
- $Java6Home = $JavaHomeProperty.$Java6RegValue
- }
-}
-
-# this is configured here for path checking, but also in the .props and .targets files
-[xml]$pom = Get-Content "..\tool\pom.xml"
-$CSharpToolVersionNodeInfo = Select-Xml "/mvn:project/mvn:version" -Namespace @{mvn='http://maven.apache.org/POM/4.0.0'} $pom
-$CSharpToolVersion = $CSharpToolVersionNodeInfo.Node.InnerText.trim()
-
-# build the main project
-$msbuild = "$env:windir\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe"
-
-&$msbuild '/nologo' '/m' '/nr:false' "/t:$Target" "/p:Configuration=$BuildConfig" "/p:VisualStudioVersion=$VisualStudioVersion" $SolutionPath
-if ($LASTEXITCODE -ne 0) {
- $host.ui.WriteErrorLine('Build failed, aborting!')
- exit $p.ExitCode
-}
-
-# build the compact framework project
-$msbuild = "$env:windir\Microsoft.NET\Framework\v4.0.30319\msbuild.exe"
-
-&$msbuild '/nologo' '/m' '/nr:false' '/t:rebuild' "/p:Configuration=$BuildConfig" $CF35SolutionPath
-if ($LASTEXITCODE -ne 0) {
- $host.ui.WriteErrorLine('.NET 3.5 Compact Framework Build failed, aborting!')
- exit $p.ExitCode
-}
-
-if (-not (Test-Path 'nuget')) {
- mkdir "nuget"
-}
-
-# Build the Java library using Maven
-If (-not $SkipMaven) {
- $OriginalPath = $PWD
-
- cd '..\tool'
- $MavenPath = "$MavenHome\bin\mvn.bat"
- If (-not (Test-Path $MavenPath)) {
- $host.ui.WriteErrorLine("Couldn't locate Maven binary: $MavenPath")
- cd $OriginalPath
- exit 1
- }
-
- If (-not (Test-Path $Java6Home)) {
- $host.ui.WriteErrorLine("Couldn't locate Java 6 installation: $Java6Home")
- cd $OriginalPath
- exit 1
- }
-
- $MavenGoal = 'package'
- &$MavenPath '-DskipTests=true' '--errors' '-e' '-Dgpg.useagent=true' "-Djava6.home=$Java6Home" '-Psonatype-oss-release' $MavenGoal
- if ($LASTEXITCODE -ne 0) {
- $host.ui.WriteErrorLine('Maven build of the C# Target custom Tool failed, aborting!')
- cd $OriginalPath
- exit $p.ExitCode
- }
-
- cd $OriginalPath
-}
-
-$JarPath = "..\tool\target\antlr4-csharp-$CSharpToolVersion-complete.jar"
-if (!(Test-Path $JarPath)) {
- $host.ui.WriteErrorLine("Couldn't locate the complete jar used for building C# parsers: $JarPath")
- exit 1
-}
-
-# By default, do not create a NuGet package unless the expected strong name key files were used
-if (-not $SkipKeyCheck) {
- . .\keys.ps1
-
- foreach ($pair in $Keys.GetEnumerator()) {
- $assembly = Resolve-FullPath -Path "..\runtime\CSharp\Antlr4.Runtime\bin\$($pair.Key)\$BuildConfig\Antlr4.Runtime.dll"
- # Run the actual check in a separate process or the current process will keep the assembly file locked
- powershell -Command ".\check-key.ps1 -Assembly '$assembly' -ExpectedKey '$($pair.Value)' -Build '$($pair.Key)'"
- if ($LASTEXITCODE -ne 0) {
- Exit $p.ExitCode
- }
- }
-}
-
-$packages = @(
- 'Antlr4.Runtime'
- 'Antlr4'
- 'Antlr4.VS2008')
-
-$nuget = '..\runtime\CSharp\.nuget\NuGet.exe'
-ForEach ($package in $packages) {
- If (-not (Test-Path ".\$package.nuspec")) {
- $host.ui.WriteErrorLine("Couldn't locate NuGet package specification: $package")
- exit 1
- }
-
- &$nuget 'pack' ".\$package.nuspec" '-OutputDirectory' 'nuget' '-Prop' "Configuration=$BuildConfig" '-Version' "$AntlrVersion" '-Prop' "M2_REPO=$M2_REPO" '-Prop' "CSharpToolVersion=$CSharpToolVersion" '-Symbols'
-}
diff --git a/build/check-key.ps1 b/build/check-key.ps1
deleted file mode 100644
index b92a9cdccf..0000000000
--- a/build/check-key.ps1
+++ /dev/null
@@ -1,31 +0,0 @@
-param(
- [string]$Assembly,
- [string]$ExpectedKey,
- [string]$Build = $null
-)
-
-function Get-PublicKeyToken() {
- param([string]$assembly = $null)
- if ($assembly) {
- $bytes = $null
- $bytes = [System.Reflection.Assembly]::ReflectionOnlyLoadFrom($assembly).GetName().GetPublicKeyToken()
- if ($bytes) {
- $key = ""
- for ($i=0; $i -lt $bytes.Length; $i++) {
- $key += "{0:x2}" -f $bytes[$i]
- }
-
- $key
- }
- }
-}
-
-if (-not $Build) {
- $Build = $Assembly
-}
-
-$actual = Get-PublicKeyToken -assembly $Assembly
-if ($actual -ne $ExpectedKey) {
- $host.ui.WriteErrorLine("Invalid publicKeyToken for '$Build'; expected '$ExpectedKey' but found '$actual'")
- exit 1
-}
diff --git a/build/keys.ps1 b/build/keys.ps1
deleted file mode 100644
index 4e2f34250b..0000000000
--- a/build/keys.ps1
+++ /dev/null
@@ -1,17 +0,0 @@
-# Note: these values may only change during minor release
-$Keys = @{
- 'net20' = '7983ae52036899ac'
- 'net30' = '7671200403f6656a'
- 'net35-cf' = '770a97458f51159e'
- 'net35-client' = '4307381ae04f9aa7'
- 'net40-client' = 'bb1075973a9370c4'
- 'net45' = 'edc21c04cf562012'
- 'netcore45' = 'e4e9019902d0b6e2'
- 'portable-net40' = '90bf14da8e1462b4'
- 'portable-net45' = '3d23c8e77559f391'
-}
-
-function Resolve-FullPath() {
- param([string]$Path)
- [System.IO.Path]::GetFullPath((Join-Path (pwd) $Path))
-}
diff --git a/build/push.ps1 b/build/push.ps1
deleted file mode 100644
index 17791c1cd2..0000000000
--- a/build/push.ps1
+++ /dev/null
@@ -1,29 +0,0 @@
-. .\version.ps1
-
-If ($AntlrVersion.EndsWith('-dev')) {
- $host.ui.WriteErrorLine("Cannot push development version '$AntlrVersion' to NuGet.")
- Exit 1
-}
-
-$packages = @(
- 'Antlr4.Runtime'
- 'Antlr4'
- 'Antlr4.VS2008')
-
-# Make sure all packages exist before pushing any packages
-ForEach ($package in $packages) {
- If (-not (Test-Path ".\nuget\$package.$AntlrVersion.nupkg")) {
- $host.ui.WriteErrorLine("Couldn't locate NuGet package: $JarPath")
- exit 1
- }
-
- If (-not (Test-Path ".\nuget\$package.$AntlrVersion.symbols.nupkg")) {
- $host.ui.WriteErrorLine("Couldn't locate NuGet symbols package: $JarPath")
- exit 1
- }
-}
-
-$nuget = '..\runtime\CSharp\.nuget\NuGet.exe'
-ForEach ($package in $packages) {
- &$nuget 'push' ".\nuget\$package.$AntlrVersion.nupkg"
-}
diff --git a/build/version.ps1 b/build/version.ps1
deleted file mode 100644
index 457481bd8c..0000000000
--- a/build/version.ps1
+++ /dev/null
@@ -1 +0,0 @@
-$AntlrVersion = "4.5.1"
diff --git a/contributors.txt b/contributors.txt
deleted file mode 100644
index 2de2535864..0000000000
--- a/contributors.txt
+++ /dev/null
@@ -1,243 +0,0 @@
-ANTLR Project Contributors Certification of Origin and Rights
-
-All contributors to ANTLR v4 must formally agree to abide by this
-certificate of origin by signing on the bottom with their github
-userid, full name, email address (you can obscure your e-mail, but it
-must be computable by human), and date.
-
-By signing this agreement, you are warranting and representing that
-you have the right to release code contributions or other content free
-of any obligations to third parties and are granting Terence Parr and
-ANTLR project contributors, henceforth referred to as The ANTLR
-Project, a license to incorporate it into The ANTLR Project tools
-(such as ANTLRWorks and StringTemplate) or related works under the BSD
-license. You understand that The ANTLR Project may or may not
-incorporate your contribution and you warrant and represent the
-following:
-
-1. I am the creator of all my contributions. I am the author of all
- contributed work submitted and further warrant and represent that
- such work is my original creation and I have the right to license
- it to The ANTLR Project for release under the 3-clause BSD
- license. I hereby grant The ANTLR Project a nonexclusive,
- irrevocable, royalty-free, worldwide license to reproduce,
- distribute, prepare derivative works, and otherwise use this
- contribution as part of the ANTLR project, associated
- documentation, books, and tools at no cost to The ANTLR Project.
-
-2. I have the right to submit. This submission does not violate the
- rights of any person or entity and that I have legal authority over
- this submission and to make this certification.
-
-3. If I violate another's rights, liability lies with me. I agree to
- defend, indemnify, and hold The ANTLR Project and ANTLR users
- harmless from any claim or demand, including reasonable attorney
- fees, made by any third party due to or arising out of my violation
- of these terms and conditions or my violation of the rights of
- another person or entity.
-
-4. I understand and agree that this project and the contribution are
- public and that a record of the contribution (including all
- personal information I submit with it, including my sign-off) is
- maintained indefinitely and may be redistributed consistent with
- this project or the open source license indicated in the file.
-
-I have read this agreement and do so certify by adding my signoff to
-the end of the following contributors list.
-
-CONTRIBUTORS:
-
-YYYY/MM/DD, github id, Full name, email
-2012/07/12, parrt, Terence Parr, parrt@antlr.org
-2012/09/18, sharwell, Sam Harwell, sam@tunnelvisionlabs.com
-2012/10/10, stephengaito, Stephen Gaito, stephen@percepitsys.co.uk
-2012/11/23, maguro, Alan Cabrera, adc@toolazydogs.com
-2013/01/29, metadave, Dave Parfitt, diparfitt@gmail.com
-2013/03/06, bkiers, Bart Kiers, bkiers@gmail.com
-2013/08/20, cayhorstmann, Cay Horstmann, cay@horstmann.com
-2014/03/18, aphyr, Kyle Kingsbury, aphyr@aphyr.com
-2014/06/07, ericvergnaud, Eric Vergnaud, eric.vergnaud@wanadoo.fr
-2014/07/04, jimidle, Jim Idle, jimi@Idle.ws
-2014/01/01, danmclaughlin, Dan McLaughlin, dan.mclaughlin@gmail.com
-2014/09/04. jeduden, Jan-Eric Duden, jeduden@gmail.com
-2014/09/27, petrbel, Petr Bělohlávek, antlr@petrbel.cz
-2014/10/18, sergiusignacius, Sérgio Silva, serge.a.silva@gmail.com
-2014/10/26, bdkearns, Brian Kearns, bdkearns@gmail.com
-2014/10/27, michaelpj, Michael Peyton Jones, michaelpj@gmail.com
-2015/01/29, TomLottermann, Thomas Lottermann, tomlottermann@gmail.com
-2015/02/15, pavlo, Pavlo Lysov, pavlikus@gmail.com
-2015/03/07, RedTailedHawk, Lawrence Parker, larry@answerrocket.com
-2015/04/03, rljacobson, Robert Jacobson, rljacobson@gmail.com
-2015/04/06, ojakubcik, Ondrej Jakubcik, ojakubcik@gmail.com
-2015/04/29, jszheng, Jinshan Zheng, zheng_js@hotmail.com
-2015/05/08, ViceIce, Michael Kriese, michael.kriese@gmx.de
-2015/05/09, lkraz, Luke Krasnoff, luke.krasnoff@gmail.com
-2015/05/12, Pursuit92, Josh Chase, jcjoshuachase@gmail.com
-2015/05/20, peturingi, Pétur Ingi Egilsson, petur@petur.eu
-2015/05/27, jcbrinfo, Jean-Christophe Beaupré, jcbrinfo@users.noreply.github.com
-2015/06/29, jvanzyl, Jason van Zyl, jason@takari.io
-2015/08/18, krzkaczor, Krzysztof Kaczor, krzysztof@kaczor.io
-2015/09/18, worsht, Rajiv Subrahmanyam, rajiv.public@gmail.com
-2015/09/24, HSorensen, Henrik Sorensen, henrik.b.sorensen@gmail.com
-2015/10/06, brwml, Bryan Wilhelm, bryan.wilhelm@microsoft.com
-2015/10/08, fedotovalex, Alex Fedotov, me@alexfedotov.com
-2015/10/12, KvanTTT, Ivan Kochurkin, ivan.kochurkin@gmail.com
-2015/10/21, martin-probst, Martin Probst, martin-probst@web.de
-2015/10/21, hkff, Walid Benghabrit, walid.benghabrit@mines-nantes.fr
-2015/11/12, cooperra, Robbie Cooper, cooperra@users.noreply.github.com
-2015/11/25, abego, Udo Borkowski, ub@abego.org
-2015/12/17, sebadur, Sebastian Badur, sebadur@users.noreply.github.com
-2015/12/23, pboyer, Peter Boyer, peter.b.boyer@gmail.com
-2015/12/24, dtymon, David Tymon, david.tymon@gmail.com
-2016/02/18, reitzig, Raphael Reitzig, reitzig[at]cs.uni-kl.de
-2016/03/10, mike-lischke, Mike Lischke, mike@lischke-online.de
-2016/03/27, beardlybread, Bradley Steinbacher, bradley.j.steinbacher@gmail.com
-2016/03/29, msteiger, Martin Steiger, antlr@martin-steiger.de
-2016/03/28, gagern, Martin von Gagern, gagern@ma.tum.de
-2016/07/10, twz123, Tom Wieczorek, tom.wieczorek@zalando.de
-2016/07/20, chrisheller, Chris Heller, chris.heller.greyheller@gmail.com
-2016/07/20, nburles, Nathan Burles, nburles@gmail.com
-2016/07/20, kosl90, Li Liqiang, kos1990l@gmail.com
-2016/07/27, timoc, Tim O'Callaghan, timo@linux.com
-2016/07/26, nic30, Michal Orsák, michal.o.socials@gmail.com
-2016/07/18, willfaught, Will Faught, will.faught@gmail.com
-2016/08/08, wjkohnen, Wolfgang Johannes Kohnen, wjkohnen-go-antlr@ko-sys.com
-2016/08/11, BurtHarris, Ralph "Burt" Harris, Burt_Harris_antlr4@azxs.33mail.com
-2016/08/19, andjo403, Andreas Jonson, andjo403@hotmail.com
-2016/09/27, harriman, Kurt Harriman, harriman@acm.org
-2016/10/13, cgudrian, Christian Gudrian, christian.gudrian@gmx.de
-2016/10/13, nielsbasjes, Niels Basjes, niels@basjes.nl
-2016/10/21, FloorGoddijn, Floor Goddijn, floor.goddijn[at]aimms.com
-2016/11/01, RYDB3RG, Kai Stammerjohann, RYDB3RG@users.noreply.github.com
-2016/11/05, runner-mei, meifakun, runner.mei@gmail.com
-2016/11/15, hanjoes, Hanzhou Shi, hanzhou87@gmail.com
-2016/11/16, sridharxp, Sridharan S, aurosridhar@gmail.com
-2016/11/06, NoodleOfDeath, Thom Morgan, github@bytemeapp.com
-2016/11/01, sebkur, Sebastian Kürten, sebastian@topobyte.de
-2016/04/13, renatahodovan, Renata Hodovan, reni@inf.u-szeged.hu
-2016/11/05, ewanmellor, Ewan Mellor, github@ewanmellor.org
-2016/11/06, janyou, Janyou, janyou.antlr@outlook.com
-2016/11/20, marcohu, Marco Hunsicker, antlr@hunsicker.de
-2016/09/02, lygav, Vladimir (Vladi) Lyga, lyvladi@gmail.com
-2016/09/23, ghosthope, Dmitry Shakhtanov, sudstrike@gmail.com
-2016/11/25, MrSampson, Oliver Sampson, olsam@quickaudio.com
-2016/11/29, millergarym, Gary Miller, miller.garym@gmail.com
-2016/11/29, wxio, Gary Miller, gm@wx.io
-2016/11/29, Naios, Denis Blank, naios@users.noreply.github.com
-2016/12/01, samtatasurya, Samuel Tatasurya, xemradiant@gmail.com
-2016/12/03, redxdev, Samuel Bloomberg, sam@redxdev.com
-2016/12/11, Gaulouis, Gaulouis, gaulouis.com@gmail.com
-2016/12/22, akosthekiss, Akos Kiss, akiss@inf.u-szeged.hu
-2016/12/24, adrpo, Adrian Pop, adrian.pop@liu.se
-2017/01/11, robertbrignull, Robert Brignull, robertbrignull@gmail.com
-2017/01/13, marcelo-rocha, Marcelo Rocha, mcrocha@gmail.com
-2017/01/23, bhamiltoncx, Ben Hamilton, bhamiltoncx+antlr@gmail.com
-2017/01/18, mshockwave, Bekket McClane, yihshyng223@gmail.com
-2017/02/10, lionelplessis, Lionel Plessis, lionelplessis@users.noreply.github.com
-2017/02/14, lecode-official, David Neumann, david.neumann@lecode.de
-2017/02/14, xied75, Dong Xie, xied75@gmail.com
-2017/02/20, Thomasb81, Thomas Burg, thomasb81@gmail.com
-2017/02/26, jvasileff, John Vasileff, john@vasileff.com
-2017/03/08, harry-tallbelt, Igor Vysokopoyasny, harry.tallbelt@gmail.com
-2017/03/09, teverett, Tom Everett, tom@khubla.com
-2017/03/03, chund, Christian Hund, christian.hund@gmail.com
-2017/03/15, robertvanderhulst, Robert van der Hulst, robert@xsharp.eu
-2017/03/28, cmd-johnson, Jonas Auer, jonas.auer.94@gmail.com
-2017/04/12, lys0716, Yishuang Lu, luyscmu@gmail.com
-2017/04/30, shravanrn, Shravan Narayan, shravanrn@gmail.com
-2017/05/11, jimallman, Jim Allman, jim@ibang.com
-2017/05/26, waf, Will Fuqua, wafuqua@gmail.com
-2017/05/29, kosak, Corey Kosak, kosak@kosak.com
-2017/06/11, erikbra, Erik A. Brandstadmoen, erik@brandstadmoen.net
-2017/06/10, jm-mikkelsen, Jan Martin Mikkelsen, janm@transactionware.com
-2017/06/25, alimg, Alim Gökkaya, alim.gokkaya@gmail.com
-2017/06/28, jBugman, Sergey Parshukov, codedby@bugman.me
-2017/07/09, neatnerd, Mike Arshinskiy, neatnerd@users.noreply.github.com
-2017/07/11, dhalperi, Daniel Halperin, daniel@halper.in
-2017/07/17, vaibhavaingankar09, Vaibhav Vaingankar, vbhvvaingankar9@gmail.com
-2017/07/23, venkatperi, Venkat Peri, venkatperi@gmail.com
-2017/07/27, shirou, WAKAYAMA Shirou, shirou.faw@gmail.com
-2017/07/09, neatnerd, Mike Arshinskiy, neatnerd@users.noreply.github.com
-2017/07/27, matthauck, Matt Hauck, matthauck@gmail.com
-2017/07/27, shirou, WAKAYAMA Shirou, shirou.faw@gmail.com
-2017/08/20, tiagomazzutti, Tiago Mazzutti, tiagomzt@gmail.com
-2017/08/20, milanaleksic, Milan Aleksic, milanaleksic@gmail.com
-2017/08/29, Eddy Reyes, eddy@mindsight.io
-2017/09/09, brauliobz, Bráulio Bezerra, brauliobezerra@gmail.com
-2017/09/11, sachinjain024, Sachin Jain, sachinjain024@gmail.com
-2017/09/25, kaedvann, Rostislav Listerenko, r.listerenko@gmail.com
-2017/10/06, bramp, Andrew Brampton, brampton@gmail.com
-2017/10/15, simkimsia, Sim Kim Sia, kimcity@gmail.com
-2017/10/27, Griffon26, Maurice van der Pot, griffon26@kfk4ever.com
-2017/05/29, rlfnb, Ralf Neeb, rlfnb@rlfnb.de
-2017/10/29, gendalph, Максим Прохоренко, Maxim\dotProhorenko@gm@il.com
-2017/11/02, jasonmoo, Jason Mooberry, jason.mooberry@gmail.com
-2017/11/05, ajaypanyala, Ajay Panyala, ajay.panyala@gmail.com
-2017/11/24, zqlu.cn, Zhiqiang Lu, zqlu.cn@gmail.com
-2017/11/28, niccroad, Nicolas Croad, nic.croad@gmail.com
-2017/12/01, DavidMoraisFerreira, David Morais Ferreira, david.moraisferreira@gmail.com
-2017/12/01, SebastianLng, Sebastian Lang, sebastian.lang@outlook.com
-2017/12/03, oranoran, Oran Epelbaum, oran / epelbaum me
-2017/12/12, janlinde, Jan Lindemann, jan@janware.com
-2017/12/13, enessoylu, Enes Soylu, enessoylutr@gmail.com
-2017/12/20, kbsletten, Kyle Sletten, kbsletten@gmail.com
-2017/12/27, jkmar, Jakub Marciniszyn, marciniszyn.jk@gmail.com
-2018/03/08, dannoc, Daniel Clifford, danno@google.com
-2018/03/10, uvguy, kangjoni76@gmail.com
-2018/01/06, kasbah, Kaspar Emanuel, kaspar@monostable.co.uk
-2018/01/15, xgcssch, Sönke Schau, xgcssch@users.noreply.github.com
-2018/02/08, razfriman, Raz Friman, raz@razfriman.com
-2018/02/11, io7m, Mark Raynsford, code@io7m.com
-2018/04/24, solussd, Joe Smith, joe@uwcreations.com
-2018/15/05, johnvanderholt, jan dillingh johnvanderholte@gmail.com
-2018/06/14, scadgek, Sergey Chupov, scadgek@live.com
-2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com
-2018/06/27, wu-sheng, Wu Sheng, wu.sheng@foxmail.com
-2018/02/25, chaseoxide, Marcus Ong, taccs97[at]gmail[dot]com
-2018/05/15, johnvanderholt, jan dillingh johnvanderholte@gmail.com
-2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com
-2018/05/15, johnvanderholt, jan dillingh johnvanderholte@gmail.com
-2018/05/17, sinopsysHK, Eric Bardes, sinofwd@gmail.com
-2018/05/23, srvance, Stephen Vance, steve@vance.com
-2018/06/14, alecont, Alessandro Contenti, alecontenti@hotmail.com
-2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com
-2018/07/03, jgoppert, James Goppert, james.goppert@gmail.com
-2018/07/27, Maksim Novikov, mnovikov.work@gmail.com
-2018/08/03, ENDOH takanao, djmchl@gmail.com
-2018/10/18, edirgarcia, Edir García Lazo, edirgl@hotmail.com
-2018/07/31, Lucas Henrqiue, lucashenrique580@gmail.com
-2018/08/03, ENDOH takanao, djmchl@gmail.com
-2018/10/29, chrisaycock, Christopher Aycock, chris[at]chrisaycock[dot]com
-2018/11/12, vinoski, Steve Vinoski, vinoski@ieee.org
-2018/11/14, nxtstep, Adriaan (Arjan) Duz, codewithadriaan[et]gmail[dot]com
-2018/11/15, amykyta3, Alex Mykyta, amykyta3@users.noreply.github.com
-2018/11/29, hannemann-tamas, Ralf Hannemann-Tamas, ralf.ht@gmail.com
-2018/12/20, WalterCouto, Walter Couto, WalterCouto@users.noreply.github.com
-2018/12/23, youkaichao, Kaichao You, youkaichao@gmail.com
-2019/01/16, kuegi, Markus Zancolo, markus.zancolo@roomle.com
-2019/02/06, ralucado, Cristina Raluca Vijulie, ralucris.v[at]gmail[dot]com
-2019/02/23, gedimitr, Gerasimos Dimitriadis, gedimitr@gmail.com
-2019/03/13, base698, Justin Thomas, justin.thomas1@gmail.com
-2019/03/18, carlodri, Carlo Dri, carlo.dri@gmail.com
-2019/05/02, askingalot, Andy Collins, askingalot@gmail.com
-2019/07/11, olowo726, Olof Wolgast, olof@baah.se
-2019/07/16, abhijithneilabraham, Abhijith Neil Abraham, abhijithneilabrahampk@gmail.com
-2019/07/26, Braavos96, Eric Hettiaratchi, erichettiaratchi@gmail.com
-2019/08/23, akaJes, Oleksandr Mamchyts, akaJes@gmail.com
-2019/09/10, ImanHosseini, Iman Hosseini, hosseini.iman@yahoo.com
-2019/09/03, João Henrique, johnnyonflame@hotmail.com
-2019/09/10, neko1235, Ihar Mokharau, igor.mohorev@gmail.com
-2019/09/10, yar3333, Yaroslav Sivakov, yar3333@gmail.com
-2019/09/10, marcospassos, Marcos Passos, marcospassos.com@gmail.com
-2019/09/10, amorimjuliana, Juliana Amorim, juu.amorim@gmail.com
-2019/09/17, kaz, Kazuki Sawada, kazuki@6715.jp
-2019/09/28, lmy269, Mingyang Liu, lmy040758@gmail.com
-2019/10/29, tehbone, Tabari Alexander, tehbone@gmail.com
-2019/10/31, a-square, Alexei Averchenko, lex.aver@gmail.com
-2019/11/11, foxeverl, Liu Xinfeng, liuxf1986[at]gmail[dot]com
-2019/11/17, felixn, Felix Nieuwenhuizhen, felix@tdlrali.com
-2019/11/18, mlilback, Mark Lilback, mark@lilback.com
-2020/02/02, carocad, Camilo Roca, carocad@unal.edu.co
-2020/02/10, rrevenantt, Konstantin Anisimov, rrevenantt[at]gmail.com
-2025/05/28, alexsnaps, Alex Snaps, alex@wcgw.dev
-2025/09/12, torbensen, Torben Magne, torbenmagne@gmail.com
diff --git a/developer-cert-of-origin.txt b/developer-cert-of-origin.txt
new file mode 100644
index 0000000000..7274c56507
--- /dev/null
+++ b/developer-cert-of-origin.txt
@@ -0,0 +1,52 @@
+As of 4.10, ANTLR uses the Linux Foundation's Developer
+Certificate of Origin, DCO, version 1.1. See either
+https://developercertificate.org/ or the text below.
+
+Each commit requires a "signature", which is simple as
+using `-s` (not `-S`) to the git commit command:
+
+git commit -s -m 'This is my commit message'
+
+Github's pull request process enforces the sig and gives
+instructions on how to fix any commits that lack the sig.
+See https://github.com/apps/dco for more info.
+
+No signature is required in this file (unlike the
+previous ANTLR contributor's certificate of origin.)
+
+----- https://developercertificate.org/ ------
+
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part
+ by me, under the same open source license (unless I am
+ permitted to submit under a different license), as indicated
+ in the file; or
+
+(c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified
+ it.
+
+(d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
diff --git a/doc/IDEs.md b/doc/IDEs.md
index 7c21e8af01..9e98503d3c 100644
--- a/doc/IDEs.md
+++ b/doc/IDEs.md
@@ -1,5 +1,5 @@
# Integrating ANTLR into Development Systems
-The Java target is the reference implementation mirrored by other targets. The following pages help you integrate ANTLR into development environments and build systems appropriate for your target language. As of December 2016, we have Java, C#, Python 2, Python 3, JavaScript, Go, C++, and Swift targets.
+The Java target is the reference implementation mirrored by other targets. The following pages help you integrate ANTLR into development environments and build systems appropriate for your target language. As of December 2016, we have Java, C#, Python 3, JavaScript, Go, C++, and Swift targets.
The easiest thing is probably just to use an [ANTLR plug-in](http://www.antlr.org/tools.html) for your favorite development environment.
diff --git a/doc/actions.md b/doc/actions.md
index ef51c8f4c3..2eef7e4f6d 100644
--- a/doc/actions.md
+++ b/doc/actions.md
@@ -65,7 +65,7 @@ Most of the time you access the attributes of the token, but sometimes it is use
|text|String|The text matched for the token; translates to a call to getText. Example: $ID.text.|
|type|int|The token type (nonzero positive integer) of the token such as INT; translates to a call to getType. Example: $ID.type.|
|line|int|The line number on which the token occurs, counting from 1; translates to a call to getLine. Example: $ID.line.|
-|pos|int|The character position within the line at which the token’s first character occurs counting from zero; translates to a call togetCharPositionInLine. Example: $ID.pos.|
+|pos|int|The character position within the line at which the token’s first character occurs counting from zero; translates to a call to getCharPositionInLine. Example: $ID.pos.|
|index|int|The overall index of this token in the token stream, counting from zero; translates to a call to getTokenIndex. Example: $ID.index.|
|channel|int|The token’s channel number. The parser tunes to only one channel, effectively ignoring off-channel tokens. The default channel is 0 (Token.DEFAULT_CHANNEL), and the default hidden channel is Token.HIDDEN_CHANNEL. Translates to a call to getChannel. Example: $ID.channel.|
|int|int|The integer value of the text held by this token; it assumes that the text is a valid numeric string. Handy for building calculators and so on. Translates to Integer.valueOf(text-of-token). Example: $INT.int.|
@@ -81,10 +81,10 @@ returnStat : 'return' expr {System.out.println("matched "+$expr.text);} ;
Using a rule label looks like this:
```
-returnStat : 'return' e=expr {System.out.println("matched "+e.text);} ;
+returnStat : 'return' e=expr {System.out.println("matched "+$e.text);} ;
```
-You can also use `$ followed by the name of the attribute to access the value associated with the currently executing rule. For example, `$start` is the starting token of the current rule.
+You can also use `$` followed by the name of the attribute to access the value associated with the currently executing rule. For example, `$start` is the starting token of the current rule.
```
returnStat : 'return' expr {System.out.println("first token "+$start.getText());} ;
@@ -98,6 +98,7 @@ returnStat : 'return' expr {System.out.println("first token "+$start.getText());
|start|Token|The first token to be potentially matched by the rule that is on the main token channel; in other words, this attribute is never a hidden token. For rules that end up matching no tokens, this attribute points at the first token that could have been matched by this rule. When referring to the current rule, this attribute is available to any action within the rule.|
|stop|Token|The last nonhidden channel token to be matched by the rule. When referring to the current rule, this attribute is available only to the after and finally actions.|
|ctx|ParserRuleContext|The rule context object associated with a rule invocation. All of the other attributes are available through this attribute. For example, `$ctx.start` accesses the start field within the current rules context object. It’s the same as `$start`.|
+|parser|Parser|The parser itself. This attribute can be used, for example, to invoke a method defined in the parser's `@members` section from a semantic predicate.|
## Dynamically-Scoped Attributes
diff --git a/doc/antlr-project-testing.md b/doc/antlr-project-testing.md
index 1ff46aae9b..8968a4bdfb 100644
--- a/doc/antlr-project-testing.md
+++ b/doc/antlr-project-testing.md
@@ -2,266 +2,162 @@
## Introduction
-Because ANTLR supports multiple target languages, the unit tests are broken into two groups: the unit tests that test the tool itself (in `tool-testsuite`) and the unit tests that test the parser runtimes (in `antlr4/runtime-testsuite`). The tool tests are straightforward because they are Java code testing Java code; see the section at the bottom of this file.
-
-The runtime tests must be specified in a generic fashion to work across language targets. Furthermore, we must test the various targets from Java. This usually means Java launching processes to compile, say, C++ and run parsers.
-
-As of 4.6, we use [a Java descriptor object](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeTestDescriptor.java) to describe each runtime test. Unit tests are grouped together into categories such as [ParserExecDescriptors](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserExecDescriptors.java), which has multiple nested descriptor objects, one per test. For example, here is the start of that file:
-
-```java
-public class ParserExecDescriptors {
- public static class APlus extends BaseParserTestDescriptor {
- public String input = "a b c";
- public String output = "abc\n";
- public String errors = "";
- public String startRule = "a";
- public String grammarName = "T";
-
- /**
- grammar T;
- a : ID+ {
-
- };
- ID : 'a'..'z'+;
- WS : (' '|'\n') -> skip;
- */
- @CommentHasStringValue
- public String grammar;
- }
-```
-
-The mysterious `@CommentHasStringValue` annotation is a bit of a hack that allows multi-line strings in Java. This kung fu is required so that we can use Java classes rather than StringTemplate group files to specify runtime tests (the legacy system used those and it was hard to get them right). Here are all the [Runtime test descriptors](https://github.com/antlr/antlr4/tree/master/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors) organized into groups.
+Because ANTLR supports multiple target languages, the unit tests are broken into two groups:
+the unit tests that test the tool itself (in `tool-testsuite`) and the unit tests that test the parser runtimes (in `antlr4/runtime-testsuite`).
+The tool tests are straightforward because they are Java code testing Java code; see the section at the bottom of this file.
-The grammars are strings representing StringTemplates (`ST` objects) so `` will get replace when the unit test file is generated (`Test.java`, `Test.cs`, ...). The `writeln` template must be defined per target. Here are all of the
-[Target templates for runtime tests](https://github.com/antlr/antlr4/tree/master/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates).
+The runtime tests must be specified in a generic fashion to work across language targets.
+Furthermore, the various targets from Java must be tested.
-## Requirements
+This usually means Java launching processes to compile, say, C++ and run parsers.
-In order to perform the tests on all target languages, you need to have the following languages installed:
+As of 4.10, a Java descriptor file held as an [RuntimeTestDescriptor.java](../runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeTestDescriptor.java)
+is used to represent each runtime test.
-* `mono` (e.g., `brew install mono`) on non-Windows boxes (on Windows it uses the Microsoft .net stack). Also must [`xbuild` the runtime](https://github.com/antlr/antlr4/blob/master/doc/releasing-antlr.md) before tests will run; see below
-* `nodejs`
-* Python 2.7
-* Python 3.6
-* Go
-* Swift 4 (via XCode 10.x) tested currently only osx
-* clang (for C++ target)
-*
-To **install into local repository** `~/.m2/repository/org/antlr`, do this:
+Each test is described with a text file with various sections and resides in a group directory;
+see [directories under descriptors' dir](../runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors).
+Here is a sample test descriptor:
-```bash
-$ export MAVEN_OPTS="-Xmx1G" # don't forget this on linux
-$ mvn install -DskipTests=true # make sure all artifacts are visible on this machine
```
+[notes]
+This is a regression test for blah blah blah...
-Now, make sure C# runtime is built and installed locally.
+[type]
+Parser
-```bash
-cd ~/antlr/code/antlr4/runtime/CSharp/runtime/CSharp
-# kill previous ones manually as "xbuild /t:Clean" didn't seem to do it
-find . -name '*.dll' -exec rm {} \;
-# build
-xbuild /p:Configuration=Release Antlr4.Runtime/Antlr4.Runtime.mono.csproj
-```
+[grammar]
+grammar T;
+a : ID* {
+
+};
+ID : 'a'..'z'+;
+WS : (' '|'\n') -> skip;
-C++ test rig automatically builds C++ runtime during tests. Others don't need a prebuilt lib.
+[start]
+a
+[input]
+a b c
-## Running the runtime tests
+[output]
+"""abc
+"""
+```
-A single test rig is sufficient to test all targets against all descriptors using the [junit parameterized tests](https://github.com/junit-team/junit4/wiki/parameterized-tests) mechanism. But, that is inconvenient because we often want to test just a single target or perhaps even just a single test within a single group of a single target. I have automatically generated a bunch of
-[Target runtime test rigs](https://github.com/antlr/antlr4/tree/master/runtime-testsuite/test/org/antlr/v4/test/runtime) that allow developers such flexibility. For example, here are the Python3 test rigs in intellij:
+The grammars are strings representing StringTemplates (`ST` objects) so `` will get replace when the unit test file is generated (`Test.java`, `Test.cs`, ...).
+The `writeln` template must be defined per target.
+Here are all the
+[Target templates for runtime tests](../runtime-testsuite/resources/org/antlr/v4/test/runtime/templates).
+Use triple-quotes `"""` when whitespace matters (usually input/output sections).
-
+## Requirements
-And the result of testing the entire subdirectory:
+In order to perform the tests on all target languages, the following tools should be installed:
-
+* dotnet
+* Node.js
+* Python 3
+* Go
+* Swift
+* Clang (Linux, Mac) or MSBuild (Windows) for C++
+* Dart
+* PHP
-From `mvn`, on the commandline, you will see:
+To **install into local repository** `~/.m2/repository/org/antlr`, do this:
```bash
-$ cd antlr4
-$ mvn test
-...
--------------------------------------------------------
- T E S T S
--------------------------------------------------------
-Running org.antlr.v4.test.runtime.csharp.TestCompositeLexers
-dir /var/folders/s1/h3qgww1x0ks3pb30l8t1wgd80000gn/T/TestCompositeLexers-1446068612451
-Starting build /usr/bin/xbuild /p:Configuration=Release /var/folders/s1/h3qgww1x0ks3pb30l8t1wgd80000gn/T/TestCompositeLexers-1446068612451/Antlr4.Test.mono.csproj
-dir /var/folders/s1/h3qgww1x0ks3pb30l8t1wgd80000gn/T/TestCompositeLexers-1446068615081
-Starting build /usr/bin/xbuild /p:Configuration=Release /var/folders/s1/h3qgww1x0ks3pb30l8t1wgd80000gn/T/TestCompositeLexers-1446068615081/Antlr4.Test.mono.csproj
-Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 3.451 sec
-Running org.antlr.v4.test.runtime.csharp.TestCompositeParsers
-dir /var/folders/s1/h3qgww1x0ks3pb30l8t1wgd80000gn/T/TestCompositeParsers-1446068615864
-antlr reports warnings from [-visitor, -Dlanguage=CSharp, -o, /var/folders/s1/h3qgww1x0ks3pb30l8t1wgd80000gn/T/TestCompositeParsers-1446068615864, -lib, /var/folders/s1/h3qgww1x0ks3pb30l8t1wgd80000gn/T/TestCompositeParsers-1446068615864, -encoding, UTF-8, /var/folders/s1/h3qgww1x0ks3pb30l8t1wgd80000gn/T/TestCompositeParsers-1446068615864/M.g4]
-...
-[INFO] ------------------------------------------------------------------------
-[INFO] Reactor Summary:
-[INFO]
-[INFO] ANTLR 4 ............................................ SUCCESS [ 0.445 s]
-[INFO] ANTLR 4 Runtime .................................... SUCCESS [ 3.392 s]
-[INFO] ANTLR 4 Tool ....................................... SUCCESS [ 1.373 s]
-[INFO] ANTLR 4 Maven plugin ............................... SUCCESS [ 1.519 s]
-[INFO] ANTLR 4 Runtime Test Annotations ................... SUCCESS [ 0.086 s]
-[INFO] ANTLR 4 Runtime Test Processors .................... SUCCESS [ 0.014 s]
-[INFO] ANTLR 4 Runtime Tests (2nd generation) ............. SUCCESS [06:39 min]
-[INFO] ANTLR 4 Tool Tests ................................. SUCCESS [ 6.922 s]
-[INFO] ------------------------------------------------------------------------
-[INFO] BUILD SUCCESS
-[INFO] ------------------------------------------------------------------------
-[INFO] Total time: 06:53 min
-[INFO] Finished at: 2016-11-16T15:36:56-08:00
-[INFO] Final Memory: 44M/458M
-[INFO] ------------------------------------------------------------------------
+$ export MAVEN_OPTS="-Xmx1G" # don't forget this on linux
+$ mvn install -DskipTests # make sure all artifacts are visible on this machine
```
-Note: That is actually result of running the much faster:
-
-```bash
-mvn -Dparallel=methods -DthreadCount=4 install
-```
+## Running the runtime tests
-## Running test subsets
+A single test rig is sufficient to test all targets against all descriptors using the [junit dynamic tests](https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests) mechanism.
+But it's often convenient to test just a single target or perhaps even just a single test within a single group of a single target.
+IntelliJ automatically generates a bunch of
+[Target runtime test rigs](../runtime-testsuite/test/org/antlr/v4/test/runtime) that allows developers such flexibility.
+For example, here are the Python3 test rigs in IntelliJ:
-*From the `runtime-testsuite` dir*
+
-### Run one test group across targets
+And the result of testing the entire subdirectory:
-```bash
-$ cd runtime-testsuite
-$ export MAVEN_OPTS="-Xmx1G" # don't forget this on linux
-$ mvn -Dtest=TestParserExec test
--------------------------------------------------------
- T E S T S
--------------------------------------------------------
-Running org.antlr.v4.test.runtime.cpp.TestParserExec
-...
-Tests run: 32, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 114.283 sec
-Running org.antlr.v4.test.runtime.csharp.TestParserExec
-...
-```
+
-Or run all lexer related tests:
+All test are run in parallel both via maven and via IDE.
-```
-$ cd runtime-testsuite
-$ mvn -Dtest=Test*Lexer* test
--------------------------------------------------------
- T E S T S
--------------------------------------------------------
-Running org.antlr.v4.test.runtime.cpp.TestCompositeLexers
-...
-```
+In IntelliJ, it's very easy to go to source by right-clicking on any test and pressing `Jump to source` (F4).
-### Run all tests for a single target
+## Running test subsets
-```bash
-$ cd runtime-testsuite
-$ mvn -Dtest=java.* test
-...
-```
+From the `runtime-testsuite` dir
-Or run all lexer related tests in Java target only:
+### Run all tests for a single target
```bash
$ cd runtime-testsuite
-$ mvn -Dtest=java.*Lexer* test
-...
+$ export MAVEN_OPTS="-Xmx1G" # don't forget this on linux
+$ mvn -Dtest='java.**' test
-------------------------------------------------------
T E S T S
-------------------------------------------------------
-Running org.antlr.v4.test.runtime.java.TestCompositeLexers
-Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.277 sec
-Running org.antlr.v4.test.runtime.java.TestLexerErrors
-Tests run: 12, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.376 sec
-Running org.antlr.v4.test.runtime.java.TestLexerExec
-Tests run: 38, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.07 sec
-Running org.antlr.v4.test.runtime.java.TestSemPredEvalLexer
-Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.255 sec
-
-Results :
-
-Tests run: 59, Failures: 0, Errors: 0, Skipped: 0
-```
-
-## Testing in parallel
-
-Use this to run tests in parallel:
-
-```bash
-$ export MAVEN_OPTS="-Xmx1G"
-$ mvn -Dparallel=methods -DthreadCount=4 test
+[INFO] Running org.antlr.v4.test.runtime.java.TestIntegerList
+[INFO] Running org.antlr.v4.test.runtime.java.JavaRuntimeTests
...
--------------------------------------------------------
- T E S T S
--------------------------------------------------------
-Concurrency config is parallel='methods', perCoreThreadCount=true, threadCount=4, useUnlimitedThreads=false
+[INFO] Tests run: 6, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.023 s - in org.antlr.v4.test.runtime.java.TestIntegerList
+[INFO] Tests run: 348, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 19.269 s - in org.antlr.v4.test.runtime.java.JavaRuntimeTests
...
```
-This can be combined with other `-D` above.
-
## Adding a runtime test
-To add a new runtime test, first determine which [group of tests](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors) it belongs to. Then, add a new [RuntimeTestDescriptor](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/RuntimeTestDescriptor.java) implementation by subclassing one of:
+To add a new runtime test, first determine which [group (dir) of tests](../runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors) it belongs to.
+Then, add a new descriptor file implementation by filling in one of these (omitting unused sections):
-* [BaseParserTestDescriptor](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/BaseParserTestDescriptor.java); see example [APlus](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserExecDescriptors.java#L7).
-* [BaseDiagnosticParserTestDescriptor](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/BaseDiagnosticParserTestDescriptor) if you want to test parser diagnostic output; see [example output](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/FullContextParsingDescriptors.java#L16).
-* [BaseCompositeParserTestDescriptor](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/BaseCompositeParserTestDescriptor.java); see example [BringInLiteralsFromDelegate](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/CompositeParsersDescriptors.java#L11)
-* [BaseLexerTestDescriptor](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/BaseLexerTestDescriptor.java); see example [ActionPlacement](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/LexerExecDescriptors.java#L12).
-* [BaseCompositeLexerTestDescriptor](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/BaseCompositeLexerTestDescriptor.java); see example [LexerDelegatorInvokesDelegateRule](https://github.com/antlr/antlr4/blob/master/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/CompositeLexersDescriptors.java#L11)
+```
+[notes]
+[type]
-Each descriptor object describes the following mandatory elements for the test:
+[grammar]
- * the test type
- * the grammar
- * the start rule
- * the input text to parse or lex
- * the expected output
- * the expected errors
+[slaveGrammar]
-Your best bet is to find a similar test in the appropriate group and then copy and paste the descriptor object, creating a new nested class within the test group class. Modify the field definitions to suit your new problem.
+[start]
-If you need to create a whole new group of tests, it requires a new descriptor class; call it `XDescriptors`. Then, in each [target subdirectory](https://github.com/antlr/antlr4/tree/master/runtime-testsuite/test/org/antlr/v4/test/runtime), you need to create a new test rig `TestX.java` file:
+[input]
-```java
-package org.antlr.v4.test.runtime.java;
+[output]
-import org.antlr.v4.test.runtime.BaseRuntimeTest;
-import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
-import org.antlr.v4.test.runtime.descriptors.ListenersDescriptors;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+[errors]
-@RunWith(Parameterized.class)
-public class TestX extends BaseRuntimeTest {
- public TestX(RuntimeTestDescriptor descriptor) {
- super(descriptor,new BaseTest());
- }
+[flags]
- @Parameterized.Parameters(name="{0}")
- public static RuntimeTestDescriptor[] getAllTestDescriptors() {
- return BaseRuntimeTest.getRuntimeTestDescriptors(XDescriptors.class, "");
- }
-}
+[skip]
```
-where `` is replaced with Java, Cpp, CSharp, Python2, ... in the various subdirectories.
+Your best bet is to find a similar test in the appropriate group and then copy and paste the descriptor file, creating a new file within the test group dir.
+Modify the sections to suit your new problem.
### Ignoring tests
-In order to turn off a test for a particular target, we need to use the `ignore` method. Given a target name, a descriptor object can decide whether to ignore the test. This is not always convenient but it is fully general and works well for the one case we have now where we have to ignore `Visitor` tests in all targets except JavaScript.
+In order to turn off a test for a particular target, the `skip` section in the descriptor file should be used.
+For example, the following skips PHP and Dart targets:
+
+```
+[skip]
+PHP
+Dart
+```
### Target API/library testing
-Some parts of the runtime API need to be tested with code written specifically in the target language. For example, you can see all of the Java runtime API tests here:
+Some parts of the runtime API need to be tested with code written specifically in the target language.
+For example, all the Java runtime API tests are placed here:
-[https://github.com/antlr/antlr4/tree/master/runtime-testsuite/test/org/antlr/v4/test/runtime/java/api](https://github.com/antlr/antlr4/tree/master/runtime-testsuite/test/org/antlr/v4/test/runtime/java/api)
+[runtime-testsuite/test/org/antlr/v4/test/runtime/java/api](../runtime-testsuite/test/org/antlr/v4/test/runtime/java/api)
-Notice that it is under an `api` dir. The directory above is where all of the `Test*` files go.
+Notice that it is under an `api` dir. The directory above is where all of the `*Test*` files go.
### Cross-language actions embedded within grammars
@@ -277,7 +173,7 @@ Use instead the language-neutral:
```
-Template file [runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Java.test.stg](https://github.com/antlr/antlr4/tree/master/runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Java.test.stg) has templates like:
+Template file [Java.test.stg](../runtime-testsuite/resources/org/antlr/v4/test/runtime/templates/Java.test.stg) has templates like:
```
writeln(s) ::= <);>>
@@ -287,6 +183,6 @@ that translate generic operations to target-specific language statements or expr
## Adding an ANTLR tool unit test
-Just go into the appropriate Java test class in dir [antlr4/tool-testsuite/test/org/antlr/v4/test/tool](https://github.com/antlr/antlr4/tree/master/tool-testsuite/test/org/antlr/v4/test/tool) and add your unit test.
+Just go into the appropriate Java test class in dir [antlr4/tool-testsuite/test/org/antlr/v4/test/tool](../tool-testsuite/test/org/antlr/v4/test/tool) and add your unit test.
diff --git a/doc/building-antlr.md b/doc/building-antlr.md
index 494bea81de..76bdbcd0b6 100644
--- a/doc/building-antlr.md
+++ b/doc/building-antlr.md
@@ -7,7 +7,7 @@ Most programmers do not need the information on this page because they will simp
I will assume that the root directory is `/tmp` for the purposes of explaining how to build ANTLR in this document.
-*As of 4.6, ANTLR tool and Java-target runtime requires Java 7.*
+*As of 4.6, ANTLR tool and Java-target runtime requires Java 7. As of 4.10, we have verified that the tool itself builds with Java 8 and 11.*
# Get the source
@@ -25,43 +25,53 @@ Checking connectivity... done.
Checking out files: 100% (1427/1427), done.
```
-# Compile
+# Check your environment
+
+If you are starting from a clean, minimum Ubuntu OS, check your environment.
+
```bash
-$ cd /tmp/antlr4
-$ export MAVEN_OPTS="-Xmx1G" # don't forget this on linux
-$ mvn clean # must be separate, not part of install/compile
-$ mvn -DskipTests install
+$ sudo apt-get update
+$ # Get Java
+$ java > /dev/null 2>&1
+$ if [[ "$?" != "0" ]]; then sudo apt install -y openjdk-11-jre-headless; fi
+$ # Get Mvn
+$ mvn > /dev/null 2>&1
+$ if [[ "$?" != "0" ]]; then sudo apt install -y maven; fi
+
+```
+
+# Compile
+
+The current maven build seems complicated to me because there is a dependency of the project on itself. The runtime tests naturally depend on the current version being available but it won't compile without the current version. Once you have the generated/installed jar, mvn builds but otherwise there's a dependency on what you are going to build. You will get this error when you try to clean but you can ignore it:
+
+```
+[INFO] ANTLR 4 Runtime Tests (4th generation) ............. FAILURE [ 0.073 s]
...
-[INFO] ------------------------------------------------------------------------
-[INFO] Reactor Summary:
-[INFO]
-[INFO] ANTLR 4 ............................................ SUCCESS [ 0.287 s]
-[INFO] ANTLR 4 Runtime .................................... SUCCESS [ 4.915 s]
-[INFO] ANTLR 4 Tool ....................................... SUCCESS [ 1.315 s]
-[INFO] ANTLR 4 Maven plugin ............................... SUCCESS [ 2.393 s]
-[INFO] ANTLR 4 Runtime Test Annotations ................... SUCCESS [ 0.078 s]
-[INFO] ANTLR 4 Runtime Test Processors .................... SUCCESS [ 0.019 s]
-[INFO] ANTLR 4 Runtime Tests (2nd generation) ............. SUCCESS [ 1.986 s]
-[INFO] ANTLR 4 Tool Tests ................................. SUCCESS [ 0.513 s]
-[INFO] ------------------------------------------------------------------------
-[INFO] BUILD SUCCESS
-[INFO] ------------------------------------------------------------------------
-[INFO] Total time: 12.005 s
-[INFO] Finished at: 2016-11-21T11:42:42-08:00
-[INFO] Final Memory: 52M/434M
-[INFO] ------------------------------------------------------------------------
+[ERROR] Plugin org.antlr:antlr4-maven-plugin:4.10-SNAPSHOT or one of its dependencies could not be resolved: Could not find artifact org.antlr:antlr4-maven-plugin:jar:4.10-SNAPSHOT -> [Help 1]
+```
+
+To be super squeaky clean, you can wipe out the repository cache, then do the build:
+
+```
+$ export MAVEN_OPTS="-Xmx1G" # don't forget this on linux
+cd /tmp/antlr4 # or wherever you have the software
+rm -rf ~/.m2/repository/org/antlr*
+mvn clean
+mvn -DskipTests install
```
**NOTE:** We do `install` not `compile` as tool tests and such refer to modules that must be pulled from the maven install local cache.
+Once you have completed this process once and there is a jar hanging around in the repository cache.
+
# Installing libs to mvn cache locally
To skip the tests (which require all the target languages be installed) and **install into local repository** `~/.m2/repository/org/antlr`, do this:
```bash
$ export MAVEN_OPTS="-Xmx1G" # don't forget this on linux
-$ mvn install -DskipTests=true # make sure all artifacts are visible on this machine
+$ mvn install -DskipTests # make sure all artifacts are visible on this machine
```
You should see these jars (when building 4.6-SNAPSHOT):
@@ -69,8 +79,6 @@ You should see these jars (when building 4.6-SNAPSHOT):
```bash
/Users/parrt/.m2/repository/org/antlr $ find antlr4* -name '*.jar'
antlr4-maven-plugin/4.6-SNAPSHOT/antlr4-maven-plugin-4.6-SNAPSHOT.jar
-antlr4-runtime-test-annotation-processors/4.6-SNAPSHOT/antlr4-runtime-test-annotation-processors-4.6-SNAPSHOT.jar
-antlr4-runtime-test-annotations/4.6-SNAPSHOT/antlr4-runtime-test-annotations-4.6-SNAPSHOT.jar
antlr4-runtime-testsuite/4.6-SNAPSHOT/antlr4-runtime-testsuite-4.6-SNAPSHOT-tests.jar
antlr4-runtime-testsuite/4.6-SNAPSHOT/antlr4-runtime-testsuite-4.6-SNAPSHOT.jar
antlr4-runtime/4.6-SNAPSHOT/antlr4-runtime-4.6-SNAPSHOT.jar
diff --git a/doc/case-insensitive-lexing.md b/doc/case-insensitive-lexing.md
deleted file mode 100644
index 4c42484383..0000000000
--- a/doc/case-insensitive-lexing.md
+++ /dev/null
@@ -1,79 +0,0 @@
-# Case-Insensitive Lexing
-
-In some languages, keywords are case insensitive meaning that `BeGiN` means the same thing as `begin` or `BEGIN`. ANTLR has two mechanisms to support building grammars for such languages:
-
-1. Build lexical rules that match either upper or lower case.
- * **Advantage**: no changes required to ANTLR, makes it clear in the grammar that the language in this case insensitive.
- * **Disadvantage**: might have a small efficiency cost and grammar is a more verbose and more of a hassle to write.
-
-2. Build lexical rules that match keywords in all uppercase and then parse with a custom [character stream](https://github.com/antlr/antlr4/blob/master/runtime/Java/src/org/antlr/v4/runtime/CharStream.java) that converts all characters to uppercase before sending them to the lexer (via the `LA()` method). Care must be taken not to convert all characters in the stream to uppercase because characters within strings and comments should be unaffected. All we really want is to trick the lexer into thinking the input is all uppercase.
- * **Advantage**: Could have a speed advantage depending on implementation, no change required to the grammar.
- * **Disadvantage**: Requires that the case-insensitive stream and grammar are used in correctly in conjunction with each other, makes all characters appear as uppercase/lowercase to the lexer but some grammars are case sensitive outside of keywords, errors new case insensitive streams and language output targets (java, C#, C++, ...).
-
-For the 4.7.1 release, we discussed both approaches in [detail](https://github.com/antlr/antlr4/pull/2046) and even possibly altering the ANTLR metalanguage to directly support case-insensitive lexing. We discussed including the case insensitive streams into the runtime but not all would be immediately supported. I decided to simply make documentation that clearly states how to handle this and include the appropriate snippets that people can cut-and-paste into their grammars.
-
-## Case-insensitive grammars
-
-As a prime example of a grammar that specifically describes case insensitive keywords, see the
-[SQLite grammar](https://github.com/antlr/grammars-v4/blob/master/sqlite/SQLite.g4). To match a case insensitive keyword, there are rules such as
-
-```
-K_UPDATE : U P D A T E;
-```
-
-that will match `UpdaTE` and `upDATE` etc... as the `update` keyword. This rule makes use of some generically useful fragment rules that you can cut-and-paste into your grammars:
-
-```
-fragment A : [aA]; // match either an 'a' or 'A'
-fragment B : [bB];
-fragment C : [cC];
-fragment D : [dD];
-fragment E : [eE];
-fragment F : [fF];
-fragment G : [gG];
-fragment H : [hH];
-fragment I : [iI];
-fragment J : [jJ];
-fragment K : [kK];
-fragment L : [lL];
-fragment M : [mM];
-fragment N : [nN];
-fragment O : [oO];
-fragment P : [pP];
-fragment Q : [qQ];
-fragment R : [rR];
-fragment S : [sS];
-fragment T : [tT];
-fragment U : [uU];
-fragment V : [vV];
-fragment W : [wW];
-fragment X : [xX];
-fragment Y : [yY];
-fragment Z : [zZ];
-```
-
-No special streams are required to use this mechanism for case insensitivity.
-
-## Custom character streams approach
-
-The other approach is to use lexical rules that match either all uppercase or all lowercase, such as:
-
-```
-K_UPDATE : 'UPDATE';
-```
-
-Then, when creating the character stream to parse from, we need a custom class that overrides methods used by the lexer. Below you will find custom character streams for a number of the targets that you can copy into your projects, but here is how to use the streams in Java as an example:
-
-```java
-CharStream s = CharStreams.fromPath(Paths.get('test.sql'));
-CaseChangingCharStream upper = new CaseChangingCharStream(s, true);
-Lexer lexer = new SomeSQLLexer(upper);
-```
-
-Here are implementations of `CaseChangingCharStream` in various target languages:
-
-* [C#](https://github.com/antlr/antlr4/blob/master/doc/resources/CaseChangingCharStream.cs)
-* [Go](https://github.com/antlr/antlr4/blob/master/doc/resources/case_changing_stream.go)
-* [Java](https://github.com/antlr/antlr4/blob/master/doc/resources/CaseChangingCharStream.java)
-* [JavaScript](https://github.com/antlr/antlr4/blob/master/doc/resources/CaseChangingStream.js)
-* [Python2/3](https://github.com/antlr/antlr4/blob/master/doc/resources/CaseChangingStream.py)
diff --git a/doc/cpp-target.md b/doc/cpp-target.md
index eec7cf88bd..ed0dcd2f8f 100644
--- a/doc/cpp-target.md
+++ b/doc/cpp-target.md
@@ -1,6 +1,6 @@
# C++
-The C++ target supports all platforms that can either run MS Visual Studio 2013 (or newer), XCode 7 (or newer) or CMake (C++11 required). All build tools can either create static or dynamic libraries, both as 64bit or 32bit arch. Additionally, XCode can create an iOS library. Also see [Antlr4 for C++ with CMake: A practical example](http://blorente.me//Antlr-,-C++-and-CMake-Wait-what.html).
+The C++ target supports all platforms that can either run MS Visual Studio 2017 (or newer), XCode 7 (or newer) or CMake (C++17 required). All build tools can either create static or dynamic libraries, both as 64bit or 32bit arch. Additionally, XCode can create an iOS library. Also see [Antlr4 for C++ with CMake: A practical example](http://blorente.me/beyond-the-loop/Antlr-cpp-cmake/).
## How to create a C++ lexer or parser?
This is pretty much the same as creating a Java lexer or parser, except you need to specify the language target, for example:
@@ -65,20 +65,20 @@ int main(int argc, const char* argv[]) {
tree::ParseTree *tree = parser.key();
TreeShapeListener listener;
- tree::ParseTreeWalker::DEFAULT->walk(&listener, tree);
+ tree::ParseTreeWalker::DEFAULT.walk(&listener, tree);
return 0;
}
```
-This example assumes your grammar contains a parser rule named `key` for which the enterKey function was generated.
+This example assumes your grammar contains a parser rule named `key` for which the `enterKey` function was generated.
-## Specialities of this ANTLR target
+## Special cases for this ANTLR target
There are a couple of things that only the C++ ANTLR target has to deal with. They are described here.
-### Build Aspects
+### Code Generation Aspects
The code generation (by running the ANTLR4 jar) allows to specify 2 values you might find useful for better integration of the generated files into your application (both are optional):
* A **namespace**: use the **`-package`** parameter to specify the namespace you want.
@@ -102,8 +102,20 @@ In order to create a static lib in Visual Studio define the `ANTLR4CPP_STATIC` m
For gcc and clang it is possible to use the `-fvisibility=hidden` setting to hide all symbols except those that are made default-visible (which has been defined for all public classes in the runtime).
+### Compile Aspects
+
+When compiling generated files, you can configure a compile option according to your needs (also optional):
+
+* A **thread local DFA macro**: Add `-DANTLR4_USE_THREAD_LOCAL_CACHE=1` to the compilation options
+will enable using thread local DFA cache (disabled by default), after that, each thread uses its own DFA.
+This will increase memory usage to store thread local DFAs and redundant computation to build thread local DFAs (not too much).
+The benefit is that it can improve the concurrent performance running with multiple threads.
+In other words, when you find your concurent throughput is not high enough, you should consider turning on this option.
+
### Memory Management
-Since C++ has no built-in memory management we need to take extra care. For that we rely mostly on smart pointers, which however might cause time penalties or memory side effects (like cyclic references) if not used with care. Currently however the memory household looks very stable. Generally, when you see a raw pointer in code consider this as being managed elsewehere. You should never try to manage such a pointer (delete, assign to smart pointer etc.).
+Since C++ has no built-in memory management we need to take extra care. For that we rely mostly on smart pointers, which however might cause time penalties or memory side effects (like cyclic references) if not used with care. Currently however the memory household looks very stable. Generally, when you see a raw pointer in code consider this as being managed elsewhere. You should never try to manage such a pointer (delete, assign to smart pointer etc.).
+
+Accordingly a parse tree is only valid for the lifetime of its parser. The parser, in turn, is only valid for the lifetime of its token stream, and so on back to the original `ANTLRInputStream` (or equivalent). To retain a tree across function calls you'll need to create and store all of these and `delete` all but the tree when you no longer need it.
### Unicode Support
Encoding is mostly an input issue, i.e. when the lexer converts text input into lexer tokens. The parser is completely encoding unaware.
@@ -111,7 +123,7 @@ Encoding is mostly an input issue, i.e. when the lexer converts text input into
The C++ target always expects UTF-8 input (either in a string or stream) which is then converted to UTF-32 (a char32_t array) and fed to the lexer.
### Named Actions
-In order to help customizing the generated files there are a number of additional socalled **named actions**. These actions are tight to specific areas in the generated code and allow to add custom (target specific) code. All targets support these actions
+In order to help customizing the generated files there are a number of additional so-called **named actions**. These actions are tight to specific areas in the generated code and allow to add custom (target specific) code. All targets support these actions
* @parser::header
* @parser::members
@@ -127,7 +139,7 @@ In addition to that the C++ target supports many more such named actions. Unfort
* **@lexer::preinclude** - Placed right before the first #include (e.g. good for headers that must appear first, for system headers etc.). Appears in both lexer h and cpp file.
* **@lexer::postinclude** - Placed right after the last #include, but before any class code (e.g. for additional namespaces). Appears in both lexer h and cpp file.
* **@lexer::context** - Placed right before the lexer class declaration. Use for e.g. additional types, aliases, forward declarations and the like. Appears in the lexer h file.
-* **@lexer::declarations** - Placed in the private section of the lexer declaration (generated sections in all classes strictly follow the pattern: public, protected, privat, from top to bottom). Use this for private vars etc.
+* **@lexer::declarations** - Placed in the private section of the lexer declaration (generated sections in all classes strictly follow the pattern: public, protected, private, from top to bottom). Use this for private vars etc.
* **@lexer::definitions** - Placed before other implementations in the cpp file (but after *@postinclude*). Use this to implement e.g. private types.
For the parser there are the same actions as shown above for the lexer. In addition to that there are even more actions for visitor and listener classes:
diff --git a/doc/creating-a-language-target.md b/doc/creating-a-language-target.md
index ff7db290ea..723b865f2c 100644
--- a/doc/creating-a-language-target.md
+++ b/doc/creating-a-language-target.md
@@ -6,17 +6,76 @@ This document describes how to make ANTLR generate parsers in a new language, *X
Creating a new target involves the following key elements:
-1. For the tool, create class *X*Target as a subclass of class `Target` in package `org.antlr.v4.codegen.target`. This class describes language specific details about escape characters and strings and so on. There is very little to do here typically.
-1. Create *X*.stg in directory tool/resources/org/antlr/v4/tool/templates/codegen/*X*/*X*.stg. This is a [StringTemplate](http://www.stringtemplate.org/) group file (`.stg`) that tells ANTLR how to express all of the parsing elements needed to generate code. You will see templates called `ParserFile`, `Parser`, `Lexer`, `CodeBlockForAlt`, `AltBlock`, etc... Each of these must be described how to build the indicated chunk of code. Your best bet is to find the closest existing target, copy that template file, and tweak to suit.
-1. Create a runtime library to support the parsers generated by ANTLR. Under directory runtime/*X*, you are in complete control of the directory structure as dictated by common usage of that target language. For example, Java has: `runtime/Java/lib` and `runtime/Java/src` directories. Under `src`, you will find a directory structure for package `org.antlr.v4.runtime` and below.
-1. Create a template file for runtime tests. All you have to do is provide a few templates that indicate how to print values and declare variables. Our runtime test mechanism in dir `runtime-testsuite` will automatically generate code using these templates for each target and check the test results. It needs to know how to define various class fields, compare members and so on. You must create a *X*.test.stg file underneath [runtime-testsuite/resources/org/antlr/v4/test/runtime](https://github.com/antlr/antlr4/tree/master/runtime-testsuite/resources/org/antlr/v4/test/runtime). Again, your best bet is to copy the templates from the closest language to your target and tweak it to suit.
+1. For the tool, create class *X*Target as a subclass of class `Target` in package `org.antlr.v4.codegen.target`.
+ This class describes language specific details about escape characters and strings and so on.
+ There is very little to do here typically.
+2. Create `*X*.stg` in directory `tool/resources/org/antlr/v4/tool/templates/codegen/*X*/*X*.stg`.
+ This is a [StringTemplate](http://www.stringtemplate.org/) group file (`.stg`) that tells ANTLR how to express
+ all the parsing elements needed to generate code.
+ You will see templates called `ParserFile`, `Parser`, `Lexer`, `CodeBlockForAlt`, `AltBlock`, etc...
+ Each of these must be described how to build the indicated chunk of code.
+ Your best bet is to find the closest existing target, copy that template file, and tweak to suit.
+3. Create a runtime library to support the parsers generated by ANTLR.
+ Under directory `runtime/*X*`, you are in complete control of the directory structure as dictated by common usage of that target language.
+ For example, Java has: `runtime/Java/lib` and `runtime/Java/src` directories.
+ Under `src`, you will find a directory structure for package `org.antlr.v4.runtime` and below.
+4. Create a template file for runtime tests.
+ All you have to do is provide a few templates that indicate how to print values and declare variables.
+ Our runtime test mechanism in dir `runtime-testsuite` will automatically generate code using these templates for each target and check the test results.
+ It needs to know how to define various class fields, compare members and so on.
+ You must create a `*X*.test.stg` file underneath [runtime-testsuite/resources/org/antlr/v4/test/runtime](../runtime-testsuite/resources/org/antlr/v4/test/runtime)
+ and `Test.*x*.stg` underneath [runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers](../runtime-testsuite/resources/org/antlr/v4/test/runtime/helpers).
+ Again, your best bet is to copy the templates from the closest language to your target and tweak it to suit.
+6. Create test files under [/runtime-testsuite/test/org/antlr/v4/test/runtime](../runtime-testsuite/test/org/antlr/v4/test/runtime).
+ They will load defined test cases in each test descriptor.
+ Also add the `/runtime-testsuite/test/org/antlr/v4/test/runtime/X/BaseXTest.java` which defines how test cases will execute and output.
+7. Create/edit shell scripts in [/.github](../.github) to run tests in CI pipelines.
## Getting started
-1. Fork the `antlr/antlr4` repository at github to your own user so that you have repository `username/antlr4`.
-2. Clone `username/antlr4`, the forked repository, to your local disk. Your remote `origin` will be the forked repository on GitHub. Add a remote `upstream` to the original `antlr/antlr4` repository (URL `https://github.com/antlr/antlr4.git`). Changes that you would like to contribute back to the project are done with [pull requests](https://help.github.com/articles/using-pull-requests/).
+1. Fork the `antlr/antlr4` repository at GitHub to your own user so that you have repository `username/antlr4`.
+2. Clone `username/antlr4`, the forked repository, to your local disk.
+ Your remote `origin` will be the forked repository on GitHub.
+ Add a remote `upstream` to the original `antlr/antlr4` repository (URL `https://github.com/antlr/antlr4.git`).
+ Changes that you would like to contribute back to the project are done with [pull requests](https://help.github.com/articles/using-pull-requests/).
3. Try to build it before doing anything
+
```bash
$ mvn compile
```
+
That should proceed with success. See [Building ANTLR](building-antlr.md) for more details.
+
+## Comparing your target's parsing decisionmaking with Java's
+
+ANTLR's power comes from it's dynamic parsing strategy, but that means each target
+must implement that complicated algorithm. You should compare your target's debug
+output for ParserATNSimulator with Java's.
+
+Run this so we get right jars before trying this script:
+
+```
+cd ANTLR-ROOT-DIR
+mvn install -DskipTests=true
+cd runtime-tests
+mvn install -DskipTests=true # yes do it again
+```
+
+Run the script from `runtime-tests` dir with
+
+```
+../scripts/traceatn.sh /tmp/JSON.g4 json -target Go /tmp/foo.json
+```
+
+or whatever your test grammar, start rule, target, test input are.
+
+### Debugging the PHP target
+
+Because the PHP target is hosted in a separate repository, you will need to clone the [antlr/php-antlr-runtime](https://github.com/antlr/antlr-php-runtime)
+repository into the `runtime/PHP` and install the dependencies with `composer install` before you can run the tests.
+
+```
+git clone -b dev https://github.com/antlr/antlr-php-runtime.git runtime/PHP
+cd runtime/PHP
+composer install
+```
diff --git a/doc/csharp-target.md b/doc/csharp-target.md
index a869a82f60..1fcce06de7 100644
--- a/doc/csharp-target.md
+++ b/doc/csharp-target.md
@@ -36,11 +36,10 @@ using Antlr4.Runtime.Tree;
public void MyParseMethod() {
String input = "your text to parse here";
- ICharStream stream = CharStreams.fromstring(input);
+ ICharStream stream = CharStreams.fromString(input);
ITokenSource lexer = new MyGrammarLexer(stream);
ITokenStream tokens = new CommonTokenStream(lexer);
MyGrammarParser parser = new MyGrammarParser(tokens);
- parser.BuildParseTree = true;
IParseTree tree = parser.StartRule();
}
```
@@ -86,7 +85,7 @@ In order to execute this listener, you would simply add the following lines to t
...
IParseTree tree = parser.StartRule() - only repeated here for reference
KeyPrinter printer = new KeyPrinter();
-ParseTreeWalker.DEFAULT.walk(printer, tree);
+ParseTreeWalker.Default.Walk(printer, tree);
```
Further information can be found from The Definitive ANTLR Reference book.
diff --git a/doc/dart-target.md b/doc/dart-target.md
new file mode 100644
index 0000000000..270766fd81
--- /dev/null
+++ b/doc/dart-target.md
@@ -0,0 +1,129 @@
+# ANTLR4 Runtime for Dart
+
+From version 4.9 onwards antlr's dart generated code is null sound safety compatible and sets the minimum dart sdk version to 2.12.0.
+
+### First steps
+
+#### 1. Install ANTLR4
+
+[The getting started guide](https://github.com/antlr/antlr4/blob/master/doc/getting-started.md)
+should get you started.
+
+#### 2. Install the Dart ANTLR runtime
+
+Each target language for ANTLR has a runtime package for running parser
+generated by ANTLR4. The runtime provides a common set of tools for using your parser.
+
+Install the runtime with the same version as the main ANTLR tool:
+
+Add this to your package's pubspec.yaml file:
+```yaml
+...
+dependencies:
+ antlr4:
+...
+```
+
+#### 3. Generate your parser
+
+You use the ANTLR4 "tool" to generate a parser. These will reference the ANTLR
+runtime, installed above.
+
+Suppose you're using a UNIX system and have set up an alias for the ANTLR4 tool
+as described in [the getting started guide](https://github.com/antlr/antlr4/blob/master/doc/getting-started.md).
+To generate your Dart parser, run the following command:
+
+```shell script
+antlr4 -Dlanguage=Dart MyGrammar.g4
+```
+
+For a full list of antlr4 tool options, please visit the
+[tool documentation page](https://github.com/antlr/antlr4/blob/master/doc/tool-options.md).
+
+### Complete example
+
+Suppose you're using the JSON grammar from https://github.com/antlr/grammars-v4/tree/master/json.
+
+Then, invoke `antlr4 -Dlanguage=Dart JSON.g4`. The result of this is a
+collection of `.dart` including:
+
+* JsonLexer.dart
+* JsonParser.dart
+* JsonBaseListener.dart
+* JsonListener.dart (if you have not activated the -no-listener option)
+* JsonVisitor.dart (if you have activated the -visitor option)
+
+We'll write a small main func to call the generated parser/lexer
+(assuming they are separate). This one writes out the encountered
+`ParseTreeContext`'s:
+
+```dart
+import 'package:antlr4/antlr4.dart';
+import 'package:my_project/JSONParser.dart';
+import 'package:my_project/JSONLexer.dart';
+
+class TreeShapeListener implements ParseTreeListener {
+ @override
+ void enterEveryRule(ParserRuleContext ctx) {
+ print(ctx.text);
+ }
+
+ @override
+ void exitEveryRule(ParserRuleContext node) {
+ }
+
+ @override
+ void visitErrorNode(ErrorNode node) {
+ }
+
+ @override
+ void visitTerminal(TerminalNode node) {
+ }
+}
+
+void main(List args) async {
+ JSONLexer.checkVersion();
+ JSONParser.checkVersion();
+ final input = await InputStream.fromPath(args[0]);
+ final lexer = JSONLexer(input);
+ final tokens = CommonTokenStream(lexer);
+ final parser = JSONParser(tokens);
+ parser.addErrorListener(DiagnosticErrorListener());
+ final tree = parser.json();
+ ParseTreeWalker.DEFAULT.walk(TreeShapeListener(), tree);
+}
+```
+
+Create a `example.json` file:
+```json
+{"a":1}
+```
+
+Parse the input file:
+
+```shell script
+dart bin/main.dart example.json
+```
+
+The expected output is:
+
+```
+{"a":1}
+{"a":1}
+{"a":1}
+"a":1
+1
+```
+
+### Debug
+
+We have some logs in place that can ease the debugging process, in order to turn these logs on you can enable the following environment declarations:
+
+- ANTLR_LEXER_DEBUG
+- ANTLR_LEXER_DFA_DEBUG
+- ANTLR_PARSER_DEBUG
+- ANTLR_PARSER_LIST_ATN_DECISIONS_DEBUG
+- ANTLR_PARSER_DFA_DEBUG
+- ANTLR_PARSER_RETRY_DEBUG
+
+If you're using flutter, you can define these variables by adding an `--dart-define` arguments, eg. `flutter run --dart-define LEXER_DEBUG=false`
diff --git a/doc/faq/index.md b/doc/faq/index.md
index 734fc6c13a..9dd72165ff 100644
--- a/doc/faq/index.md
+++ b/doc/faq/index.md
@@ -38,8 +38,8 @@ This is the main landing page for the ANTLR 4 FAQ. The links below will take you
## Translation
-* [ASTs vs parse trees](parse-trees.md)
-* [Decoupling input walking from output generation](parse-trees.md)
+* [ASTs vs parse trees](translation.md)
+* [Decoupling input walking from output generation](translation.md)
## Actions and semantic predicates
diff --git a/doc/faq/parse-trees.md b/doc/faq/parse-trees.md
index 5a243cedb6..48ce56315d 100644
--- a/doc/faq/parse-trees.md
+++ b/doc/faq/parse-trees.md
@@ -50,7 +50,7 @@ For writing a compiler, either generate [LLVM-type static-single-assignment](htt
### XPath
-XPath works great when you need to find specific nodes, possibly in certain contexts. The context is limited to the parents on the way to the root of the tree. For example, if you want to find all ID nodes, use path `//ID`. If you want all variable declarations, you might use path `//vardecl`. If you only want fields declarations, then you can use some context information via path `/classdef/vardecl`, which would only find vardecls that our children of class definitions. You can merge the results of multiple XPath `findAll()`s simulating a set union for XPath. The only caveat is that the order from the original tree is not preserved when you union multiple `findAll()` sets.
+XPath works great when you need to find specific nodes, possibly in certain contexts. The context is limited to the parents on the way to the root of the tree. For example, if you want to find all ID nodes, use path `//ID`. If you want all variable declarations, you might use path `//vardecl`. If you only want fields declarations, then you can use some context information via path `/classdef/vardecl`, which would only find vardecls that are children of class definitions. You can merge the results of multiple XPath `findAll()`s simulating a set union for XPath. The only caveat is that the order from the original tree is not preserved when you union multiple `findAll()` sets.
### Tree pattern matching
@@ -70,4 +70,4 @@ scopeStack.peek().define(new VariableSymbol("foo"))
That way each listener function does not have to compute its appropriate scope.
-Examples: [DefScopesAndSymbols.java](https://github.com/mantra/compiler/blob/master/src/java/mantra/semantics/DefScopesAndSymbols.java) and [SetScopeListener.java](https://github.com/mantra/compiler/blob/master/src/java/mantra/semantics/SetScopeListener.java) and [VerifyListener.java](https://github.com/mantra/compiler/blob/master/src/java/mantra/semantics/VerifyListener.java)
\ No newline at end of file
+Examples: [DefScopesAndSymbols.java](https://github.com/mantra/compiler/blob/master/src/java/mantra/semantics/DefScopesAndSymbols.java) and [SetScopeListener.java](https://github.com/mantra/compiler/blob/master/src/java/mantra/semantics/SetScopeListener.java) and [VerifyListener.java](https://github.com/mantra/compiler/blob/master/src/java/mantra/semantics/VerifyListener.java)
diff --git a/doc/getting-started.md b/doc/getting-started.md
index 4614c67f6b..a4296dfcf5 100644
--- a/doc/getting-started.md
+++ b/doc/getting-started.md
@@ -1,51 +1,177 @@
# Getting Started with ANTLR v4
-Hi and welcome to the version 4 release of ANTLR! It's named after the fearless hero of the [Crazy Nasty-Ass Honey Badger](http://www.youtube.com/watch?v=4r7wHMg5Yjg) since ANTLR v4 takes whatever you give it--it just doesn't give a crap! See [Why do we need ANTLR v4?](faq/general.md) and the [preface of the ANTLR v4 book](http://media.pragprog.com/titles/tpantlr2/preface.pdf).
+Hi and welcome to the version 4 release of ANTLR! See [Why do we need ANTLR v4?](faq/general.md) and the [preface of the ANTLR v4 book](http://media.pragprog.com/titles/tpantlr2/preface.pdf).
+
+## Getting started the easy way using antlr4-tools
+
+To play around with ANTLR without having to worry about installing it and the Java needed to execute it, use [antlr4-tools](https://github.com/antlr/antlr4-tools). The only requirement is Python3, which is typically installed on all developer machines on all operating systems. (See below for Windows issue.)
+
+```bash
+$ pip install antlr4-tools
+```
+
+That command creates `antlr4` and `antlr4-parse` executables that, if necessary, will download and install Java 11 plus the latest ANTLR jar:
+
+```bash
+$ antlr4
+Downloading antlr4-4.13.2-complete.jar
+ANTLR tool needs Java to run; install Java JRE 11 yes/no (default yes)? y
+Installed Java in /Users/parrt/.jre/jdk-11.0.15+10-jre; remove that dir to uninstall
+ANTLR Parser Generator Version 4.13.2
+ -o ___ specify output directory where all output is generated
+ -lib ___ specify location of grammars, tokens files
+...
+```
+
+Let's play with a simple grammar:
+
+```
+grammar Expr;
+prog: expr EOF ;
+expr: expr ('*'|'/') expr
+ | expr ('+'|'-') expr
+ | INT
+ | '(' expr ')'
+ ;
+NEWLINE : [\r\n]+ -> skip;
+INT : [0-9]+ ;
+```
+
+### Windows-specific issues
+
+On Windows, the `pip` command doesn't just work---you need to add the `...\local-packages\python38\scripts` dir to your `PATH`, which itself might require a fun reboot. If you use WSL on Windows, then the pip install will also properly at the scripts directly (if you run from bash shell).
+
+
+1. Go to the Microsoft Store
+2. Search in Microsoft Store for Python
+3. Select the newest version of Python (3.11).
+4. Click the "Get" button. Store installs python and pip at "c:\Users...\AppData\Local\Microsoft\WindowsApps\python.exe" and "c:\Users...\AppData\Local\Microsoft\WindowsApps\pip.exe", respectively. And, it updates the search path immediately with the install.
+5. Open a "cmd" terminal.
+6. You can now type "python" and "pip", and "pip install antlr4-tools". 7. Unfortunately, it does not add that to the search path.
+7. Update the search path to contain `c:\Users...\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p8\LocalCache\local-packages\Python310\Scripts`. You may need to install MSYS2, then do a `find /c/ -name antlr4.exe 2> /dev/null` and enter that path.
+8. Or, you can set up an alias to antlr4.exe on that path.
+
+The good news is that the ANTLR4 Python tool downloads the ANTLR jar in a standard location, and you don't need to do that manually. It's also possible to go in a browser, go to python.org, and download the python package. But, it's likely you will need to update the path for antlr4.exe as before.
+
+### Try parsing with a sample grammar
+
+To parse and get the parse tree in text form, use:
+
+```bash
+$ antlr4-parse Expr.g4 prog -tree
+10+20*30
+^D
+(prog:1 (expr:2 (expr:3 10) + (expr:1 (expr:3 20) * (expr:3 30))) )
+```
+(Note: `^D` means control-D and indicates "end of input" on Unix; use `^Z` on Windows.)
+
+Here's how to get the tokens and trace through the parse:
+
+```bash
+$ antlr4-parse Expr.g4 prog -tokens -trace
+10+20*30
+^D
+[@0,0:1='10',,1:0]
+[@1,2:2='+',<'+'>,1:2]
+[@2,3:4='20',,1:3]
+[@3,5:5='*',<'*'>,1:5]
+[@4,6:7='30',,1:6]
+[@5,9:8='',,2:0]
+enter prog, LT(1)=10
+enter expr, LT(1)=10
+consume [@0,0:1='10',<8>,1:0] rule expr
+enter expr, LT(1)=+
+consume [@1,2:2='+',<3>,1:2] rule expr
+enter expr, LT(1)=20
+consume [@2,3:4='20',<8>,1:3] rule expr
+enter expr, LT(1)=*
+consume [@3,5:5='*',<1>,1:5] rule expr
+enter expr, LT(1)=30
+consume [@4,6:7='30',<8>,1:6] rule expr
+exit expr, LT(1)=
+exit expr, LT(1)=
+exit expr, LT(1)=
+consume [@5,9:8='',<-1>,2:0] rule prog
+exit prog, LT(1)=
+```
+
+Here's how to get a visual tree view:
+
+```bash
+$ antlr4-parse Expr.g4 prog -gui
+10+20*30
+^D
+```
+
+The following will pop up in a Java-based GUI window:
+
+
+
+### Generating parser code
+
+The previous section used a built-in ANTLR interpreter but typically you will ask ANTLR to generate code in the language used by your project (there are about 10 languages to choose from as of 4.11). Here's how to generate Java code from a grammar:
+
+```bash
+$ antlr4 Expr.g4
+$ ls Expr*.java
+ExprBaseListener.java ExprLexer.java ExprListener.java ExprParser.java
+```
+
+And, here's how to generate C++ code from the same grammar:
+
+```bash
+$ antlr4 -Dlanguage=Cpp Expr.g4
+$ ls Expr*.cpp Expr*.h
+ExprBaseListener.cpp ExprLexer.cpp ExprListener.cpp ExprParser.cpp
+ExprBaseListener.h ExprLexer.h ExprListener.h ExprParser.h
+```
## Installation
-ANTLR is really two things: a tool that translates your grammar to a parser/lexer in Java (or other target language) and the runtime needed by the generated parsers/lexers. Even if you are using the ANTLR Intellij plug-in or ANTLRWorks to run the ANTLR tool, the generated code will still need the runtime library.
+ANTLR is really two things: a tool written in Java that translates your grammar to a parser/lexer in Java (or other target language) and the runtime library needed by the generated parsers/lexers. Even if you are using the ANTLR Intellij plug-in or ANTLRWorks to run the ANTLR tool, the generated code will still need the runtime library.
-The first thing you should do is probably download and install a development tool plug-in. Even if you only use such tools for editing, they are great. Then, follow the instructions below to get the runtime environment available to your system to run generated parsers/lexers. In what follows, I talk about antlr-4.7.1-complete.jar, which has the tool and the runtime and any other support libraries (e.g., ANTLR v4 is written in v3).
+The first thing you should do is probably download and install a development tool plug-in. Even if you only use such tools for editing, they are great. Then, follow the instructions below to get the runtime environment available to your system to run generated parsers/lexers. In what follows, I talk about antlr-4.13.2-complete.jar, which has the tool and the runtime and any other support libraries (e.g., ANTLR v4 is written in v3).
-If you are going to integrate ANTLR into your existing build system using mvn, ant, or want to get ANTLR into your IDE such as eclipse or intellij, see Integrating ANTLR into Development Systems.
+If you are going to integrate ANTLR into your existing build system using mvn, ant, or want to get ANTLR into your IDE such as eclipse or intellij, see [Integrating ANTLR into Development Systems](https://github.com/antlr/antlr4/blob/master/doc/IDEs.md).
### UNIX
-0. Install Java (version 1.6 or higher)
+0. Install Java (version 11 or higher)
1. Download
```
$ cd /usr/local/lib
-$ curl -O https://www.antlr.org/download/antlr-4.7.1-complete.jar
+$ curl -O https://www.antlr.org/download/antlr-4.13.2-complete.jar
```
Or just download in browser from website:
[https://www.antlr.org/download.html](https://www.antlr.org/download.html)
and put it somewhere rational like `/usr/local/lib`.
-2. Add `antlr-4.7.1-complete.jar` to your `CLASSPATH`:
+if you are using lower version jdk, just download from [website download](https://github.com/antlr/website-antlr4/tree/gh-pages/download) for previous version, and antlr version before 4.13.2 support jdk 1.8
+
+2. Add `antlr-4.13.2-complete.jar` to your `CLASSPATH`:
```
-$ export CLASSPATH=".:/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH"
+$ export CLASSPATH=".:/usr/local/lib/antlr-4.13.2-complete.jar:$CLASSPATH"
```
It's also a good idea to put this in your `.bash_profile` or whatever your startup script is.
3. Create aliases for the ANTLR Tool, and `TestRig`.
```
-$ alias antlr4='java -Xmx500M -cp "/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
-$ alias grun='java -Xmx500M -cp "/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig'
+$ alias antlr4='java -Xmx500M -cp "/usr/local/lib/antlr-4.13.2-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
+$ alias grun='java -Xmx500M -cp "/usr/local/lib/antlr-4.13.2-complete.jar:$CLASSPATH" org.antlr.v4.gui.TestRig'
```
### WINDOWS
(*Thanks to Graham Wideman*)
-0. Install Java (version 1.6 or higher)
-1. Download antlr-4.7.1-complete.jar (or whatever version) from [https://www.antlr.org/download/](https://www.antlr.org/download/)
+0. Install Java (version 1.7 or higher)
+1. Download antlr-4.13.2-complete.jar (or whatever version) from [https://www.antlr.org/download.html](https://www.antlr.org/download.html)
Save to your directory for 3rd party Java libraries, say `C:\Javalib`
-2. Add `antlr-4.7.1-complete.jar` to CLASSPATH, either:
+2. Add `antlr-4.13.2-complete.jar` to CLASSPATH, either:
* Permanently: Using System Properties dialog > Environment variables > Create or append to `CLASSPATH` variable
* Temporarily, at command line:
```
-SET CLASSPATH=.;C:\Javalib\antlr-4.7.1-complete.jar;%CLASSPATH%
+SET CLASSPATH=.;C:\Javalib\antlr-4.13.2-complete.jar;%CLASSPATH%
```
3. Create short convenient commands for the ANTLR Tool, and TestRig, using batch files or doskey commands:
* Batch files (in directory in system PATH) antlr4.bat and grun.bat
@@ -71,7 +197,7 @@ Either launch org.antlr.v4.Tool directly:
```
$ java org.antlr.v4.Tool
-ANTLR Parser Generator Version 4.7.1
+ANTLR Parser Generator Version 4.13.2
-o ___ specify output directory where all output is generated
-lib ___ specify location of .tokens files
...
@@ -80,8 +206,8 @@ ANTLR Parser Generator Version 4.7.1
or use -jar option on java:
```
-$ java -jar /usr/local/lib/antlr-4.7.1-complete.jar
-ANTLR Parser Generator Version 4.7.1
+$ java -jar /usr/local/lib/antlr-4.13.2-complete.jar
+ANTLR Parser Generator Version 4.13.2
-o ___ specify output directory where all output is generated
-lib ___ specify location of .tokens files
...
@@ -133,7 +259,12 @@ That pops up a dialog box showing that rule `r` matched keyword `hello` followed
The book has lots and lots of examples that should be useful too. You can download them here for free:
-[http://pragprog.com/titles/tpantlr2/source_code](http://pragprog.com/titles/tpantlr2/source_code)
+[ANTLR reference book examples in Java](https://media.pragprog.com/titles/tpantlr2/code/tpantlr2-code.zip)
+[ANTLR reference book examples in C#](https://github.com/Philippe-Laval/tpantlr2)
+
+
+[Language implementation patterns book examples in Java](https://media.pragprog.com/titles/tpdsl/code/tpdsl-code.zip)
+[Language implementation patterns book examples in C#](https://github.com/Philippe-Laval/tpdsl)
Also, there is a large collection of grammars for v4 at github:
diff --git a/doc/go-changes.md b/doc/go-changes.md
new file mode 100644
index 0000000000..fb6dce814f
--- /dev/null
+++ b/doc/go-changes.md
@@ -0,0 +1,179 @@
+# Changes to the Go Runtime over time
+
+## v4.12.0 to v4.13.0
+
+Strictly speaking, if ANTLR was a go only project following [SemVer](https://semver.org/) release v4.13.0 would be
+at least a minor version change and arguably a bump to v5. However, we must follow the ANTLR conventions here or the
+release numbers would quickly become confusing. I apologize for being unable to follow the Go release rules absolutely
+to the letter.
+
+There are a lot of changes and improvements in this release, but only the change of repo holding the runtime code,
+and possibly the removal of interfaces will cause any code changes. There are no breaking changes to the runtime
+interfaces.
+
+ANTLR Go Maintainer: [Jim Idle](https://github.com/jimidle) - Email: [jimi@idle.ws](mailto:jimi@idle.ws)
+
+### Code Relocation
+
+For complicated reasons, including not breaking the builds of some users who use a monorepo and eschew modules, as well
+as not making substantial changes to the internal test suite, the Go runtime code will continue to be maintained in
+the main ANTLR4 repo `antlr/antlr4`. If you wish to contribute changes to the Go runtime code, please continue to submit
+PRs to this main repo, against the `dev` branch.
+
+The code located in the main repo at about the depth of the Mariana Trench, means that the go tools cannot reconcile
+the module correctly. After some debate, it was decided that we would create a dedicated release repo for the Go runtime
+so that it will behave exactly as the Go tooling expects. This repo is auto-maintained and keeps both the dev and master
+branches up to date.
+
+Henceforth, all future projects using the ANTLR Go runtime, should import as follows:
+
+```go
+import (
+ "github.com/antlr4-go/antlr/v4"
+ )
+```
+
+And use the command:
+
+```shell
+go get github.com/antlr4-go/antlr
+```
+
+To get the module - `go mod tidy` is probably the best way once imports have been changed.
+
+Please note that there is no longer any source code kept in the ANTLR repo under `github.com/antlr/antlr4/runtime/Go/antlr`.
+If you are using the code without modules, then sync the code from the new release repo.
+
+### Documentation
+
+Prior to this release, the godocs were essentially unusable as the go doc code was essentially copied without
+change, from teh Java runtime. The godocs are now properly formatted for Go and pkg.dev.
+
+Please feel free to raise an issue if you find any remaining mistakes. Or submit a PR (remember - not to the new repo).
+It is expected that it might take a few iterations to get the docs 100% squeaky clean.
+
+### Removal of Unnecessary Interfaces
+
+The Go runtime was originally produced as almost a copy of the Java runtime but with go syntax. This meant that everything
+had an interface. There is no need to use interfaces in Go if there is only ever going to be one implementation of
+some struct and its methods. Interfaces cause an extra deference at runtime and are detrimental to performance if you
+are trying to squeeze out every last nanosecond, which some users will be trying to do.
+
+This is 99% an internal refactoring of the runtime with no outside effects to the user.
+
+### Generated Recognizers Return *struct and not Interfaces
+
+The generated recognizer code generated an interface for the parsers and lexers. As they can only be implemented by the
+generated code, the interfaces were removed. This is possibly the only place you may need to make a code change to
+your driver code.
+
+If your code looked like this:
+
+```go
+var lexer = parser.NewMySqlLexer(nil)
+var p = parser.NewMySqlParser(nil)
+```
+
+Or this:
+
+```go
+lexer := parser.NewMySqlLexer(nil)
+p := parser.NewMySqlParser(nil)
+```
+
+Then no changes need to be made. However, fi you predeclared the parser and lexer variables with there type, such as like
+this:
+
+```go
+var lexer parser.MySqlLexer
+var p parser.MySqlParser
+// ...
+lexer = parser.NewMySqlLexer(nil)
+p = parser.NewMySqlParser(nil)
+```
+
+You will need to change your variable declarations to pointers (note the introduction of the `*` below.
+
+```go
+var lexer *parser.MySqlLexer
+var p *parser.MySqlParser
+// ...
+lexer = parser.NewMySqlLexer(nil)
+p = parser.NewMySqlParser(nil)
+```
+
+This is the only user facing change that I can see. This change though has a very beneficial side effect in that you
+no longer need to cast the interface into a struct so that you can access methods and data within it. Any code you
+had that needed to do that, will be cleaner and faster.
+
+The performance improvement is worth the change and there was no tidy way for me to avoid it.
+
+### Parser Error Recovery Does Not Use Panic
+
+THe generated parser code was again essentially trying to be Java code in disguise. This meant that every parser rule
+executed a `defer {}` and a `recover()`, even if there wer no outstanding parser errors. Parser errors were issued by
+issuing a `panic()`!
+
+While some major work has been performed in the go compiler and runtime to make `defer {}` as fast as possible,
+`recover()` is (relatively) slow as it is not meant to be used as a general error mechanism, but to recover from say
+an internal library problem if that problem can be recovered to a known state.
+
+The generated code now stores a recognition error and a flag in the main parser struct and use `goto` to exit the
+rule instead of a `panic()`. As might be imagined, this is significantly faster through the happy path. It is also
+faster at generating errors.
+
+The ANTLR runtime tests do check error raising and recovery, but if you find any differences in the error handling
+behavior of your parsers, please raise an issue.
+
+### Reduction in use of Pointers
+
+Certain internal structs, such as interval sets are small and immutable, but were being passed around as pointers
+anyway. These have been change to use copies, and resulted in significant performance increases in some cases.
+There is more work to come in this regard.
+
+### ATN Deserialization
+
+When the ATN and associated structures are deserialized for the first time, there was a bug that caused a needed
+optimization to fail to be executed. This could have a significant performance effect on recognizers that were written
+in a suboptimal way (as in poorly formed grammars). This is now fixed.
+
+### Prediction Context Caching was not Working
+
+This has a massive effect when reusing a parser for a second and subsequent run. The PredictionContextCache merely
+used memory but did not speed up subsequent executions. This is now fixed, and you should see a big difference in
+performance when reusing a parser. This single paragraph does not do this fix justice ;)
+
+### Cumulative Performance Improvements
+
+Though too numerous to mention, there are a lot of small performance improvements, that add up in accumulation. Everything
+from improvements in collection performance to slightly better algorithms or specific non-generic algorithms.
+
+### Cumulative Memory Improvements
+
+The real improvements in memory usage, allocation and garbage collection are saved for the next major release. However,
+if your grammar is well-formed and does not require almost infinite passes using ALL(*), then both memory and performance
+will be improved with this release.
+
+### Bug Fixes
+
+Other small bug fixes have been addressed, such as potential panics in funcs that did not check input parameters. There
+are a lot of bug fixes in this release that most people were probably not aware of. All known bugs are fixed at the
+time of release preparation.
+
+### A Note on Poorly Constructed Grammars
+
+Though I have made some significant strides on improving the performance of poorly formed grammars, those that are
+particularly bad will see much less of an incremental improvement compared to those that are fairly well-formed.
+
+This is deliberately so in this release as I felt that those people who have put in effort to optimize the form of their
+grammar are looking for performance, where those that have grammars that parser in seconds, tens of seconds or even
+minutes, are presumed to not care about performance.
+
+A particularly good (or bad) example is the MySQL grammar in the ANTLR grammar repository (apologies to the Author
+if you read this note - this isn't an attack). Although I have improved its runtime performance
+drastically in the Go runtime, it still takes about a minute to parse complex select statements. As it is constructed,
+there are no magic answers. I will look in more detail at improvements for such parsers, such as not freeing any
+memory until the parse is finished (improved 100x in experiments).
+
+The best advice I can give is to put some effort in to the actual grammar itself. well-formed grammars will potentially
+see some huge improvements with this release. Badly formed grammars, not so much.
diff --git a/doc/go-target.md b/doc/go-target.md
index 4f7e64e059..f40709949a 100644
--- a/doc/go-target.md
+++ b/doc/go-target.md
@@ -1,57 +1,220 @@
# ANTLR4 Language Target, Runtime for Go
+### Changes from ANTLR 4.12.0
+
+Please see [Changes in ANTLR Go runtimes](go-changes.md), but in summary:
+ - The Go runtime is now stored in the repo `antlr4-go/antlr` - change your import, remove the old location from
+ `go.mod` and use `go get github.com/antlr4-go/antlr`
+ - There are some new `@actions` for adding to the generated import statements and recognizer structure
+ - The recognizer rules are no longer called via an interface, for performance reasons
+ - Memory usage improvements
+ - Performance improvements
+ - Documentation in true Go format
+ - Git tags now work correctly with go tools
+
+### Removal of non v4 code
+
+Prior to the release of the v4 tagged runtime, the source code for the Go runtime module existed at
+`runtime/Go/antlr`, which is the pre-v4 version of the code, and also under `runtime/Go/antlr/v4`. If your project
+was not using modules, you could merely sync to the latest hash in the master branch and use the code. This has changed.
+
+As of the current release, the source code for the Go runtime module has been moved to its own repo in its own
+GitHub organization. As of now, you can still use the code without modules, but you must use the code
+in the repo at https://github.com/antlr4-go/antlr instead of the code in the main ANTLR repo.
+
+This is for historic reasons as the code was originally written before modules were a
+thing, and the go runtime source was - and the maintainer's version still is - a part of the monorepo
+that is `antlr/antlr4/...`.
+
+Note that I am unable to properly deprecate the go.mod in the non-V4 directory, for hte same reason that I
+cannot use tag the v4 module at this depth in the source tree.
+
+We strongly advise you to use modules, though it is not required. See below for more information.
+
+ANTLR Go Maintainer: [Jim Idle](https://github.com/jimidle) - Email: [jimi@idle.ws](mailto:jimi@idle.ws)
+
### First steps
#### 1. Install ANTLR4
-[The getting started guide](getting-started.md) should get you started.
+See: [The getting started guide](getting-started.md).
#### 2. Get the Go ANTLR runtime
-Each target language for ANTLR has a runtime package for running parser generated by ANTLR4. The runtime provides a common set of tools for using your parser.
+Each target language for ANTLR has a runtime package for running a recognizer generated by ANTLR4.
+The runtime provides a common set of tools for using your parser/lexer. Note that if you have existing projects and have
+yet to replace the `v1.x.x` modules with the `v4` modules, then you can skip ahead to the section *Upgrading to v4
+from earlier versions*
+
+The Go runtime uses modules and has a version path of `/v4` to stay in sync with the runtime versions of all the other
+runtimes and the tool itself.
-Get the runtime and install it on your GOPATH:
+Setup is the same as any other module based project:
```bash
-go get github.com/antlr/antlr4/runtime/Go/antlr
+$ cd mymodproject
+$ go mod init mymodproject
```
-#### 3. Set the release tag (optional)
+After which, you can use go get, to get the latest release version of the ANTLR v4 runtime using:
-`go get` has no native way to specify a branch or commit. So, when you run it, you'll download the latest commits. This may or may not be your preference.
+```bash
+go get github.com/antlr4-go/antlr
+```
-You'll need to use git to set the release. For example, to set the release tag for release 4.6.0:
+If your project was already using the v4 runtime from the main ANTLR repo, then you can upgrade to the latest release
+by removing the `github.com/antlr/antlr4/runtime/Go/antlr/v4` reference in your module, and changing the associated
+import in your project code. The following script may be useful in changing your imports:
-```bash
-cd $GOPATH/src/github.com/antlr/antlr4 # enter the antlr4 source directory
-git checkout tags/4.6.0 # the go runtime was added in release 4.6.0
+```shell
+find . -type f \
+ -name '*.go' \
+ -exec sed -i -e 's,github.com/antlr/antlr4/runtime/Go/antlr/v4,github.com/antlr4-go/antlr/v4,g' {} \;
+```
+Note that the import package still imports with the final path as `antlr`, so only the import statement itself needs to
+change.
+
+If you are already using the repo and import `github.com/antlr4-go/antlr/v4` then you can upgrade to the latest version
+using the standard.
+
+```shell
+go get -u github.com/antlr4-go/antlr
+```
+
+If you have not yet upgraded existing projects to the `/v4` module path, consult the section *Upgrading to v4
+from earlier versions*
+
+The ANTLR runtime has only one external transient dependency, and that is part of the go system itself:
+
+```
+golang.org/x/exp
+```
+
+A complete list of releases can be found on [the release page](https://github.com/antlr/antlr4/releases). The Go
+runtime will be tagged using standard Go tags, so release 4.13.2 in the `antlr4-go/antlr` repo, will be tagged with
+`v4.13.2` and go get will pick that up from the ANTLR repo.
+
+#### 3. Configuring `go generate` in your project
+
+In order to promote the use of repeatable builds, it is often useful to add the latest tool jar to your project's
+repo and configure a `generate.sh` and `generate.go` file. You can of course globally alias the java command required to run the
+tool. Your own CI and dev environment will guide you.
+
+Here is how you can configure `go generate` for your project, assuming that you follow the general recommendation to
+place the ANTLR grammar files in their own package in your project structure. Here is a general template as a starting point:
+
+```
+ .
+ ├── myproject
+ ├── parser
+ │ ├── mygrammar.g4
+ │ ├── antlr-4.13.2-complete.jar
+ │ ├── generate.go
+ │ └── generate.sh
+ ├── parsing # Generated code goes here
+ │ └── error_listeners.go
+ ├── go.mod
+ ├── go.sum
+ ├── main.go
+ └── main_test.go
+```
+
+Make sure that the package statement in your grammar file(s) reflects the go package the go code will be generated in.
+The `generate.go` file then looks like this:
+
+```golang
+ package parser
+
+ //go:generate ./generate.sh
+```
+
+And the `generate.sh` file will look similar to this:
+
+```shell
+ #!/bin/sh
+
+ alias antlr4='java -Xmx500M -cp "./antlr-4.13.2-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
+ antlr4 -Dlanguage=Go -no-visitor -package parsing *.g4
```
-A complete list of releases can be found on [the release page](https://github.com/antlr/antlr4/releases).
+From the command line at the root of your package - the location of the `go.mod` file - you can then simply issue the command:
+
+```shell
+ go generate ./...
+```
-#### 4. Generate your parser
+If you have not yet run a `go get`, you can now run `go mod tidy` and update your
+
+#### 4. Generate your parser manually
You use the ANTLR4 "tool" to generate a parser. These will reference the ANTLR runtime, installed above.
-Suppose you're using a UNIX system and have set up an alias for the ANTLR4 tool as described in [the getting started guide](getting-started.md). To generate your go parser, you'll need to invoke:
+Suppose you're using a UNIX system and have set up an alias for the ANTLR4 tool as described in
+[the getting started guide](getting-started.md).
-```bash
-antlr4 -Dlanguage=Go MyGrammar.g4
+To generate your go parser, you'll need to invoke:
+
+```shell
+ antlr4 -Dlanguage=Go MyGrammar.g4
```
For a full list of antlr4 tool options, please visit the [tool documentation page](tool-options.md).
+### Upgrading to `/v4` from the default path
+
+*NB: While switching to new module path would normally imply that the public interface for the runtime has changed, this is
+not actually the case - you will not need to change your existing code to upgrade. The main point of the repo change is so
+that git tagging works with the ANTLR Go runtime and the go tools.*
+
+Prior to release v4.11.0 the Go runtime shipped with a module but the module had no version path. This meant that
+the tags in the ANTLR repo did not work, as any tag above `v1` must refer to a matching module path.
+So the command `go get github.com/antlr/antlr4/runtime/Go/antlr` would just bring in
+whatever was the `HEAD` of the master branch. While this *kind of* worked, it is obviously subject to problems and does
+not fit properly with the idiomatic ways of Go.
+
+As of v4.13.0 the runtime code exists in its own repo, `github.com/antlr4-go/antlr`, and is correctly tagged.
+However, this means you need to perform a few simple actions in order to upgrade to the `/v4` path.
+
+ - Firstly, make sure that you are using an ANTLR tool jar with a version number of 4.13.0 or greater.
+ - Next you replace any mention of the old (default) path to ANTLR in your go source files.
+ - If using modules, remove any existing reference to the ANTLR Go runtime
+ - Now regenerate your grammar files either manually or using `go generate ./...` (see above)
+ - Consider whether you can move to using modules in your project
+
+A quick way to replace the original module path references is to use this script from your module's base directory:
+
+```shell
+find . -type f \
+ -name '*.go' \
+ -exec sed -i -e 's,github.com/antlr/antlr4/runtime/Go/antlr,github.com/antlr4-go/antlr/v4,g' {} \;
+```
+
+After performing the steps above, and you are using modules issuing:
+
+```shell
+go mod tidy
+```
+Should fix up your `go.mod` file to reference only the `v4` version of the ANTLR Go runtime:
+
+```shell
+require github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.13.0
+```
+
+From this point on, your go mod commands will work correctly with the ANTLR repo and upgrades and downgrades will work
+as you expect. As will branch version such as @dev
+
### Referencing the Go ANTLR runtime
You can reference the go ANTLR runtime package like this:
-```go
-import "github.com/antlr/antlr4/runtime/Go/antlr"
+```golang
+import "github.com/antlr4-go/antlr/v4"
```
### Complete example
-Suppose you're using the JSON grammar from https://github.com/antlr/grammars-v4/tree/master/json.
+Suppose you're using the JSON grammar from https://github.com/antlr/grammars-v4/tree/master/json placed in the parser
+directory and have initialized your `go mod` file.
Then, invoke `antlr4 -Dlanguage=Go JSON.g4`. The result of this is a collection of .go files in the `parser` directory including:
```
@@ -61,16 +224,18 @@ json_lexer.go
json_listener.go
```
-Another common option to the ANTLR tool is `-visitor`, which generates a parse tree visitor, but we won't be doing that here. For a full list of antlr4 tool options, please visit the [tool documentation page](tool-options.md).
+Another common option to the ANTLR tool is `-visitor`, which generates a parse tree visitor, but we won't be doing that here.
+For a full list of antlr4 tool options, please visit the [tool documentation page](tool-options.md).
-We'll write a small main func to call the generated parser/lexer (assuming they are separate). This one writes out the encountered `ParseTreeContext`'s. Suppose the gen'ed parser code is in the `parser` directory relative to this code:
+We'll write a small main func to call the generated parser/lexer (assuming they are separate). This one writes out the
+encountered `ParseTreeContext`'s. Assuming the generated parser code is in the `parser` directory relative to this code:
-```
+```golang
package main
import (
- "github.com/antlr/antlr4/runtime/Go/antlr"
- "./parser"
+ "github.com/antlr4-go/antlr/v4"
+ "./parser" // Note that with modules you may not be able to use a relative immport path
"os"
"fmt"
)
@@ -93,12 +258,17 @@ func main() {
stream := antlr.NewCommonTokenStream(lexer,0)
p := parser.NewJSONParser(stream)
p.AddErrorListener(antlr.NewDiagnosticErrorListener(true))
- p.BuildParseTrees = true
tree := p.Json()
antlr.ParseTreeWalkerDefault.Walk(NewTreeShapeListener(), tree)
}
```
+Fix up your `go.mod` file:
+
+```shell
+go mod tidy
+```
+
This one expects the input to be passed on the command line:
```
diff --git a/doc/grammars.md b/doc/grammars.md
index 5f88bf20ac..97ad2659ec 100644
--- a/doc/grammars.md
+++ b/doc/grammars.md
@@ -98,7 +98,7 @@ Not every kind of grammar can import every other kind of grammar:
* Parsers can import parsers.
* Combined grammars can import parsers or lexers without modes.
-ANTLR adds imported rules to the end of the rule list in a main lexer grammar. That means lexer rules in the main grammar get precedence over imported rules. For example, if a main grammar defines rule `IF : ’if’ ;` and an imported grammar defines rule `ID : [a-z]+ ;` (which also recognizes `if`), the imported `ID` won’t hide the main grammar’s `IF` token definition.
+ANTLR adds imported rules to the end of the rule list in a main lexer grammar. That means lexer rules in the main grammar get precedence over imported rules. For example, if a main grammar defines rule `IF : 'if' ;` and an imported grammar defines rule `ID : [a-z]+ ;` (which also recognizes `if`), the imported `ID` won’t hide the main grammar’s `IF` token definition.
## Tokens Section
diff --git a/doc/images/PR-on-dev.png b/doc/images/PR-on-dev.png
new file mode 100644
index 0000000000..f0890f8e24
Binary files /dev/null and b/doc/images/PR-on-dev.png differ
diff --git a/doc/images/new-antlr-branches.png b/doc/images/new-antlr-branches.png
new file mode 100644
index 0000000000..85fd4706d5
Binary files /dev/null and b/doc/images/new-antlr-branches.png differ
diff --git a/doc/images/python3-tests.png b/doc/images/python3-tests.png
index 3f278e30e4..9d8a9c079e 100644
Binary files a/doc/images/python3-tests.png and b/doc/images/python3-tests.png differ
diff --git a/doc/images/testrigs.png b/doc/images/testrigs.png
index 00e05b7cef..a9fc04a822 100644
Binary files a/doc/images/testrigs.png and b/doc/images/testrigs.png differ
diff --git a/doc/index.md b/doc/index.md
index 2ecb5099f4..9dfc2e2766 100644
--- a/doc/index.md
+++ b/doc/index.md
@@ -57,10 +57,10 @@ For those using Java, here's a great [set of ANTLR in Intellij notes](https://do
* [Parsing binary streams](parsing-binary-files.md)
-* [Case-Insensitive Lexing](case-insensitive-lexing.md)
-
* [Parser and lexer interpreters](interpreters.md)
+* [Writing target-agnostic grammars](target-agnostic-grammars.md)
+
* [Resources](resources.md)
# Building / releasing ANTLR itself
diff --git a/doc/java-target.md b/doc/java-target.md
index 60612a9fd5..1760dccbcb 100644
--- a/doc/java-target.md
+++ b/doc/java-target.md
@@ -134,12 +134,12 @@ Edit the pom.xml file. Now we need to extensively modify the pom.xml file. The f
org.antlr
antlr4-runtime
- 4.5
+ 4.9.3
junit
junit
- 3.8.1
+ 4.13.1
@@ -150,8 +150,8 @@ Edit the pom.xml file. Now we need to extensively modify the pom.xml file. The f
maven-compiler-plugin
3.1
- 1.7
- 1.7
+ 1.8
+ 1.8
' ;
-CDATA : '' ;OPEN : '<' -> pushMode(INSIDE) ;
+CDATA : '' ;
+OPEN : '<' -> pushMode(INSIDE) ;
...
XMLDeclOpen : ' pushMode(INSIDE) ;
SPECIAL_OPEN: '' Name -> more, pushMode(PROC_INSTR) ;
@@ -305,3 +308,16 @@ As of 4.5, you can also define channel names like enumerations with the followin
```
channels { WSCHANNEL, MYHIDDEN }
```
+
+## Lexer Rule Options
+
+### caseInsensitive
+
+Defines if the current lexer rule is case-insensitive.
+The argument can be `true` or `false`.
+The option rewrites `caseInsensitive` grammar option value if it's defined.
+
+```g4
+options { caseInsensitive=true; }
+STRING options { caseInsensitive=false; } : 'N'? '\'' (~'\'' | '\'\'')* '\''; // lower n is not allowed
+```
diff --git a/doc/lexicon.md b/doc/lexicon.md
index 078dc3e7ae..a8f0427606 100644
--- a/doc/lexicon.md
+++ b/doc/lexicon.md
@@ -26,8 +26,8 @@ The Javadoc comments are hidden from the parser and are ignored at the moment.
Token names always start with a capital letter and so do lexer rules as defined by Java’s `Character.isUpperCase` method. Parser rule names always start with a lowercase letter (those that fail `Character.isUpperCase`). The initial character can be followed by uppercase and lowercase letters, digits, and underscores. Here are some sample names:
```
-ID, LPAREN, RIGHT_CURLY // token names/rules
-expr, simpleDeclarator, d2, header_file // rule names
+ID, LPAREN, RIGHT_CURLY // token names/lexer rules
+expr, simpleDeclarator, d2, header_file // parser rule names
```
Like Java, ANTLR accepts Unicode characters in ANTLR names:
@@ -79,13 +79,13 @@ These more or less correspond to `isJavaIdentifierPart` and `isJavaIdentifierSta
## Literals
-ANTLR does not distinguish between character and string literals as most languages do. All literal strings one or more characters in length are enclosed in single quotes such as `’;’`, `’if’`, `’>=’`, and `’\’` (refers to the one-character string containing the single quote character). Literals never contain regular expressions.
+ANTLR does not distinguish between character and string literals as most languages do. All literal strings one or more characters in length are enclosed in single quotes such as `';'`, `'if'`, `'>='`, and `'\''` (refers to the one-character string containing the single quote character). Literals never contain regular expressions.
-Literals can contain Unicode escape sequences of the form `’\uXXXX’` (for Unicode code points up to `’U+FFFF’`) or `’\u{XXXXXX}’` (for all Unicode code points), where `’XXXX’` is the hexadecimal Unicode code point value.
+Literals can contain Unicode escape sequences of the form `'\uXXXX'` (for Unicode code points up to `'U+FFFF'`) or `'\u{XXXXXX}'` (for all Unicode code points), where `'XXXX'` is the hexadecimal Unicode code point value.
-For example, `’\u00E8’` is the French letter with a grave accent: `’è’`, and `’\u{1F4A9}’` is the famous emoji: `’💩’`.
+For example, `'\u00E8'` is the French letter with a grave accent: `'è'`, and `'\u{1F4A9}'` is the famous emoji: `'💩'`.
-ANTLR also understands the usual special escape sequences: `’\n’` (newline), `’\r’` (carriage return), `’\t’` (tab), `’\b’` (backspace), and `’\f’` (form feed). You can use Unicode code points directly within literals or use the Unicode escape sequences:
+ANTLR also understands the usual special escape sequences: `'\n'` (newline), `'\r'` (carriage return), `'\t'` (tab), `'\b'` (backspace), and `'\f'` (form feed). You can use Unicode code points directly within literals or use the Unicode escape sequences:
```
grammar Foreign;
@@ -96,7 +96,7 @@ The recognizers that ANTLR generates assume a character vocabulary containing al
## Actions
-Actions are code blocks written in the target language. You can use actions in a number of places within a grammar, but the syntax is always the same: arbitrary text surrounded by curly braces. You don’t need to escape a closing curly character if it’s in a string or comment: `"}"` or `/*}*/`. If the curlies are balanced, you also don’t need to escape }: `{...}`. Otherwise, escape extra curlies with a backslash: `\{` or `\}`. The action text should conform to the target language as specified with thelanguage option.
+Actions are code blocks written in the target language. You can use actions in a number of places within a grammar, but the syntax is always the same: arbitrary text surrounded by curly braces. You don’t need to escape a closing curly character if it’s in a string or comment: `"}"` or `/*}*/`. If the curlies are balanced, you also don’t need to escape }: `{...}`. Otherwise, escape extra curlies with a backslash: `\{` or `\}`. The action text should conform to the target language as specified with the language option.
Embedded code can appear in: `@header` and `@members` named actions, parser and lexer rules, exception catching specifications, attribute sections for parser rules (return values, arguments, and locals), and some rule element options (currently predicates).
diff --git a/doc/listeners.md b/doc/listeners.md
index c3bcad9c1c..834d2ed906 100644
--- a/doc/listeners.md
+++ b/doc/listeners.md
@@ -19,7 +19,7 @@ public interface JavaListener extends ParseTreeListener {
}
```
-where there is an enter and exit method for each rule in the parser grammar. ANTLR also generates a base listener with the fall empty implementations of all listener interface methods, in this case called JavaBaseListener. You can build your listener by subclassing this base and overriding the methods of interest.
+where there is an enter and exit method for each rule in the parser grammar. ANTLR also generates a base listener with empty implementations of all listener interface methods, in this case called JavaBaseListener. You can build your listener by subclassing this base and overriding the methods of interest.
Assuming you've created a listener object called `MyListener`, here is how to call the Java parser and walk the parse tree:
@@ -36,3 +36,131 @@ ParseTreeWalker.DEFAULT.walk(extractor, tree); // initiate walk of tree with lis
Listeners and visitors are great because they keep application-specific code out of grammars, making grammars easier to read and preventing them from getting entangled with a particular application.
See the book for more information on listeners and to learn how to use visitors. (The biggest difference between the listener and visitor mechanisms is that listener methods are called independently by an ANTLR-provided walker object, whereas visitor methods must walk their children with explicit visit calls. Forgetting to invoke visitor methods on a node’s children, means those subtrees don’t get visited.)
+
+## Listening during the parse
+
+We can also use listeners to execute code during the parse instead of waiting for a tree walker walks the resulting parse tree. Let's say we have the following simple expression grammar.
+
+```
+grammar CalcNoLR;
+
+s : expr EOF ;
+
+expr: add ((MUL | DIV) add)* ;
+
+add : atom ((ADD | SUB) atom)* ;
+
+atom : INT ;
+
+INT : [0-9]+;
+MUL : '*';
+DIV : '/';
+ADD : '+';
+SUB : '-';
+WS : [ \t]+ -> channel(HIDDEN);
+```
+
+We can create a listener that executes during the parse by implementing the listener interface as before:
+
+
+```java
+class CountListener extends CalcNoLRBaseListener {
+ public int nums = 0;
+ public boolean execExitS = false;
+
+ @Override
+ public void exitS(CalcNoLRParser.SContext ctx) {
+ execExitS = true;
+ }
+
+ @Override
+ public void exitAtom(CalcNoLRParser.AtomContext ctx) {
+ nums++;
+ }
+}
+```
+
+And then passing it to `addParseListener()`:
+
+```java
+String input = "2 + 8 / 2";
+CalcNoLRLexer lexer = new CalcNoLRLexer(new ANTLRInputStream(input));
+CalcNoLRParser parser = new CalcNoLRParser(new CommonTokenStream(lexer));
+CountListener counter = new CountListener();
+parser.addParseListener(counter);
+
+// Check that the purses valid first
+CalcNoLRParser.SContext context = parser.s();
+String parseTreeS = context.toStringTree(parser);
+assertEquals("(s (expr (add (atom 2) + (atom 8)) / (add (atom 2))) )", parseTreeS);
+assertEquals(3, counter.nums);
+assertEquals(true, counter.execExitS);
+```
+
+One should not do very complicated work during the parse because the parser is throwing exception to handle syntax errors. If you're complicated code throws different kind of exception it will screw up the parsing and things will go nuts. If you want to catch and properly handle exceptions in your listener code during the parse, you should override this method from `Parser`:
+
+```java
+protected boolean listenerExceptionOccurred = false;
+
+/**
+ * Notify any parse listeners of an exit rule event.
+ *
+ * @see #addParseListener
+ */
+@override
+protected void triggerExitRuleEvent() {
+ if ( listenerExceptionOccurred ) return;
+ try {
+ // reverse order walk of listeners
+ for (int i = _parseListeners.size() - 1; i >= 0; i--) {
+ ParseTreeListener listener = _parseListeners.get(i);
+ _ctx.exitRule(listener);
+ listener.exitEveryRule(_ctx);
+ }
+ }
+ catch (Throwable e) {
+ // If an exception is thrown in the user's listener code, we need to bail out
+ // completely out of the parser, without executing anymore user code. We
+ // must also stop the parse otherwise other listener actions will attempt to execute
+ // almost certainly with invalid results. So, record the fact an exception occurred
+ listenerExceptionOccurred = true;
+ throw e;
+ }
+}
+```
+
+Now, if you throw an exception inside one of the listener methods:
+
+```java
+// Now throw an exception in the listener
+class ErrorListener extends CalcNoLRBaseListener {
+ public boolean execExitS = false;
+ public boolean execExitAtom = false;
+
+ @Override
+ public void exitS(CalcNoLRParser.SContext ctx) {
+ execExitS = true;
+ }
+
+ @Override
+ public void exitAtom(CalcNoLRParser.AtomContext ctx) {
+ execExitAtom = true;
+ throw new NullPointerException("bail out");
+ }
+}
+```
+
+then the exception will properly cause the parser to bailout and the exception will not be thrown out:
+
+```
+java.lang.NullPointerException: bail out
+
+ at org.antlr.v4.test.runtime.java.api.TestParseListener$2ErrorListener.exitAtom(TestParseListener.java:102)
+ at org.antlr.v4.test.runtime.java.api.CalcNoLRParser$AtomContext.exitRule(CalcNoLRParser.java:311)
+ at org.antlr.v4.runtime.Parser.triggerExitRuleEvent(Parser.java:412)
+ at org.antlr.v4.runtime.Parser.exitRule(Parser.java:654)
+ at org.antlr.v4.test.runtime.java.api.CalcNoLRParser.atom(CalcNoLRParser.java:336)
+ at org.antlr.v4.test.runtime.java.api.CalcNoLRParser.add(CalcNoLRParser.java:261)
+ at org.antlr.v4.test.runtime.java.api.CalcNoLRParser.expr(CalcNoLRParser.java:181)
+ at org.antlr.v4.test.runtime.java.api.CalcNoLRParser.s(CalcNoLRParser.java:123)
+```
diff --git a/doc/options.md b/doc/options.md
index 7ce277551e..f5faa7ec37 100644
--- a/doc/options.md
+++ b/doc/options.md
@@ -12,7 +12,10 @@ where a value can be an identifier, a qualified identifier (for example, a.b.c),
All grammars can use the following options. In combined grammars, all options except language pertain only to the generated parser. Options may be set either within the grammar file using the options syntax (described above) or when invoking ANTLR on the command line, using the `-D` option. (see Section 15.9, [ANTLR Tool Command Line Options](tool-options.md).) The following examples demonstrate both mechanisms; note that `-D` overrides options within the grammar.
-* `superClass`. Set the superclass of the generated parser or lexer. For combined grammars, it sets the superclass of the parser.
+### `superClass`
+
+Set the superclass of the generated parser or lexer. For combined grammars, it sets the superclass of the parser.
+
```
$ cat Hi.g4
grammar Hi;
@@ -23,12 +26,20 @@ public class HiParser extends XX {
$ grep 'public class' HiLexer.java
public class HiLexer extends Lexer {
```
-* `language` Generate code in the indicated language, if ANTLR is able to do so. Otherwise, you will see an error message like this:
+
+### `language`
+
+Generate code in the indicated language, if ANTLR is able to do so. Otherwise, you will see an error message like this:
+
```
$ antlr4 -Dlanguage=C MyGrammar.g4
error(31): ANTLR cannot generate C code as of version 4.0
```
-* `tokenVocab` ANTLR assigns token type numbers to the tokens as it encounters them in a file. To use different token type values, such as with a separate lexer, use this option to have ANTLR pull in the tokens file. ANTLR generates a tokens file from each grammar.
+
+### `tokenVocab`
+
+ANTLR assigns token type numbers to the tokens as it encounters them in a file. To use different token type values, such as with a separate lexer, use this option to have ANTLR pull in the tokens file. ANTLR generates a tokens file from each grammar.
+
```
$ cat SomeLexer.g4
lexer grammar SomeLexer;
@@ -48,7 +59,11 @@ B=3
C=4
ID=1
```
-* `TokenLabelType` ANTLR normally uses type Token when it generates variables referencing tokens. If you have passed a TokenFactory to your parser and lexer so that they create custom tokens, you should set this option to your specific type. This ensures that the context objects know your type for fields and method return values.
+
+### `TokenLabelType`
+
+ANTLR normally uses type Token when it generates variables referencing tokens. If you have passed a TokenFactory to your parser and lexer so that they create custom tokens, you should set this option to your specific type. This ensures that the context objects know your type for fields and method return values.
+
```
$ cat T2.g4
grammar T2;
@@ -58,20 +73,46 @@ $ antlr4 T2.g4
$ grep MyToken T2Parser.java
public MyToken x;
```
-* `contextSuperClass`. Specify the super class of parse tree internal nodes. Default is `ParserRuleContext`. Should derive from ultimately `RuleContext` at minimum.
-Java target can use `contextSuperClass=org.antlr.v4.runtime.RuleContextWithAltNum` for convenience. It adds a backing field for `altNumber`, the alt matched for the associated rule node.
-## Rule Options
+### `contextSuperClass`
-There are currently no valid rule-level options, but the tool still supports the following syntax for future use:
+Specify the super class of parse tree internal nodes. Default is `ParserRuleContext`. Should derive from ultimately `RuleContext` at minimum.
+Java target can use `contextSuperClass=org.antlr.v4.runtime.RuleContextWithAltNum` for convenience. It adds a backing field for `altNumber`, the alt matched for the associated rule node.
+### `caseInsensitive`
+
+As of 4.10, ANTLR supports case-insensitive lexers using a grammar option. For example, the parser from the following grammar:
+
+```g4
+lexer grammar L;
+options { caseInsensitive = true; }
+ENGLISH_TOKEN: [a-z]+;
+GERMAN_TOKEN: [äéöüß]+;
+FRENCH_TOKEN: [àâæ-ëîïôœùûüÿ]+;
+CROATIAN_TOKEN: [ćčđšž]+;
+ITALIAN_TOKEN: [àèéìòù]+;
+SPANISH_TOKEN: [áéíñóúü¡¿]+;
+GREEK_TOKEN: [α-ω]+;
+RUSSIAN_TOKEN: [а-я]+;
+WS: [ ]+ -> skip;
```
-rulename
-options {...}
- : ...
- ;
+
+matches words such as the following:
+
+```
+abcXYZ äéöüßÄÉÖÜß àâæçÙÛÜŸ ćčđĐŠŽ àèéÌÒÙ áéÚÜ¡¿ αβγΧΨΩ абвЭЮЯ
```
+ANTLR considers only one-length chars in all cases. For instance, german lower `ß` is not treated as upper `ss` and vice versa.
+
+The mechanism works by automatically transforming grammar references to characters to there upper/lower case equivalent; e.g., `a` to `[aA]`. This means that you do not need to convert your input characters to uppercase--token text will be as it appears in the input stream.
+
+## Rule Options
+
+### caseInsensitive
+
+The tool support `caseInsensitive` lexer rule option that is described in [lexer-rules.md](lexer-rules.md#caseinsensitive).
+
## Rule Element Options
Token options have the form `T` as we saw in Section 5.4, [Dealing with Precedence, Left Recursion, and Associativity](http://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference). The only token option is `assoc`, and it accepts values `left` and `right`. Here’s a sample grammar with a left-recursive expression rule that specifies a token option on the `^` exponent operator token:
diff --git a/doc/parser-rules.md b/doc/parser-rules.md
index 73c363b990..e1a32fe736 100644
--- a/doc/parser-rules.md
+++ b/doc/parser-rules.md
@@ -196,7 +196,7 @@ ANTLR generates a field holding the list of context objects:
## Rule Elements
-Rule elements specify what the parser should do at a given moment just like statements in a programming language. The elements can be rule, token, string literal like expression, ID, and ’return’. Here’s a complete list of the rule elements (we’ll look at actions and predicates in more detail later):
+Rule elements specify what the parser should do at a given moment just like statements in a programming language. The elements can be rule, token, string literal like expression, ID, and 'return'. Here’s a complete list of the rule elements (we’ll look at actions and predicates in more detail later):
@@ -207,7 +207,7 @@ Rule elements specify what the parser should do at a given moment just like stat
Match token T at the current input position. Tokens always begin with a capital letter.
-’literal’
+ 'literal'
Match the string literal at the current input position. A string literal is simply a token with a fixed string.
@@ -232,7 +232,7 @@ Match any single token except for the end of file token. The “dot” operator
-When you want to match everything but a particular token or set of tokens, use the `~` “not” operator. This operator is rarely used in the parser but is available. `~INT` matches any token except the `INT` token. `~’,’` matches any token except the comma. `~(INT|ID)` matches any token except an INT or an ID.
+When you want to match everything but a particular token or set of tokens, use the `~` “not” operator. This operator is rarely used in the parser but is available. `~INT` matches any token except the `INT` token. `~','` matches any token except the comma. `~(INT|ID)` matches any token except an INT or an ID.
Token, string literal, and semantic predicate rule elements can take options. See Rule Element Options.
@@ -486,4 +486,4 @@ Invalid input would cause `config` to return immediately without matching any in
```
file : element* EOF; // don't stop early. must match all input
-```
\ No newline at end of file
+```
diff --git a/doc/php-target.md b/doc/php-target.md
index 75eae465ce..a87410fff9 100644
--- a/doc/php-target.md
+++ b/doc/php-target.md
@@ -15,7 +15,7 @@ generated by ANTLR4. The runtime provides a common set of tools for using your p
Install the runtime with Composer:
```bash
-composer install antlr/antlr4
+composer require antlr/antlr4-php-runtime
```
#### 3. Generate your parser
@@ -84,7 +84,6 @@ $lexer = new JSONLexer($input);
$tokens = new CommonTokenStream($lexer);
$parser = new JSONParser($tokens);
$parser->addErrorListener(new DiagnosticErrorListener());
-$parser->setBuildParseTree(true);
$tree = $parser->json();
ParseTreeWalker::default()->walk(new TreeShapeListener(), $tree);
@@ -108,4 +107,4 @@ The expected output is:
{"a":1}
"a":1
1
-```
\ No newline at end of file
+```
diff --git a/doc/predicates.md b/doc/predicates.md
index 09998c4257..e04d2464b0 100644
--- a/doc/predicates.md
+++ b/doc/predicates.md
@@ -136,7 +136,7 @@ If, on the other hand, the next character after input `enum` is a letter, then o
Predicates come into play by pruning the set of viable lexer rules. When the lexer encounters a false predicate, it deactivates that rule just like parsers deactivate alternatives with false predicates.
-Like parser predicates, lexer predicates can't depend on side effects from lexer actions. That's because actions can only execute after the lexer positively identifies the rule to match. Since predicates are part of the rule selection process, they can't rely on action side effects. Lexer actions must appear after predicates in lexer rules. As an example, here's another way to match enum as a keyword in the lexer:
+Like parser predicates, lexer predicates can't depend on side effects from lexer actions. That said, the predicate can depend on a side effect of an action that occured during the recognition of the previous token. That's because actions can only execute after the lexer positively identifies the rule to match. Since predicates are part of the rule selection process, they can't rely on action side effects created by actions in currently-prospective rules. Lexer actions must appear after predicates in lexer rules. As an example, here's another way to match enum as a keyword in the lexer:
```
ENUM: [a-z]+ {getText().equals("enum")}?
@@ -162,3 +162,17 @@ That works great, but it's really just for instructional purposes. It's easier t
```
ENUM : 'enum' ;
```
+
+Here's another example of a predicate. It's important to note that the predicate is evaluated before the action because actions are only executed if the lexer rule matches. The actions are not executed in line; they are collected and executed en mass later.
+
+```
+INDENT : [ \t]+ {System.out.println("INDENT")>} {this.getCharPositionInLine()==0}? ;
+```
+
+For more information on how actions and predicates operate in the lexer, see [Lexer actions and semantic predicates are executed out of order](https://github.com/antlr/antlr4/issues/3611) and [Lexer.getCharIndex() return value not behaving as expected](https://github.com/antlr/antlr4/issues/3606). The lexer rule that will not work as expected is:
+
+```
+Stuff : ( 'a'+ {count++;} | 'b') 'c' 'd' {count == 3}? ;
+```
+
+The `count++` code we'll not execute until after `Stuff` has been recognized (assuming count!=3).
\ No newline at end of file
diff --git a/doc/python-target.md b/doc/python-target.md
index 7ed73c281e..1ef34e74d5 100644
--- a/doc/python-target.md
+++ b/doc/python-target.md
@@ -1,129 +1,262 @@
-# Python (2 and 3)
+# Python 3
-The examples from the ANTLR 4 book converted to Python are [here](https://github.com/jszheng/py3antlr4book).
+## Requirements
-There are 2 Python targets: `Python2` and `Python3`. This is because there is only limited compatibility between those 2 versions of the language. Please refer to the [Python documentation](https://wiki.python.org/moin/Python2orPython3) for full details.
-
-How to create a Python lexer or parser?
-This is pretty much the same as creating a Java lexer or parser, except you need to specify the language target, for example:
-
-```
-$ antlr4 -Dlanguage=Python2 MyGrammar.g4
-```
-
-or
-
-```
-$ antlr4 -Dlanguage=Python3 MyGrammar.g4
-```
-
-For a full list of antlr4 tool options, please visit the tool documentation page.
-
-## Where can I get the runtime?
-
-Once you've generated the lexer and/or parser code, you need to download the runtime. The Python runtimes are available from PyPI:
-
-* https://pypi.python.org/pypi/antlr4-python2-runtime/
-* https://pypi.python.org/pypi/antlr4-python3-runtime/
-
-The runtimes are provided in the form of source code, so no additional installation is required.
-
-We will not document here how to refer to the runtime from your Python project, since this would differ a lot depending on your project type and IDE.
-
-## How do I run the generated lexer and/or parser?
-
-Let's suppose that your grammar is named, as above, "MyGrammar". Let's suppose this parser comprises a rule named "startRule". The tool will have generated for you the following files:
-
-* MyGrammarLexer.py
-* MyGrammarParser.py
-* MyGrammarListener.py (if you have not activated the -no-listener option)
-* MyGrammarVisitor.py (if you have activated the -visitor option)
-
-(Developers used to Java/C# AntLR will notice that there is no base listener or visitor generated, this is because Python having no support for interfaces, the generated listener and visitor are fully fledged classes)
-
-Now a fully functioning script might look like the following:
-
-```python
-import sys
-from antlr4 import *
-from MyGrammarLexer import MyGrammarLexer
-from MyGrammarParser import MyGrammarParser
-
-def main(argv):
- input_stream = FileStream(argv[1])
- lexer = MyGrammarLexer(input_stream)
- stream = CommonTokenStream(lexer)
- parser = MyGrammarParser(stream)
- tree = parser.startRule()
-
-if __name__ == '__main__':
- main(sys.argv)
-```
-
-This program will work. But it won't be useful unless you do one of the following:
-
-* you visit the parse tree using a custom listener
-* you visit the parse tree using a custom visitor
-* your grammar comprises production code (like ANTLR3)
-
-(please note that production code is target specific, so you can't have multi target grammars that include production code, except for very limited use cases, see below)
-
-## How do I create and run a custom listener?
-
-Let's suppose your MyGrammar grammar comprises 2 rules: "key" and "value". The antlr4 tool will have generated the following listener:
-
-```python
-class MyGrammarListener(ParseTreeListener):
- def enterKey(self, ctx):
- pass
- def exitKey(self, ctx):
- pass
- def enterValue(self, ctx):
- pass
- def exitValue(self, ctx):
- pass
-```
-
-In order to provide custom behavior, you might want to create the following class:
-
-```python
-class KeyPrinter(MyGrammarListener):
- def exitKey(self, ctx):
- print("Oh, a key!")
-```
-
-In order to execute this listener, you would simply add the following lines to the above code:
-
-```
- ...
- tree = parser.startRule() - only repeated here for reference
- printer = KeyPrinter()
- walker = ParseTreeWalker()
- walker.walk(printer, tree)
-```
-
-Further information can be found from the ANTLR 4 definitive guide.
+You will need to install Python and Pip, version 3.6 or better.
+See https://www.python.org/downloads/
+and https://www.geeksforgeeks.org/how-to-install-pip-on-windows/.
+
+## A simple example targeting Python3
+
+An example of a parser for the Python3 target consists of the following files.
+* An Antlr4 grammar, e.g., Expr.g4:
+ ```antlr
+ grammar Expr;
+ start_ : expr (';' expr)* EOF;
+ expr : atom | ('+' | '-') expr | expr '**' expr | expr ('*' | '/') expr | expr ('+' | '-') expr | '(' expr ')' | atom ;
+ atom : INT ;
+ INT : [0-9]+ ;
+ WS : [ \t\n\r]+ -> skip ;
+ ```
+* Driver.py:
+The driver code opens a file, creates a lexer, token stream,
+and parser, then calls the parser.
+ ```python
+ import sys
+ from antlr4 import *
+ from ExprLexer import ExprLexer
+ from ExprParser import ExprParser
+ from VisitorInterp import VisitorInterp
+
+ def main(argv):
+ input_stream = FileStream(argv[1])
+ lexer = ExprLexer(input_stream)
+ stream = CommonTokenStream(lexer)
+ parser = ExprParser(stream)
+ tree = parser.start_()
+
+ if __name__ == '__main__':
+ main(sys.argv)
+ ```
+* requirements.txt:
+This file contains a list of the
+required packages for the program. Required
+packages are downloaded by `pip`. The file
+must include a reference to the Antlr Python3 runtime.
+ ```
+ antlr4-python3-runtime==4.13.0
+ ```
+* A build script, e.g., build.sh:
+You should provide a script that builds the program.
+ ```
+ pip install -r requirements.txt
+ antlr4 -Dlanguage=Python3 Expr.g4
+ ```
+_It is vital that the versions for the
+Antlr tool used to generate the parser
+and the Antlr Python3 runtime match.
+E.g., 4.13.0. Using build files will help
+eliminate common errors from happening._
+
+_For a list of antlr4 tool options, please visit [ANTLR Tool Command Line Options](https://github.com/antlr/antlr4/blob/master/doc/tool-options.md)._
+* Input, e.g., input.txt:
+ ```
+ -(1 + 2)/3;
+ 1;
+ 2+3;
+ 8*9
+ ```
+* A run script, which runs your program.
+ ```
+ python Driver.py input.txt
+ ```
+
+## Parse tree traversal
+
+Tree traversal is used to implement
+[static](https://en.wikipedia.org/wiki/Static_program_analysis) or [dynamic](https://en.wikipedia.org/wiki/Dynamic_program_analysis)
+program analysis.
+Antlr generates two types of tree traversals: visitors and listeners.
+
+Understanding when to choose a visitor versus a listener is a good idea.
+For further information, see https://tomassetti.me/listeners-and-visitors/.
+
+A visitor is the best choice when computing only a single [synthesized attribute](https://en.wikipedia.org/wiki/Attribute_grammar#Synthesized_attributes)
+or when you want to control the order of parse tree nodes visited.
+Alternatively, a listener is the best choice when computing both synthesized
+and [inherited attributes](https://en.wikipedia.org/wiki/Attribute_grammar#Inherited_attributes).
+
+In many situations, they are interchangeable.
+
+### Visitors
+
+Antlr visitors generally implement a post-order tree walk. If you write
+`visit...` methods, the method must contain code to visit the children
+in the order you want. For a post-order tree walk, visit the children first.
+
+To implement a visitor, add the `-visitor` option to the `antlr4` command.
+Create a class that inherits from the generated visitor,
+then add `visit` methods that implement the analysis. Your driver code
+should call the `visit()` method for the root of the parse tree.
+
+For example, the following code implements an expression evaluator for the Expr.g4 grammar using a visitor.
-The Python implementation of ANTLR is as close as possible to the Java one, so you shouldn't find it difficult to adapt the examples for Python.
+* Driver.py:
+ ```python
+ import sys
+ from antlr4 import *
+ from ExprLexer import ExprLexer
+ from ExprParser import ExprParser
+ from VisitorInterp import VisitorInterp
-## Target agnostic grammars
+ def main(argv):
+ input_stream = FileStream(argv[1])
+ lexer = ExprLexer(input_stream)
+ stream = CommonTokenStream(lexer)
+ parser = ExprParser(stream)
+ tree = parser.start_()
+ if parser.getNumberOfSyntaxErrors() > 0:
+ print("syntax errors")
+ else:
+ vinterp = VisitorInterp()
+ vinterp.visit(tree)
-If your grammar is targeted to Python only, you may ignore the following. But if your goal is to get your Java parser to also run in Python, then you might find it useful.
+ if __name__ == '__main__':
+ main(sys.argv)
+ ```
+* VisitorInterp.py:
+ ```python
+ import sys
+ from antlr4 import *
+ from ExprParser import ExprParser
+ from ExprVisitor import ExprVisitor
-1. Do not embed production code inside your grammar. This is not portable and will not be. Move all your code to listeners or visitors.
-1. The only production code absolutely required to sit with the grammar should be semantic predicates, like:
-```
-ID {$text.equals("test")}?
-```
+ class VisitorInterp(ExprVisitor):
+ def visitAtom(self, ctx:ExprParser.AtomContext):
+ return int(ctx.getText())
-Unfortunately, this is not portable, but you can work around it. The trick involves:
+ def visitExpr(self, ctx:ExprParser.ExprContext):
+ if ctx.getChildCount() == 3:
+ if ctx.getChild(0).getText() == "(":
+ return self.visit(ctx.getChild(1))
+ op = ctx.getChild(1).getText()
+ v1 = self.visit(ctx.getChild(0))
+ v2 = self.visit(ctx.getChild(2))
+ if op == "+":
+ return v1 + v2
+ if op == "-":
+ return v1 - v2
+ if op == "*":
+ return v1 * v2
+ if op == "/":
+ return v1 / v2
+ return 0
+ if ctx.getChildCount() == 2:
+ opc = ctx.getChild(0).getText()
+ if opc == "+":
+ return self.visit(ctx.getChild(1))
+ if opc == "-":
+ return - self.visit(ctx.getChild(1))
+ return 0
+ if ctx.getChildCount() == 1:
+ return self.visit(ctx.getChild(0))
+ return 0
-* deriving your parser from a parser you provide, such as BaseParser
-* implementing utility methods in this BaseParser, such as "isEqualText"
-* adding a "self" field to the Java/C# BaseParser, and initialize it with "this"
+ def visitStart_(self, ctx:ExprParser.Start_Context):
+ for i in range(0, ctx.getChildCount(), 2):
+ print(self.visit(ctx.getChild(i)))
+ return 0
+ ```
-Thanks to the above, you should be able to rewrite the above semantic predicate as follows:
+### Listeners
+
+Antlr listeners perform an LR tree traversal. `enter` and `exit` methods are
+called during the tranversal. A parse tree node is visited twice, first for
+the `enter` method, then the `exit` method after all children have been walked.
+
+To implement a listener, add the `-listener` option to the `antlr4` command.
+Add a class that inherits from the generated listener
+with code that implements the analysis.
+
+The following example implements an expression evaluator using a listener.
+
+* Driver.py:
+ ```python
+ import sys
+ from antlr4 import *
+ from ExprLexer import ExprLexer
+ from ExprParser import ExprParser
+ from ListenerInterp import ListenerInterp
+
+ def main(argv):
+ input_stream = FileStream(argv[1])
+ lexer = ExprLexer(input_stream)
+ stream = CommonTokenStream(lexer)
+ parser = ExprParser(stream)
+ tree = parser.start_()
+ if parser.getNumberOfSyntaxErrors() > 0:
+ print("syntax errors")
+ else:
+ linterp = ListenerInterp()
+ walker = ParseTreeWalker()
+ walker.walk(linterp, tree)
+
+ if __name__ == '__main__':
+ main(sys.argv)
+ ```
+ * ListenerInterp.py:
+ ```python
+ import sys
+ from antlr4 import *
+ from ExprParser import ExprParser
+ from ExprListener import ExprListener
+
+ class ListenerInterp(ExprListener):
+ def __init__(self):
+ self.result = {}
+
+ def exitAtom(self, ctx:ExprParser.AtomContext):
+ self.result[ctx] = int(ctx.getText())
+
+ def exitExpr(self, ctx:ExprParser.ExprContext):
+ if ctx.getChildCount() == 3:
+ if ctx.getChild(0).getText() == "(":
+ self.result[ctx] = self.result[ctx.getChild(1)]
+ else:
+ opc = ctx.getChild(1).getText()
+ v1 = self.result[ctx.getChild(0)]
+ v2 = self.result[ctx.getChild(2)]
+ if opc == "+":
+ self.result[ctx] = v1 + v2
+ elif opc == "-":
+ self.result[ctx] = v1 - v2
+ elif opc == "*":
+ self.result[ctx] = v1 * v2
+ elif opc == "/":
+ self.result[ctx] = v1 / v2
+ else:
+ ctx.result[ctx] = 0
+ elif ctx.getChildCount() == 2:
+ opc = ctx.getChild(0).getText()
+ if opc == "+":
+ v = self.result[ctx.getChild(1)]
+ self.result[ctx] = v
+ elif opc == "-":
+ v = self.result[ctx.getChild(1)]
+ self.result[ctx] = - v
+ elif ctx.getChildCount() == 1:
+ self.result[ctx] = self.result[ctx.getChild(0)]
+
+ def exitStart_(self, ctx:ExprParser.Start_Context):
+ for i in range(0, ctx.getChildCount(), 2):
+ print(self.result[ctx.getChild(i)])
+ ```
+
+Further information can be found from the ANTLR 4 definitive guide.
+
+## Examples
+
+The examples from the ANTLR 4 book converted to Python are [here](https://github.com/jszheng/py3antlr4book).
-```
-ID {$self.isEqualText($text,"test")}?
-```
+There are many examples of grammars that target the Python3 target in the
+[grammars-v4 Github repository](https://github.com/antlr/grammars-v4).
diff --git a/doc/releasing-antlr.md b/doc/releasing-antlr.md
index cd1d0b9b47..6c1ffc516d 100644
--- a/doc/releasing-antlr.md
+++ b/doc/releasing-antlr.md
@@ -2,90 +2,112 @@
## Github
-Create a pre-release or full release at github; [Example 4.5-rc-1](https://github.com/antlr/antlr4/releases/tag/4.5-rc-1).
+### Get dev merged into master
+
+Do this or make a PR:
+
+```bash
+cd ~/antlr/code/antlr4
+git checkout master
+git merge dev
+```
+
+### Turn on DCO Enforcement
+
+As of 4.10.1, we will be using the Linux DCO not the previous contributors license agreement that required signing the file. Now, we use the DCO and contributors must use `-s` on each commit to the branch associated with a pull request.
+
+See [GitHub App DCO](https://github.com/apps/dco).
+
+Make sure this feature is turned on for the `antlr4` repo upon release.
### Delete existing release tag
Wack any existing tag as mvn will create one and it fails if already there.
```
-$ git tag -d 4.8
-$ git push origin :refs/tags/4.8
-$ git push upstream :refs/tags/4.8
+$ git tag -d 4.13.2
+$ git push origin :refs/tags/4.13.2
+$ git push upstream :refs/tags/4.13.2
```
-### Create release candidate tag
+### Go release tags
-```bash
-$ git tag -a 4.8-rc1 -m 'heading towards 4.8'
-$ git push origin 4.8-rc1
-$ git push upstream 4.8-rc1
+*I don't think this is necessary anymore as we have moved it release branch to https://github.com/antlr4-go/antlr*
+
+It seems that [Go needs a `v` in the release git tag](https://go.dev/ref/mod#glos-version) so make sure that we double up with 4.13.2 and v4.13.2.
+
+```
+$ git tag -a runtime/Go/antlr/v4/v4.13.2 -m "Go runtime module only"
+$ git push upstream runtime/Go/antlr/v4/v4.13.2
+$ git push origin runtime/Go/antlr/v4/v4.13.2
```
-## Update submodules
-Make sure you tell git to pull in the submodule (for every clone you do of antlr4):
+## Bump version in code and other files
-```bash
-git submodule init
-```
+There are a number of files that require inversion number be updated.
-Also bump version to 4.8 in `runtime/PHP/src/RuntimeMetaData.php`.
-Update the runtime submodules by running the following command:
+Here is a simple script to display any line from the critical files with, say, `4.11.1` in it. Here's an example run of the script:
```bash
-git submodule update --recursive
-git submodule update --remote --merge # might only need this last one but do both
+~/antlr/code/antlr4 $ python scripts/update_antlr_version.py 4.13.1 4.13.2
+Updating ANTLR version from 4.13.1 to 4.13.2
+Set ANTLR repo root (default ~/antlr/code/antlr4):
+Perform antlr4 `mvn clean` and wipe build dirs Y/N? (default no):
+Ok, not cleaning antlr4 dir
+4.13.1 appears on 2 lines so _not_ updating /tmp/antlr4/runtime/JavaScript/package-lock.json
+4.13.1 not in /tmp/antlr4/doc/releasing-antlr.md
```
-Make sure these changes go back to antlr4 repo:
+Make sure this file doesn't have `-SNAPSHOT` when releasing!
-```bash
-git add runtime/PHP
-git commit -m "Update PHP Runtime to latest version"
-```
-
-## Bump version
-
-Edit the repository looking for 4.5 or whatever and update it. Bump version in the following files:
-
- * runtime/Java/src/org/antlr/v4/runtime/RuntimeMetaData.java
- * runtime/Python2/setup.py
- * runtime/Python2/src/antlr4/Recognizer.py
- * runtime/Python3/setup.py
- * runtime/Python3/src/antlr4/Recognizer.py
- * runtime/CSharp/runtime/CSharp/Antlr4.Runtime/Properties/AssemblyInfo.cs
- * runtime/CSharp/runtime/CSharp/Antlr4.Runtime/Antlr4.Runtime.dotnet.csproj
- * runtime/JavaScript/package.json
- * runtime/JavaScript/src/antlr4/Recognizer.js
- * runtime/Cpp/VERSION
- * runtime/Cpp/runtime/src/RuntimeMetaData.cpp
- * runtime/Cpp/cmake/ExternalAntlr4Cpp.cmake
- * runtime/Cpp/demo/generate.cmd
- * runtime/Go/antlr/recognizer.go
- * runtime/Swift/Antlr4/org/antlr/v4/runtime/RuntimeMetaData.swift
- * tool/src/org/antlr/v4/codegen/target/GoTarget.java
- * tool/src/org/antlr/v4/codegen/target/CppTarget.java
- * tool/src/org/antlr/v4/codegen/target/CSharpTarget.java
- * tool/src/org/antlr/v4/codegen/target/JavaScriptTarget.java
- * tool/src/org/antlr/v4/codegen/target/Python2Target.java
- * tool/src/org/antlr/v4/codegen/target/Python3Target.java
- * tool/src/org/antlr/v4/codegen/target/SwiftTarget.java
- * tool/src/org/antlr/v4/codegen/Target.java
- * tool/resources/org/antlr/v4/tool/templates/codegen/Swift/Swift.stg
-
-Here is a simple script to display any line from the critical files with, say, `4.5` in it:
+```
+runtime/Java/src/org/antlr/v4/runtime/RuntimeMetaData.java
+```
+
+It's also worth doing a quick check to see if you find any other references to a version:
```bash
-find tool runtime -type f -exec grep -l '4\.6' {} \;
+mvn clean
+find . -type f -exec grep -l '4\.12.0' {} \; | grep -v -E '\.o|\.a|\.jar|\.dylib|node_modules/|\.class|tests/|CHANGELOG|\.zip|\.gz|.iml|.svg'
```
Commit to repository.
-## Building
+### PHP runtime
+
+We only have to copy the PHP runtime into the ANTLR repository to run the unittests. But, we still need to bump the version to 4.13.2 in `~/antlr/code/antlr-php-runtime/src/RuntimeMetaData.php` in the separate repository, commit, and push.
-ugh. apparently you have to `mvn install` and then `mvn compile` or some such or subdir pom.xml's won't see the latest runtime build.
+```
+cd ~/antlr/code/antlr-php-runtime/src
+git checkout dev # Should be the default
+git pull origin dev
+... vi RuntimeMetaData.php ...
+git commit -a -m "Update PHP Runtime to latest version"
+git push origin dev
+git checkout master
+git pull origin master
+git merge dev
+git push origin master
+```
+
+## Build XPath parsers
+
+This section addresses a [circular dependency regarding XPath](https://github.com/antlr/antlr4/issues/3600). In the java target I avoided a circular dependency (gen 4.13.2 parser for XPath using 4.13.2 which needs it to build) by hand building the parser: runtime/Java/src/org/antlr/v4/runtime/tree/xpath/XPath.java. Probably we won't have to rerun this for the patch releases, just major ones that alter the ATN serialization.
+
+```bash
+cd ~/antlr/code/antlr4/runtime/Cpp/runtime/src/tree/xpath
+java -cp ":/Users/parrt/.m2/repository/org/antlr/antlr4/4.13.2-SNAPSHOT/antlr4-4.13.2-SNAPSHOT-complete.jar:$CLASSPATH" org.antlr.v4.Tool -Dlanguage=Cpp XPathLexer.g4
+
+cd ~/antlr/code/antlr4/runtime/CSharp/src/Tree/Xpath
+java -cp ":/Users/parrt/.m2/repository/org/antlr/antlr4/4.13.2-SNAPSHOT/antlr4-4.13.2-SNAPSHOT-complete.jar:$CLASSPATH" org.antlr.v4.Tool -Dlanguage=CSharp XPathLexer.g4
+
+cd ~/antlr/code/antlr4/runtime/Python3/tests/expr
+java -cp ":/Users/parrt/.m2/repository/org/antlr/antlr4/4.13.2-SNAPSHOT/antlr4-4.13.2-SNAPSHOT-complete.jar:$CLASSPATH" org.antlr.v4.Tool -Dlanguage=Python3 Expr.g4
+cd ~/antlr/code/antlr4/runtime/Python3/src/antlr4/xpath
+java -cp ":/Users/parrt/.m2/repository/org/antlr/antlr4/4.13.2-SNAPSHOT/antlr4-4.13.2-SNAPSHOT-complete.jar:$CLASSPATH" org.antlr.v4.Tool -Dlanguage=Python3 XPathLexer.g4
+```
## Maven Repository Settings
@@ -134,23 +156,14 @@ Here is the file template
## Maven deploy snapshot
-The goal is to get a snapshot, such as `4.8-SNAPSHOT`, to the staging server: [antlr4 tool](https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4) and [antlr4 java runtime](https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-runtime).
+The goal is to get a snapshot, such as `4.13.2-SNAPSHOT`, to the staging server: [antlr4 tool](https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4/4.13.2-SNAPSHOT/) and [antlr4 java runtime](https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-runtime/4.13.2-SNAPSHOT/).
Do this:
```bash
+$ mvn install -DskipTests # seems required to get the jar files visible to maven
$ mvn deploy -DskipTests
...
-[INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ antlr4-tool-testsuite ---
-Downloading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.8-SNAPSHOT/maven-metadata.xml
-Uploading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.8-SNAPSHOT/antlr4-tool-testsuite-4.8-20161211.173752-1.jar
-Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.8-SNAPSHOT/antlr4-tool-testsuite-4.8-20161211.173752-1.jar (3 KB at 3.4 KB/sec)
-Uploading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.8-SNAPSHOT/antlr4-tool-testsuite-4.8-20161211.173752-1.pom
-Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.8-SNAPSHOT/antlr4-tool-testsuite-4.8-20161211.173752-1.pom (3 KB at 6.5 KB/sec)
-Downloading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/maven-metadata.xml
-Downloaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/maven-metadata.xml (371 B at 1.4 KB/sec)
-Uploading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.8-SNAPSHOT/maven-metadata.xml
-Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.8-SNAPSHOT/maven-metadata.xml (774 B at 1.8 KB/sec)
Uploading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/maven-metadata.xml
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/maven-metadata.xml (388 B at 0.9 KB/sec)
[INFO] ------------------------------------------------------------------------
@@ -162,7 +175,7 @@ Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antl
[INFO] ANTLR 4 Maven plugin ............................... SUCCESS [ 6.547 s]
[INFO] ANTLR 4 Runtime Test Annotations ................... SUCCESS [ 2.519 s]
[INFO] ANTLR 4 Runtime Test Processors .................... SUCCESS [ 2.385 s]
-[INFO] ANTLR 4 Runtime Tests (2nd generation) ............. SUCCESS [ 15.276 s]
+[INFO] ANTLR 4 Runtime Tests (4th generation) ............. SUCCESS [ 15.276 s]
[INFO] ANTLR 4 Tool Tests ................................. SUCCESS [ 2.233 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
@@ -178,60 +191,54 @@ Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antl
The maven deploy lifecycle phased deploys the artifacts and the poms for the ANTLR project to the [sonatype remote staging server](https://oss.sonatype.org/content/repositories/snapshots/).
```bash
-export JAVA_HOME=`/usr/libexec/java_home -v 1.7`; mvn deploy -DskipTests
+mvn deploy -DskipTests
```
-With JDK 1.7 (not 6 or 8), do this:
+Make sure `gpg` is installed (`brew install gpg` on mac). Also must [create a key and publish it](https://blog.sonatype.com/2010/01/how-to-generate-pgp-signatures-with-maven/) then update `.m2/settings` to use that public key.
+
+Then:
```bash
-export JAVA_HOME=`/usr/libexec/java_home -v 1.7`; mvn release:prepare -Darguments="-DskipTests"
+mvn release:prepare -Darguments="-DskipTests"
```
-Hm...per https://github.com/keybase/keybase-issues/issues/1712 we need this to make gpg work:
+Hmm...per https://github.com/keybase/keybase-issues/issues/1712 we need this to make gpg work:
```bash
export GPG_TTY=$(tty)
```
-Side note to set jdk 1.7 on os x:
+You should see 0x37 in generated .class files after 0xCAFEBABE; see [Java SE 11 = 55 (0x37 hex)](https://en.wikipedia.org/wiki/Java_class_file):
```bash
-alias java='/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin/java'
-alias javac='/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin/javac'
-alias javadoc='/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin/javadoc'
-alias jar='/Library/Java/JavaVirtualMachines/jdk1.7.0_21.jdk/Contents/Home/bin/jar'
-export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
-```
-
-But I think just this on front of mvn works:
-
-```
-export JAVA_HOME=`/usr/libexec/java_home -v 1.7`; mvn ...
+~/antlr/code/antlr4 $ od -h tool/target/classes/org/antlr/v4/Tool.class |head -1
+0000000 feca beba 0000 3700 ed04 0207 0a9d 0100
+ ^^
```
-You should see 0x33 in generated .class files after 0xCAFEBABE; see [Java SE 7 = 51 (0x33 hex)](https://en.wikipedia.org/wiki/Java_class_file):
+Also verify run time is 1.8:
```bash
-beast:/tmp/org/antlr/v4 $ od -h Tool.class |head -1
-0000000 feca beba 0000 3300 fa04 0207 0ab8 0100
+od -h runtime/Java/target/classes/org/antlr/v4/runtime/Token.class | head -1
+0000000 feca beba 0000 3400 2500 0007 0722 2300
```
It will start out by asking you the version number:
```
...
-What is the release version for "ANTLR 4"? (org.antlr:antlr4-master) 4.8: : 4.8
-What is the release version for "ANTLR 4 Runtime"? (org.antlr:antlr4-runtime) 4.8: :
-What is the release version for "ANTLR 4 Tool"? (org.antlr:antlr4) 4.8: :
-What is the release version for "ANTLR 4 Maven plugin"? (org.antlr:antlr4-maven-plugin) 4.8: :
-What is the release version for "ANTLR 4 Runtime Test Generator"? (org.antlr:antlr4-runtime-testsuite) 4.8: :
-What is the release version for "ANTLR 4 Tool Tests"? (org.antlr:antlr4-tool-testsuite) 4.8: :
-What is SCM release tag or label for "ANTLR 4"? (org.antlr:antlr4-master) antlr4-master-4.8: : 4.8
-What is the new development version for "ANTLR 4"? (org.antlr:antlr4-master) 4.8.1-SNAPSHOT:
+What is the release version for "ANTLR 4"? (org.antlr:antlr4-master) 4.13.2: : 4.13.2
+What is the release version for "ANTLR 4 Runtime"? (org.antlr:antlr4-runtime) 4.13.2: :
+What is the release version for "ANTLR 4 Tool"? (org.antlr:antlr4) 4.13.2: :
+What is the release version for "ANTLR 4 Maven plugin"? (org.antlr:antlr4-maven-plugin) 4.13.2: :
+What is the release version for "ANTLR 4 Runtime Test Generator"? (org.antlr:antlr4-runtime-testsuite) 4.13.2: :
+What is the release version for "ANTLR 4 Tool Tests"? (org.antlr:antlr4-tool-testsuite) 4.13.2: :
+What is SCM release tag or label for "ANTLR 4"? (org.antlr:antlr4-master) antlr4-master-4.13.2: : 4.13.2
+What is the new development version for "ANTLR 4"? (org.antlr:antlr4-master) 4.13.3-SNAPSHOT:
...
```
-Maven will go through your pom.xml files to update versions from 4.8-SNAPSHOT to 4.8 for release and then to 4.8.1-SNAPSHOT after release, which is done with:
+Maven will go through your pom.xml files to update versions from 4.13.2-SNAPSHOT to 4.13.2 for release and then to 4.13.2-SNAPSHOT after release, which is done with:
```bash
mvn release:perform -Darguments="-DskipTests"
@@ -245,97 +252,55 @@ Now, go here:
and on the left click "Staging Repositories". You click the staging repo and close it, then you refresh, click it and release it. It's done when you see it here:
- [https://oss.sonatype.org/service/local/repositories/releases/content/org/antlr/antlr4-runtime/4.8-1/antlr4-runtime-4.8-1.jar](https://oss.sonatype.org/service/local/repositories/releases/content/org/antlr/antlr4-runtime/4.8-1/antlr4-runtime-4.8-1.jar)
-
-All releases should be here: https://repo1.maven.org/maven2/org/antlr/antlr4-runtime/
-
-Copy the jars to antlr.org site and update download/index.html
-
-```bash
-cp ~/.m2/repository/org/antlr/antlr4-runtime/4.8/antlr4-runtime-4.8.jar ~/antlr/sites/website-antlr4/download/antlr-runtime-4.8.jar
-cp ~/.m2/repository/org/antlr/antlr4/4.8/antlr4-4.8-complete.jar ~/antlr/sites/website-antlr4/download/antlr-4.8-complete.jar
-cd ~/antlr/sites/website-antlr4/download
-git add antlr-4.8-complete.jar
-git add antlr-runtime-4.8.jar
-```
-
-Update on site:
+ [https://oss.sonatype.org/service/local/repositories/releases/content/org/antlr/antlr4-runtime/4.13.2/antlr4-runtime-4.13.2.jar](https://oss.sonatype.org/service/local/repositories/releases/content/org/antlr/antlr4-runtime/4.13.2/antlr4-runtime-4.13.2.jar)
-* download.html
-* index.html
-* api/index.html
-* download/index.html
-* scripts/topnav.js
-
-```
-git commit -a -m 'add 4.8 jars'
-git push origin gh-pages
-```
+All releases should be here: [https://repo1.maven.org/maven2/org/antlr/antlr4-runtime](https://repo1.maven.org/maven2/org/antlr/antlr4-runtime).
## Deploying Targets
### JavaScript
-```bash
-cd runtime/JavaScript
-# git add, commit, push
-```
-
**Push to npm**
+(I think this has to be run before the unit test can run locally as it installs the global lib)
+
```bash
-cd runtime/JavaScript
-npm login
-npm publish antlr4
+cd ~/antlr/code/antlr4/runtime/JavaScript
+rm -rf node_modules # seems we might need this later but try it here
+npm update
+npm install
+npm run build
+npm login # asks for username/password/2FA (npmjs.com)
+npm publish # don't put antlr4 on there or it will try to push the old version for some reason
```
-Move target to website
+Move (and zip) target to website:
```bash
-npm run build
-cp /dist/antlr4.js ~/antlr/sites/website-antlr4/download
+cd src
+zip -r ~/antlr/sites/website-antlr4/download/antlr-javascript-runtime-4.13.2.zip .
```
### CSharp
-Now we have [appveyor create artifact](https://ci.appveyor.com/project/parrt/antlr4/build/artifacts). Go to [nuget](https://www.nuget.org/packages/manage/upload) to upload the `.nupkg`.
-
-### Publishing to Nuget from Windows
+As of writing, you can only release from a Windows box, because Visual Studio for Mac can only build the netstandard2.0 version
**Install the pre-requisites**
-Of course you need Mono and `nuget` to be installed. On mac:
+You need 'msbuild' and `nuget` to be installed.
-- .NET build tools - can be loaded from [here](https://www.visualstudio.com/downloads/)
-- nuget - download [nuget.exe](https://www.nuget.org/downloads)
-- dotnet - follow [the instructions here](https://www.microsoft.com/net/core)
+**Creating the signed assembly**
-Alternatively, you can install Visual Studio 2017 and make sure to check boxes with .NET Core SDK.
+cd ~/antlr/code/antlr4/runtime/CSharp/src
+dotnet build -c Release Antlr4.csproj
-You also need to enable .NET Framework 3.5 support in Windows "Programs and Features".
+check that the bin/Release folder contains both the netstandard2.0 and the net45 builds
+the binaries are already signed, but it's worth double checking
-If everything is ok, the following command will restore nuget packages, build Antlr for .NET Standard and .NET 3.5 and create nuget package:
+sn -v bin/Release/netstandard2.0/Antlr4.Runtime.Standard.dll
+sn -v bin/Release/net45/Antlr4.Runtime.Standard.dll
-```PS
-msbuild /target:restore /target:rebuild /target:pack /property:Configuration=Release .\Antlr4.dotnet.sln /verbosity:minimal
-```
-
-This should display something like this:
-
-**Creating and packaging the assembly**
-
-```
-Microsoft (R) Build Engine version 15.4.8.50001 for .NET Framework
-Copyright (C) Microsoft Corporation. All rights reserved.
-
- Restoring packages for C:\Code\antlr4-fork\runtime\CSharp\runtime\CSharp\Antlr4.Runtime\Antlr4.Runtime.dotnet.csproj...
- Generating MSBuild file C:\Code\antlr4-fork\runtime\CSharp\runtime\CSharp\Antlr4.Runtime\obj\Antlr4.Runtime.dotnet.csproj.nuget.g.props.
- Generating MSBuild file C:\Code\antlr4-fork\runtime\CSharp\runtime\CSharp\Antlr4.Runtime\obj\Antlr4.Runtime.dotnet.csproj.nuget.g.targets.
- Restore completed in 427.62 ms for C:\Code\antlr4-fork\runtime\CSharp\runtime\CSharp\Antlr4.Runtime\Antlr4.Runtime.dotnet.csproj.
- Antlr4.Runtime.dotnet -> C:\Code\antlr4-fork\runtime\CSharp\runtime\CSharp\Antlr4.Runtime\lib\Release\netstandard1.3\Antlr4.Runtime.Standard.dll
- Antlr4.Runtime.dotnet -> C:\Code\antlr4-fork\runtime\CSharp\runtime\CSharp\Antlr4.Runtime\lib\Release\net35\Antlr4.Runtime.Standard.dll
- Successfully created package 'C:\Code\antlr4-fork\runtime\CSharp\runtime\CSharp\Antlr4.Runtime\lib\Release\Antlr4.Runtime.Standard.4.8.2.nupkg'.
-```
+both should say the dll is valid
**Publishing to NuGet**
@@ -345,14 +310,15 @@ As a registered NuGet user, you can then manually upload the package here: [http
Alternately, you can publish from the cmd line. You need to get your NuGet key from [https://www.nuget.org/account#](https://www.nuget.org/account#) and then from the cmd line, you can then type:
```cmd
+cd bin/Release
nuget push Antlr4.Runtime.Standard..nupkg -Source https://www.nuget.org/api/v2/package
```
-Nuget packages are also accessible as artifacts of [AppVeyor builds](https://ci.appveyor.com/project/parrt/antlr4/build/artifacts).
-
### Python
-The Python targets get deployed with `setup.py`. First, set up `~/.pypirc` with tight privileges:
+The Python target gets deployed with `twine` for Python 3.
+
+First, set up `~/.pypirc` with tight privileges:
```bash
beast:~ $ ls -l ~/.pypirc
@@ -374,20 +340,13 @@ username: parrt
password: xxx
```
-Then run the usual python set up stuff:
-
-```bash
-cd ~/antlr/code/antlr4/runtime/Python2
-# assume you have ~/.pypirc set up
-python2 setup.py sdist upload
-```
-
-and do again for Python 3 target
+Then run the python build and upload:
```bash
cd ~/antlr/code/antlr4/runtime/Python3
+python -m build
# assume you have ~/.pypirc set up
-python3 setup.py sdist upload
+twine upload dist/antlr4_python3_runtime-4.13.2.tar.gz dist/antlr4_python3_runtime-4.13.2-py3-none-any.whl
```
There are links to the artifacts in [download.html](http://www.antlr.org/download.html) already.
@@ -408,49 +367,112 @@ For each platform there's a deployment script which generates zip archives and c
On a Mac (with XCode 7+ installed):
```bash
-cd runtime/Cpp
+cd ~/antlr/code/antlr4/runtime/Cpp
+rm CMakeCache.txt # otherwise can't find some include files
./deploy-macos.sh
-cp antlr4-cpp-runtime-macos.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.8-macos.zip
+cp antlr4-cpp-runtime-macos.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.13.2-macos.zip
```
On any Mac or Linux machine:
```bash
-cd runtime/Cpp
+cd ~/antlr/code/antlr4/runtime/Cpp
./deploy-source.sh
-cp antlr4-cpp-runtime-source.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.8-source.zip
+cp antlr4-cpp-runtime-source.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.13.2-source.zip
```
On a Windows machine the build scripts checks if VS 2017 and/or VS 2019 are installed and builds binaries for each, if found. This script requires 7z to be installed (http://7-zip.org then do `set PATH=%PATH%;C:\Program Files\7-Zip\` from DOS not powershell).
```bash
-cd runtime/Cpp
+cd ~/antlr/code/antlr4/runtime/Cpp
deploy-windows.cmd Community
-cp antlr4-cpp-runtime-vs2019.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.8-vs2019.zip
+cp antlr4-cpp-runtime-vs2019.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.13.2-vs2019.zip
```
Move target to website (**_rename to a specific ANTLR version first if needed_**):
```bash
pushd ~/antlr/sites/website-antlr4/download
-# vi index.html
-git add antlr4cpp-runtime-4.8-macos.zip
-git add antlr4cpp-runtime-4.8-windows.zip
-git add antlr4cpp-runtime-4.8-source.zip
+git add antlr4-cpp-runtime-4.13.2-macos.zip
+git add antlr4-cpp-runtime-4.13.2-windows.zip
+git add antlr4-cpp-runtime-4.13.2-source.zip
git commit -a -m 'update C++ runtime'
git push origin gh-pages
popd
```
-## Update javadoc for runtime and tool
+### Dart
+
+Install Dart SDK from https://dart.dev/get-dart
-First, gen javadoc:
+Push to pub.dev
```bash
-$ cd antlr4
-$ mvn -DskipTests javadoc:jar install
+cd ~/antlr/code/antlr4/runtime/Dart
+dart pub publish
+```
+
+It will warn that no change log found for the new version.
+Otherwise enter `N` to ignore the warning.
+
+## Update website
+
+### javadoc for runtime and tool
+
+Jars are in:
+
+```
+~/.m2/repository/org/antlr/antlr4-runtime/4.13.2/antlr4-runtime-4.13.2
```
+### Update version and copy jars / api
+
+Copy javadoc and java jars to website using this script:
+
+```bash
+cd ~/antlr/code/antlr4
+python scripts/deploy_to_website.py 4.13.1 4.13.2
+```
+
+Output:
+
+```bash
+Updating ANTLR version from 4.13.1 to 4.13.2
+Set ANTLR website root (default /Users/parrt/antlr/sites/website-antlr4):
+Version string updated. Please commit/push:
+Javadoc copied:
+ api/Java updated from antlr4-runtime-4.13.2-javadoc.jar
+ api/JavaTool updated from antlr4-4.13.2-javadoc.jar
+Jars copied:
+ antlr-4.13.2-complete.jar
+ antlr-runtime-4.13.2.jar
+
+Please look for and add new api files!!
+Then MANUALLY commit/push:
+
+git commit -a -m 'Update website, javadoc, jars to 4.13.2'
+git push origin gh-pages
+```
+
+
+
+Once it's done, you must do the following manually:
+
+```
+cd ~/antlr/sites/website-antlr4
+git commit -a -m 'Update website, javadoc, jars to 4.13.2'
+git push origin gh-pages
+```
+
+
+
+## Get fresh dev branch
+
+```bash
+git checkout master
+git pull upstream master
+git checkout dev
+git pull upstream dev
+git merge master
+git push origin dev
+git push upstream dev
+```
-## Update Intellij plug-in
+## Other updates
-Rebuild antlr plugin with new antlr jar.
+* Rebuild antlr Intellij plug-in with new antlr jar.
+* Cut release notes in github
+* Update lab.antlr.org
diff --git a/doc/resources/CaseChangingCharStream.cs b/doc/resources/CaseChangingCharStream.cs
deleted file mode 100644
index 9f73a03826..0000000000
--- a/doc/resources/CaseChangingCharStream.cs
+++ /dev/null
@@ -1,105 +0,0 @@
-/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
- * Use of this file is governed by the BSD 3-clause license that
- * can be found in the LICENSE.txt file in the project root.
- */
-using System;
-using Antlr4.Runtime.Misc;
-
-namespace Antlr4.Runtime
-{
- ///
- /// This class supports case-insensitive lexing by wrapping an existing
- /// and forcing the lexer to see either upper or
- /// lowercase characters. Grammar literals should then be either upper or
- /// lower case such as 'BEGIN' or 'begin'. The text of the character
- /// stream is unaffected. Example: input 'BeGiN' would match lexer rule
- /// 'BEGIN' if constructor parameter upper=true but getText() would return
- /// 'BeGiN'.
- ///
- public class CaseChangingCharStream : ICharStream
- {
- private ICharStream stream;
- private bool upper;
-
- ///
- /// Constructs a new CaseChangingCharStream wrapping the given forcing
- /// all characters to upper case or lower case.
- ///
- /// The stream to wrap.
- /// If true force each symbol to upper case, otherwise force to lower.
- public CaseChangingCharStream(ICharStream stream, bool upper)
- {
- this.stream = stream;
- this.upper = upper;
- }
-
- public int Index
- {
- get
- {
- return stream.Index;
- }
- }
-
- public int Size
- {
- get
- {
- return stream.Size;
- }
- }
-
- public string SourceName
- {
- get
- {
- return stream.SourceName;
- }
- }
-
- public void Consume()
- {
- stream.Consume();
- }
-
- [return: NotNull]
- public string GetText(Interval interval)
- {
- return stream.GetText(interval);
- }
-
- public int LA(int i)
- {
- int c = stream.LA(i);
-
- if (c <= 0)
- {
- return c;
- }
-
- char o = (char)c;
-
- if (upper)
- {
- return (int)char.ToUpperInvariant(o);
- }
-
- return (int)char.ToLowerInvariant(o);
- }
-
- public int Mark()
- {
- return stream.Mark();
- }
-
- public void Release(int marker)
- {
- stream.Release(marker);
- }
-
- public void Seek(int index)
- {
- stream.Seek(index);
- }
- }
-}
diff --git a/doc/resources/CaseChangingCharStream.java b/doc/resources/CaseChangingCharStream.java
deleted file mode 100644
index d069d0188a..0000000000
--- a/doc/resources/CaseChangingCharStream.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package org.antlr.v4.runtime;
-
-import org.antlr.v4.runtime.misc.Interval;
-
-/**
- * This class supports case-insensitive lexing by wrapping an existing
- * {@link CharStream} and forcing the lexer to see either upper or
- * lowercase characters. Grammar literals should then be either upper or
- * lower case such as 'BEGIN' or 'begin'. The text of the character
- * stream is unaffected. Example: input 'BeGiN' would match lexer rule
- * 'BEGIN' if constructor parameter upper=true but getText() would return
- * 'BeGiN'.
- */
-public class CaseChangingCharStream implements CharStream {
-
- final CharStream stream;
- final boolean upper;
-
- /**
- * Constructs a new CaseChangingCharStream wrapping the given {@link CharStream} forcing
- * all characters to upper case or lower case.
- * @param stream The stream to wrap.
- * @param upper If true force each symbol to upper case, otherwise force to lower.
- */
- public CaseChangingCharStream(CharStream stream, boolean upper) {
- this.stream = stream;
- this.upper = upper;
- }
-
- @Override
- public String getText(Interval interval) {
- return stream.getText(interval);
- }
-
- @Override
- public void consume() {
- stream.consume();
- }
-
- @Override
- public int LA(int i) {
- int c = stream.LA(i);
- if (c <= 0) {
- return c;
- }
- if (upper) {
- return Character.toUpperCase(c);
- }
- return Character.toLowerCase(c);
- }
-
- @Override
- public int mark() {
- return stream.mark();
- }
-
- @Override
- public void release(int marker) {
- stream.release(marker);
- }
-
- @Override
- public int index() {
- return stream.index();
- }
-
- @Override
- public void seek(int index) {
- stream.seek(index);
- }
-
- @Override
- public int size() {
- return stream.size();
- }
-
- @Override
- public String getSourceName() {
- return stream.getSourceName();
- }
-}
diff --git a/doc/resources/CaseChangingStream.js b/doc/resources/CaseChangingStream.js
deleted file mode 100644
index 3af1ad6127..0000000000
--- a/doc/resources/CaseChangingStream.js
+++ /dev/null
@@ -1,65 +0,0 @@
-//
-/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
- * Use of this file is governed by the BSD 3-clause license that
- * can be found in the LICENSE.txt file in the project root.
- */
-//
-
-function CaseChangingStream(stream, upper) {
- this._stream = stream;
- this._upper = upper;
-}
-
-CaseChangingStream.prototype.LA = function(offset) {
- var c = this._stream.LA(offset);
- if (c <= 0) {
- return c;
- }
- return String.fromCodePoint(c)[this._upper ? "toUpperCase" : "toLowerCase"]().codePointAt(0);
-};
-
-CaseChangingStream.prototype.reset = function() {
- return this._stream.reset();
-};
-
-CaseChangingStream.prototype.consume = function() {
- return this._stream.consume();
-};
-
-CaseChangingStream.prototype.LT = function(offset) {
- return this._stream.LT(offset);
-};
-
-CaseChangingStream.prototype.mark = function() {
- return this._stream.mark();
-};
-
-CaseChangingStream.prototype.release = function(marker) {
- return this._stream.release(marker);
-};
-
-CaseChangingStream.prototype.seek = function(_index) {
- return this._stream.seek(_index);
-};
-
-CaseChangingStream.prototype.getText = function(start, stop) {
- return this._stream.getText(start, stop);
-};
-
-CaseChangingStream.prototype.toString = function() {
- return this._stream.toString();
-};
-
-Object.defineProperty(CaseChangingStream.prototype, "index", {
- get: function() {
- return this._stream.index;
- }
-});
-
-Object.defineProperty(CaseChangingStream.prototype, "size", {
- get: function() {
- return this._stream.size;
- }
-});
-
-exports.CaseChangingStream = CaseChangingStream;
diff --git a/doc/resources/CaseChangingStream.py b/doc/resources/CaseChangingStream.py
deleted file mode 100644
index 6d2815de41..0000000000
--- a/doc/resources/CaseChangingStream.py
+++ /dev/null
@@ -1,13 +0,0 @@
-class CaseChangingStream():
- def __init__(self, stream, upper):
- self._stream = stream
- self._upper = upper
-
- def __getattr__(self, name):
- return self._stream.__getattribute__(name)
-
- def LA(self, offset):
- c = self._stream.LA(offset)
- if c <= 0:
- return c
- return ord(chr(c).upper() if self._upper else chr(c).lower())
diff --git a/doc/resources/case_changing_stream.go b/doc/resources/case_changing_stream.go
deleted file mode 100644
index 5b510fa321..0000000000
--- a/doc/resources/case_changing_stream.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package antlr_resource
-
-import (
- "unicode"
-
- "github.com/antlr/antlr4/runtime/Go/antlr"
-)
-
-// CaseChangingStream wraps an existing CharStream, but upper cases, or
-// lower cases the input before it is tokenized.
-type CaseChangingStream struct {
- antlr.CharStream
-
- upper bool
-}
-
-// NewCaseChangingStream returns a new CaseChangingStream that forces
-// all tokens read from the underlying stream to be either upper case
-// or lower case based on the upper argument.
-func NewCaseChangingStream(in antlr.CharStream, upper bool) *CaseChangingStream {
- return &CaseChangingStream{in, upper}
-}
-
-// LA gets the value of the symbol at offset from the current position
-// from the underlying CharStream and converts it to either upper case
-// or lower case.
-func (is *CaseChangingStream) LA(offset int) int {
- in := is.CharStream.LA(offset)
- if in < 0 {
- // Such as antlr.TokenEOF which is -1
- return in
- }
- if is.upper {
- return int(unicode.ToUpper(rune(in)))
- }
- return int(unicode.ToLower(rune(in)))
-}
diff --git a/doc/resources/worker-base.js b/doc/resources/worker-base.js
deleted file mode 100644
index 3494b39169..0000000000
--- a/doc/resources/worker-base.js
+++ /dev/null
@@ -1,1079 +0,0 @@
-"no use strict";
-(function(e) {
- if (typeof e.window != "undefined" && e.document) return;
- e.console = function() {
- var e = Array.prototype.slice.call(arguments, 0);
- postMessage({
- type: "log",
- data: e
- })
- }, e.console.error = e.console.warn = e.console.log = e.console.trace = e.console, e.window = e, e.ace = e, e.onerror = function(e, t, n, r, i) {
- postMessage({
- type: "error",
- data: {
- message: e,
- file: t,
- line: n,
- col: r,
- stack: i.stack
- }
- })
- }, e.normalizeModule = function(t, n) {
- if (n.indexOf("!") !== -1) {
- var r = n.split("!");
- return e.normalizeModule(t, r[0]) + "!" + e.normalizeModule(t, r[1])
- }
- if (n.charAt(0) == ".") {
- var i = t.split("/")
- .slice(0, -1)
- .join("/");
- n = (i ? i + "/" : "") + n;
- while (n.indexOf(".") !== -1 && s != n) {
- var s = n;
- n = n.replace(/^\.\//, "")
- .replace(/\/\.\//, "/")
- .replace(/[^\/]+\/\.\.\//, "")
- }
- }
- return n
- }, e.require = function(t, n) {
- n || (n = t, t = null);
- if (!n.charAt) throw new Error("worker.js require() accepts only (parentId, id) as arguments");
- n = e.normalizeModule(t, n);
- var r = e.require.modules[n];
- if (r) return r.initialized || (r.initialized = !0, r.exports = r.factory()
- .exports), r.exports;
- var i = n.split("/");
- if (!e.require.tlns) return console.log("unable to load " + n);
- i[0] = e.require.tlns[i[0]] || i[0];
- var s = i.join("/") + ".js";
- return e.require.id = n, importScripts(s), e.require(t, n)
- }, e.require.modules = {}, e.require.tlns = {}, e.define = function(t, n, r) {
- arguments.length == 2 ? (r = n, typeof t != "string" && (n = t, t = e.require.id)) : arguments.length == 1 && (r = t, n = [], t = e.require.id);
- if (typeof r != "function") {
- e.require.modules[t] = {
- exports: r,
- initialized: !0
- };
- return
- }
- n.length || (n = ["require", "exports", "module"]);
- var i = function(n) {
- return e.require(t, n)
- };
- e.require.modules[t] = {
- exports: {},
- factory: function() {
- var e = this,
- t = r.apply(this, n.map(function(t) {
- switch (t) {
- case "require":
- return i;
- case "exports":
- return e.exports;
- case "module":
- return e;
- default:
- return i(t)
- }
- }));
- return t && (e.exports = t), e
- }
- }
- }, e.define.amd = {}, e.initBaseUrls = function(t) {
- require.tlns = t
- }, e.initSender = function() {
- var n = e.require("ace/lib/event_emitter")
- .EventEmitter,
- r = e.require("ace/lib/oop"),
- i = function() {};
- return function() {
- r.implement(this, n), this.callback = function(e, t) {
- postMessage({
- type: "call",
- id: t,
- data: e
- })
- }, this.emit = function(e, t) {
- postMessage({
- type: "event",
- name: e,
- data: t
- })
- }
- }.call(i.prototype), new i
- };
- var t = e.main = null,
- n = e.sender = null;
- e.onmessage = function(r) {
- var i = r.data;
- if (i.command) {
- if (!t[i.command]) throw new Error("Unknown command:" + i.command);
- t[i.command].apply(t, i.args)
- } else if (i.init) {
- initBaseUrls(i.tlns), require("ace/lib/es5-shim"), n = e.sender = initSender();
- var s = require(i.module)[i.classname];
- t = e.main = new s(n)
- } else i.event && n && n._signal(i.event, i.data)
- }
-})(this), ace.define("ace/lib/oop", ["require", "exports", "module"], function(e, t, n) {
- "use strict";
- t.inherits = function(e, t) {
- e.super_ = t, e.prototype = Object.create(t.prototype, {
- constructor: {
- value: e,
- enumerable: !1,
- writable: !0,
- configurable: !0
- }
- })
- }, t.mixin = function(e, t) {
- for (var n in t) e[n] = t[n];
- return e
- }, t.implement = function(e, n) {
- t.mixin(e, n)
- }
-}), ace.define("ace/lib/event_emitter", ["require", "exports", "module"], function(e, t, n) {
- "use strict";
- var r = {},
- i = function() {
- this.propagationStopped = !0
- },
- s = function() {
- this.defaultPrevented = !0
- };
- r._emit = r._dispatchEvent = function(e, t) {
- this._eventRegistry || (this._eventRegistry = {}), this._defaultHandlers || (this._defaultHandlers = {});
- var n = this._eventRegistry[e] || [],
- r = this._defaultHandlers[e];
- if (!n.length && !r) return;
- if (typeof t != "object" || !t) t = {};
- t.type || (t.type = e), t.stopPropagation || (t.stopPropagation = i), t.preventDefault || (t.preventDefault = s), n = n.slice();
- for (var o = 0; o < n.length; o++) {
- n[o](t, this);
- if (t.propagationStopped) break
- }
- if (r && !t.defaultPrevented) return r(t, this)
- }, r._signal = function(e, t) {
- var n = (this._eventRegistry || {})[e];
- if (!n) return;
- n = n.slice();
- for (var r = 0; r < n.length; r++) n[r](t, this)
- }, r.once = function(e, t) {
- var n = this;
- t && this.addEventListener(e, function r() {
- n.removeEventListener(e, r), t.apply(null, arguments)
- })
- }, r.setDefaultHandler = function(e, t) {
- var n = this._defaultHandlers;
- n || (n = this._defaultHandlers = {
- _disabled_: {}
- });
- if (n[e]) {
- var r = n[e],
- i = n._disabled_[e];
- i || (n._disabled_[e] = i = []), i.push(r);
- var s = i.indexOf(t);
- s != -1 && i.splice(s, 1)
- }
- n[e] = t
- }, r.removeDefaultHandler = function(e, t) {
- var n = this._defaultHandlers;
- if (!n) return;
- var r = n._disabled_[e];
- if (n[e] == t) {
- var i = n[e];
- r && this.setDefaultHandler(e, r.pop())
- } else if (r) {
- var s = r.indexOf(t);
- s != -1 && r.splice(s, 1)
- }
- }, r.on = r.addEventListener = function(e, t, n) {
- this._eventRegistry = this._eventRegistry || {};
- var r = this._eventRegistry[e];
- return r || (r = this._eventRegistry[e] = []), r.indexOf(t) == -1 && r[n ? "unshift" : "push"](t), t
- }, r.off = r.removeListener = r.removeEventListener = function(e, t) {
- this._eventRegistry = this._eventRegistry || {};
- var n = this._eventRegistry[e];
- if (!n) return;
- var r = n.indexOf(t);
- r !== -1 && n.splice(r, 1)
- }, r.removeAllListeners = function(e) {
- this._eventRegistry && (this._eventRegistry[e] = [])
- }, t.EventEmitter = r
-}), ace.define("ace/range", ["require", "exports", "module"], function(e, t, n) {
- "use strict";
- var r = function(e, t) {
- return e.row - t.row || e.column - t.column
- },
- i = function(e, t, n, r) {
- this.start = {
- row: e,
- column: t
- }, this.end = {
- row: n,
- column: r
- }
- };
- (function() {
- this.isEqual = function(e) {
- return this.start.row === e.start.row && this.end.row === e.end.row && this.start.column === e.start.column && this.end.column === e.end.column
- }, this.toString = function() {
- return "Range: [" + this.start.row + "/" + this.start.column + "] -> [" + this.end.row + "/" + this.end.column + "]"
- }, this.contains = function(e, t) {
- return this.compare(e, t) == 0
- }, this.compareRange = function(e) {
- var t, n = e.end,
- r = e.start;
- return t = this.compare(n.row, n.column), t == 1 ? (t = this.compare(r.row, r.column), t == 1 ? 2 : t == 0 ? 1 : 0) : t == -1 ? -2 : (t = this.compare(r.row, r.column), t == -1 ? -1 : t == 1 ? 42 : 0)
- }, this.comparePoint = function(e) {
- return this.compare(e.row, e.column)
- }, this.containsRange = function(e) {
- return this.comparePoint(e.start) == 0 && this.comparePoint(e.end) == 0
- }, this.intersects = function(e) {
- var t = this.compareRange(e);
- return t == -1 || t == 0 || t == 1
- }, this.isEnd = function(e, t) {
- return this.end.row == e && this.end.column == t
- }, this.isStart = function(e, t) {
- return this.start.row == e && this.start.column == t
- }, this.setStart = function(e, t) {
- typeof e == "object" ? (this.start.column = e.column, this.start.row = e.row) : (this.start.row = e, this.start.column = t)
- }, this.setEnd = function(e, t) {
- typeof e == "object" ? (this.end.column = e.column, this.end.row = e.row) : (this.end.row = e, this.end.column = t)
- }, this.inside = function(e, t) {
- return this.compare(e, t) == 0 ? this.isEnd(e, t) || this.isStart(e, t) ? !1 : !0 : !1
- }, this.insideStart = function(e, t) {
- return this.compare(e, t) == 0 ? this.isEnd(e, t) ? !1 : !0 : !1
- }, this.insideEnd = function(e, t) {
- return this.compare(e, t) == 0 ? this.isStart(e, t) ? !1 : !0 : !1
- }, this.compare = function(e, t) {
- return !this.isMultiLine() && e === this.start.row ? t < this.start.column ? -1 : t > this.end.column ? 1 : 0 : e < this.start.row ? -1 : e > this.end.row ? 1 : this.start.row === e ? t >= this.start.column ? 0 : -1 : this.end.row === e ? t <= this.end.column ? 0 : 1 : 0
- }, this.compareStart = function(e, t) {
- return this.start.row == e && this.start.column == t ? -1 : this.compare(e, t)
- }, this.compareEnd = function(e, t) {
- return this.end.row == e && this.end.column == t ? 1 : this.compare(e, t)
- }, this.compareInside = function(e, t) {
- return this.end.row == e && this.end.column == t ? 1 : this.start.row == e && this.start.column == t ? -1 : this.compare(e, t)
- }, this.clipRows = function(e, t) {
- if (this.end.row > t) var n = {
- row: t + 1,
- column: 0
- };
- else if (this.end.row < e) var n = {
- row: e,
- column: 0
- };
- if (this.start.row > t) var r = {
- row: t + 1,
- column: 0
- };
- else if (this.start.row < e) var r = {
- row: e,
- column: 0
- };
- return i.fromPoints(r || this.start, n || this.end)
- }, this.extend = function(e, t) {
- var n = this.compare(e, t);
- if (n == 0) return this;
- if (n == -1) var r = {
- row: e,
- column: t
- };
- else var s = {
- row: e,
- column: t
- };
- return i.fromPoints(r || this.start, s || this.end)
- }, this.isEmpty = function() {
- return this.start.row === this.end.row && this.start.column === this.end.column
- }, this.isMultiLine = function() {
- return this.start.row !== this.end.row
- }, this.clone = function() {
- return i.fromPoints(this.start, this.end)
- }, this.collapseRows = function() {
- return this.end.column == 0 ? new i(this.start.row, 0, Math.max(this.start.row, this.end.row - 1), 0) : new i(this.start.row, 0, this.end.row, 0)
- }, this.toScreenRange = function(e) {
- var t = e.documentToScreenPosition(this.start),
- n = e.documentToScreenPosition(this.end);
- return new i(t.row, t.column, n.row, n.column)
- }, this.moveBy = function(e, t) {
- this.start.row += e, this.start.column += t, this.end.row += e, this.end.column += t
- }
- })
- .call(i.prototype), i.fromPoints = function(e, t) {
- return new i(e.row, e.column, t.row, t.column)
- }, i.comparePoints = r, i.comparePoints = function(e, t) {
- return e.row - t.row || e.column - t.column
- }, t.Range = i
-}), ace.define("ace/anchor", ["require", "exports", "module", "ace/lib/oop", "ace/lib/event_emitter"], function(e, t, n) {
- "use strict";
- var r = e("./lib/oop"),
- i = e("./lib/event_emitter")
- .EventEmitter,
- s = t.Anchor = function(e, t, n) {
- this.$onChange = this.onChange.bind(this), this.attach(e), typeof n == "undefined" ? this.setPosition(t.row, t.column) : this.setPosition(t, n)
- };
- (function() {
- r.implement(this, i), this.getPosition = function() {
- return this.$clipPositionToDocument(this.row, this.column)
- }, this.getDocument = function() {
- return this.document
- }, this.$insertRight = !1, this.onChange = function(e) {
- var t = e.data,
- n = t.range;
- if (n.start.row == n.end.row && n.start.row != this.row) return;
- if (n.start.row > this.row) return;
- if (n.start.row == this.row && n.start.column > this.column) return;
- var r = this.row,
- i = this.column,
- s = n.start,
- o = n.end;
- if (t.action === "insertText")
- if (s.row === r && s.column <= i) {
- if (s.column !== i || !this.$insertRight) s.row === o.row ? i += o.column - s.column : (i -= s.column, r += o.row - s.row)
- } else s.row !== o.row && s.row < r && (r += o.row - s.row);
- else t.action === "insertLines" ? (s.row !== r || i !== 0 || !this.$insertRight) && s.row <= r && (r += o.row - s.row) : t.action === "removeText" ? s.row === r && s.column < i ? o.column >= i ? i = s.column : i = Math.max(0, i - (o.column - s.column)) : s.row !== o.row && s.row < r ? (o.row === r && (i = Math.max(0, i - o.column) + s.column), r -= o.row - s.row) : o.row === r && (r -= o.row - s.row, i = Math.max(0, i - o.column) + s.column) : t.action == "removeLines" && s.row <= r && (o.row <= r ? r -= o.row - s.row : (r = s.row, i = 0));
- this.setPosition(r, i, !0)
- }, this.setPosition = function(e, t, n) {
- var r;
- n ? r = {
- row: e,
- column: t
- } : r = this.$clipPositionToDocument(e, t);
- if (this.row == r.row && this.column == r.column) return;
- var i = {
- row: this.row,
- column: this.column
- };
- this.row = r.row, this.column = r.column, this._signal("change", {
- old: i,
- value: r
- })
- }, this.detach = function() {
- this.document.removeEventListener("change", this.$onChange)
- }, this.attach = function(e) {
- this.document = e || this.document, this.document.on("change", this.$onChange)
- }, this.$clipPositionToDocument = function(e, t) {
- var n = {};
- return e >= this.document.getLength() ? (n.row = Math.max(0, this.document.getLength() - 1), n.column = this.document.getLine(n.row)
- .length) : e < 0 ? (n.row = 0, n.column = 0) : (n.row = e, n.column = Math.min(this.document.getLine(n.row)
- .length, Math.max(0, t))), t < 0 && (n.column = 0), n
- }
- })
- .call(s.prototype)
-}), ace.define("ace/document", ["require", "exports", "module", "ace/lib/oop", "ace/lib/event_emitter", "ace/range", "ace/anchor"], function(e, t, n) {
- "use strict";
- var r = e("./lib/oop"),
- i = e("./lib/event_emitter")
- .EventEmitter,
- s = e("./range")
- .Range,
- o = e("./anchor")
- .Anchor,
- u = function(e) {
- this.$lines = [], e.length === 0 ? this.$lines = [""] : Array.isArray(e) ? this._insertLines(0, e) : this.insert({
- row: 0,
- column: 0
- }, e)
- };
- (function() {
- r.implement(this, i), this.setValue = function(e) {
- var t = this.getLength();
- this.remove(new s(0, 0, t, this.getLine(t - 1)
- .length)), this.insert({
- row: 0,
- column: 0
- }, e)
- }, this.getValue = function() {
- return this.getAllLines()
- .join(this.getNewLineCharacter())
- }, this.createAnchor = function(e, t) {
- return new o(this, e, t)
- }, "aaa".split(/a/)
- .length === 0 ? this.$split = function(e) {
- return e.replace(/\r\n|\r/g, "\n")
- .split("\n")
- } : this.$split = function(e) {
- return e.split(/\r\n|\r|\n/)
- }, this.$detectNewLine = function(e) {
- var t = e.match(/^.*?(\r\n|\r|\n)/m);
- this.$autoNewLine = t ? t[1] : "\n", this._signal("changeNewLineMode")
- }, this.getNewLineCharacter = function() {
- switch (this.$newLineMode) {
- case "windows":
- return "\r\n";
- case "unix":
- return "\n";
- default:
- return this.$autoNewLine || "\n"
- }
- }, this.$autoNewLine = "", this.$newLineMode = "auto", this.setNewLineMode = function(e) {
- if (this.$newLineMode === e) return;
- this.$newLineMode = e, this._signal("changeNewLineMode")
- }, this.getNewLineMode = function() {
- return this.$newLineMode
- }, this.isNewLine = function(e) {
- return e == "\r\n" || e == "\r" || e == "\n"
- }, this.getLine = function(e) {
- return this.$lines[e] || ""
- }, this.getLines = function(e, t) {
- return this.$lines.slice(e, t + 1)
- }, this.getAllLines = function() {
- return this.getLines(0, this.getLength())
- }, this.getLength = function() {
- return this.$lines.length
- }, this.getTextRange = function(e) {
- if (e.start.row == e.end.row) return this.getLine(e.start.row)
- .substring(e.start.column, e.end.column);
- var t = this.getLines(e.start.row, e.end.row);
- t[0] = (t[0] || "")
- .substring(e.start.column);
- var n = t.length - 1;
- return e.end.row - e.start.row == n && (t[n] = t[n].substring(0, e.end.column)), t.join(this.getNewLineCharacter())
- }, this.$clipPosition = function(e) {
- var t = this.getLength();
- return e.row >= t ? (e.row = Math.max(0, t - 1), e.column = this.getLine(t - 1)
- .length) : e.row < 0 && (e.row = 0), e
- }, this.insert = function(e, t) {
- if (!t || t.length === 0) return e;
- e = this.$clipPosition(e), this.getLength() <= 1 && this.$detectNewLine(t);
- var n = this.$split(t),
- r = n.splice(0, 1)[0],
- i = n.length == 0 ? null : n.splice(n.length - 1, 1)[0];
- return e = this.insertInLine(e, r), i !== null && (e = this.insertNewLine(e), e = this._insertLines(e.row, n), e = this.insertInLine(e, i || "")), e
- }, this.insertLines = function(e, t) {
- return e >= this.getLength() ? this.insert({
- row: e,
- column: 0
- }, "\n" + t.join("\n")) : this._insertLines(Math.max(e, 0), t)
- }, this._insertLines = function(e, t) {
- if (t.length == 0) return {
- row: e,
- column: 0
- };
- while (t.length > 2e4) {
- var n = this._insertLines(e, t.slice(0, 2e4));
- t = t.slice(2e4), e = n.row
- }
- var r = [e, 0];
- r.push.apply(r, t), this.$lines.splice.apply(this.$lines, r);
- var i = new s(e, 0, e + t.length, 0),
- o = {
- action: "insertLines",
- range: i,
- lines: t
- };
- return this._signal("change", {
- data: o
- }), i.end
- }, this.insertNewLine = function(e) {
- e = this.$clipPosition(e);
- var t = this.$lines[e.row] || "";
- this.$lines[e.row] = t.substring(0, e.column), this.$lines.splice(e.row + 1, 0, t.substring(e.column, t.length));
- var n = {
- row: e.row + 1,
- column: 0
- },
- r = {
- action: "insertText",
- range: s.fromPoints(e, n),
- text: this.getNewLineCharacter()
- };
- return this._signal("change", {
- data: r
- }), n
- }, this.insertInLine = function(e, t) {
- if (t.length == 0) return e;
- var n = this.$lines[e.row] || "";
- this.$lines[e.row] = n.substring(0, e.column) + t + n.substring(e.column);
- var r = {
- row: e.row,
- column: e.column + t.length
- },
- i = {
- action: "insertText",
- range: s.fromPoints(e, r),
- text: t
- };
- return this._signal("change", {
- data: i
- }), r
- }, this.remove = function(e) {
- e instanceof s || (e = s.fromPoints(e.start, e.end)), e.start = this.$clipPosition(e.start), e.end = this.$clipPosition(e.end);
- if (e.isEmpty()) return e.start;
- var t = e.start.row,
- n = e.end.row;
- if (e.isMultiLine()) {
- var r = e.start.column == 0 ? t : t + 1,
- i = n - 1;
- e.end.column > 0 && this.removeInLine(n, 0, e.end.column), i >= r && this._removeLines(r, i), r != t && (this.removeInLine(t, e.start.column, this.getLine(t)
- .length), this.removeNewLine(e.start.row))
- } else this.removeInLine(t, e.start.column, e.end.column);
- return e.start
- }, this.removeInLine = function(e, t, n) {
- if (t == n) return;
- var r = new s(e, t, e, n),
- i = this.getLine(e),
- o = i.substring(t, n),
- u = i.substring(0, t) + i.substring(n, i.length);
- this.$lines.splice(e, 1, u);
- var a = {
- action: "removeText",
- range: r,
- text: o
- };
- return this._signal("change", {
- data: a
- }), r.start
- }, this.removeLines = function(e, t) {
- return e < 0 || t >= this.getLength() ? this.remove(new s(e, 0, t + 1, 0)) : this._removeLines(e, t)
- }, this._removeLines = function(e, t) {
- var n = new s(e, 0, t + 1, 0),
- r = this.$lines.splice(e, t - e + 1),
- i = {
- action: "removeLines",
- range: n,
- nl: this.getNewLineCharacter(),
- lines: r
- };
- return this._signal("change", {
- data: i
- }), r
- }, this.removeNewLine = function(e) {
- var t = this.getLine(e),
- n = this.getLine(e + 1),
- r = new s(e, t.length, e + 1, 0),
- i = t + n;
- this.$lines.splice(e, 2, i);
- var o = {
- action: "removeText",
- range: r,
- text: this.getNewLineCharacter()
- };
- this._signal("change", {
- data: o
- })
- }, this.replace = function(e, t) {
- e instanceof s || (e = s.fromPoints(e.start, e.end));
- if (t.length == 0 && e.isEmpty()) return e.start;
- if (t == this.getTextRange(e)) return e.end;
- this.remove(e);
- if (t) var n = this.insert(e.start, t);
- else n = e.start;
- return n
- }, this.applyDeltas = function(e) {
- for (var t = 0; t < e.length; t++) {
- var n = e[t],
- r = s.fromPoints(n.range.start, n.range.end);
- n.action == "insertLines" ? this.insertLines(r.start.row, n.lines) : n.action == "insertText" ? this.insert(r.start, n.text) : n.action == "removeLines" ? this._removeLines(r.start.row, r.end.row - 1) : n.action == "removeText" && this.remove(r)
- }
- }, this.revertDeltas = function(e) {
- for (var t = e.length - 1; t >= 0; t--) {
- var n = e[t],
- r = s.fromPoints(n.range.start, n.range.end);
- n.action == "insertLines" ? this._removeLines(r.start.row, r.end.row - 1) : n.action == "insertText" ? this.remove(r) : n.action == "removeLines" ? this._insertLines(r.start.row, n.lines) : n.action == "removeText" && this.insert(r.start, n.text)
- }
- }, this.indexToPosition = function(e, t) {
- var n = this.$lines || this.getAllLines(),
- r = this.getNewLineCharacter()
- .length;
- for (var i = t || 0, s = n.length; i < s; i++) {
- e -= n[i].length + r;
- if (e < 0) return {
- row: i,
- column: e + n[i].length + r
- }
- }
- return {
- row: s - 1,
- column: n[s - 1].length
- }
- }, this.positionToIndex = function(e, t) {
- var n = this.$lines || this.getAllLines(),
- r = this.getNewLineCharacter()
- .length,
- i = 0,
- s = Math.min(e.row, n.length);
- for (var o = t || 0; o < s; ++o) i += n[o].length + r;
- return i + e.column
- }
- })
- .call(u.prototype), t.Document = u
-}), ace.define("ace/lib/lang", ["require", "exports", "module"], function(e, t, n) {
- "use strict";
- t.last = function(e) {
- return e[e.length - 1]
- }, t.stringReverse = function(e) {
- return e.split("")
- .reverse()
- .join("")
- }, t.stringRepeat = function(e, t) {
- var n = "";
- while (t > 0) {
- t & 1 && (n += e);
- if (t >>= 1) e += e
- }
- return n
- };
- var r = /^\s\s*/,
- i = /\s\s*$/;
- t.stringTrimLeft = function(e) {
- return e.replace(r, "")
- }, t.stringTrimRight = function(e) {
- return e.replace(i, "")
- }, t.copyObject = function(e) {
- var t = {};
- for (var n in e) t[n] = e[n];
- return t
- }, t.copyArray = function(e) {
- var t = [];
- for (var n = 0, r = e.length; n < r; n++) e[n] && typeof e[n] == "object" ? t[n] = this.copyObject(e[n]) : t[n] = e[n];
- return t
- }, t.deepCopy = function s(e) {
- if (typeof e != "object" || !e) return e;
- var t;
- if (Array.isArray(e)) {
- t = [];
- for (var n = 0; n < e.length; n++) t[n] = s(e[n]);
- return t
- }
- var r = e.constructor;
- if (r === RegExp) return e;
- t = r();
- for (var n in e) t[n] = s(e[n]);
- return t
- }, t.arrayToMap = function(e) {
- var t = {};
- for (var n = 0; n < e.length; n++) t[e[n]] = 1;
- return t
- }, t.createMap = function(e) {
- var t = Object.create(null);
- for (var n in e) t[n] = e[n];
- return t
- }, t.arrayRemove = function(e, t) {
- for (var n = 0; n <= e.length; n++) t === e[n] && e.splice(n, 1)
- }, t.escapeRegExp = function(e) {
- return e.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1")
- }, t.escapeHTML = function(e) {
- return e.replace(/&/g, "&")
- .replace(/"/g, """)
- .replace(/'/g, "'")
- .replace(/ 0 || -1) * Math.floor(Math.abs(e))), e
- }
-
- function B(e) {
- var t = typeof e;
- return e === null || t === "undefined" || t === "boolean" || t === "number" || t === "string"
- }
-
- function j(e) {
- var t, n, r;
- if (B(e)) return e;
- n = e.valueOf;
- if (typeof n == "function") {
- t = n.call(e);
- if (B(t)) return t
- }
- r = e.toString;
- if (typeof r == "function") {
- t = r.call(e);
- if (B(t)) return t
- }
- throw new TypeError
- }
- Function.prototype.bind || (Function.prototype.bind = function(t) {
- var n = this;
- if (typeof n != "function") throw new TypeError("Function.prototype.bind called on incompatible " + n);
- var i = u.call(arguments, 1),
- s = function() {
- if (this instanceof s) {
- var e = n.apply(this, i.concat(u.call(arguments)));
- return Object(e) === e ? e : this
- }
- return n.apply(t, i.concat(u.call(arguments)))
- };
- return n.prototype && (r.prototype = n.prototype, s.prototype = new r, r.prototype = null), s
- });
- var i = Function.prototype.call,
- s = Array.prototype,
- o = Object.prototype,
- u = s.slice,
- a = i.bind(o.toString),
- f = i.bind(o.hasOwnProperty),
- l, c, h, p, d;
- if (d = f(o, "__defineGetter__")) l = i.bind(o.__defineGetter__), c = i.bind(o.__defineSetter__), h = i.bind(o.__lookupGetter__), p = i.bind(o.__lookupSetter__);
- if ([1, 2].splice(0)
- .length != 2)
- if (! function() {
- function e(e) {
- var t = new Array(e + 2);
- return t[0] = t[1] = 0, t
- }
- var t = [],
- n;
- t.splice.apply(t, e(20)), t.splice.apply(t, e(26)), n = t.length, t.splice(5, 0, "XXX"), n + 1 == t.length;
- if (n + 1 == t.length) return !0
- }()) Array.prototype.splice = function(e, t) {
- var n = this.length;
- e > 0 ? e > n && (e = n) : e == void 0 ? e = 0 : e < 0 && (e = Math.max(n + e, 0)), e + t < n || (t = n - e);
- var r = this.slice(e, e + t),
- i = u.call(arguments, 2),
- s = i.length;
- if (e === n) s && this.push.apply(this, i);
- else {
- var o = Math.min(t, n - e),
- a = e + o,
- f = a + s - o,
- l = n - a,
- c = n - o;
- if (f < a)
- for (var h = 0; h < l; ++h) this[f + h] = this[a + h];
- else if (f > a)
- for (h = l; h--;) this[f + h] = this[a + h];
- if (s && e === c) this.length = c, this.push.apply(this, i);
- else {
- this.length = c + s;
- for (h = 0; h < s; ++h) this[e + h] = i[h]
- }
- }
- return r
- };
- else {
- var v = Array.prototype.splice;
- Array.prototype.splice = function(e, t) {
- return arguments.length ? v.apply(this, [e === void 0 ? 0 : e, t === void 0 ? this.length - e : t].concat(u.call(arguments, 2))) : []
- }
- }
- Array.isArray || (Array.isArray = function(t) {
- return a(t) == "[object Array]"
- });
- var m = Object("a"),
- g = m[0] != "a" || !(0 in m);
- Array.prototype.forEach || (Array.prototype.forEach = function(t) {
- var n = F(this),
- r = g && a(this) == "[object String]" ? this.split("") : n,
- i = arguments[1],
- s = -1,
- o = r.length >>> 0;
- if (a(t) != "[object Function]") throw new TypeError;
- while (++s < o) s in r && t.call(i, r[s], s, n)
- }), Array.prototype.map || (Array.prototype.map = function(t) {
- var n = F(this),
- r = g && a(this) == "[object String]" ? this.split("") : n,
- i = r.length >>> 0,
- s = Array(i),
- o = arguments[1];
- if (a(t) != "[object Function]") throw new TypeError(t + " is not a function");
- for (var u = 0; u < i; u++) u in r && (s[u] = t.call(o, r[u], u, n));
- return s
- }), Array.prototype.filter || (Array.prototype.filter = function(t) {
- var n = F(this),
- r = g && a(this) == "[object String]" ? this.split("") : n,
- i = r.length >>> 0,
- s = [],
- o, u = arguments[1];
- if (a(t) != "[object Function]") throw new TypeError(t + " is not a function");
- for (var f = 0; f < i; f++) f in r && (o = r[f], t.call(u, o, f, n) && s.push(o));
- return s
- }), Array.prototype.every || (Array.prototype.every = function(t) {
- var n = F(this),
- r = g && a(this) == "[object String]" ? this.split("") : n,
- i = r.length >>> 0,
- s = arguments[1];
- if (a(t) != "[object Function]") throw new TypeError(t + " is not a function");
- for (var o = 0; o < i; o++)
- if (o in r && !t.call(s, r[o], o, n)) return !1;
- return !0
- }), Array.prototype.some || (Array.prototype.some = function(t) {
- var n = F(this),
- r = g && a(this) == "[object String]" ? this.split("") : n,
- i = r.length >>> 0,
- s = arguments[1];
- if (a(t) != "[object Function]") throw new TypeError(t + " is not a function");
- for (var o = 0; o < i; o++)
- if (o in r && t.call(s, r[o], o, n)) return !0;
- return !1
- }), Array.prototype.reduce || (Array.prototype.reduce = function(t) {
- var n = F(this),
- r = g && a(this) == "[object String]" ? this.split("") : n,
- i = r.length >>> 0;
- if (a(t) != "[object Function]") throw new TypeError(t + " is not a function");
- if (!i && arguments.length == 1) throw new TypeError("reduce of empty array with no initial value");
- var s = 0,
- o;
- if (arguments.length >= 2) o = arguments[1];
- else
- do {
- if (s in r) {
- o = r[s++];
- break
- }
- if (++s >= i) throw new TypeError("reduce of empty array with no initial value")
- } while (!0);
- for (; s < i; s++) s in r && (o = t.call(void 0, o, r[s], s, n));
- return o
- }), Array.prototype.reduceRight || (Array.prototype.reduceRight = function(t) {
- var n = F(this),
- r = g && a(this) == "[object String]" ? this.split("") : n,
- i = r.length >>> 0;
- if (a(t) != "[object Function]") throw new TypeError(t + " is not a function");
- if (!i && arguments.length == 1) throw new TypeError("reduceRight of empty array with no initial value");
- var s, o = i - 1;
- if (arguments.length >= 2) s = arguments[1];
- else
- do {
- if (o in r) {
- s = r[o--];
- break
- }
- if (--o < 0) throw new TypeError("reduceRight of empty array with no initial value")
- } while (!0);
- do o in this && (s = t.call(void 0, s, r[o], o, n)); while (o--);
- return s
- });
- if (!Array.prototype.indexOf || [0, 1].indexOf(1, 2) != -1) Array.prototype.indexOf = function(t) {
- var n = g && a(this) == "[object String]" ? this.split("") : F(this),
- r = n.length >>> 0;
- if (!r) return -1;
- var i = 0;
- arguments.length > 1 && (i = H(arguments[1])), i = i >= 0 ? i : Math.max(0, r + i);
- for (; i < r; i++)
- if (i in n && n[i] === t) return i;
- return -1
- };
- if (!Array.prototype.lastIndexOf || [0, 1].lastIndexOf(0, -3) != -1) Array.prototype.lastIndexOf = function(t) {
- var n = g && a(this) == "[object String]" ? this.split("") : F(this),
- r = n.length >>> 0;
- if (!r) return -1;
- var i = r - 1;
- arguments.length > 1 && (i = Math.min(i, H(arguments[1]))), i = i >= 0 ? i : r - Math.abs(i);
- for (; i >= 0; i--)
- if (i in n && t === n[i]) return i;
- return -1
- };
- Object.getPrototypeOf || (Object.getPrototypeOf = function(t) {
- return t.__proto__ || (t.constructor ? t.constructor.prototype : o)
- });
- if (!Object.getOwnPropertyDescriptor) {
- var y = "Object.getOwnPropertyDescriptor called on a non-object: ";
- Object.getOwnPropertyDescriptor = function(t, n) {
- if (typeof t != "object" && typeof t != "function" || t === null) throw new TypeError(y + t);
- if (!f(t, n)) return;
- var r, i, s;
- r = {
- enumerable: !0,
- configurable: !0
- };
- if (d) {
- var u = t.__proto__;
- t.__proto__ = o;
- var i = h(t, n),
- s = p(t, n);
- t.__proto__ = u;
- if (i || s) return i && (r.get = i), s && (r.set = s), r
- }
- return r.value = t[n], r
- }
- }
- Object.getOwnPropertyNames || (Object.getOwnPropertyNames = function(t) {
- return Object.keys(t)
- });
- if (!Object.create) {
- var b;
- Object.prototype.__proto__ === null ? b = function() {
- return {
- __proto__: null
- }
- } : b = function() {
- var e = {};
- for (var t in e) e[t] = null;
- return e.constructor = e.hasOwnProperty = e.propertyIsEnumerable = e.isPrototypeOf = e.toLocaleString = e.toString = e.valueOf = e.__proto__ = null, e
- }, Object.create = function(t, n) {
- var r;
- if (t === null) r = b();
- else {
- if (typeof t != "object") throw new TypeError("typeof prototype[" + typeof t + "] != 'object'");
- var i = function() {};
- i.prototype = t, r = new i, r.__proto__ = t
- }
- return n !== void 0 && Object.defineProperties(r, n), r
- }
- }
- if (Object.defineProperty) {
- var E = w({}),
- S = typeof document == "undefined" || w(document.createElement("div"));
- if (!E || !S) var x = Object.defineProperty
- }
- if (!Object.defineProperty || x) {
- var T = "Property description must be an object: ",
- N = "Object.defineProperty called on non-object: ",
- C = "getters & setters can not be defined on this javascript engine";
- Object.defineProperty = function(t, n, r) {
- if (typeof t != "object" && typeof t != "function" || t === null) throw new TypeError(N + t);
- if (typeof r != "object" && typeof r != "function" || r === null) throw new TypeError(T + r);
- if (x) try {
- return x.call(Object, t, n, r)
- } catch (i) {}
- if (f(r, "value"))
- if (d && (h(t, n) || p(t, n))) {
- var s = t.__proto__;
- t.__proto__ = o, delete t[n], t[n] = r.value, t.__proto__ = s
- } else t[n] = r.value;
- else {
- if (!d) throw new TypeError(C);
- f(r, "get") && l(t, n, r.get), f(r, "set") && c(t, n, r.set)
- }
- return t
- }
- }
- Object.defineProperties || (Object.defineProperties = function(t, n) {
- for (var r in n) f(n, r) && Object.defineProperty(t, r, n[r]);
- return t
- }), Object.seal || (Object.seal = function(t) {
- return t
- }), Object.freeze || (Object.freeze = function(t) {
- return t
- });
- try {
- Object.freeze(function() {})
- } catch (k) {
- Object.freeze = function(t) {
- return function(n) {
- return typeof n == "function" ? n : t(n)
- }
- }(Object.freeze)
- }
- Object.preventExtensions || (Object.preventExtensions = function(t) {
- return t
- }), Object.isSealed || (Object.isSealed = function(t) {
- return !1
- }), Object.isFrozen || (Object.isFrozen = function(t) {
- return !1
- }), Object.isExtensible || (Object.isExtensible = function(t) {
- if (Object(t) === t) throw new TypeError;
- var n = "";
- while (f(t, n)) n += "?";
- t[n] = !0;
- var r = f(t, n);
- return delete t[n], r
- });
- if (!Object.keys) {
- var L = !0,
- A = ["toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "constructor"],
- O = A.length;
- for (var M in {
- toString: null
- }) L = !1;
- Object.keys = function I(e) {
- if (typeof e != "object" && typeof e != "function" || e === null) throw new TypeError("Object.keys called on a non-object");
- var I = [];
- for (var t in e) f(e, t) && I.push(t);
- if (L)
- for (var n = 0, r = O; n < r; n++) {
- var i = A[n];
- f(e, i) && I.push(i)
- }
- return I
- }
- }
- Date.now || (Date.now = function() {
- return (new Date)
- .getTime()
- });
- var _ = " \n\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff";
- if (!String.prototype.trim || _.trim()) {
- _ = "[" + _ + "]";
- var D = new RegExp("^" + _ + _ + "*"),
- P = new RegExp(_ + _ + "*$");
- String.prototype.trim = function() {
- return String(this)
- .replace(D, "")
- .replace(P, "")
- }
- }
- var F = function(e) {
- if (e == null) throw new TypeError("can't convert " + e + " to object");
- return Object(e)
- }
-})
\ No newline at end of file
diff --git a/doc/swift-target.md b/doc/swift-target.md
index d023ee4f70..9f04349b9c 100644
--- a/doc/swift-target.md
+++ b/doc/swift-target.md
@@ -1,15 +1,10 @@
# ANTLR4 Language Target, Runtime for Swift
-## Requirements
-
-ANTLR 4.7.2 requires Swift 4.2. It works on Swift 4.2.1 also.
-
-ANTLR 4.7.1 requires Swift 4.0, and does not work on Swift 4.2. (The status of
-Swift 4.1 support is unknown.)
-
## Performance Note
-To use ANTLR4 Swift target in production environment, make sure to turn on compiler optimizations by following [these instructions](https://github.com/apple/swift-package-manager/blob/master/Documentation/Usage.md#build-configurations) if you use SwiftPM to build your project. If you are using Xcode to build your project, it's unlikely you will not use `release` build for production build.
+To use ANTLR4 Swift target in production environment, make sure to turn on compiler optimizations by following [these instructions](https://github.com/apple/swift-package-manager/blob/main/Documentation/Usage.md#setting-the-build-configuration) if you use SwiftPM to build your project.
+
+If you are using Xcode to build your project, it's unlikely you will not use `release` build for production build.
Conclusion is, you need to turn on `release` mode (which will have all the optimization pre configured for you) so the ANTLR4 Swift target can have reasonable parsing speed.
@@ -60,10 +55,7 @@ Note that even if you are otherwise using ANTLR from a binary distribution,
you should compile the ANTLR Swift runtime from source, because the Swift
language does not yet have a stable ABI.
-ANTLR uses Swift Package Manager to generate Xcode project files. Note that
-Swift Package Manager does not currently support iOS, watchOS, or tvOS, so
-if you wish to use those platforms, you will need to alter the project build
-settings manually as appropriate.
+ANTLR uses Swift Package Manager to generate Xcode project files.
#### Download source code for ANTLR
@@ -135,29 +127,12 @@ The runtime and generated grammar should now build correctly.
### Swift Package Manager Projects
-Since we cannot have a separate repository for Swift target (see issue [#1774](https://github.com/antlr/antlr4/issues/1774)),
-and Swift is currently not ABI stable. We currently support support SPM-based
-projects by creating temporary local repository.
+Add Antlr4 as a dependency to your `Package.swift` file. For more information, please see the [Swift Package Manager documentation](https://github.com/apple/swift-package-manager/tree/master/Documentation).
-For people using [Swift Package Manager](https://swift.org/package-manager/),
-the __boot.py__ script supports generating local repository that can be used
-as a dependency to your project. Simply run:
+```swift
+.package(url: "https://github.com/antlr/antlr4", from: "4.13.2")
```
-python boot.py --gen-spm-module
-```
-
-The prompt will show something like below:
-
-
-
-Put the SPM directive that contains the url to temporary repository to your
-project's Package.swift. And run `swift build` in your project.
-
-The project is generated in your system's `/tmp/` directory, if you find it
-inconvenient, consider copy that generated ANTLR repository to some place
-that won't be cleaned automatically and update `url` parameter in your
-`Package.swift` file.
## Swift access levels
diff --git a/doc/target-agnostic-grammars.md b/doc/target-agnostic-grammars.md
new file mode 100644
index 0000000000..62ee48231a
--- /dev/null
+++ b/doc/target-agnostic-grammars.md
@@ -0,0 +1,82 @@
+# Writing target-agnostic grammars
+
+Some grammars require
+[semantic predicates](https://github.com/antlr/antlr4/blob/dev/doc/predicates.md)
+to add context-sensitive parsing to what would generally be a context-free grammar.
+
+For example:
+* In Fortran90, [lines that begin with a 'C' in column 1
+are comments](https://github.com/antlr/grammars-v4/blob/43fbb16fec1d474d38a603cc6a6bcbe5edf07b1e/fortran/fortran90/slow/hw.f90#L1),
+which should be placed on a token stream other than the default.
+But, if the 'C' does not begin in
+column 1, then the input is invalid and should be flagged as so.
+ ```fortran
+ c Hello World.
+ c This is a syntax error because 'c' does not start in column 1
+ program hello
+ print *, 'Hello World!'
+ end
+ ```
+
+* In CSharp, two [greater-than signs](https://util.unicode.org/UnicodeJsps/character.jsp?a=003E)
+`'>>'` can either mean
+[a right shift expression](https://github.com/antlr/grammars-v4/blob/43fbb16fec1d474d38a603cc6a6bcbe5edf07b1e/csharp/examples/AllInOneNoPreprocessor.cs#L657C15-L657C17)
+or [part of a type declaration with templates](https://github.com/antlr/grammars-v4/blob/master/csharp/examples/AllInOneNoPreprocessor.cs#L463C33-L463C35).
+Since lexers in Antlr are not parser aware,
+the lexer must tokenize the two greater-than signs as two separate tokens.
+A semantic predicate should be added to disallow a space between the two greater-than signs in the context
+of an expression, but allowed in the context of a type declaration.
+ ```C#
+ class Foo {
+ void Func()
+ {
+ int x = 1000 > > 2; // syntax error if a space exists in the double greater-than sign
+ }
+ Dictionary > mapping; // nested template declaration, valid
+ }
+ ```
+
+Antlr does not have a general-purpose language for predicates. These must be
+written in the target language of the generated parser. The problem is that
+a grammar would need to be forked for each target desired, which adds to the
+burden of maintenance.
+
+However, it is possible to write the grammar such that forking is not required,
+using _target-agnostic format_.
+
+## Rules in writing target-agnostic grammars
+
+1) You will need to [split your grammar](https://github.com/antlr/antlr4/blob/dev/doc/grammars.md#grammar-structure)
+into separate lexer and parser grammars. Then, add `options { tokenVocab=...; }` to the parser grammar.
+2) Create target-specific source code files that contain methods in a base class for
+the parser or lexer grammar. In these source code files, write the code for the semantic
+predicate. For example, the files for the Cpp target would be `Python3LexerBase.{cpp,h}`, `Python3ParserBase.{cpp,h}`.
+3) In the grammar(s), add `options { superClass=... }`. This will
+[superclass the recognizer](https://github.com/antlr/antlr4/blob/dev/doc/options.md#superclass).
+For example, `options { superclass=Python3ParserBase; }`.
+4) In the grammar(s), write code to make a single
+call to the base-class method. The call should have a `this.` string
+before the name of the method, e.g., `OPEN_PAREN : '(' {this.openBrace();};`
+The action code must not reference Antlr attributes,
+variables, types, or have semi-colons as statement separators or
+control-flow statements of any kind.
+5) For some targets like Cpp and PHP, you may need to add code to include source
+code files so that the generated code compiles.
+For these, add a comment
+such as `// Insert here @header for lexer include.` or `// Insert here @header for parser include.`
+to the grammar, before the first rule.
+5) Add a Python script called "transformGrammar.py" that rewrites the grammar(s)
+with some target-specific code syntax.
+ a) For Cpp: replace `this.` strings with `this->`.
+ b) For PHP: replace `this.` strings with `$this->`.
+ c) For Python: replace `this.` strings with `self.`, `l.`, or `p.` depending on
+where the action or predicate is in the grammar.
+ d) For Cpp: replace `// Insert here @header for lexer include.` (or parser) with
+`@header::lexer {#include ...}`.
+ e) For PHP: replace `// Insert here @header for lexer include.` (or parser) with
+`@header::lexer {require ...}`.
+ e) Run `python transformGrammar.py *.g4` before generating the parser and lexer.
+
+## Examples of target-agnostic grammars
+* [fortran90](https://github.com/antlr/grammars-v4/tree/master/fortran/fortran90)
+* [csharp](https://github.com/antlr/grammars-v4/tree/master/csharp)
diff --git a/doc/targets.md b/doc/targets.md
index f2a63689ae..0c61b6f3a8 100644
--- a/doc/targets.md
+++ b/doc/targets.md
@@ -4,19 +4,21 @@ This page lists the available and upcoming ANTLR runtimes. Please note that you
* [Java](java-target.md). The [ANTLR v4 book](http://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference) has a decent summary of the runtime library. We have added a useful XPath feature since the book was printed that lets you select bits of parse trees. See [Runtime API](http://www.antlr.org/api/Java/index.html) and [Getting Started with ANTLR v4](getting-started.md)
* [C#](csharp-target.md)
-* [Python](python-target.md) (2 and 3)
+* [Python](python-target.md) (3)
* [JavaScript](javascript-target.md)
+* [TypeScript](typescript-target.md)
* [Go](go-target.md)
* [C++](cpp-target.md)
* [Swift](swift-target.md)
* [PHP](php-target.md)
+* [Dart](dart-target.md)
* [Rust](rust-target.md) (Unstable)
## Target feature parity
New features generally appear in the Java target and then migrate to the other targets, but these other targets don't always get updated in the same overall tool release. This section tries to identify features added to Java that have not been added to the other targets.
-|Feature|Java|C♯|Python2|Python3|JavaScript|Go|C++|Swift|PHP
+|Feature|Java|C♯|Python3|JavaScript|Go|C++|Swift|PHP|Dart
|---|---|---|---|---|---|---|---|---|---|
|Ambiguous tree construction|4.5.1|-|-|-|-|-|-|-|-|
diff --git a/doc/tree-matching.md b/doc/tree-matching.md
index f4c6d278cc..b0ec83bb5a 100644
--- a/doc/tree-matching.md
+++ b/doc/tree-matching.md
@@ -52,15 +52,6 @@ m.setDelimiters("<<", ">>", "$"); // $ is the escape character
This would allow pattern `<> = <> ;$<< ick $>>` to be interpreted as elements: `ID`, ` = `, `expr`, and ` ;<< ick >>`.
-```java
-String xpath = "//blockStatement/*";
-String treePattern = "int = ;";
-ParseTreePattern p =
-parser.compileParseTreePattern(treePattern,
-JavaParser.RULE_localVariableDeclarationStatement);
-List matches = p.findAll(tree, xpath);
-```
-
### Pattern labels
The tree pattern matcher tracks the nodes in the tree at matches against the tags in a tree pattern. That way we can use the `get()` and `getAll()` methods to retrieve components of the matched subtree. For example, for pattern ``, `get("ID")` returns the node matched for that `ID`. If more than one node matched the specified token or rule tag, only the first match is returned. If there is no node associated with the label, this returns null.
diff --git a/doc/typescript-target.md b/doc/typescript-target.md
new file mode 100644
index 0000000000..af03575d03
--- /dev/null
+++ b/doc/typescript-target.md
@@ -0,0 +1,125 @@
+# TypeScript
+
+Antlr4 TypeScript runtime uses the JavaScript runtime and adds type files to it.
+This guarantees the same behaviour and performance across both target languages.
+Generated lexers, parsers, listeners and visitors are generated in TypeScript.
+
+The runtime is built using TypeScript v4.8.3, node 16.17 and webpack 5.66.
+It may work with older versions but they have not been tested and they will not be supported.
+
+
+## How to create a TypeScript lexer or parser?
+
+This is pretty much the same as creating a Java lexer or parser, except you need to specify the language target, for example:
+
+```bash
+$ antlr4 -Dlanguage=TypeScript MyGrammar.g4
+```
+
+For a full list of antlr4 tool options, please visit the [tool documentation page](tool-options.md).
+
+## Where can I get the runtime?
+
+Once you've generated the lexer and/or parser code, you need to download the runtime from [npm](https://www.npmjs.com/package/antlr4).
+
+We will not document here how to refer to the runtime from your project, since this would differ a lot depending on your project type and IDE.
+
+## How do I get the runtime in my browser?
+
+The runtime is webpacked and sits in the dist folder. A .map file is also provided.
+
+## How do I run the generated lexer and/or parser?
+
+Let's suppose that your grammar is named, as above, "MyGrammar". Let's suppose this parser comprises a rule named "MyStartRule". The tool will have generated for you the following files:
+
+* MyGrammarLexer.ts
+* MyGrammarParser.ts
+* MyGrammarListener.ts (if you have not activated the -no-listener option)
+* MyGrammarVisitor.ts (if you have activated the -visitor option)
+
+There is no listener or visitor interface generated, instead the generated listener and visitor class methods are implemented using lambdas.
+
+Now a fully functioning script might look like the following:
+
+```typescript
+import { CharStream, CommonTokenStream } from 'antlr4';
+import MyGrammarLexer from './MyGrammarLexer';
+import MyGrammarParser from './MyGrammarParser';
+
+const input = "your text to parse here"
+const chars = new CharStream(input); // replace this with a FileStream as required
+const lexer = new MyGrammarLexer(chars);
+const tokens = new CommonTokenStream(lexer);
+const parser = new MyGrammarParser(tokens);
+const tree = parser.MyStartRule();
+
+```
+
+Tha above program will work. But it won't be useful unless you do one of the following:
+
+* you visit the parse tree using a custom listener
+* you visit the parse tree using a custom visitor
+* your grammar contains production code (like AntLR3)
+
+(please note that production code is target specific, so you can't have multi target grammars that include production code)
+
+## How do I create and run a visitor?
+
+You need to create a custom visitor and use it to visit the parse tree, as follows:
+```typescript
+
+import { ParserRuleContext } from 'antlr4';
+import MyGrammarVisitor from './MyGrammarVisitor';
+
+class CustomVisitor extends MyGrammarVisitor {
+
+ visitChildren(ctx: ParserRuleContext) {
+ if (!ctx) {
+ return;
+ }
+ if (ctx.children) {
+ return ctx.children.map(child => {
+ if (child.children && child.children.length != 0) {
+ return child.accept(this);
+ } else {
+ return child.getText();
+ }
+ });
+ }
+ }
+}
+
+tree.accept(new CustomVisitor());
+````
+
+## How do I create and run a custom listener?
+
+You need to create a custom listener and use it to visit the parse tree, as follows:
+
+```typescript
+
+import { ParseTreeWalker } from 'antlr4';
+import MyGrammarListener from './MyGrammarListener';
+
+class MyTreeWalker extends MyGrammarListener {
+
+ exitMyStartRule = (ctx: MyStartRuleContext) => {
+ console.log("In MyStartRule");
+ };
+
+}
+
+const walker = new MyTreeWalker();
+ParseTreeWalker.DEFAULT.walk(walker, tree);
+
+```
+
+## How do I integrate my parser with ACE editor?
+
+This specific task is described in this [dedicated page](ace-javascript-target.md).
+
+## How can I learn more about ANTLR?
+
+Further information can be found from "The definitive ANTLR 4 reference" book.
+
+The TypeScript implementation of ANTLR is based on the JavaScript implementation, which is as close as possible to the Java one, so you shouldn't find it difficult to adapt the book's examples to TypeScript.
diff --git a/doc/wildcard.md b/doc/wildcard.md
index f3d1c3a0b5..a597c649c9 100644
--- a/doc/wildcard.md
+++ b/doc/wildcard.md
@@ -61,7 +61,7 @@ END : '>>' ;
After crossing through a nongreedy subrule within a lexical rule, all decision-making from then on is "first match wins."
-For example, literal `ab` in rule right-hand side (grammar fragment) `.*? (’a’|’ab’)` is dead code and can never be matched. If the input is ab, the first alternative, ’a’, matches the first character and therefore succeeds. (’a’|’ab’) by itself on the right-hand side of a rule properly matches the second alternative for input ab. This quirk arises from a nongreedy design decision that’s too complicated to go into here.
+For example, literal `ab` in rule right-hand side (grammar fragment) `.*? ('a'|'ab')` is dead code and can never be matched. If the input is ab, the first alternative, 'a', matches the first character and therefore succeeds. ('a'|'ab') by itself on the right-hand side of a rule properly matches the second alternative for input ab. This quirk arises from a nongreedy design decision that’s too complicated to go into here.
@@ -74,7 +74,7 @@ ACTION3 : '<' ( STRING | ~[">] )* '>' ; // Doesn't allow <"foo>; greedy *
STRING : '"' ( '\\"' | . )*? '"' ;
```
-Rule `ACTION1` allows unterminated strings, such as `"foo`, because input `"foo` matches to the wildcard part of the loop. It doesn’t have to go into rule `STRING` to match a quote. To fix that, rule `ACTION2` uses `~’"’` to match any character but the quote. Expression `~’"’` is still ambiguous with the `’]’` that ends the rule, but the fact that the subrule is nongreedy means that the lexer will exit the loop upon a right square bracket. To avoid a nongreedy subrule, make the alternatives explicit. Expression `~[">]` matches anything but the quote and right angle bracket. Here’s a sample run:
+Rule `ACTION1` allows unterminated strings, such as `"foo`, because input `"foo` matches to the wildcard part of the loop. It doesn’t have to go into rule `STRING` to match a quote. To fix that, rule `ACTION2` uses `~'"'` to match any character but the quote. Expression `~'"'` is still ambiguous with the `']'` that ends the rule, but the fact that the subrule is nongreedy means that the lexer will exit the loop upon a right square bracket. To avoid a nongreedy subrule, make the alternatives explicit. Expression `~[">]` matches anything but the quote and right angle bracket. Here’s a sample run:
```bash
$ antlr4 Actions.g4
@@ -225,4 +225,4 @@ ANY : . ;
You get:
-
\ No newline at end of file
+
diff --git a/docker/.dockerignore b/docker/.dockerignore
new file mode 100644
index 0000000000..1455bc2c3d
--- /dev/null
+++ b/docker/.dockerignore
@@ -0,0 +1,7 @@
+tool-testsuite
+runtime-testsuite
+.git*
+README.adoc
+README.md
+cache
+tests
diff --git a/docker/Dockerfile b/docker/Dockerfile
new file mode 100644
index 0000000000..c5c2a9e655
--- /dev/null
+++ b/docker/Dockerfile
@@ -0,0 +1,21 @@
+FROM eclipse-temurin:21 AS builder
+
+WORKDIR /opt/antlr4
+
+ARG ANTLR_VERSION="4.13.2"
+ARG MAVEN_OPTS="-Xmx1G"
+
+
+RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install maven git -y \
+ && git clone https://github.com/antlr/antlr4.git \
+ && cd antlr4 \
+ && git checkout $ANTLR_VERSION \
+ && mvn clean --projects tool --also-make \
+ && mvn -DskipTests install --projects tool --also-make \
+ && mv ./tool/target/antlr4-*-complete.jar antlr4-tool.jar
+
+FROM eclipse-temurin:21-jre
+
+COPY --from=builder /opt/antlr4/antlr4/antlr4-tool.jar /usr/local/lib/
+WORKDIR /work
+ENTRYPOINT ["java", "-Xmx500M", "-cp", "/usr/local/lib/antlr4-tool.jar", "org.antlr.v4.Tool"]
diff --git a/docker/README.md b/docker/README.md
new file mode 100644
index 0000000000..b1d9e77ce2
--- /dev/null
+++ b/docker/README.md
@@ -0,0 +1,34 @@
+# Docker Image for ANTLR4
+
+This Docker image wraps current version of **ANTLR4** inclusive **Java runtime environment** so it can be executed as transparent command line tool even on machines without installed Java.
+
+## Docker Image
+
+The image uses the official [eclipse-temurin:11](https://hub.docker.com/_/eclipse-temurin/tags?page=1&name=11&ordering=-name) image
+for building a distribution of ANTLR4 and [eclipse-temurin:11-jre](https://hub.docker.com/_/eclipse-temurin/tags?page=1&name=11-jre&ordering=-name) for runtime.
+
+## Build
+
+You can build docker image from source code locally.
+
+ git clone https://github.com/antlr/antlr4.git
+ cd antlr4/docker
+ docker build -t antlr/antlr4 --platform linux/amd64 .
+
+
+## Run
+
+For security reasons is **ANTLR4 Docker image** designed to run in the current folder only, so a container doesn't have any access to any other folders on a host system. Since this is a transparent call of Docker image from command line, where new files are generated, it is also a good idea to execute code inside a Docker as a non root user and match it to the host caller.
+
+Calling a dockerized ANTLR4 image can look like this:
+
+```shell
+wget https://raw.githubusercontent.com/antlr/grammars-v4/master/json/JSON.g4
+docker run --rm -u $(id -u ${USER}):$(id -g ${USER}) -v `pwd`:/work antlr/antlr4 -Dlanguage=Go JSON.g4
+```
+
+## Integration as alias
+
+ alias antlr4='docker run -it -u $(id -u ${USER}):$(id -g ${USER}) -v $(pwd):/work antlr/antlr4 $@'
+
+
diff --git a/historical-contributors-agreement.txt b/historical-contributors-agreement.txt
new file mode 100644
index 0000000000..a7d5ca8f84
--- /dev/null
+++ b/historical-contributors-agreement.txt
@@ -0,0 +1,335 @@
+ANTLR Project Contributors Certification of Origin and Rights
+
+All contributors to ANTLR v4 must formally agree to abide by this
+certificate of origin by signing on the bottom with their github
+userid, full name, email address (you can obscure your e-mail, but it
+must be computable by human), and date.
+
+By signing this agreement, you are warranting and representing that
+you have the right to release code contributions or other content free
+of any obligations to third parties and are granting Terence Parr and
+ANTLR project contributors, henceforth referred to as The ANTLR
+Project, a license to incorporate it into The ANTLR Project tools
+(such as ANTLRWorks and StringTemplate) or related works under the BSD
+license. You understand that The ANTLR Project may or may not
+incorporate your contribution and you warrant and represent the
+following:
+
+1. I am the creator of all my contributions. I am the author of all
+ contributed work submitted and further warrant and represent that
+ such work is my original creation and I have the right to license
+ it to The ANTLR Project for release under the 3-clause BSD
+ license. I hereby grant The ANTLR Project a nonexclusive,
+ irrevocable, royalty-free, worldwide license to reproduce,
+ distribute, prepare derivative works, and otherwise use this
+ contribution as part of the ANTLR project, associated
+ documentation, books, and tools at no cost to The ANTLR Project.
+
+2. I have the right to submit. This submission does not violate the
+ rights of any person or entity and that I have legal authority over
+ this submission and to make this certification.
+
+3. If I violate another's rights, liability lies with me. I agree to
+ defend, indemnify, and hold The ANTLR Project and ANTLR users
+ harmless from any claim or demand, including reasonable attorney
+ fees, made by any third party due to or arising out of my violation
+ of these terms and conditions or my violation of the rights of
+ another person or entity.
+
+4. I understand and agree that this project and the contribution are
+ public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license indicated in the file.
+
+I have read this agreement and do so certify by adding my signoff to
+the end of the following contributors list.
+
+CONTRIBUTORS:
+
+YYYY/MM/DD, github id, Full name, email
+2012/07/12, parrt, Terence Parr, parrt@antlr.org
+2012/09/18, sharwell, Sam Harwell, sam@tunnelvisionlabs.com
+2012/10/10, stephengaito, Stephen Gaito, stephen@percepitsys.co.uk
+2012/11/23, maguro, Alan Cabrera, adc@toolazydogs.com
+2013/01/29, metadave, Dave Parfitt, diparfitt@gmail.com
+2013/03/06, bkiers, Bart Kiers, bkiers@gmail.com
+2013/08/20, cayhorstmann, Cay Horstmann, cay@horstmann.com
+2014/03/18, aphyr, Kyle Kingsbury, aphyr@aphyr.com
+2014/06/07, ericvergnaud, Eric Vergnaud, eric.vergnaud@wanadoo.fr
+2014/07/04, jimidle, Jim Idle, jimi@Idle.ws
+2014/01/01, danmclaughlin, Dan McLaughlin, dan.mclaughlin@gmail.com
+2014/09/04. jeduden, Jan-Eric Duden, jeduden@gmail.com
+2014/09/27, petrbel, Petr Bělohlávek, antlr@petrbel.cz
+2014/10/18, sergiusignacius, Sérgio Silva, serge.a.silva@gmail.com
+2014/10/26, bdkearns, Brian Kearns, bdkearns@gmail.com
+2014/10/27, michaelpj, Michael Peyton Jones, michaelpj@gmail.com
+2015/01/29, TomLottermann, Thomas Lottermann, tomlottermann@gmail.com
+2015/02/15, pavlo, Pavlo Lysov, pavlikus@gmail.com
+2015/03/07, RedTailedHawk, Lawrence Parker, larry@answerrocket.com
+2015/04/03, rljacobson, Robert Jacobson, rljacobson@gmail.com
+2015/04/06, ojakubcik, Ondrej Jakubcik, ojakubcik@gmail.com
+2015/04/29, jszheng, Jinshan Zheng, zheng_js@hotmail.com
+2015/05/08, ViceIce, Michael Kriese, michael.kriese@gmx.de
+2015/05/09, lkraz, Luke Krasnoff, luke.krasnoff@gmail.com
+2015/05/12, Pursuit92, Josh Chase, jcjoshuachase@gmail.com
+2015/05/20, peturingi, Pétur Ingi Egilsson, petur@petur.eu
+2015/05/27, jcbrinfo, Jean-Christophe Beaupré, jcbrinfo@users.noreply.github.com
+2015/06/29, jvanzyl, Jason van Zyl, jason@takari.io
+2015/08/18, krzkaczor, Krzysztof Kaczor, krzysztof@kaczor.io
+2015/09/18, worsht, Rajiv Subrahmanyam, rajiv.public@gmail.com
+2015/09/24, HSorensen, Henrik Sorensen, henrik.b.sorensen@gmail.com
+2015/10/06, brwml, Bryan Wilhelm, bryan.wilhelm@microsoft.com
+2015/10/08, fedotovalex, Alex Fedotov, me@alexfedotov.com
+2015/10/12, KvanTTT, Ivan Kochurkin, ivan.kochurkin@gmail.com
+2015/10/21, martin-probst, Martin Probst, martin-probst@web.de
+2015/10/21, hkff, Walid Benghabrit, walid.benghabrit@mines-nantes.fr
+2015/11/12, cooperra, Robbie Cooper, cooperra@users.noreply.github.com
+2015/11/25, abego, Udo Borkowski, ub@abego.org
+2015/12/17, sebadur, Sebastian Badur, sebadur@users.noreply.github.com
+2015/12/23, pboyer, Peter Boyer, peter.b.boyer@gmail.com
+2015/12/24, dtymon, David Tymon, david.tymon@gmail.com
+2016/02/18, reitzig, Raphael Reitzig, reitzig[at]cs.uni-kl.de
+2016/03/10, mike-lischke, Mike Lischke, mike@lischke-online.de
+2016/03/27, beardlybread, Bradley Steinbacher, bradley.j.steinbacher@gmail.com
+2016/03/29, msteiger, Martin Steiger, antlr@martin-steiger.de
+2016/03/28, gagern, Martin von Gagern, gagern@ma.tum.de
+2016/07/10, twz123, Tom Wieczorek, tom.wieczorek@zalando.de
+2016/07/20, chrisheller, Chris Heller, chris.heller.greyheller@gmail.com
+2016/07/20, nburles, Nathan Burles, nburles@gmail.com
+2016/07/20, kosl90, Li Liqiang, kos1990l@gmail.com
+2016/07/27, timoc, Tim O'Callaghan, timo@linux.com
+2016/07/26, nic30, Michal Orsák, michal.o.socials@gmail.com
+2016/07/18, willfaught, Will Faught, will.faught@gmail.com
+2016/08/08, wjkohnen, Wolfgang Johannes Kohnen, wjkohnen-go-antlr@ko-sys.com
+2016/08/11, BurtHarris, Ralph "Burt" Harris, Burt_Harris_antlr4@azxs.33mail.com
+2016/08/19, andjo403, Andreas Jonson, andjo403@hotmail.com
+2016/09/27, harriman, Kurt Harriman, harriman@acm.org
+2016/10/13, cgudrian, Christian Gudrian, christian.gudrian@gmx.de
+2016/10/13, nielsbasjes, Niels Basjes, niels@basjes.nl
+2016/10/21, FloorGoddijn, Floor Goddijn, floor.goddijn[at]aimms.com
+2016/11/01, RYDB3RG, Kai Stammerjohann, RYDB3RG@users.noreply.github.com
+2016/11/05, runner-mei, meifakun, runner.mei@gmail.com
+2016/11/15, hanjoes, Hanzhou Shi, hanzhou87@gmail.com
+2016/11/16, sridharxp, Sridharan S, aurosridhar@gmail.com
+2016/11/06, NoodleOfDeath, Thom Morgan, github@bytemeapp.com
+2016/11/01, sebkur, Sebastian Kürten, sebastian@topobyte.de
+2016/04/13, renatahodovan, Renata Hodovan, reni@inf.u-szeged.hu
+2016/11/05, ewanmellor, Ewan Mellor, github@ewanmellor.org
+2016/11/06, janyou, Janyou, janyou.antlr@outlook.com
+2016/11/20, marcohu, Marco Hunsicker, antlr@hunsicker.de
+2016/09/02, lygav, Vladimir (Vladi) Lyga, lyvladi@gmail.com
+2016/09/23, ghosthope, Dmitry Shakhtanov, sudstrike@gmail.com
+2016/11/25, MrSampson, Oliver Sampson, olsam@quickaudio.com
+2016/11/29, millergarym, Gary Miller, miller.garym@gmail.com
+2016/11/29, wxio, Gary Miller, gm@wx.io
+2016/11/29, Naios, Denis Blank, naios@users.noreply.github.com
+2016/12/01, samtatasurya, Samuel Tatasurya, xemradiant@gmail.com
+2016/12/03, redxdev, Samuel Bloomberg, sam@redxdev.com
+2016/12/11, Gaulouis, Gaulouis, gaulouis.com@gmail.com
+2016/12/22, akosthekiss, Akos Kiss, akiss@inf.u-szeged.hu
+2016/12/24, adrpo, Adrian Pop, adrian.pop@liu.se
+2017/01/11, robertbrignull, Robert Brignull, robertbrignull@gmail.com
+2017/01/13, marcelo-rocha, Marcelo Rocha, mcrocha@gmail.com
+2017/01/23, bhamiltoncx, Ben Hamilton, bhamiltoncx+antlr@gmail.com
+2017/01/18, mshockwave, Bekket McClane, yihshyng223@gmail.com
+2017/02/10, lionelplessis, Lionel Plessis, lionelplessis@users.noreply.github.com
+2017/02/14, lecode-official, David Neumann, david.neumann@lecode.de
+2017/02/14, xied75, Dong Xie, xied75@gmail.com
+2017/02/20, Thomasb81, Thomas Burg, thomasb81@gmail.com
+2017/02/26, jvasileff, John Vasileff, john@vasileff.com
+2017/03/08, harry-tallbelt, Igor Vysokopoyasny, harry.tallbelt@gmail.com
+2017/03/09, teverett, Tom Everett, tom@khubla.com
+2017/03/03, chund, Christian Hund, christian.hund@gmail.com
+2017/03/15, robertvanderhulst, Robert van der Hulst, robert@xsharp.eu
+2017/03/28, cmd-johnson, Jonas Auer, jonas.auer.94@gmail.com
+2017/04/12, lys0716, Yishuang Lu, luyscmu@gmail.com
+2017/04/30, shravanrn, Shravan Narayan, shravanrn@gmail.com
+2017/05/11, jimallman, Jim Allman, jim@ibang.com
+2017/05/26, waf, Will Fuqua, wafuqua@gmail.com
+2017/05/29, kosak, Corey Kosak, kosak@kosak.com
+2017/06/11, erikbra, Erik A. Brandstadmoen, erik@brandstadmoen.net
+2017/06/10, jm-mikkelsen, Jan Martin Mikkelsen, janm@transactionware.com
+2017/06/25, alimg, Alim Gökkaya, alim.gokkaya@gmail.com
+2017/06/28, jBugman, Sergey Parshukov, codedby@bugman.me
+2017/07/09, neatnerd, Mike Arshinskiy, neatnerd@users.noreply.github.com
+2017/07/11, dhalperi, Daniel Halperin, daniel@halper.in
+2017/07/17, vaibhavaingankar09, Vaibhav Vaingankar, vbhvvaingankar9@gmail.com
+2017/07/23, venkatperi, Venkat Peri, venkatperi@gmail.com
+2017/07/27, shirou, WAKAYAMA Shirou, shirou.faw@gmail.com
+2017/07/09, neatnerd, Mike Arshinskiy, neatnerd@users.noreply.github.com
+2017/07/27, matthauck, Matt Hauck, matthauck@gmail.com
+2017/07/27, shirou, WAKAYAMA Shirou, shirou.faw@gmail.com
+2017/08/20, tiagomazzutti, Tiago Mazzutti, tiagomzt@gmail.com
+2017/08/20, milanaleksic, Milan Aleksic, milanaleksic@gmail.com
+2017/08/29, Eddy Reyes, eddy@mindsight.io
+2017/09/09, brauliobz, Bráulio Bezerra, brauliobezerra@gmail.com
+2017/09/11, sachinjain024, Sachin Jain, sachinjain024@gmail.com
+2017/09/25, kaedvann, Rostislav Listerenko, r.listerenko@gmail.com
+2017/10/06, bramp, Andrew Brampton, brampton@gmail.com
+2017/10/15, simkimsia, Sim Kim Sia, kimcity@gmail.com
+2017/10/27, Griffon26, Maurice van der Pot, griffon26@kfk4ever.com
+2017/05/29, rlfnb, Ralf Neeb, rlfnb@rlfnb.de
+2017/10/29, gendalph, Максим Прохоренко, Maxim\dotProhorenko@gm@il.com
+2017/11/02, jasonmoo, Jason Mooberry, jason.mooberry@gmail.com
+2017/11/05, ajaypanyala, Ajay Panyala, ajay.panyala@gmail.com
+2017/11/24, zqlu.cn, Zhiqiang Lu, zqlu.cn@gmail.com
+2017/11/28, niccroad, Nicolas Croad, nic.croad@gmail.com
+2017/12/01, DavidMoraisFerreira, David Morais Ferreira, david.moraisferreira@gmail.com
+2017/12/01, SebastianLng, Sebastian Lang, sebastian.lang@outlook.com
+2017/12/03, oranoran, Oran Epelbaum, oran / epelbaum me
+2017/12/12, janlinde, Jan Lindemann, jan@janware.com
+2017/12/13, enessoylu, Enes Soylu, enessoylutr@gmail.com
+2017/12/20, kbsletten, Kyle Sletten, kbsletten@gmail.com
+2017/12/27, jkmar, Jakub Marciniszyn, marciniszyn.jk@gmail.com
+2018/03/08, dannoc, Daniel Clifford, danno@google.com
+2018/03/10, uvguy, kangjoni76@gmail.com
+2018/01/06, kasbah, Kaspar Emanuel, kaspar@monostable.co.uk
+2018/01/15, xgcssch, Sönke Schau, xgcssch@users.noreply.github.com
+2018/02/08, razfriman, Raz Friman, raz@razfriman.com
+2018/02/11, io7m, Mark Raynsford, code@io7m.com
+2018/04/24, solussd, Joe Smith, joe@uwcreations.com
+2018/15/05, johnvanderholt, jan dillingh johnvanderholte@gmail.com
+2018/06/14, scadgek, Sergey Chupov, scadgek@live.com
+2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com
+2018/06/27, wu-sheng, Wu Sheng, wu.sheng@foxmail.com
+2018/02/25, chaseoxide, Marcus Ong, taccs97[at]gmail[dot]com
+2018/05/15, johnvanderholt, jan dillingh johnvanderholte@gmail.com
+2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com
+2018/05/15, johnvanderholt, jan dillingh johnvanderholte@gmail.com
+2018/05/17, sinopsysHK, Eric Bardes, sinofwd@gmail.com
+2018/05/23, srvance, Stephen Vance, steve@vance.com
+2018/06/14, alecont, Alessandro Contenti, alecontenti@hotmail.com
+2018/06/16, EternalPhane, Zongyuan Zuo, eternalphane@gmail.com
+2018/07/03, jgoppert, James Goppert, james.goppert@gmail.com
+2018/07/27, Maksim Novikov, mnovikov.work@gmail.com
+2018/08/03, ENDOH takanao, djmchl@gmail.com
+2018/10/08, xsIceman, Andreas Skaar, andreas.skaar@gmail.com
+2018/10/18, edirgarcia, Edir García Lazo, edirgl@hotmail.com
+2018/07/31, Lucas Henrqiue, lucashenrique580@gmail.com
+2018/08/03, ENDOH takanao, djmchl@gmail.com
+2018/10/29, chrisaycock, Christopher Aycock, chris[at]chrisaycock[dot]com
+2018/11/12, vinoski, Steve Vinoski, vinoski@ieee.org
+2018/11/14, nxtstep, Adriaan (Arjan) Duz, codewithadriaan[et]gmail[dot]com
+2018/11/15, amykyta3, Alex Mykyta, amykyta3@users.noreply.github.com
+2018/11/29, hannemann-tamas, Ralf Hannemann-Tamas, ralf.ht@gmail.com
+2018/12/20, WalterCouto, Walter Couto, WalterCouto@users.noreply.github.com
+2018/12/23, youkaichao, Kaichao You, youkaichao@gmail.com
+2019/01/01, khoroshilov, Alexey Khoroshilov, khoroshilov@ispras.ru
+2019/01/02, wkhemir, Wail Khemir, khemirwail@gmail.com
+2019/01/16, kuegi, Markus Zancolo, markus.zancolo@roomle.com
+2019/01/29, hc-codersatlas, Harry Chan, harry.chan@codersatlas.com
+2019/02/06, ralucado, Cristina Raluca Vijulie, ralucris.v[at]gmail[dot]com
+2019/02/23, gedimitr, Gerasimos Dimitriadis, gedimitr@gmail.com
+2019/03/13, base698, Justin Thomas, justin.thomas1@gmail.com
+2019/03/18, carlodri, Carlo Dri, carlo.dri@gmail.com
+2019/05/02, askingalot, Andy Collins, askingalot@gmail.com
+2019/05/13, mapio, Massimo Santini, massimo.santini@gmail.com
+2019/07/11, olowo726, Olof Wolgast, olof@baah.se
+2019/07/16, abhijithneilabraham, Abhijith Neil Abraham, abhijithneilabrahampk@gmail.com
+2019/07/26, Braavos96, Eric Hettiaratchi, erichettiaratchi@gmail.com
+2019/08/02, thron7, Thomas Herchenroeder, thron7[at]users[dot]sourceforge[dot]net
+2019/08/12, easonlin404, Eason Lin, easonlin404@gmail.com
+2019/08/23, akaJes, Oleksandr Mamchyts, akaJes@gmail.com
+2019/08/27, wurzelpeter, Markus Franke, markus[hyphen]franke[at]web[dot]de
+2019/09/10, ImanHosseini, Iman Hosseini, hosseini.iman@yahoo.com
+2019/09/03, João Henrique, johnnyonflame@hotmail.com
+2019/09/10, neko1235, Ihar Mokharau, igor.mohorev@gmail.com
+2019/09/10, yar3333, Yaroslav Sivakov, yar3333@gmail.com
+2019/09/10, marcospassos, Marcos Passos, marcospassos.com@gmail.com
+2019/09/10, amorimjuliana, Juliana Amorim, juu.amorim@gmail.com
+2019/09/15, sullis, Sean Sullivan, github@seansullivan.com
+2019/09/17, kaz, Kazuki Sawada, kazuki@6715.jp
+2019/09/28, lmy269, Mingyang Liu, lmy040758@gmail.com
+2019/10/29, tehbone, Tabari Alexander, tehbone@gmail.com
+2019/10/31, a-square, Alexei Averchenko, lex.aver@gmail.com
+2019/11/05, listba, Ben List, ben.list89@gmail.com
+2019/11/11, foxeverl, Liu Xinfeng, liuxf1986[at]gmail[dot]com
+2019/11/17, felixn, Felix Nieuwenhuizhen, felix@tdlrali.com
+2019/11/18, mlilback, Mark Lilback, mark@lilback.com
+2020/01/19, lingyv-li, Lingyu Li, lingyv.li@gmail.com
+2020/02/02, carocad, Camilo Roca, carocad@unal.edu.co
+2020/02/10, rrevenantt, Konstantin Anisimov, rrevenantt[at]gmail.com
+2020/02/10, julibert, Julián Bermúdez Ortega, julibert.dev@gmail.com
+2020/02/17, quantumsheep, Nathanael Demacon, nathanael.dmc@outlook.fr
+2020/02/21, StochasticTinkr, Daniel Pitts, github@coloraura.com
+2020/03/17, XsongyangX, Song Yang, songyang1218@gmail.com
+2020/04/07, deniskyashif, Denis Kyashif, denis.kyashif@gmail.com
+2020/04/08, lwehmeier, Leon Wehmeier, wehmeier@st.ovgu.de
+2020/04/10, agrabski, Adam Grabski, adam.gr@outlook.com
+2020/04/23, martinvw, Martin van Wingerden, martin@martinvw.nl
+2020/04/23, kaczmarj, Jakub Kaczmarzyk, jakub.kaczmarzyk@stonybrookmedicine.edu
+2020/04/30, TristonianJones, Tristan Swadell, tswadell@google.com
+2020/05/06, iammosespaulr, Moses Paul R, iammosespaulr@gmail.com
+2020/05/10, gomerser, Erik Gomersbach, gomerser@gomersba.ch
+2020/05/22, keywan-ghadami-oxid, Keywan Ghadami, keywan.ghadami@oxid-esales.com
+2020/05/25, graknol, Sindre van der Linden, graknol@gmail.com
+2020/05/31, d-markey, David Markey, dmarkey@free.fr
+2020/06/02, cohomology, Kilian Kilger, kkilger AT gmail.com
+2020/06/04, IohannRabeson, Iohann Rabeson, iotaka6@gmail.com
+2020/06/04, sigmasoldi3r, Pablo Blanco, pablobc.1995@gmail.com
+2020/06/15, mattpaletta, Matthew Paletta, mattpaletta@gmail.com
+2020/07/01, sha-N, Shan M Mathews, admin@bluestarqatar.com
+2020/08/22, stevenjohnstone, Steven Johnstone, steven.james.johnstone@gmail.com
+2020/09/06, ArthurSonzogni, Sonzogni Arthur, arthursonzogni@gmail.com
+2020/09/10, Khailian, Arunav Sanyal, arunav.sanyal91@gmail.com
+2020/09/12, Clcanny, Charles Ruan, a837940593@gmail.com
+2020/09/15, rmcgregor1990, Robert McGregor, rmcgregor1990@gmail.com
+2020/09/16, trenki2, Markus Trenkwalder, trenki2[at]gmx[dot]net
+2020/10/08, Marti2203, Martin Mirchev, mirchevmartin2203@gmail.com
+2020/10/16, adarshbhat, Adarsh Bhat, adarshbhat@users.noreply.github.com
+2020/10/20, adamwojs, Adam Wójs, adam[at]wojs.pl
+2020/10/24, cliid, Jiwu Jang, jiwujang@naver.com
+2020/11/05, MichelHartmann, Michel Hartmann, MichelHartmann@users.noreply.github.com
+2020/11/26, mr-c, Michael R. Crusoe, 1330696+mr-c@users.noreply.github.com
+2020/12/01, maxence-lefebvre, Maxence Lefebvre, maxence-lefebvre@users.noreply.github.com
+2020/12/03, electrum, David Phillips, david@acz.org
+2021/01/03, niw, Yoshimasa Niwa, niw@niw.at
+2021/01/25, l215884529, Qiheng Liu, 13607681+l215884529@users.noreply.github.com
+2021/02/02, tsotnikov, Taras Sotnikov, taras.sotnikov@gmail.com
+2021/02/10, jirislaby, Jiri Slaby, jirislaby@gmail.com
+2021/02/21, namasikanam, Xingyu Xie, namasikanam@gmail.com
+2021/02/26, ahooper, Andrew Hooper, ahooper at kos dot net
+2021/02/27, khmarbaise, Karl Heinz Marbaise, github@soebes.com
+2021/02/28, Dante-Broggi, Dante Broggi, 34220985+Dante-Broggi@users.noreply.github.com
+2021/03/02, hackeris
+2021/03/03, xTachyon, Damian Andrei, xTachyon@users.noreply.github.com
+2021/03/22, 100mango, Fangqiu Fang, 100mango@gmail.com
+2021/04/07, b1f6c1c4, Jinzheng Tu, b1f6c1c4@gmail.com
+2021/04/17, jaggerjo, Josua Jäger, mail@jaggerjo.com
+2021/04/24, bigerl, Alexander Bigerl, alexander [äät] bigerl [pkt] eu
+2021/05/02, michalharakal, Michal Harakal, michal.harakal@users.noreply.github.com
+2021/05/03, redexp, Sergii Kliuchnyk, redexp@users.noreply.github.com
+2021/05/03, mitar, Mi Tar, mitar.git@tnode.com
+2021/05/04, joakker, Joaquín León, joaquinandresleon108@gmail.com
+2021/05/06, renancaraujo, Renan C. Araújo, renancaraujo@users.noreply.github.com
+2021/05/06, canastro, Ricardo Canastro, ricardocanastro@users.noreply.github.com
+2021/06/19, abe149, Abe Skolnik, abe 149 at gmail . com
+2021/07/01, appel1, Johan Appelgren, johan.appelgren@gmail.com
+2021/07/01, marcauberer, Marc Auberer, marc.auberer@chillibits.com
+2021/07/14, renzhentaxibaerde, Renzhentaxi Baerde, renzhentaxibaerde@gmail.com
+2021/07/21, skittlepox, Benjamin Spiegel, bspiegel@cs.brown.edu
+2021/07/29, ksyx, Qixing Xue, qixingxue@outlook.com
+2021/07/29, rachidlamouri, Rachid Lamouri, rachidlamouri@gmail.com
+2021/08/02, minjoosur, Minjoo Sur, msur@salesforce.com
+2021/08/05, jjeffcaii, Jeff Tsai, caiweiwei.cww@alibaba-inc.com
+2021/08/08, ansiemens, Yi-Hong Lin, ansiemens@gmail.com
+2021/08/25, XenoAmess, Jin Xu, xenoamess@gmail.com
+2021/09/08, jmcken8, Joel McKenzie, joel.b.mckenzie@gmail.com
+2021/09/23, skalt, Steven Kalt, kalt.steven@gmail.com
+2021/09/26, idraper, Isaac Draper, idraper@byu.edu
+2021/10/10, tools4origins, Erwan Guyomarc'h, contact@erwan-guyomarch.fr
+2021/10/19, jcking, Justin King, jcking@google.com
+2021/10/31, skef, Skef Iterum, github@skef.org
+2021/10/31, hlstwizard, h.l.s.t@163.com
+2021/11/30, bollwyvl, Nick Bollweg, bollwyvl@users.noreply.github.com
+2021/12/03, eneko, Eneko Alonso, eneko.alonso@gmail.com
+2021/12/16, Ketler13, Oleksandr Martyshchenko, oleksandr.martyshchenko@gmail.com
+2021/12/25, Tinker1024, Tinker1024, tinker@huawei.com
+2021/12/31, Biswa96, Biswapriyo Nath, nathbappai@gmail.com
+2022/03/07, chenquan, chenquan, chenquan.dev@gmail.com
+2022/03/15, hzeller, Henner Zeller, h.zeller@acm.org
+2025/05/28, alexsnaps, Alex Snaps, alex@wcgw.dev
+2025/07/09, cyqw, Chen Yong, cyqw@163.com
+
+2025/09/12, torbensen, Torben Magne, torbenmagne@gmail.com
diff --git a/pom.xml b/pom.xml
index 7cf5813dee..f85f7af2a7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,22 +13,26 @@
org.antlr
antlr4-master
- 4.8-2-SNAPSHOT
+ 4.13.3-SNAPSHOT
pom
ANTLR 4
ANTLR 4 Master Build POM
- http://www.antlr.org
+ https://www.antlr.org/
1992
ANTLR
- http://www.antlr.org
+ https://www.antlr.org/
-
+
+ 3.8
+
+
+
- The BSD License
- http://www.antlr.org/license.html
+ BSD-3-Clause
+ https://www.antlr.org/license.html
repo
@@ -36,7 +40,7 @@
Terence Parr
- http://parrt.cs.usfca.edu
+ https://github.com/parrt
Project lead - ANTLR
@@ -63,9 +67,10 @@
Jim Idle
jimi@idle.ws
- http://www.linkedin.com/in/jimidle
+ https://www.linkedin.com/in/jimidle/
Developer - Maven Plugin
+ Developer - Go runtime
@@ -87,17 +92,16 @@
tool
antlr4-maven-plugin
tool-testsuite
- runtime-testsuite/annotations
- runtime-testsuite/processors
runtime-testsuite
UTF-8
UTF-8
+ 1722710576
true
- 1.8
- 1.8
+ 11
+ 11
@@ -113,10 +117,10 @@
- https://github.com/antlr/antlr4/tree/master
+ https://github.com/antlr/antlr4/tree/master
scm:git:git://github.com/antlr/antlr4.git
scm:git:git@github.com:antlr/antlr4.git
- HEAD
+ 4.13.0
@@ -133,7 +137,7 @@
maven-clean-plugin
- 3.0.0
+ 3.1.0
@@ -151,7 +155,7 @@
org.apache.maven.plugins
maven-compiler-plugin
- 3.6.0
+ 3.8.1
${maven.compiler.source}
${maven.compiler.target}
@@ -161,6 +165,16 @@
org.apache.maven.plugins
maven-javadoc-plugin
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.2.2
+
+
+ org.apache.maven.plugins
+ maven-release-plugin
+ 3.0.0-M6
+
diff --git a/runtime-testsuite/annotations/pom.xml b/runtime-testsuite/annotations/pom.xml
deleted file mode 100644
index 97bf786495..0000000000
--- a/runtime-testsuite/annotations/pom.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
- 4.0.0
-
- org.antlr
- antlr4-master
- 4.8-2-SNAPSHOT
- ../../pom.xml
-
- antlr4-runtime-test-annotations
- ANTLR 4 Runtime Test Annotations
- The ANTLR 4 Runtime
-
-
- src
-
-
- org.apache.felix
- maven-bundle-plugin
- 2.5.4
-
-
- bundle-manifest
- process-classes
-
-
- org.antlr.antlr4-runtime-osgi
- ANTLR 4 Runtime
- ANTLR
- org.antlr
- ${project.version}
-
-
-
- manifest
-
-
-
-
-
- maven-jar-plugin
- 2.4
-
-
-
-
diff --git a/runtime-testsuite/annotations/src/org/antlr/v4/test/runtime/CommentHasStringValue.java b/runtime-testsuite/annotations/src/org/antlr/v4/test/runtime/CommentHasStringValue.java
deleted file mode 100644
index 8b48eb1569..0000000000
--- a/runtime-testsuite/annotations/src/org/antlr/v4/test/runtime/CommentHasStringValue.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
- * Use of this file is governed by the BSD 3-clause license that
- * can be found in the LICENSE.txt file in the project root.
- */
-
-package org.antlr.v4.test.runtime;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** This is just a tag that indicates the javadoc comment has a multi-line string */
-@Retention(RetentionPolicy.SOURCE)
-@Target({ElementType.FIELD, ElementType.METHOD})
-@Inherited
-public @interface CommentHasStringValue {
-}
diff --git a/runtime-testsuite/pom.xml b/runtime-testsuite/pom.xml
index ff068e0a3e..d2dfc73189 100644
--- a/runtime-testsuite/pom.xml
+++ b/runtime-testsuite/pom.xml
@@ -10,23 +10,27 @@
org.antlr
antlr4-master
- 4.8-2-SNAPSHOT
+ 4.13.3-SNAPSHOT
antlr4-runtime-testsuite
- ANTLR 4 Runtime Tests (2nd generation)
+ ANTLR 4 Runtime Tests (4th generation)
A collection of tests for ANTLR 4 Runtime libraries.
- 3.0
+ 3.8
2009
+
+ 5.9.0
+
+
org.antlr
ST4
- 4.3
+ 4.3.4
test
@@ -42,89 +46,46 @@
test
- org.antlr
- antlr4-runtime-test-annotations
- ${project.version}
- test
-
-
- org.antlr
- antlr4-runtime-test-annotation-processors
- ${project.version}
- test
-
-
- junit
- junit
- 4.12
+ org.junit.jupiter
+ junit-jupiter-api
+ ${jUnitVersion}
test
- org.seleniumhq.selenium
- selenium-java
- 2.46.0
+ org.junit.jupiter
+ junit-jupiter-engine
+ ${jUnitVersion}
test
-
- org.eclipse.jetty
- jetty-server
-
- 9.4.19.v20190610
- test
-
org.glassfish
javax.json
- 1.0.4
+ 1.1.4
test
org.openjdk.jol
jol-core
- 0.8
+ 0.16
test
-
-
- resources
-
-
- ../runtime
-
- **/.build/**
- **/target/**
- Swift/*.xcodeproj/**
-
-
-
org.apache.maven.plugins
maven-surefire-plugin
- 2.19.1
+ 2.22.0
-Dfile.encoding=UTF-8
-
- **/csharp/Test*.java
- **/java/Test*.java
- **/rust/Test*.java
- **/go/Test*.java
- **/javascript/node/Test*.java
- **/python2/Test*.java
- **/python3/Test*.java
- **/php/Test*.java
- ${antlr.tests.swift}
-
-
+
org.apache.maven.plugins
maven-jar-plugin
- 2.4
+ 3.2.0
@@ -151,20 +112,15 @@
-
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 8
+ 9
+ 9
+
+
+
-
-
-
- includeSwiftTests
-
-
- mac
-
-
-
- **/swift/Test*.java
-
-
-
diff --git a/runtime-testsuite/processors/pom.xml b/runtime-testsuite/processors/pom.xml
deleted file mode 100644
index c417c626d1..0000000000
--- a/runtime-testsuite/processors/pom.xml
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
- 4.0.0
-
- org.antlr
- antlr4-master
- 4.8-2-SNAPSHOT
- ../../pom.xml
-
- antlr4-runtime-test-annotation-processors
- ANTLR 4 Runtime Test Processors
- The ANTLR 4 Runtime
-
-
-
- com.github.olivergondza
- maven-jdk-tools-wrapper
- 0.1
-
-
- org.antlr
- antlr4-runtime-test-annotations
- ${project.version}
-
-
-
-
- src
-
-
- resources
-
-
-
-
- org.apache.maven.plugins
- maven-compiler-plugin
-
- true
- ${maven.compiler.source}
- ${maven.compiler.target}
-
- -proc:none
-
-
-
-
-
-
diff --git a/runtime-testsuite/processors/resources/META-INF/services/javax.annotation.processing.Processor b/runtime-testsuite/processors/resources/META-INF/services/javax.annotation.processing.Processor
deleted file mode 100644
index 95b9a3a03a..0000000000
--- a/runtime-testsuite/processors/resources/META-INF/services/javax.annotation.processing.Processor
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
-# Use of this file is governed by the BSD 3-clause license that
-# can be found in the LICENSE.txt file in the project root.
-#
-
-org.antlr.v4.test.runtime.CommentHasStringValueProcessor
diff --git a/runtime-testsuite/processors/src/org/antlr/v4/test/runtime/CommentHasStringValueProcessor.java b/runtime-testsuite/processors/src/org/antlr/v4/test/runtime/CommentHasStringValueProcessor.java
deleted file mode 100644
index 9c902c01fc..0000000000
--- a/runtime-testsuite/processors/src/org/antlr/v4/test/runtime/CommentHasStringValueProcessor.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
- * Use of this file is governed by the BSD 3-clause license that
- * can be found in the LICENSE.txt file in the project root.
- */
-
-package org.antlr.v4.test.runtime;
-
-import com.sun.tools.javac.model.JavacElements;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.TreeMaker;
-import com.sun.tools.javac.util.List;
-
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.ProcessingEnvironment;
-import javax.annotation.processing.RoundEnvironment;
-import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.annotation.processing.SupportedSourceVersion;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.Element;
-import javax.lang.model.element.TypeElement;
-import java.util.Set;
-
-/**
- I think I figured out how to use annotation processors in maven. It's
- more or less automatic and you don't even need to tell maven, with one minor
- exception. The idea is to create a project for the annotation and another
- for the annotation processor. Then, a project that uses the annotation
- can simply set up the dependency on the other projects. You have to turn
- off processing, -proc:none on the processor project itself but other than
- that, java 6+ more or less tries to apply any processors it finds during
- compilation. maven just works.
-
- Also you need a META-INF/services/javax.annotation.processing.Processor file
- with "org.antlr.v4.test.runtime.CommentHasStringValueProcessor" in it.
- */
-@SupportedAnnotationTypes({"org.antlr.v4.test.runtime.CommentHasStringValue"})
-@SupportedSourceVersion(SourceVersion.RELEASE_7)
-public class CommentHasStringValueProcessor extends AbstractProcessor {
- protected JavacElements utilities;
- protected TreeMaker treeMaker;
-
- @Override
- public synchronized void init(ProcessingEnvironment processingEnv) {
- super.init(processingEnv);
-// Messager messager = processingEnv.getMessager();
-// messager.printMessage(Diagnostic.Kind.NOTE, "WOW INIT--------------------");
- JavacProcessingEnvironment javacProcessingEnv = (JavacProcessingEnvironment) processingEnv;
- utilities = javacProcessingEnv.getElementUtils();
- treeMaker = TreeMaker.instance(javacProcessingEnv.getContext());
- }
-
- @Override
- public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
-// Messager messager = processingEnv.getMessager();
-// messager.printMessage(Diagnostic.Kind.NOTE, "PROCESS--------------------");
- Set extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(CommentHasStringValue.class);
- for (Element annotatedElement : annotatedElements) {
- String docComment = utilities.getDocComment(annotatedElement);
- JCTree.JCLiteral literal = treeMaker.Literal(docComment!=null ? docComment : "");
- JCTree elementTree = utilities.getTree(annotatedElement);
- if ( elementTree instanceof JCTree.JCVariableDecl ) {
- ((JCTree.JCVariableDecl)elementTree).init = literal;
- }
- else if ( elementTree instanceof JCTree.JCMethodDecl ) {
- JCTree.JCStatement[] statements = new JCTree.JCStatement[1];
- statements[0] = treeMaker.Return(literal);
- JCTree.JCBlock body = treeMaker.Block(0, List.from(statements));
- ((JCTree.JCMethodDecl)elementTree).body = body;
- }
- }
- return true;
- }
-
- @Override
- public SourceVersion getSupportedSourceVersion() {
- return SourceVersion.latestSupported();
- }
-}
diff --git a/runtime-testsuite/resources/junit-platform.properties b/runtime-testsuite/resources/junit-platform.properties
new file mode 100644
index 0000000000..ad19ea833b
--- /dev/null
+++ b/runtime-testsuite/resources/junit-platform.properties
@@ -0,0 +1,3 @@
+junit.jupiter.execution.parallel.enabled = true
+junit.jupiter.execution.parallel.mode.default = concurrent
+junit.jupiter.execution.parallel.mode.classes.default = concurrent
\ No newline at end of file
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/LargeLexer.g4 b/runtime-testsuite/resources/org/antlr/v4/test/runtime/LargeLexer.g4
deleted file mode 100644
index 07572dae8e..0000000000
--- a/runtime-testsuite/resources/org/antlr/v4/test/runtime/LargeLexer.g4
+++ /dev/null
@@ -1,4003 +0,0 @@
-/** Has to be in separate file; LexerExec group loads this as resource */
-lexer grammar L;
-WS : [ \t\r\n]+ -> skip;
-KW0 : 'KW' '0';
-KW1 : 'KW' '1';
-KW2 : 'KW' '2';
-KW3 : 'KW' '3';
-KW4 : 'KW' '4';
-KW5 : 'KW' '5';
-KW6 : 'KW' '6';
-KW7 : 'KW' '7';
-KW8 : 'KW' '8';
-KW9 : 'KW' '9';
-KW10 : 'KW' '10';
-KW11 : 'KW' '11';
-KW12 : 'KW' '12';
-KW13 : 'KW' '13';
-KW14 : 'KW' '14';
-KW15 : 'KW' '15';
-KW16 : 'KW' '16';
-KW17 : 'KW' '17';
-KW18 : 'KW' '18';
-KW19 : 'KW' '19';
-KW20 : 'KW' '20';
-KW21 : 'KW' '21';
-KW22 : 'KW' '22';
-KW23 : 'KW' '23';
-KW24 : 'KW' '24';
-KW25 : 'KW' '25';
-KW26 : 'KW' '26';
-KW27 : 'KW' '27';
-KW28 : 'KW' '28';
-KW29 : 'KW' '29';
-KW30 : 'KW' '30';
-KW31 : 'KW' '31';
-KW32 : 'KW' '32';
-KW33 : 'KW' '33';
-KW34 : 'KW' '34';
-KW35 : 'KW' '35';
-KW36 : 'KW' '36';
-KW37 : 'KW' '37';
-KW38 : 'KW' '38';
-KW39 : 'KW' '39';
-KW40 : 'KW' '40';
-KW41 : 'KW' '41';
-KW42 : 'KW' '42';
-KW43 : 'KW' '43';
-KW44 : 'KW' '44';
-KW45 : 'KW' '45';
-KW46 : 'KW' '46';
-KW47 : 'KW' '47';
-KW48 : 'KW' '48';
-KW49 : 'KW' '49';
-KW50 : 'KW' '50';
-KW51 : 'KW' '51';
-KW52 : 'KW' '52';
-KW53 : 'KW' '53';
-KW54 : 'KW' '54';
-KW55 : 'KW' '55';
-KW56 : 'KW' '56';
-KW57 : 'KW' '57';
-KW58 : 'KW' '58';
-KW59 : 'KW' '59';
-KW60 : 'KW' '60';
-KW61 : 'KW' '61';
-KW62 : 'KW' '62';
-KW63 : 'KW' '63';
-KW64 : 'KW' '64';
-KW65 : 'KW' '65';
-KW66 : 'KW' '66';
-KW67 : 'KW' '67';
-KW68 : 'KW' '68';
-KW69 : 'KW' '69';
-KW70 : 'KW' '70';
-KW71 : 'KW' '71';
-KW72 : 'KW' '72';
-KW73 : 'KW' '73';
-KW74 : 'KW' '74';
-KW75 : 'KW' '75';
-KW76 : 'KW' '76';
-KW77 : 'KW' '77';
-KW78 : 'KW' '78';
-KW79 : 'KW' '79';
-KW80 : 'KW' '80';
-KW81 : 'KW' '81';
-KW82 : 'KW' '82';
-KW83 : 'KW' '83';
-KW84 : 'KW' '84';
-KW85 : 'KW' '85';
-KW86 : 'KW' '86';
-KW87 : 'KW' '87';
-KW88 : 'KW' '88';
-KW89 : 'KW' '89';
-KW90 : 'KW' '90';
-KW91 : 'KW' '91';
-KW92 : 'KW' '92';
-KW93 : 'KW' '93';
-KW94 : 'KW' '94';
-KW95 : 'KW' '95';
-KW96 : 'KW' '96';
-KW97 : 'KW' '97';
-KW98 : 'KW' '98';
-KW99 : 'KW' '99';
-KW100 : 'KW' '100';
-KW101 : 'KW' '101';
-KW102 : 'KW' '102';
-KW103 : 'KW' '103';
-KW104 : 'KW' '104';
-KW105 : 'KW' '105';
-KW106 : 'KW' '106';
-KW107 : 'KW' '107';
-KW108 : 'KW' '108';
-KW109 : 'KW' '109';
-KW110 : 'KW' '110';
-KW111 : 'KW' '111';
-KW112 : 'KW' '112';
-KW113 : 'KW' '113';
-KW114 : 'KW' '114';
-KW115 : 'KW' '115';
-KW116 : 'KW' '116';
-KW117 : 'KW' '117';
-KW118 : 'KW' '118';
-KW119 : 'KW' '119';
-KW120 : 'KW' '120';
-KW121 : 'KW' '121';
-KW122 : 'KW' '122';
-KW123 : 'KW' '123';
-KW124 : 'KW' '124';
-KW125 : 'KW' '125';
-KW126 : 'KW' '126';
-KW127 : 'KW' '127';
-KW128 : 'KW' '128';
-KW129 : 'KW' '129';
-KW130 : 'KW' '130';
-KW131 : 'KW' '131';
-KW132 : 'KW' '132';
-KW133 : 'KW' '133';
-KW134 : 'KW' '134';
-KW135 : 'KW' '135';
-KW136 : 'KW' '136';
-KW137 : 'KW' '137';
-KW138 : 'KW' '138';
-KW139 : 'KW' '139';
-KW140 : 'KW' '140';
-KW141 : 'KW' '141';
-KW142 : 'KW' '142';
-KW143 : 'KW' '143';
-KW144 : 'KW' '144';
-KW145 : 'KW' '145';
-KW146 : 'KW' '146';
-KW147 : 'KW' '147';
-KW148 : 'KW' '148';
-KW149 : 'KW' '149';
-KW150 : 'KW' '150';
-KW151 : 'KW' '151';
-KW152 : 'KW' '152';
-KW153 : 'KW' '153';
-KW154 : 'KW' '154';
-KW155 : 'KW' '155';
-KW156 : 'KW' '156';
-KW157 : 'KW' '157';
-KW158 : 'KW' '158';
-KW159 : 'KW' '159';
-KW160 : 'KW' '160';
-KW161 : 'KW' '161';
-KW162 : 'KW' '162';
-KW163 : 'KW' '163';
-KW164 : 'KW' '164';
-KW165 : 'KW' '165';
-KW166 : 'KW' '166';
-KW167 : 'KW' '167';
-KW168 : 'KW' '168';
-KW169 : 'KW' '169';
-KW170 : 'KW' '170';
-KW171 : 'KW' '171';
-KW172 : 'KW' '172';
-KW173 : 'KW' '173';
-KW174 : 'KW' '174';
-KW175 : 'KW' '175';
-KW176 : 'KW' '176';
-KW177 : 'KW' '177';
-KW178 : 'KW' '178';
-KW179 : 'KW' '179';
-KW180 : 'KW' '180';
-KW181 : 'KW' '181';
-KW182 : 'KW' '182';
-KW183 : 'KW' '183';
-KW184 : 'KW' '184';
-KW185 : 'KW' '185';
-KW186 : 'KW' '186';
-KW187 : 'KW' '187';
-KW188 : 'KW' '188';
-KW189 : 'KW' '189';
-KW190 : 'KW' '190';
-KW191 : 'KW' '191';
-KW192 : 'KW' '192';
-KW193 : 'KW' '193';
-KW194 : 'KW' '194';
-KW195 : 'KW' '195';
-KW196 : 'KW' '196';
-KW197 : 'KW' '197';
-KW198 : 'KW' '198';
-KW199 : 'KW' '199';
-KW200 : 'KW' '200';
-KW201 : 'KW' '201';
-KW202 : 'KW' '202';
-KW203 : 'KW' '203';
-KW204 : 'KW' '204';
-KW205 : 'KW' '205';
-KW206 : 'KW' '206';
-KW207 : 'KW' '207';
-KW208 : 'KW' '208';
-KW209 : 'KW' '209';
-KW210 : 'KW' '210';
-KW211 : 'KW' '211';
-KW212 : 'KW' '212';
-KW213 : 'KW' '213';
-KW214 : 'KW' '214';
-KW215 : 'KW' '215';
-KW216 : 'KW' '216';
-KW217 : 'KW' '217';
-KW218 : 'KW' '218';
-KW219 : 'KW' '219';
-KW220 : 'KW' '220';
-KW221 : 'KW' '221';
-KW222 : 'KW' '222';
-KW223 : 'KW' '223';
-KW224 : 'KW' '224';
-KW225 : 'KW' '225';
-KW226 : 'KW' '226';
-KW227 : 'KW' '227';
-KW228 : 'KW' '228';
-KW229 : 'KW' '229';
-KW230 : 'KW' '230';
-KW231 : 'KW' '231';
-KW232 : 'KW' '232';
-KW233 : 'KW' '233';
-KW234 : 'KW' '234';
-KW235 : 'KW' '235';
-KW236 : 'KW' '236';
-KW237 : 'KW' '237';
-KW238 : 'KW' '238';
-KW239 : 'KW' '239';
-KW240 : 'KW' '240';
-KW241 : 'KW' '241';
-KW242 : 'KW' '242';
-KW243 : 'KW' '243';
-KW244 : 'KW' '244';
-KW245 : 'KW' '245';
-KW246 : 'KW' '246';
-KW247 : 'KW' '247';
-KW248 : 'KW' '248';
-KW249 : 'KW' '249';
-KW250 : 'KW' '250';
-KW251 : 'KW' '251';
-KW252 : 'KW' '252';
-KW253 : 'KW' '253';
-KW254 : 'KW' '254';
-KW255 : 'KW' '255';
-KW256 : 'KW' '256';
-KW257 : 'KW' '257';
-KW258 : 'KW' '258';
-KW259 : 'KW' '259';
-KW260 : 'KW' '260';
-KW261 : 'KW' '261';
-KW262 : 'KW' '262';
-KW263 : 'KW' '263';
-KW264 : 'KW' '264';
-KW265 : 'KW' '265';
-KW266 : 'KW' '266';
-KW267 : 'KW' '267';
-KW268 : 'KW' '268';
-KW269 : 'KW' '269';
-KW270 : 'KW' '270';
-KW271 : 'KW' '271';
-KW272 : 'KW' '272';
-KW273 : 'KW' '273';
-KW274 : 'KW' '274';
-KW275 : 'KW' '275';
-KW276 : 'KW' '276';
-KW277 : 'KW' '277';
-KW278 : 'KW' '278';
-KW279 : 'KW' '279';
-KW280 : 'KW' '280';
-KW281 : 'KW' '281';
-KW282 : 'KW' '282';
-KW283 : 'KW' '283';
-KW284 : 'KW' '284';
-KW285 : 'KW' '285';
-KW286 : 'KW' '286';
-KW287 : 'KW' '287';
-KW288 : 'KW' '288';
-KW289 : 'KW' '289';
-KW290 : 'KW' '290';
-KW291 : 'KW' '291';
-KW292 : 'KW' '292';
-KW293 : 'KW' '293';
-KW294 : 'KW' '294';
-KW295 : 'KW' '295';
-KW296 : 'KW' '296';
-KW297 : 'KW' '297';
-KW298 : 'KW' '298';
-KW299 : 'KW' '299';
-KW300 : 'KW' '300';
-KW301 : 'KW' '301';
-KW302 : 'KW' '302';
-KW303 : 'KW' '303';
-KW304 : 'KW' '304';
-KW305 : 'KW' '305';
-KW306 : 'KW' '306';
-KW307 : 'KW' '307';
-KW308 : 'KW' '308';
-KW309 : 'KW' '309';
-KW310 : 'KW' '310';
-KW311 : 'KW' '311';
-KW312 : 'KW' '312';
-KW313 : 'KW' '313';
-KW314 : 'KW' '314';
-KW315 : 'KW' '315';
-KW316 : 'KW' '316';
-KW317 : 'KW' '317';
-KW318 : 'KW' '318';
-KW319 : 'KW' '319';
-KW320 : 'KW' '320';
-KW321 : 'KW' '321';
-KW322 : 'KW' '322';
-KW323 : 'KW' '323';
-KW324 : 'KW' '324';
-KW325 : 'KW' '325';
-KW326 : 'KW' '326';
-KW327 : 'KW' '327';
-KW328 : 'KW' '328';
-KW329 : 'KW' '329';
-KW330 : 'KW' '330';
-KW331 : 'KW' '331';
-KW332 : 'KW' '332';
-KW333 : 'KW' '333';
-KW334 : 'KW' '334';
-KW335 : 'KW' '335';
-KW336 : 'KW' '336';
-KW337 : 'KW' '337';
-KW338 : 'KW' '338';
-KW339 : 'KW' '339';
-KW340 : 'KW' '340';
-KW341 : 'KW' '341';
-KW342 : 'KW' '342';
-KW343 : 'KW' '343';
-KW344 : 'KW' '344';
-KW345 : 'KW' '345';
-KW346 : 'KW' '346';
-KW347 : 'KW' '347';
-KW348 : 'KW' '348';
-KW349 : 'KW' '349';
-KW350 : 'KW' '350';
-KW351 : 'KW' '351';
-KW352 : 'KW' '352';
-KW353 : 'KW' '353';
-KW354 : 'KW' '354';
-KW355 : 'KW' '355';
-KW356 : 'KW' '356';
-KW357 : 'KW' '357';
-KW358 : 'KW' '358';
-KW359 : 'KW' '359';
-KW360 : 'KW' '360';
-KW361 : 'KW' '361';
-KW362 : 'KW' '362';
-KW363 : 'KW' '363';
-KW364 : 'KW' '364';
-KW365 : 'KW' '365';
-KW366 : 'KW' '366';
-KW367 : 'KW' '367';
-KW368 : 'KW' '368';
-KW369 : 'KW' '369';
-KW370 : 'KW' '370';
-KW371 : 'KW' '371';
-KW372 : 'KW' '372';
-KW373 : 'KW' '373';
-KW374 : 'KW' '374';
-KW375 : 'KW' '375';
-KW376 : 'KW' '376';
-KW377 : 'KW' '377';
-KW378 : 'KW' '378';
-KW379 : 'KW' '379';
-KW380 : 'KW' '380';
-KW381 : 'KW' '381';
-KW382 : 'KW' '382';
-KW383 : 'KW' '383';
-KW384 : 'KW' '384';
-KW385 : 'KW' '385';
-KW386 : 'KW' '386';
-KW387 : 'KW' '387';
-KW388 : 'KW' '388';
-KW389 : 'KW' '389';
-KW390 : 'KW' '390';
-KW391 : 'KW' '391';
-KW392 : 'KW' '392';
-KW393 : 'KW' '393';
-KW394 : 'KW' '394';
-KW395 : 'KW' '395';
-KW396 : 'KW' '396';
-KW397 : 'KW' '397';
-KW398 : 'KW' '398';
-KW399 : 'KW' '399';
-KW400 : 'KW' '400';
-KW401 : 'KW' '401';
-KW402 : 'KW' '402';
-KW403 : 'KW' '403';
-KW404 : 'KW' '404';
-KW405 : 'KW' '405';
-KW406 : 'KW' '406';
-KW407 : 'KW' '407';
-KW408 : 'KW' '408';
-KW409 : 'KW' '409';
-KW410 : 'KW' '410';
-KW411 : 'KW' '411';
-KW412 : 'KW' '412';
-KW413 : 'KW' '413';
-KW414 : 'KW' '414';
-KW415 : 'KW' '415';
-KW416 : 'KW' '416';
-KW417 : 'KW' '417';
-KW418 : 'KW' '418';
-KW419 : 'KW' '419';
-KW420 : 'KW' '420';
-KW421 : 'KW' '421';
-KW422 : 'KW' '422';
-KW423 : 'KW' '423';
-KW424 : 'KW' '424';
-KW425 : 'KW' '425';
-KW426 : 'KW' '426';
-KW427 : 'KW' '427';
-KW428 : 'KW' '428';
-KW429 : 'KW' '429';
-KW430 : 'KW' '430';
-KW431 : 'KW' '431';
-KW432 : 'KW' '432';
-KW433 : 'KW' '433';
-KW434 : 'KW' '434';
-KW435 : 'KW' '435';
-KW436 : 'KW' '436';
-KW437 : 'KW' '437';
-KW438 : 'KW' '438';
-KW439 : 'KW' '439';
-KW440 : 'KW' '440';
-KW441 : 'KW' '441';
-KW442 : 'KW' '442';
-KW443 : 'KW' '443';
-KW444 : 'KW' '444';
-KW445 : 'KW' '445';
-KW446 : 'KW' '446';
-KW447 : 'KW' '447';
-KW448 : 'KW' '448';
-KW449 : 'KW' '449';
-KW450 : 'KW' '450';
-KW451 : 'KW' '451';
-KW452 : 'KW' '452';
-KW453 : 'KW' '453';
-KW454 : 'KW' '454';
-KW455 : 'KW' '455';
-KW456 : 'KW' '456';
-KW457 : 'KW' '457';
-KW458 : 'KW' '458';
-KW459 : 'KW' '459';
-KW460 : 'KW' '460';
-KW461 : 'KW' '461';
-KW462 : 'KW' '462';
-KW463 : 'KW' '463';
-KW464 : 'KW' '464';
-KW465 : 'KW' '465';
-KW466 : 'KW' '466';
-KW467 : 'KW' '467';
-KW468 : 'KW' '468';
-KW469 : 'KW' '469';
-KW470 : 'KW' '470';
-KW471 : 'KW' '471';
-KW472 : 'KW' '472';
-KW473 : 'KW' '473';
-KW474 : 'KW' '474';
-KW475 : 'KW' '475';
-KW476 : 'KW' '476';
-KW477 : 'KW' '477';
-KW478 : 'KW' '478';
-KW479 : 'KW' '479';
-KW480 : 'KW' '480';
-KW481 : 'KW' '481';
-KW482 : 'KW' '482';
-KW483 : 'KW' '483';
-KW484 : 'KW' '484';
-KW485 : 'KW' '485';
-KW486 : 'KW' '486';
-KW487 : 'KW' '487';
-KW488 : 'KW' '488';
-KW489 : 'KW' '489';
-KW490 : 'KW' '490';
-KW491 : 'KW' '491';
-KW492 : 'KW' '492';
-KW493 : 'KW' '493';
-KW494 : 'KW' '494';
-KW495 : 'KW' '495';
-KW496 : 'KW' '496';
-KW497 : 'KW' '497';
-KW498 : 'KW' '498';
-KW499 : 'KW' '499';
-KW500 : 'KW' '500';
-KW501 : 'KW' '501';
-KW502 : 'KW' '502';
-KW503 : 'KW' '503';
-KW504 : 'KW' '504';
-KW505 : 'KW' '505';
-KW506 : 'KW' '506';
-KW507 : 'KW' '507';
-KW508 : 'KW' '508';
-KW509 : 'KW' '509';
-KW510 : 'KW' '510';
-KW511 : 'KW' '511';
-KW512 : 'KW' '512';
-KW513 : 'KW' '513';
-KW514 : 'KW' '514';
-KW515 : 'KW' '515';
-KW516 : 'KW' '516';
-KW517 : 'KW' '517';
-KW518 : 'KW' '518';
-KW519 : 'KW' '519';
-KW520 : 'KW' '520';
-KW521 : 'KW' '521';
-KW522 : 'KW' '522';
-KW523 : 'KW' '523';
-KW524 : 'KW' '524';
-KW525 : 'KW' '525';
-KW526 : 'KW' '526';
-KW527 : 'KW' '527';
-KW528 : 'KW' '528';
-KW529 : 'KW' '529';
-KW530 : 'KW' '530';
-KW531 : 'KW' '531';
-KW532 : 'KW' '532';
-KW533 : 'KW' '533';
-KW534 : 'KW' '534';
-KW535 : 'KW' '535';
-KW536 : 'KW' '536';
-KW537 : 'KW' '537';
-KW538 : 'KW' '538';
-KW539 : 'KW' '539';
-KW540 : 'KW' '540';
-KW541 : 'KW' '541';
-KW542 : 'KW' '542';
-KW543 : 'KW' '543';
-KW544 : 'KW' '544';
-KW545 : 'KW' '545';
-KW546 : 'KW' '546';
-KW547 : 'KW' '547';
-KW548 : 'KW' '548';
-KW549 : 'KW' '549';
-KW550 : 'KW' '550';
-KW551 : 'KW' '551';
-KW552 : 'KW' '552';
-KW553 : 'KW' '553';
-KW554 : 'KW' '554';
-KW555 : 'KW' '555';
-KW556 : 'KW' '556';
-KW557 : 'KW' '557';
-KW558 : 'KW' '558';
-KW559 : 'KW' '559';
-KW560 : 'KW' '560';
-KW561 : 'KW' '561';
-KW562 : 'KW' '562';
-KW563 : 'KW' '563';
-KW564 : 'KW' '564';
-KW565 : 'KW' '565';
-KW566 : 'KW' '566';
-KW567 : 'KW' '567';
-KW568 : 'KW' '568';
-KW569 : 'KW' '569';
-KW570 : 'KW' '570';
-KW571 : 'KW' '571';
-KW572 : 'KW' '572';
-KW573 : 'KW' '573';
-KW574 : 'KW' '574';
-KW575 : 'KW' '575';
-KW576 : 'KW' '576';
-KW577 : 'KW' '577';
-KW578 : 'KW' '578';
-KW579 : 'KW' '579';
-KW580 : 'KW' '580';
-KW581 : 'KW' '581';
-KW582 : 'KW' '582';
-KW583 : 'KW' '583';
-KW584 : 'KW' '584';
-KW585 : 'KW' '585';
-KW586 : 'KW' '586';
-KW587 : 'KW' '587';
-KW588 : 'KW' '588';
-KW589 : 'KW' '589';
-KW590 : 'KW' '590';
-KW591 : 'KW' '591';
-KW592 : 'KW' '592';
-KW593 : 'KW' '593';
-KW594 : 'KW' '594';
-KW595 : 'KW' '595';
-KW596 : 'KW' '596';
-KW597 : 'KW' '597';
-KW598 : 'KW' '598';
-KW599 : 'KW' '599';
-KW600 : 'KW' '600';
-KW601 : 'KW' '601';
-KW602 : 'KW' '602';
-KW603 : 'KW' '603';
-KW604 : 'KW' '604';
-KW605 : 'KW' '605';
-KW606 : 'KW' '606';
-KW607 : 'KW' '607';
-KW608 : 'KW' '608';
-KW609 : 'KW' '609';
-KW610 : 'KW' '610';
-KW611 : 'KW' '611';
-KW612 : 'KW' '612';
-KW613 : 'KW' '613';
-KW614 : 'KW' '614';
-KW615 : 'KW' '615';
-KW616 : 'KW' '616';
-KW617 : 'KW' '617';
-KW618 : 'KW' '618';
-KW619 : 'KW' '619';
-KW620 : 'KW' '620';
-KW621 : 'KW' '621';
-KW622 : 'KW' '622';
-KW623 : 'KW' '623';
-KW624 : 'KW' '624';
-KW625 : 'KW' '625';
-KW626 : 'KW' '626';
-KW627 : 'KW' '627';
-KW628 : 'KW' '628';
-KW629 : 'KW' '629';
-KW630 : 'KW' '630';
-KW631 : 'KW' '631';
-KW632 : 'KW' '632';
-KW633 : 'KW' '633';
-KW634 : 'KW' '634';
-KW635 : 'KW' '635';
-KW636 : 'KW' '636';
-KW637 : 'KW' '637';
-KW638 : 'KW' '638';
-KW639 : 'KW' '639';
-KW640 : 'KW' '640';
-KW641 : 'KW' '641';
-KW642 : 'KW' '642';
-KW643 : 'KW' '643';
-KW644 : 'KW' '644';
-KW645 : 'KW' '645';
-KW646 : 'KW' '646';
-KW647 : 'KW' '647';
-KW648 : 'KW' '648';
-KW649 : 'KW' '649';
-KW650 : 'KW' '650';
-KW651 : 'KW' '651';
-KW652 : 'KW' '652';
-KW653 : 'KW' '653';
-KW654 : 'KW' '654';
-KW655 : 'KW' '655';
-KW656 : 'KW' '656';
-KW657 : 'KW' '657';
-KW658 : 'KW' '658';
-KW659 : 'KW' '659';
-KW660 : 'KW' '660';
-KW661 : 'KW' '661';
-KW662 : 'KW' '662';
-KW663 : 'KW' '663';
-KW664 : 'KW' '664';
-KW665 : 'KW' '665';
-KW666 : 'KW' '666';
-KW667 : 'KW' '667';
-KW668 : 'KW' '668';
-KW669 : 'KW' '669';
-KW670 : 'KW' '670';
-KW671 : 'KW' '671';
-KW672 : 'KW' '672';
-KW673 : 'KW' '673';
-KW674 : 'KW' '674';
-KW675 : 'KW' '675';
-KW676 : 'KW' '676';
-KW677 : 'KW' '677';
-KW678 : 'KW' '678';
-KW679 : 'KW' '679';
-KW680 : 'KW' '680';
-KW681 : 'KW' '681';
-KW682 : 'KW' '682';
-KW683 : 'KW' '683';
-KW684 : 'KW' '684';
-KW685 : 'KW' '685';
-KW686 : 'KW' '686';
-KW687 : 'KW' '687';
-KW688 : 'KW' '688';
-KW689 : 'KW' '689';
-KW690 : 'KW' '690';
-KW691 : 'KW' '691';
-KW692 : 'KW' '692';
-KW693 : 'KW' '693';
-KW694 : 'KW' '694';
-KW695 : 'KW' '695';
-KW696 : 'KW' '696';
-KW697 : 'KW' '697';
-KW698 : 'KW' '698';
-KW699 : 'KW' '699';
-KW700 : 'KW' '700';
-KW701 : 'KW' '701';
-KW702 : 'KW' '702';
-KW703 : 'KW' '703';
-KW704 : 'KW' '704';
-KW705 : 'KW' '705';
-KW706 : 'KW' '706';
-KW707 : 'KW' '707';
-KW708 : 'KW' '708';
-KW709 : 'KW' '709';
-KW710 : 'KW' '710';
-KW711 : 'KW' '711';
-KW712 : 'KW' '712';
-KW713 : 'KW' '713';
-KW714 : 'KW' '714';
-KW715 : 'KW' '715';
-KW716 : 'KW' '716';
-KW717 : 'KW' '717';
-KW718 : 'KW' '718';
-KW719 : 'KW' '719';
-KW720 : 'KW' '720';
-KW721 : 'KW' '721';
-KW722 : 'KW' '722';
-KW723 : 'KW' '723';
-KW724 : 'KW' '724';
-KW725 : 'KW' '725';
-KW726 : 'KW' '726';
-KW727 : 'KW' '727';
-KW728 : 'KW' '728';
-KW729 : 'KW' '729';
-KW730 : 'KW' '730';
-KW731 : 'KW' '731';
-KW732 : 'KW' '732';
-KW733 : 'KW' '733';
-KW734 : 'KW' '734';
-KW735 : 'KW' '735';
-KW736 : 'KW' '736';
-KW737 : 'KW' '737';
-KW738 : 'KW' '738';
-KW739 : 'KW' '739';
-KW740 : 'KW' '740';
-KW741 : 'KW' '741';
-KW742 : 'KW' '742';
-KW743 : 'KW' '743';
-KW744 : 'KW' '744';
-KW745 : 'KW' '745';
-KW746 : 'KW' '746';
-KW747 : 'KW' '747';
-KW748 : 'KW' '748';
-KW749 : 'KW' '749';
-KW750 : 'KW' '750';
-KW751 : 'KW' '751';
-KW752 : 'KW' '752';
-KW753 : 'KW' '753';
-KW754 : 'KW' '754';
-KW755 : 'KW' '755';
-KW756 : 'KW' '756';
-KW757 : 'KW' '757';
-KW758 : 'KW' '758';
-KW759 : 'KW' '759';
-KW760 : 'KW' '760';
-KW761 : 'KW' '761';
-KW762 : 'KW' '762';
-KW763 : 'KW' '763';
-KW764 : 'KW' '764';
-KW765 : 'KW' '765';
-KW766 : 'KW' '766';
-KW767 : 'KW' '767';
-KW768 : 'KW' '768';
-KW769 : 'KW' '769';
-KW770 : 'KW' '770';
-KW771 : 'KW' '771';
-KW772 : 'KW' '772';
-KW773 : 'KW' '773';
-KW774 : 'KW' '774';
-KW775 : 'KW' '775';
-KW776 : 'KW' '776';
-KW777 : 'KW' '777';
-KW778 : 'KW' '778';
-KW779 : 'KW' '779';
-KW780 : 'KW' '780';
-KW781 : 'KW' '781';
-KW782 : 'KW' '782';
-KW783 : 'KW' '783';
-KW784 : 'KW' '784';
-KW785 : 'KW' '785';
-KW786 : 'KW' '786';
-KW787 : 'KW' '787';
-KW788 : 'KW' '788';
-KW789 : 'KW' '789';
-KW790 : 'KW' '790';
-KW791 : 'KW' '791';
-KW792 : 'KW' '792';
-KW793 : 'KW' '793';
-KW794 : 'KW' '794';
-KW795 : 'KW' '795';
-KW796 : 'KW' '796';
-KW797 : 'KW' '797';
-KW798 : 'KW' '798';
-KW799 : 'KW' '799';
-KW800 : 'KW' '800';
-KW801 : 'KW' '801';
-KW802 : 'KW' '802';
-KW803 : 'KW' '803';
-KW804 : 'KW' '804';
-KW805 : 'KW' '805';
-KW806 : 'KW' '806';
-KW807 : 'KW' '807';
-KW808 : 'KW' '808';
-KW809 : 'KW' '809';
-KW810 : 'KW' '810';
-KW811 : 'KW' '811';
-KW812 : 'KW' '812';
-KW813 : 'KW' '813';
-KW814 : 'KW' '814';
-KW815 : 'KW' '815';
-KW816 : 'KW' '816';
-KW817 : 'KW' '817';
-KW818 : 'KW' '818';
-KW819 : 'KW' '819';
-KW820 : 'KW' '820';
-KW821 : 'KW' '821';
-KW822 : 'KW' '822';
-KW823 : 'KW' '823';
-KW824 : 'KW' '824';
-KW825 : 'KW' '825';
-KW826 : 'KW' '826';
-KW827 : 'KW' '827';
-KW828 : 'KW' '828';
-KW829 : 'KW' '829';
-KW830 : 'KW' '830';
-KW831 : 'KW' '831';
-KW832 : 'KW' '832';
-KW833 : 'KW' '833';
-KW834 : 'KW' '834';
-KW835 : 'KW' '835';
-KW836 : 'KW' '836';
-KW837 : 'KW' '837';
-KW838 : 'KW' '838';
-KW839 : 'KW' '839';
-KW840 : 'KW' '840';
-KW841 : 'KW' '841';
-KW842 : 'KW' '842';
-KW843 : 'KW' '843';
-KW844 : 'KW' '844';
-KW845 : 'KW' '845';
-KW846 : 'KW' '846';
-KW847 : 'KW' '847';
-KW848 : 'KW' '848';
-KW849 : 'KW' '849';
-KW850 : 'KW' '850';
-KW851 : 'KW' '851';
-KW852 : 'KW' '852';
-KW853 : 'KW' '853';
-KW854 : 'KW' '854';
-KW855 : 'KW' '855';
-KW856 : 'KW' '856';
-KW857 : 'KW' '857';
-KW858 : 'KW' '858';
-KW859 : 'KW' '859';
-KW860 : 'KW' '860';
-KW861 : 'KW' '861';
-KW862 : 'KW' '862';
-KW863 : 'KW' '863';
-KW864 : 'KW' '864';
-KW865 : 'KW' '865';
-KW866 : 'KW' '866';
-KW867 : 'KW' '867';
-KW868 : 'KW' '868';
-KW869 : 'KW' '869';
-KW870 : 'KW' '870';
-KW871 : 'KW' '871';
-KW872 : 'KW' '872';
-KW873 : 'KW' '873';
-KW874 : 'KW' '874';
-KW875 : 'KW' '875';
-KW876 : 'KW' '876';
-KW877 : 'KW' '877';
-KW878 : 'KW' '878';
-KW879 : 'KW' '879';
-KW880 : 'KW' '880';
-KW881 : 'KW' '881';
-KW882 : 'KW' '882';
-KW883 : 'KW' '883';
-KW884 : 'KW' '884';
-KW885 : 'KW' '885';
-KW886 : 'KW' '886';
-KW887 : 'KW' '887';
-KW888 : 'KW' '888';
-KW889 : 'KW' '889';
-KW890 : 'KW' '890';
-KW891 : 'KW' '891';
-KW892 : 'KW' '892';
-KW893 : 'KW' '893';
-KW894 : 'KW' '894';
-KW895 : 'KW' '895';
-KW896 : 'KW' '896';
-KW897 : 'KW' '897';
-KW898 : 'KW' '898';
-KW899 : 'KW' '899';
-KW900 : 'KW' '900';
-KW901 : 'KW' '901';
-KW902 : 'KW' '902';
-KW903 : 'KW' '903';
-KW904 : 'KW' '904';
-KW905 : 'KW' '905';
-KW906 : 'KW' '906';
-KW907 : 'KW' '907';
-KW908 : 'KW' '908';
-KW909 : 'KW' '909';
-KW910 : 'KW' '910';
-KW911 : 'KW' '911';
-KW912 : 'KW' '912';
-KW913 : 'KW' '913';
-KW914 : 'KW' '914';
-KW915 : 'KW' '915';
-KW916 : 'KW' '916';
-KW917 : 'KW' '917';
-KW918 : 'KW' '918';
-KW919 : 'KW' '919';
-KW920 : 'KW' '920';
-KW921 : 'KW' '921';
-KW922 : 'KW' '922';
-KW923 : 'KW' '923';
-KW924 : 'KW' '924';
-KW925 : 'KW' '925';
-KW926 : 'KW' '926';
-KW927 : 'KW' '927';
-KW928 : 'KW' '928';
-KW929 : 'KW' '929';
-KW930 : 'KW' '930';
-KW931 : 'KW' '931';
-KW932 : 'KW' '932';
-KW933 : 'KW' '933';
-KW934 : 'KW' '934';
-KW935 : 'KW' '935';
-KW936 : 'KW' '936';
-KW937 : 'KW' '937';
-KW938 : 'KW' '938';
-KW939 : 'KW' '939';
-KW940 : 'KW' '940';
-KW941 : 'KW' '941';
-KW942 : 'KW' '942';
-KW943 : 'KW' '943';
-KW944 : 'KW' '944';
-KW945 : 'KW' '945';
-KW946 : 'KW' '946';
-KW947 : 'KW' '947';
-KW948 : 'KW' '948';
-KW949 : 'KW' '949';
-KW950 : 'KW' '950';
-KW951 : 'KW' '951';
-KW952 : 'KW' '952';
-KW953 : 'KW' '953';
-KW954 : 'KW' '954';
-KW955 : 'KW' '955';
-KW956 : 'KW' '956';
-KW957 : 'KW' '957';
-KW958 : 'KW' '958';
-KW959 : 'KW' '959';
-KW960 : 'KW' '960';
-KW961 : 'KW' '961';
-KW962 : 'KW' '962';
-KW963 : 'KW' '963';
-KW964 : 'KW' '964';
-KW965 : 'KW' '965';
-KW966 : 'KW' '966';
-KW967 : 'KW' '967';
-KW968 : 'KW' '968';
-KW969 : 'KW' '969';
-KW970 : 'KW' '970';
-KW971 : 'KW' '971';
-KW972 : 'KW' '972';
-KW973 : 'KW' '973';
-KW974 : 'KW' '974';
-KW975 : 'KW' '975';
-KW976 : 'KW' '976';
-KW977 : 'KW' '977';
-KW978 : 'KW' '978';
-KW979 : 'KW' '979';
-KW980 : 'KW' '980';
-KW981 : 'KW' '981';
-KW982 : 'KW' '982';
-KW983 : 'KW' '983';
-KW984 : 'KW' '984';
-KW985 : 'KW' '985';
-KW986 : 'KW' '986';
-KW987 : 'KW' '987';
-KW988 : 'KW' '988';
-KW989 : 'KW' '989';
-KW990 : 'KW' '990';
-KW991 : 'KW' '991';
-KW992 : 'KW' '992';
-KW993 : 'KW' '993';
-KW994 : 'KW' '994';
-KW995 : 'KW' '995';
-KW996 : 'KW' '996';
-KW997 : 'KW' '997';
-KW998 : 'KW' '998';
-KW999 : 'KW' '999';
-KW1000 : 'KW' '1000';
-KW1001 : 'KW' '1001';
-KW1002 : 'KW' '1002';
-KW1003 : 'KW' '1003';
-KW1004 : 'KW' '1004';
-KW1005 : 'KW' '1005';
-KW1006 : 'KW' '1006';
-KW1007 : 'KW' '1007';
-KW1008 : 'KW' '1008';
-KW1009 : 'KW' '1009';
-KW1010 : 'KW' '1010';
-KW1011 : 'KW' '1011';
-KW1012 : 'KW' '1012';
-KW1013 : 'KW' '1013';
-KW1014 : 'KW' '1014';
-KW1015 : 'KW' '1015';
-KW1016 : 'KW' '1016';
-KW1017 : 'KW' '1017';
-KW1018 : 'KW' '1018';
-KW1019 : 'KW' '1019';
-KW1020 : 'KW' '1020';
-KW1021 : 'KW' '1021';
-KW1022 : 'KW' '1022';
-KW1023 : 'KW' '1023';
-KW1024 : 'KW' '1024';
-KW1025 : 'KW' '1025';
-KW1026 : 'KW' '1026';
-KW1027 : 'KW' '1027';
-KW1028 : 'KW' '1028';
-KW1029 : 'KW' '1029';
-KW1030 : 'KW' '1030';
-KW1031 : 'KW' '1031';
-KW1032 : 'KW' '1032';
-KW1033 : 'KW' '1033';
-KW1034 : 'KW' '1034';
-KW1035 : 'KW' '1035';
-KW1036 : 'KW' '1036';
-KW1037 : 'KW' '1037';
-KW1038 : 'KW' '1038';
-KW1039 : 'KW' '1039';
-KW1040 : 'KW' '1040';
-KW1041 : 'KW' '1041';
-KW1042 : 'KW' '1042';
-KW1043 : 'KW' '1043';
-KW1044 : 'KW' '1044';
-KW1045 : 'KW' '1045';
-KW1046 : 'KW' '1046';
-KW1047 : 'KW' '1047';
-KW1048 : 'KW' '1048';
-KW1049 : 'KW' '1049';
-KW1050 : 'KW' '1050';
-KW1051 : 'KW' '1051';
-KW1052 : 'KW' '1052';
-KW1053 : 'KW' '1053';
-KW1054 : 'KW' '1054';
-KW1055 : 'KW' '1055';
-KW1056 : 'KW' '1056';
-KW1057 : 'KW' '1057';
-KW1058 : 'KW' '1058';
-KW1059 : 'KW' '1059';
-KW1060 : 'KW' '1060';
-KW1061 : 'KW' '1061';
-KW1062 : 'KW' '1062';
-KW1063 : 'KW' '1063';
-KW1064 : 'KW' '1064';
-KW1065 : 'KW' '1065';
-KW1066 : 'KW' '1066';
-KW1067 : 'KW' '1067';
-KW1068 : 'KW' '1068';
-KW1069 : 'KW' '1069';
-KW1070 : 'KW' '1070';
-KW1071 : 'KW' '1071';
-KW1072 : 'KW' '1072';
-KW1073 : 'KW' '1073';
-KW1074 : 'KW' '1074';
-KW1075 : 'KW' '1075';
-KW1076 : 'KW' '1076';
-KW1077 : 'KW' '1077';
-KW1078 : 'KW' '1078';
-KW1079 : 'KW' '1079';
-KW1080 : 'KW' '1080';
-KW1081 : 'KW' '1081';
-KW1082 : 'KW' '1082';
-KW1083 : 'KW' '1083';
-KW1084 : 'KW' '1084';
-KW1085 : 'KW' '1085';
-KW1086 : 'KW' '1086';
-KW1087 : 'KW' '1087';
-KW1088 : 'KW' '1088';
-KW1089 : 'KW' '1089';
-KW1090 : 'KW' '1090';
-KW1091 : 'KW' '1091';
-KW1092 : 'KW' '1092';
-KW1093 : 'KW' '1093';
-KW1094 : 'KW' '1094';
-KW1095 : 'KW' '1095';
-KW1096 : 'KW' '1096';
-KW1097 : 'KW' '1097';
-KW1098 : 'KW' '1098';
-KW1099 : 'KW' '1099';
-KW1100 : 'KW' '1100';
-KW1101 : 'KW' '1101';
-KW1102 : 'KW' '1102';
-KW1103 : 'KW' '1103';
-KW1104 : 'KW' '1104';
-KW1105 : 'KW' '1105';
-KW1106 : 'KW' '1106';
-KW1107 : 'KW' '1107';
-KW1108 : 'KW' '1108';
-KW1109 : 'KW' '1109';
-KW1110 : 'KW' '1110';
-KW1111 : 'KW' '1111';
-KW1112 : 'KW' '1112';
-KW1113 : 'KW' '1113';
-KW1114 : 'KW' '1114';
-KW1115 : 'KW' '1115';
-KW1116 : 'KW' '1116';
-KW1117 : 'KW' '1117';
-KW1118 : 'KW' '1118';
-KW1119 : 'KW' '1119';
-KW1120 : 'KW' '1120';
-KW1121 : 'KW' '1121';
-KW1122 : 'KW' '1122';
-KW1123 : 'KW' '1123';
-KW1124 : 'KW' '1124';
-KW1125 : 'KW' '1125';
-KW1126 : 'KW' '1126';
-KW1127 : 'KW' '1127';
-KW1128 : 'KW' '1128';
-KW1129 : 'KW' '1129';
-KW1130 : 'KW' '1130';
-KW1131 : 'KW' '1131';
-KW1132 : 'KW' '1132';
-KW1133 : 'KW' '1133';
-KW1134 : 'KW' '1134';
-KW1135 : 'KW' '1135';
-KW1136 : 'KW' '1136';
-KW1137 : 'KW' '1137';
-KW1138 : 'KW' '1138';
-KW1139 : 'KW' '1139';
-KW1140 : 'KW' '1140';
-KW1141 : 'KW' '1141';
-KW1142 : 'KW' '1142';
-KW1143 : 'KW' '1143';
-KW1144 : 'KW' '1144';
-KW1145 : 'KW' '1145';
-KW1146 : 'KW' '1146';
-KW1147 : 'KW' '1147';
-KW1148 : 'KW' '1148';
-KW1149 : 'KW' '1149';
-KW1150 : 'KW' '1150';
-KW1151 : 'KW' '1151';
-KW1152 : 'KW' '1152';
-KW1153 : 'KW' '1153';
-KW1154 : 'KW' '1154';
-KW1155 : 'KW' '1155';
-KW1156 : 'KW' '1156';
-KW1157 : 'KW' '1157';
-KW1158 : 'KW' '1158';
-KW1159 : 'KW' '1159';
-KW1160 : 'KW' '1160';
-KW1161 : 'KW' '1161';
-KW1162 : 'KW' '1162';
-KW1163 : 'KW' '1163';
-KW1164 : 'KW' '1164';
-KW1165 : 'KW' '1165';
-KW1166 : 'KW' '1166';
-KW1167 : 'KW' '1167';
-KW1168 : 'KW' '1168';
-KW1169 : 'KW' '1169';
-KW1170 : 'KW' '1170';
-KW1171 : 'KW' '1171';
-KW1172 : 'KW' '1172';
-KW1173 : 'KW' '1173';
-KW1174 : 'KW' '1174';
-KW1175 : 'KW' '1175';
-KW1176 : 'KW' '1176';
-KW1177 : 'KW' '1177';
-KW1178 : 'KW' '1178';
-KW1179 : 'KW' '1179';
-KW1180 : 'KW' '1180';
-KW1181 : 'KW' '1181';
-KW1182 : 'KW' '1182';
-KW1183 : 'KW' '1183';
-KW1184 : 'KW' '1184';
-KW1185 : 'KW' '1185';
-KW1186 : 'KW' '1186';
-KW1187 : 'KW' '1187';
-KW1188 : 'KW' '1188';
-KW1189 : 'KW' '1189';
-KW1190 : 'KW' '1190';
-KW1191 : 'KW' '1191';
-KW1192 : 'KW' '1192';
-KW1193 : 'KW' '1193';
-KW1194 : 'KW' '1194';
-KW1195 : 'KW' '1195';
-KW1196 : 'KW' '1196';
-KW1197 : 'KW' '1197';
-KW1198 : 'KW' '1198';
-KW1199 : 'KW' '1199';
-KW1200 : 'KW' '1200';
-KW1201 : 'KW' '1201';
-KW1202 : 'KW' '1202';
-KW1203 : 'KW' '1203';
-KW1204 : 'KW' '1204';
-KW1205 : 'KW' '1205';
-KW1206 : 'KW' '1206';
-KW1207 : 'KW' '1207';
-KW1208 : 'KW' '1208';
-KW1209 : 'KW' '1209';
-KW1210 : 'KW' '1210';
-KW1211 : 'KW' '1211';
-KW1212 : 'KW' '1212';
-KW1213 : 'KW' '1213';
-KW1214 : 'KW' '1214';
-KW1215 : 'KW' '1215';
-KW1216 : 'KW' '1216';
-KW1217 : 'KW' '1217';
-KW1218 : 'KW' '1218';
-KW1219 : 'KW' '1219';
-KW1220 : 'KW' '1220';
-KW1221 : 'KW' '1221';
-KW1222 : 'KW' '1222';
-KW1223 : 'KW' '1223';
-KW1224 : 'KW' '1224';
-KW1225 : 'KW' '1225';
-KW1226 : 'KW' '1226';
-KW1227 : 'KW' '1227';
-KW1228 : 'KW' '1228';
-KW1229 : 'KW' '1229';
-KW1230 : 'KW' '1230';
-KW1231 : 'KW' '1231';
-KW1232 : 'KW' '1232';
-KW1233 : 'KW' '1233';
-KW1234 : 'KW' '1234';
-KW1235 : 'KW' '1235';
-KW1236 : 'KW' '1236';
-KW1237 : 'KW' '1237';
-KW1238 : 'KW' '1238';
-KW1239 : 'KW' '1239';
-KW1240 : 'KW' '1240';
-KW1241 : 'KW' '1241';
-KW1242 : 'KW' '1242';
-KW1243 : 'KW' '1243';
-KW1244 : 'KW' '1244';
-KW1245 : 'KW' '1245';
-KW1246 : 'KW' '1246';
-KW1247 : 'KW' '1247';
-KW1248 : 'KW' '1248';
-KW1249 : 'KW' '1249';
-KW1250 : 'KW' '1250';
-KW1251 : 'KW' '1251';
-KW1252 : 'KW' '1252';
-KW1253 : 'KW' '1253';
-KW1254 : 'KW' '1254';
-KW1255 : 'KW' '1255';
-KW1256 : 'KW' '1256';
-KW1257 : 'KW' '1257';
-KW1258 : 'KW' '1258';
-KW1259 : 'KW' '1259';
-KW1260 : 'KW' '1260';
-KW1261 : 'KW' '1261';
-KW1262 : 'KW' '1262';
-KW1263 : 'KW' '1263';
-KW1264 : 'KW' '1264';
-KW1265 : 'KW' '1265';
-KW1266 : 'KW' '1266';
-KW1267 : 'KW' '1267';
-KW1268 : 'KW' '1268';
-KW1269 : 'KW' '1269';
-KW1270 : 'KW' '1270';
-KW1271 : 'KW' '1271';
-KW1272 : 'KW' '1272';
-KW1273 : 'KW' '1273';
-KW1274 : 'KW' '1274';
-KW1275 : 'KW' '1275';
-KW1276 : 'KW' '1276';
-KW1277 : 'KW' '1277';
-KW1278 : 'KW' '1278';
-KW1279 : 'KW' '1279';
-KW1280 : 'KW' '1280';
-KW1281 : 'KW' '1281';
-KW1282 : 'KW' '1282';
-KW1283 : 'KW' '1283';
-KW1284 : 'KW' '1284';
-KW1285 : 'KW' '1285';
-KW1286 : 'KW' '1286';
-KW1287 : 'KW' '1287';
-KW1288 : 'KW' '1288';
-KW1289 : 'KW' '1289';
-KW1290 : 'KW' '1290';
-KW1291 : 'KW' '1291';
-KW1292 : 'KW' '1292';
-KW1293 : 'KW' '1293';
-KW1294 : 'KW' '1294';
-KW1295 : 'KW' '1295';
-KW1296 : 'KW' '1296';
-KW1297 : 'KW' '1297';
-KW1298 : 'KW' '1298';
-KW1299 : 'KW' '1299';
-KW1300 : 'KW' '1300';
-KW1301 : 'KW' '1301';
-KW1302 : 'KW' '1302';
-KW1303 : 'KW' '1303';
-KW1304 : 'KW' '1304';
-KW1305 : 'KW' '1305';
-KW1306 : 'KW' '1306';
-KW1307 : 'KW' '1307';
-KW1308 : 'KW' '1308';
-KW1309 : 'KW' '1309';
-KW1310 : 'KW' '1310';
-KW1311 : 'KW' '1311';
-KW1312 : 'KW' '1312';
-KW1313 : 'KW' '1313';
-KW1314 : 'KW' '1314';
-KW1315 : 'KW' '1315';
-KW1316 : 'KW' '1316';
-KW1317 : 'KW' '1317';
-KW1318 : 'KW' '1318';
-KW1319 : 'KW' '1319';
-KW1320 : 'KW' '1320';
-KW1321 : 'KW' '1321';
-KW1322 : 'KW' '1322';
-KW1323 : 'KW' '1323';
-KW1324 : 'KW' '1324';
-KW1325 : 'KW' '1325';
-KW1326 : 'KW' '1326';
-KW1327 : 'KW' '1327';
-KW1328 : 'KW' '1328';
-KW1329 : 'KW' '1329';
-KW1330 : 'KW' '1330';
-KW1331 : 'KW' '1331';
-KW1332 : 'KW' '1332';
-KW1333 : 'KW' '1333';
-KW1334 : 'KW' '1334';
-KW1335 : 'KW' '1335';
-KW1336 : 'KW' '1336';
-KW1337 : 'KW' '1337';
-KW1338 : 'KW' '1338';
-KW1339 : 'KW' '1339';
-KW1340 : 'KW' '1340';
-KW1341 : 'KW' '1341';
-KW1342 : 'KW' '1342';
-KW1343 : 'KW' '1343';
-KW1344 : 'KW' '1344';
-KW1345 : 'KW' '1345';
-KW1346 : 'KW' '1346';
-KW1347 : 'KW' '1347';
-KW1348 : 'KW' '1348';
-KW1349 : 'KW' '1349';
-KW1350 : 'KW' '1350';
-KW1351 : 'KW' '1351';
-KW1352 : 'KW' '1352';
-KW1353 : 'KW' '1353';
-KW1354 : 'KW' '1354';
-KW1355 : 'KW' '1355';
-KW1356 : 'KW' '1356';
-KW1357 : 'KW' '1357';
-KW1358 : 'KW' '1358';
-KW1359 : 'KW' '1359';
-KW1360 : 'KW' '1360';
-KW1361 : 'KW' '1361';
-KW1362 : 'KW' '1362';
-KW1363 : 'KW' '1363';
-KW1364 : 'KW' '1364';
-KW1365 : 'KW' '1365';
-KW1366 : 'KW' '1366';
-KW1367 : 'KW' '1367';
-KW1368 : 'KW' '1368';
-KW1369 : 'KW' '1369';
-KW1370 : 'KW' '1370';
-KW1371 : 'KW' '1371';
-KW1372 : 'KW' '1372';
-KW1373 : 'KW' '1373';
-KW1374 : 'KW' '1374';
-KW1375 : 'KW' '1375';
-KW1376 : 'KW' '1376';
-KW1377 : 'KW' '1377';
-KW1378 : 'KW' '1378';
-KW1379 : 'KW' '1379';
-KW1380 : 'KW' '1380';
-KW1381 : 'KW' '1381';
-KW1382 : 'KW' '1382';
-KW1383 : 'KW' '1383';
-KW1384 : 'KW' '1384';
-KW1385 : 'KW' '1385';
-KW1386 : 'KW' '1386';
-KW1387 : 'KW' '1387';
-KW1388 : 'KW' '1388';
-KW1389 : 'KW' '1389';
-KW1390 : 'KW' '1390';
-KW1391 : 'KW' '1391';
-KW1392 : 'KW' '1392';
-KW1393 : 'KW' '1393';
-KW1394 : 'KW' '1394';
-KW1395 : 'KW' '1395';
-KW1396 : 'KW' '1396';
-KW1397 : 'KW' '1397';
-KW1398 : 'KW' '1398';
-KW1399 : 'KW' '1399';
-KW1400 : 'KW' '1400';
-KW1401 : 'KW' '1401';
-KW1402 : 'KW' '1402';
-KW1403 : 'KW' '1403';
-KW1404 : 'KW' '1404';
-KW1405 : 'KW' '1405';
-KW1406 : 'KW' '1406';
-KW1407 : 'KW' '1407';
-KW1408 : 'KW' '1408';
-KW1409 : 'KW' '1409';
-KW1410 : 'KW' '1410';
-KW1411 : 'KW' '1411';
-KW1412 : 'KW' '1412';
-KW1413 : 'KW' '1413';
-KW1414 : 'KW' '1414';
-KW1415 : 'KW' '1415';
-KW1416 : 'KW' '1416';
-KW1417 : 'KW' '1417';
-KW1418 : 'KW' '1418';
-KW1419 : 'KW' '1419';
-KW1420 : 'KW' '1420';
-KW1421 : 'KW' '1421';
-KW1422 : 'KW' '1422';
-KW1423 : 'KW' '1423';
-KW1424 : 'KW' '1424';
-KW1425 : 'KW' '1425';
-KW1426 : 'KW' '1426';
-KW1427 : 'KW' '1427';
-KW1428 : 'KW' '1428';
-KW1429 : 'KW' '1429';
-KW1430 : 'KW' '1430';
-KW1431 : 'KW' '1431';
-KW1432 : 'KW' '1432';
-KW1433 : 'KW' '1433';
-KW1434 : 'KW' '1434';
-KW1435 : 'KW' '1435';
-KW1436 : 'KW' '1436';
-KW1437 : 'KW' '1437';
-KW1438 : 'KW' '1438';
-KW1439 : 'KW' '1439';
-KW1440 : 'KW' '1440';
-KW1441 : 'KW' '1441';
-KW1442 : 'KW' '1442';
-KW1443 : 'KW' '1443';
-KW1444 : 'KW' '1444';
-KW1445 : 'KW' '1445';
-KW1446 : 'KW' '1446';
-KW1447 : 'KW' '1447';
-KW1448 : 'KW' '1448';
-KW1449 : 'KW' '1449';
-KW1450 : 'KW' '1450';
-KW1451 : 'KW' '1451';
-KW1452 : 'KW' '1452';
-KW1453 : 'KW' '1453';
-KW1454 : 'KW' '1454';
-KW1455 : 'KW' '1455';
-KW1456 : 'KW' '1456';
-KW1457 : 'KW' '1457';
-KW1458 : 'KW' '1458';
-KW1459 : 'KW' '1459';
-KW1460 : 'KW' '1460';
-KW1461 : 'KW' '1461';
-KW1462 : 'KW' '1462';
-KW1463 : 'KW' '1463';
-KW1464 : 'KW' '1464';
-KW1465 : 'KW' '1465';
-KW1466 : 'KW' '1466';
-KW1467 : 'KW' '1467';
-KW1468 : 'KW' '1468';
-KW1469 : 'KW' '1469';
-KW1470 : 'KW' '1470';
-KW1471 : 'KW' '1471';
-KW1472 : 'KW' '1472';
-KW1473 : 'KW' '1473';
-KW1474 : 'KW' '1474';
-KW1475 : 'KW' '1475';
-KW1476 : 'KW' '1476';
-KW1477 : 'KW' '1477';
-KW1478 : 'KW' '1478';
-KW1479 : 'KW' '1479';
-KW1480 : 'KW' '1480';
-KW1481 : 'KW' '1481';
-KW1482 : 'KW' '1482';
-KW1483 : 'KW' '1483';
-KW1484 : 'KW' '1484';
-KW1485 : 'KW' '1485';
-KW1486 : 'KW' '1486';
-KW1487 : 'KW' '1487';
-KW1488 : 'KW' '1488';
-KW1489 : 'KW' '1489';
-KW1490 : 'KW' '1490';
-KW1491 : 'KW' '1491';
-KW1492 : 'KW' '1492';
-KW1493 : 'KW' '1493';
-KW1494 : 'KW' '1494';
-KW1495 : 'KW' '1495';
-KW1496 : 'KW' '1496';
-KW1497 : 'KW' '1497';
-KW1498 : 'KW' '1498';
-KW1499 : 'KW' '1499';
-KW1500 : 'KW' '1500';
-KW1501 : 'KW' '1501';
-KW1502 : 'KW' '1502';
-KW1503 : 'KW' '1503';
-KW1504 : 'KW' '1504';
-KW1505 : 'KW' '1505';
-KW1506 : 'KW' '1506';
-KW1507 : 'KW' '1507';
-KW1508 : 'KW' '1508';
-KW1509 : 'KW' '1509';
-KW1510 : 'KW' '1510';
-KW1511 : 'KW' '1511';
-KW1512 : 'KW' '1512';
-KW1513 : 'KW' '1513';
-KW1514 : 'KW' '1514';
-KW1515 : 'KW' '1515';
-KW1516 : 'KW' '1516';
-KW1517 : 'KW' '1517';
-KW1518 : 'KW' '1518';
-KW1519 : 'KW' '1519';
-KW1520 : 'KW' '1520';
-KW1521 : 'KW' '1521';
-KW1522 : 'KW' '1522';
-KW1523 : 'KW' '1523';
-KW1524 : 'KW' '1524';
-KW1525 : 'KW' '1525';
-KW1526 : 'KW' '1526';
-KW1527 : 'KW' '1527';
-KW1528 : 'KW' '1528';
-KW1529 : 'KW' '1529';
-KW1530 : 'KW' '1530';
-KW1531 : 'KW' '1531';
-KW1532 : 'KW' '1532';
-KW1533 : 'KW' '1533';
-KW1534 : 'KW' '1534';
-KW1535 : 'KW' '1535';
-KW1536 : 'KW' '1536';
-KW1537 : 'KW' '1537';
-KW1538 : 'KW' '1538';
-KW1539 : 'KW' '1539';
-KW1540 : 'KW' '1540';
-KW1541 : 'KW' '1541';
-KW1542 : 'KW' '1542';
-KW1543 : 'KW' '1543';
-KW1544 : 'KW' '1544';
-KW1545 : 'KW' '1545';
-KW1546 : 'KW' '1546';
-KW1547 : 'KW' '1547';
-KW1548 : 'KW' '1548';
-KW1549 : 'KW' '1549';
-KW1550 : 'KW' '1550';
-KW1551 : 'KW' '1551';
-KW1552 : 'KW' '1552';
-KW1553 : 'KW' '1553';
-KW1554 : 'KW' '1554';
-KW1555 : 'KW' '1555';
-KW1556 : 'KW' '1556';
-KW1557 : 'KW' '1557';
-KW1558 : 'KW' '1558';
-KW1559 : 'KW' '1559';
-KW1560 : 'KW' '1560';
-KW1561 : 'KW' '1561';
-KW1562 : 'KW' '1562';
-KW1563 : 'KW' '1563';
-KW1564 : 'KW' '1564';
-KW1565 : 'KW' '1565';
-KW1566 : 'KW' '1566';
-KW1567 : 'KW' '1567';
-KW1568 : 'KW' '1568';
-KW1569 : 'KW' '1569';
-KW1570 : 'KW' '1570';
-KW1571 : 'KW' '1571';
-KW1572 : 'KW' '1572';
-KW1573 : 'KW' '1573';
-KW1574 : 'KW' '1574';
-KW1575 : 'KW' '1575';
-KW1576 : 'KW' '1576';
-KW1577 : 'KW' '1577';
-KW1578 : 'KW' '1578';
-KW1579 : 'KW' '1579';
-KW1580 : 'KW' '1580';
-KW1581 : 'KW' '1581';
-KW1582 : 'KW' '1582';
-KW1583 : 'KW' '1583';
-KW1584 : 'KW' '1584';
-KW1585 : 'KW' '1585';
-KW1586 : 'KW' '1586';
-KW1587 : 'KW' '1587';
-KW1588 : 'KW' '1588';
-KW1589 : 'KW' '1589';
-KW1590 : 'KW' '1590';
-KW1591 : 'KW' '1591';
-KW1592 : 'KW' '1592';
-KW1593 : 'KW' '1593';
-KW1594 : 'KW' '1594';
-KW1595 : 'KW' '1595';
-KW1596 : 'KW' '1596';
-KW1597 : 'KW' '1597';
-KW1598 : 'KW' '1598';
-KW1599 : 'KW' '1599';
-KW1600 : 'KW' '1600';
-KW1601 : 'KW' '1601';
-KW1602 : 'KW' '1602';
-KW1603 : 'KW' '1603';
-KW1604 : 'KW' '1604';
-KW1605 : 'KW' '1605';
-KW1606 : 'KW' '1606';
-KW1607 : 'KW' '1607';
-KW1608 : 'KW' '1608';
-KW1609 : 'KW' '1609';
-KW1610 : 'KW' '1610';
-KW1611 : 'KW' '1611';
-KW1612 : 'KW' '1612';
-KW1613 : 'KW' '1613';
-KW1614 : 'KW' '1614';
-KW1615 : 'KW' '1615';
-KW1616 : 'KW' '1616';
-KW1617 : 'KW' '1617';
-KW1618 : 'KW' '1618';
-KW1619 : 'KW' '1619';
-KW1620 : 'KW' '1620';
-KW1621 : 'KW' '1621';
-KW1622 : 'KW' '1622';
-KW1623 : 'KW' '1623';
-KW1624 : 'KW' '1624';
-KW1625 : 'KW' '1625';
-KW1626 : 'KW' '1626';
-KW1627 : 'KW' '1627';
-KW1628 : 'KW' '1628';
-KW1629 : 'KW' '1629';
-KW1630 : 'KW' '1630';
-KW1631 : 'KW' '1631';
-KW1632 : 'KW' '1632';
-KW1633 : 'KW' '1633';
-KW1634 : 'KW' '1634';
-KW1635 : 'KW' '1635';
-KW1636 : 'KW' '1636';
-KW1637 : 'KW' '1637';
-KW1638 : 'KW' '1638';
-KW1639 : 'KW' '1639';
-KW1640 : 'KW' '1640';
-KW1641 : 'KW' '1641';
-KW1642 : 'KW' '1642';
-KW1643 : 'KW' '1643';
-KW1644 : 'KW' '1644';
-KW1645 : 'KW' '1645';
-KW1646 : 'KW' '1646';
-KW1647 : 'KW' '1647';
-KW1648 : 'KW' '1648';
-KW1649 : 'KW' '1649';
-KW1650 : 'KW' '1650';
-KW1651 : 'KW' '1651';
-KW1652 : 'KW' '1652';
-KW1653 : 'KW' '1653';
-KW1654 : 'KW' '1654';
-KW1655 : 'KW' '1655';
-KW1656 : 'KW' '1656';
-KW1657 : 'KW' '1657';
-KW1658 : 'KW' '1658';
-KW1659 : 'KW' '1659';
-KW1660 : 'KW' '1660';
-KW1661 : 'KW' '1661';
-KW1662 : 'KW' '1662';
-KW1663 : 'KW' '1663';
-KW1664 : 'KW' '1664';
-KW1665 : 'KW' '1665';
-KW1666 : 'KW' '1666';
-KW1667 : 'KW' '1667';
-KW1668 : 'KW' '1668';
-KW1669 : 'KW' '1669';
-KW1670 : 'KW' '1670';
-KW1671 : 'KW' '1671';
-KW1672 : 'KW' '1672';
-KW1673 : 'KW' '1673';
-KW1674 : 'KW' '1674';
-KW1675 : 'KW' '1675';
-KW1676 : 'KW' '1676';
-KW1677 : 'KW' '1677';
-KW1678 : 'KW' '1678';
-KW1679 : 'KW' '1679';
-KW1680 : 'KW' '1680';
-KW1681 : 'KW' '1681';
-KW1682 : 'KW' '1682';
-KW1683 : 'KW' '1683';
-KW1684 : 'KW' '1684';
-KW1685 : 'KW' '1685';
-KW1686 : 'KW' '1686';
-KW1687 : 'KW' '1687';
-KW1688 : 'KW' '1688';
-KW1689 : 'KW' '1689';
-KW1690 : 'KW' '1690';
-KW1691 : 'KW' '1691';
-KW1692 : 'KW' '1692';
-KW1693 : 'KW' '1693';
-KW1694 : 'KW' '1694';
-KW1695 : 'KW' '1695';
-KW1696 : 'KW' '1696';
-KW1697 : 'KW' '1697';
-KW1698 : 'KW' '1698';
-KW1699 : 'KW' '1699';
-KW1700 : 'KW' '1700';
-KW1701 : 'KW' '1701';
-KW1702 : 'KW' '1702';
-KW1703 : 'KW' '1703';
-KW1704 : 'KW' '1704';
-KW1705 : 'KW' '1705';
-KW1706 : 'KW' '1706';
-KW1707 : 'KW' '1707';
-KW1708 : 'KW' '1708';
-KW1709 : 'KW' '1709';
-KW1710 : 'KW' '1710';
-KW1711 : 'KW' '1711';
-KW1712 : 'KW' '1712';
-KW1713 : 'KW' '1713';
-KW1714 : 'KW' '1714';
-KW1715 : 'KW' '1715';
-KW1716 : 'KW' '1716';
-KW1717 : 'KW' '1717';
-KW1718 : 'KW' '1718';
-KW1719 : 'KW' '1719';
-KW1720 : 'KW' '1720';
-KW1721 : 'KW' '1721';
-KW1722 : 'KW' '1722';
-KW1723 : 'KW' '1723';
-KW1724 : 'KW' '1724';
-KW1725 : 'KW' '1725';
-KW1726 : 'KW' '1726';
-KW1727 : 'KW' '1727';
-KW1728 : 'KW' '1728';
-KW1729 : 'KW' '1729';
-KW1730 : 'KW' '1730';
-KW1731 : 'KW' '1731';
-KW1732 : 'KW' '1732';
-KW1733 : 'KW' '1733';
-KW1734 : 'KW' '1734';
-KW1735 : 'KW' '1735';
-KW1736 : 'KW' '1736';
-KW1737 : 'KW' '1737';
-KW1738 : 'KW' '1738';
-KW1739 : 'KW' '1739';
-KW1740 : 'KW' '1740';
-KW1741 : 'KW' '1741';
-KW1742 : 'KW' '1742';
-KW1743 : 'KW' '1743';
-KW1744 : 'KW' '1744';
-KW1745 : 'KW' '1745';
-KW1746 : 'KW' '1746';
-KW1747 : 'KW' '1747';
-KW1748 : 'KW' '1748';
-KW1749 : 'KW' '1749';
-KW1750 : 'KW' '1750';
-KW1751 : 'KW' '1751';
-KW1752 : 'KW' '1752';
-KW1753 : 'KW' '1753';
-KW1754 : 'KW' '1754';
-KW1755 : 'KW' '1755';
-KW1756 : 'KW' '1756';
-KW1757 : 'KW' '1757';
-KW1758 : 'KW' '1758';
-KW1759 : 'KW' '1759';
-KW1760 : 'KW' '1760';
-KW1761 : 'KW' '1761';
-KW1762 : 'KW' '1762';
-KW1763 : 'KW' '1763';
-KW1764 : 'KW' '1764';
-KW1765 : 'KW' '1765';
-KW1766 : 'KW' '1766';
-KW1767 : 'KW' '1767';
-KW1768 : 'KW' '1768';
-KW1769 : 'KW' '1769';
-KW1770 : 'KW' '1770';
-KW1771 : 'KW' '1771';
-KW1772 : 'KW' '1772';
-KW1773 : 'KW' '1773';
-KW1774 : 'KW' '1774';
-KW1775 : 'KW' '1775';
-KW1776 : 'KW' '1776';
-KW1777 : 'KW' '1777';
-KW1778 : 'KW' '1778';
-KW1779 : 'KW' '1779';
-KW1780 : 'KW' '1780';
-KW1781 : 'KW' '1781';
-KW1782 : 'KW' '1782';
-KW1783 : 'KW' '1783';
-KW1784 : 'KW' '1784';
-KW1785 : 'KW' '1785';
-KW1786 : 'KW' '1786';
-KW1787 : 'KW' '1787';
-KW1788 : 'KW' '1788';
-KW1789 : 'KW' '1789';
-KW1790 : 'KW' '1790';
-KW1791 : 'KW' '1791';
-KW1792 : 'KW' '1792';
-KW1793 : 'KW' '1793';
-KW1794 : 'KW' '1794';
-KW1795 : 'KW' '1795';
-KW1796 : 'KW' '1796';
-KW1797 : 'KW' '1797';
-KW1798 : 'KW' '1798';
-KW1799 : 'KW' '1799';
-KW1800 : 'KW' '1800';
-KW1801 : 'KW' '1801';
-KW1802 : 'KW' '1802';
-KW1803 : 'KW' '1803';
-KW1804 : 'KW' '1804';
-KW1805 : 'KW' '1805';
-KW1806 : 'KW' '1806';
-KW1807 : 'KW' '1807';
-KW1808 : 'KW' '1808';
-KW1809 : 'KW' '1809';
-KW1810 : 'KW' '1810';
-KW1811 : 'KW' '1811';
-KW1812 : 'KW' '1812';
-KW1813 : 'KW' '1813';
-KW1814 : 'KW' '1814';
-KW1815 : 'KW' '1815';
-KW1816 : 'KW' '1816';
-KW1817 : 'KW' '1817';
-KW1818 : 'KW' '1818';
-KW1819 : 'KW' '1819';
-KW1820 : 'KW' '1820';
-KW1821 : 'KW' '1821';
-KW1822 : 'KW' '1822';
-KW1823 : 'KW' '1823';
-KW1824 : 'KW' '1824';
-KW1825 : 'KW' '1825';
-KW1826 : 'KW' '1826';
-KW1827 : 'KW' '1827';
-KW1828 : 'KW' '1828';
-KW1829 : 'KW' '1829';
-KW1830 : 'KW' '1830';
-KW1831 : 'KW' '1831';
-KW1832 : 'KW' '1832';
-KW1833 : 'KW' '1833';
-KW1834 : 'KW' '1834';
-KW1835 : 'KW' '1835';
-KW1836 : 'KW' '1836';
-KW1837 : 'KW' '1837';
-KW1838 : 'KW' '1838';
-KW1839 : 'KW' '1839';
-KW1840 : 'KW' '1840';
-KW1841 : 'KW' '1841';
-KW1842 : 'KW' '1842';
-KW1843 : 'KW' '1843';
-KW1844 : 'KW' '1844';
-KW1845 : 'KW' '1845';
-KW1846 : 'KW' '1846';
-KW1847 : 'KW' '1847';
-KW1848 : 'KW' '1848';
-KW1849 : 'KW' '1849';
-KW1850 : 'KW' '1850';
-KW1851 : 'KW' '1851';
-KW1852 : 'KW' '1852';
-KW1853 : 'KW' '1853';
-KW1854 : 'KW' '1854';
-KW1855 : 'KW' '1855';
-KW1856 : 'KW' '1856';
-KW1857 : 'KW' '1857';
-KW1858 : 'KW' '1858';
-KW1859 : 'KW' '1859';
-KW1860 : 'KW' '1860';
-KW1861 : 'KW' '1861';
-KW1862 : 'KW' '1862';
-KW1863 : 'KW' '1863';
-KW1864 : 'KW' '1864';
-KW1865 : 'KW' '1865';
-KW1866 : 'KW' '1866';
-KW1867 : 'KW' '1867';
-KW1868 : 'KW' '1868';
-KW1869 : 'KW' '1869';
-KW1870 : 'KW' '1870';
-KW1871 : 'KW' '1871';
-KW1872 : 'KW' '1872';
-KW1873 : 'KW' '1873';
-KW1874 : 'KW' '1874';
-KW1875 : 'KW' '1875';
-KW1876 : 'KW' '1876';
-KW1877 : 'KW' '1877';
-KW1878 : 'KW' '1878';
-KW1879 : 'KW' '1879';
-KW1880 : 'KW' '1880';
-KW1881 : 'KW' '1881';
-KW1882 : 'KW' '1882';
-KW1883 : 'KW' '1883';
-KW1884 : 'KW' '1884';
-KW1885 : 'KW' '1885';
-KW1886 : 'KW' '1886';
-KW1887 : 'KW' '1887';
-KW1888 : 'KW' '1888';
-KW1889 : 'KW' '1889';
-KW1890 : 'KW' '1890';
-KW1891 : 'KW' '1891';
-KW1892 : 'KW' '1892';
-KW1893 : 'KW' '1893';
-KW1894 : 'KW' '1894';
-KW1895 : 'KW' '1895';
-KW1896 : 'KW' '1896';
-KW1897 : 'KW' '1897';
-KW1898 : 'KW' '1898';
-KW1899 : 'KW' '1899';
-KW1900 : 'KW' '1900';
-KW1901 : 'KW' '1901';
-KW1902 : 'KW' '1902';
-KW1903 : 'KW' '1903';
-KW1904 : 'KW' '1904';
-KW1905 : 'KW' '1905';
-KW1906 : 'KW' '1906';
-KW1907 : 'KW' '1907';
-KW1908 : 'KW' '1908';
-KW1909 : 'KW' '1909';
-KW1910 : 'KW' '1910';
-KW1911 : 'KW' '1911';
-KW1912 : 'KW' '1912';
-KW1913 : 'KW' '1913';
-KW1914 : 'KW' '1914';
-KW1915 : 'KW' '1915';
-KW1916 : 'KW' '1916';
-KW1917 : 'KW' '1917';
-KW1918 : 'KW' '1918';
-KW1919 : 'KW' '1919';
-KW1920 : 'KW' '1920';
-KW1921 : 'KW' '1921';
-KW1922 : 'KW' '1922';
-KW1923 : 'KW' '1923';
-KW1924 : 'KW' '1924';
-KW1925 : 'KW' '1925';
-KW1926 : 'KW' '1926';
-KW1927 : 'KW' '1927';
-KW1928 : 'KW' '1928';
-KW1929 : 'KW' '1929';
-KW1930 : 'KW' '1930';
-KW1931 : 'KW' '1931';
-KW1932 : 'KW' '1932';
-KW1933 : 'KW' '1933';
-KW1934 : 'KW' '1934';
-KW1935 : 'KW' '1935';
-KW1936 : 'KW' '1936';
-KW1937 : 'KW' '1937';
-KW1938 : 'KW' '1938';
-KW1939 : 'KW' '1939';
-KW1940 : 'KW' '1940';
-KW1941 : 'KW' '1941';
-KW1942 : 'KW' '1942';
-KW1943 : 'KW' '1943';
-KW1944 : 'KW' '1944';
-KW1945 : 'KW' '1945';
-KW1946 : 'KW' '1946';
-KW1947 : 'KW' '1947';
-KW1948 : 'KW' '1948';
-KW1949 : 'KW' '1949';
-KW1950 : 'KW' '1950';
-KW1951 : 'KW' '1951';
-KW1952 : 'KW' '1952';
-KW1953 : 'KW' '1953';
-KW1954 : 'KW' '1954';
-KW1955 : 'KW' '1955';
-KW1956 : 'KW' '1956';
-KW1957 : 'KW' '1957';
-KW1958 : 'KW' '1958';
-KW1959 : 'KW' '1959';
-KW1960 : 'KW' '1960';
-KW1961 : 'KW' '1961';
-KW1962 : 'KW' '1962';
-KW1963 : 'KW' '1963';
-KW1964 : 'KW' '1964';
-KW1965 : 'KW' '1965';
-KW1966 : 'KW' '1966';
-KW1967 : 'KW' '1967';
-KW1968 : 'KW' '1968';
-KW1969 : 'KW' '1969';
-KW1970 : 'KW' '1970';
-KW1971 : 'KW' '1971';
-KW1972 : 'KW' '1972';
-KW1973 : 'KW' '1973';
-KW1974 : 'KW' '1974';
-KW1975 : 'KW' '1975';
-KW1976 : 'KW' '1976';
-KW1977 : 'KW' '1977';
-KW1978 : 'KW' '1978';
-KW1979 : 'KW' '1979';
-KW1980 : 'KW' '1980';
-KW1981 : 'KW' '1981';
-KW1982 : 'KW' '1982';
-KW1983 : 'KW' '1983';
-KW1984 : 'KW' '1984';
-KW1985 : 'KW' '1985';
-KW1986 : 'KW' '1986';
-KW1987 : 'KW' '1987';
-KW1988 : 'KW' '1988';
-KW1989 : 'KW' '1989';
-KW1990 : 'KW' '1990';
-KW1991 : 'KW' '1991';
-KW1992 : 'KW' '1992';
-KW1993 : 'KW' '1993';
-KW1994 : 'KW' '1994';
-KW1995 : 'KW' '1995';
-KW1996 : 'KW' '1996';
-KW1997 : 'KW' '1997';
-KW1998 : 'KW' '1998';
-KW1999 : 'KW' '1999';
-KW2000 : 'KW' '2000';
-KW2001 : 'KW' '2001';
-KW2002 : 'KW' '2002';
-KW2003 : 'KW' '2003';
-KW2004 : 'KW' '2004';
-KW2005 : 'KW' '2005';
-KW2006 : 'KW' '2006';
-KW2007 : 'KW' '2007';
-KW2008 : 'KW' '2008';
-KW2009 : 'KW' '2009';
-KW2010 : 'KW' '2010';
-KW2011 : 'KW' '2011';
-KW2012 : 'KW' '2012';
-KW2013 : 'KW' '2013';
-KW2014 : 'KW' '2014';
-KW2015 : 'KW' '2015';
-KW2016 : 'KW' '2016';
-KW2017 : 'KW' '2017';
-KW2018 : 'KW' '2018';
-KW2019 : 'KW' '2019';
-KW2020 : 'KW' '2020';
-KW2021 : 'KW' '2021';
-KW2022 : 'KW' '2022';
-KW2023 : 'KW' '2023';
-KW2024 : 'KW' '2024';
-KW2025 : 'KW' '2025';
-KW2026 : 'KW' '2026';
-KW2027 : 'KW' '2027';
-KW2028 : 'KW' '2028';
-KW2029 : 'KW' '2029';
-KW2030 : 'KW' '2030';
-KW2031 : 'KW' '2031';
-KW2032 : 'KW' '2032';
-KW2033 : 'KW' '2033';
-KW2034 : 'KW' '2034';
-KW2035 : 'KW' '2035';
-KW2036 : 'KW' '2036';
-KW2037 : 'KW' '2037';
-KW2038 : 'KW' '2038';
-KW2039 : 'KW' '2039';
-KW2040 : 'KW' '2040';
-KW2041 : 'KW' '2041';
-KW2042 : 'KW' '2042';
-KW2043 : 'KW' '2043';
-KW2044 : 'KW' '2044';
-KW2045 : 'KW' '2045';
-KW2046 : 'KW' '2046';
-KW2047 : 'KW' '2047';
-KW2048 : 'KW' '2048';
-KW2049 : 'KW' '2049';
-KW2050 : 'KW' '2050';
-KW2051 : 'KW' '2051';
-KW2052 : 'KW' '2052';
-KW2053 : 'KW' '2053';
-KW2054 : 'KW' '2054';
-KW2055 : 'KW' '2055';
-KW2056 : 'KW' '2056';
-KW2057 : 'KW' '2057';
-KW2058 : 'KW' '2058';
-KW2059 : 'KW' '2059';
-KW2060 : 'KW' '2060';
-KW2061 : 'KW' '2061';
-KW2062 : 'KW' '2062';
-KW2063 : 'KW' '2063';
-KW2064 : 'KW' '2064';
-KW2065 : 'KW' '2065';
-KW2066 : 'KW' '2066';
-KW2067 : 'KW' '2067';
-KW2068 : 'KW' '2068';
-KW2069 : 'KW' '2069';
-KW2070 : 'KW' '2070';
-KW2071 : 'KW' '2071';
-KW2072 : 'KW' '2072';
-KW2073 : 'KW' '2073';
-KW2074 : 'KW' '2074';
-KW2075 : 'KW' '2075';
-KW2076 : 'KW' '2076';
-KW2077 : 'KW' '2077';
-KW2078 : 'KW' '2078';
-KW2079 : 'KW' '2079';
-KW2080 : 'KW' '2080';
-KW2081 : 'KW' '2081';
-KW2082 : 'KW' '2082';
-KW2083 : 'KW' '2083';
-KW2084 : 'KW' '2084';
-KW2085 : 'KW' '2085';
-KW2086 : 'KW' '2086';
-KW2087 : 'KW' '2087';
-KW2088 : 'KW' '2088';
-KW2089 : 'KW' '2089';
-KW2090 : 'KW' '2090';
-KW2091 : 'KW' '2091';
-KW2092 : 'KW' '2092';
-KW2093 : 'KW' '2093';
-KW2094 : 'KW' '2094';
-KW2095 : 'KW' '2095';
-KW2096 : 'KW' '2096';
-KW2097 : 'KW' '2097';
-KW2098 : 'KW' '2098';
-KW2099 : 'KW' '2099';
-KW2100 : 'KW' '2100';
-KW2101 : 'KW' '2101';
-KW2102 : 'KW' '2102';
-KW2103 : 'KW' '2103';
-KW2104 : 'KW' '2104';
-KW2105 : 'KW' '2105';
-KW2106 : 'KW' '2106';
-KW2107 : 'KW' '2107';
-KW2108 : 'KW' '2108';
-KW2109 : 'KW' '2109';
-KW2110 : 'KW' '2110';
-KW2111 : 'KW' '2111';
-KW2112 : 'KW' '2112';
-KW2113 : 'KW' '2113';
-KW2114 : 'KW' '2114';
-KW2115 : 'KW' '2115';
-KW2116 : 'KW' '2116';
-KW2117 : 'KW' '2117';
-KW2118 : 'KW' '2118';
-KW2119 : 'KW' '2119';
-KW2120 : 'KW' '2120';
-KW2121 : 'KW' '2121';
-KW2122 : 'KW' '2122';
-KW2123 : 'KW' '2123';
-KW2124 : 'KW' '2124';
-KW2125 : 'KW' '2125';
-KW2126 : 'KW' '2126';
-KW2127 : 'KW' '2127';
-KW2128 : 'KW' '2128';
-KW2129 : 'KW' '2129';
-KW2130 : 'KW' '2130';
-KW2131 : 'KW' '2131';
-KW2132 : 'KW' '2132';
-KW2133 : 'KW' '2133';
-KW2134 : 'KW' '2134';
-KW2135 : 'KW' '2135';
-KW2136 : 'KW' '2136';
-KW2137 : 'KW' '2137';
-KW2138 : 'KW' '2138';
-KW2139 : 'KW' '2139';
-KW2140 : 'KW' '2140';
-KW2141 : 'KW' '2141';
-KW2142 : 'KW' '2142';
-KW2143 : 'KW' '2143';
-KW2144 : 'KW' '2144';
-KW2145 : 'KW' '2145';
-KW2146 : 'KW' '2146';
-KW2147 : 'KW' '2147';
-KW2148 : 'KW' '2148';
-KW2149 : 'KW' '2149';
-KW2150 : 'KW' '2150';
-KW2151 : 'KW' '2151';
-KW2152 : 'KW' '2152';
-KW2153 : 'KW' '2153';
-KW2154 : 'KW' '2154';
-KW2155 : 'KW' '2155';
-KW2156 : 'KW' '2156';
-KW2157 : 'KW' '2157';
-KW2158 : 'KW' '2158';
-KW2159 : 'KW' '2159';
-KW2160 : 'KW' '2160';
-KW2161 : 'KW' '2161';
-KW2162 : 'KW' '2162';
-KW2163 : 'KW' '2163';
-KW2164 : 'KW' '2164';
-KW2165 : 'KW' '2165';
-KW2166 : 'KW' '2166';
-KW2167 : 'KW' '2167';
-KW2168 : 'KW' '2168';
-KW2169 : 'KW' '2169';
-KW2170 : 'KW' '2170';
-KW2171 : 'KW' '2171';
-KW2172 : 'KW' '2172';
-KW2173 : 'KW' '2173';
-KW2174 : 'KW' '2174';
-KW2175 : 'KW' '2175';
-KW2176 : 'KW' '2176';
-KW2177 : 'KW' '2177';
-KW2178 : 'KW' '2178';
-KW2179 : 'KW' '2179';
-KW2180 : 'KW' '2180';
-KW2181 : 'KW' '2181';
-KW2182 : 'KW' '2182';
-KW2183 : 'KW' '2183';
-KW2184 : 'KW' '2184';
-KW2185 : 'KW' '2185';
-KW2186 : 'KW' '2186';
-KW2187 : 'KW' '2187';
-KW2188 : 'KW' '2188';
-KW2189 : 'KW' '2189';
-KW2190 : 'KW' '2190';
-KW2191 : 'KW' '2191';
-KW2192 : 'KW' '2192';
-KW2193 : 'KW' '2193';
-KW2194 : 'KW' '2194';
-KW2195 : 'KW' '2195';
-KW2196 : 'KW' '2196';
-KW2197 : 'KW' '2197';
-KW2198 : 'KW' '2198';
-KW2199 : 'KW' '2199';
-KW2200 : 'KW' '2200';
-KW2201 : 'KW' '2201';
-KW2202 : 'KW' '2202';
-KW2203 : 'KW' '2203';
-KW2204 : 'KW' '2204';
-KW2205 : 'KW' '2205';
-KW2206 : 'KW' '2206';
-KW2207 : 'KW' '2207';
-KW2208 : 'KW' '2208';
-KW2209 : 'KW' '2209';
-KW2210 : 'KW' '2210';
-KW2211 : 'KW' '2211';
-KW2212 : 'KW' '2212';
-KW2213 : 'KW' '2213';
-KW2214 : 'KW' '2214';
-KW2215 : 'KW' '2215';
-KW2216 : 'KW' '2216';
-KW2217 : 'KW' '2217';
-KW2218 : 'KW' '2218';
-KW2219 : 'KW' '2219';
-KW2220 : 'KW' '2220';
-KW2221 : 'KW' '2221';
-KW2222 : 'KW' '2222';
-KW2223 : 'KW' '2223';
-KW2224 : 'KW' '2224';
-KW2225 : 'KW' '2225';
-KW2226 : 'KW' '2226';
-KW2227 : 'KW' '2227';
-KW2228 : 'KW' '2228';
-KW2229 : 'KW' '2229';
-KW2230 : 'KW' '2230';
-KW2231 : 'KW' '2231';
-KW2232 : 'KW' '2232';
-KW2233 : 'KW' '2233';
-KW2234 : 'KW' '2234';
-KW2235 : 'KW' '2235';
-KW2236 : 'KW' '2236';
-KW2237 : 'KW' '2237';
-KW2238 : 'KW' '2238';
-KW2239 : 'KW' '2239';
-KW2240 : 'KW' '2240';
-KW2241 : 'KW' '2241';
-KW2242 : 'KW' '2242';
-KW2243 : 'KW' '2243';
-KW2244 : 'KW' '2244';
-KW2245 : 'KW' '2245';
-KW2246 : 'KW' '2246';
-KW2247 : 'KW' '2247';
-KW2248 : 'KW' '2248';
-KW2249 : 'KW' '2249';
-KW2250 : 'KW' '2250';
-KW2251 : 'KW' '2251';
-KW2252 : 'KW' '2252';
-KW2253 : 'KW' '2253';
-KW2254 : 'KW' '2254';
-KW2255 : 'KW' '2255';
-KW2256 : 'KW' '2256';
-KW2257 : 'KW' '2257';
-KW2258 : 'KW' '2258';
-KW2259 : 'KW' '2259';
-KW2260 : 'KW' '2260';
-KW2261 : 'KW' '2261';
-KW2262 : 'KW' '2262';
-KW2263 : 'KW' '2263';
-KW2264 : 'KW' '2264';
-KW2265 : 'KW' '2265';
-KW2266 : 'KW' '2266';
-KW2267 : 'KW' '2267';
-KW2268 : 'KW' '2268';
-KW2269 : 'KW' '2269';
-KW2270 : 'KW' '2270';
-KW2271 : 'KW' '2271';
-KW2272 : 'KW' '2272';
-KW2273 : 'KW' '2273';
-KW2274 : 'KW' '2274';
-KW2275 : 'KW' '2275';
-KW2276 : 'KW' '2276';
-KW2277 : 'KW' '2277';
-KW2278 : 'KW' '2278';
-KW2279 : 'KW' '2279';
-KW2280 : 'KW' '2280';
-KW2281 : 'KW' '2281';
-KW2282 : 'KW' '2282';
-KW2283 : 'KW' '2283';
-KW2284 : 'KW' '2284';
-KW2285 : 'KW' '2285';
-KW2286 : 'KW' '2286';
-KW2287 : 'KW' '2287';
-KW2288 : 'KW' '2288';
-KW2289 : 'KW' '2289';
-KW2290 : 'KW' '2290';
-KW2291 : 'KW' '2291';
-KW2292 : 'KW' '2292';
-KW2293 : 'KW' '2293';
-KW2294 : 'KW' '2294';
-KW2295 : 'KW' '2295';
-KW2296 : 'KW' '2296';
-KW2297 : 'KW' '2297';
-KW2298 : 'KW' '2298';
-KW2299 : 'KW' '2299';
-KW2300 : 'KW' '2300';
-KW2301 : 'KW' '2301';
-KW2302 : 'KW' '2302';
-KW2303 : 'KW' '2303';
-KW2304 : 'KW' '2304';
-KW2305 : 'KW' '2305';
-KW2306 : 'KW' '2306';
-KW2307 : 'KW' '2307';
-KW2308 : 'KW' '2308';
-KW2309 : 'KW' '2309';
-KW2310 : 'KW' '2310';
-KW2311 : 'KW' '2311';
-KW2312 : 'KW' '2312';
-KW2313 : 'KW' '2313';
-KW2314 : 'KW' '2314';
-KW2315 : 'KW' '2315';
-KW2316 : 'KW' '2316';
-KW2317 : 'KW' '2317';
-KW2318 : 'KW' '2318';
-KW2319 : 'KW' '2319';
-KW2320 : 'KW' '2320';
-KW2321 : 'KW' '2321';
-KW2322 : 'KW' '2322';
-KW2323 : 'KW' '2323';
-KW2324 : 'KW' '2324';
-KW2325 : 'KW' '2325';
-KW2326 : 'KW' '2326';
-KW2327 : 'KW' '2327';
-KW2328 : 'KW' '2328';
-KW2329 : 'KW' '2329';
-KW2330 : 'KW' '2330';
-KW2331 : 'KW' '2331';
-KW2332 : 'KW' '2332';
-KW2333 : 'KW' '2333';
-KW2334 : 'KW' '2334';
-KW2335 : 'KW' '2335';
-KW2336 : 'KW' '2336';
-KW2337 : 'KW' '2337';
-KW2338 : 'KW' '2338';
-KW2339 : 'KW' '2339';
-KW2340 : 'KW' '2340';
-KW2341 : 'KW' '2341';
-KW2342 : 'KW' '2342';
-KW2343 : 'KW' '2343';
-KW2344 : 'KW' '2344';
-KW2345 : 'KW' '2345';
-KW2346 : 'KW' '2346';
-KW2347 : 'KW' '2347';
-KW2348 : 'KW' '2348';
-KW2349 : 'KW' '2349';
-KW2350 : 'KW' '2350';
-KW2351 : 'KW' '2351';
-KW2352 : 'KW' '2352';
-KW2353 : 'KW' '2353';
-KW2354 : 'KW' '2354';
-KW2355 : 'KW' '2355';
-KW2356 : 'KW' '2356';
-KW2357 : 'KW' '2357';
-KW2358 : 'KW' '2358';
-KW2359 : 'KW' '2359';
-KW2360 : 'KW' '2360';
-KW2361 : 'KW' '2361';
-KW2362 : 'KW' '2362';
-KW2363 : 'KW' '2363';
-KW2364 : 'KW' '2364';
-KW2365 : 'KW' '2365';
-KW2366 : 'KW' '2366';
-KW2367 : 'KW' '2367';
-KW2368 : 'KW' '2368';
-KW2369 : 'KW' '2369';
-KW2370 : 'KW' '2370';
-KW2371 : 'KW' '2371';
-KW2372 : 'KW' '2372';
-KW2373 : 'KW' '2373';
-KW2374 : 'KW' '2374';
-KW2375 : 'KW' '2375';
-KW2376 : 'KW' '2376';
-KW2377 : 'KW' '2377';
-KW2378 : 'KW' '2378';
-KW2379 : 'KW' '2379';
-KW2380 : 'KW' '2380';
-KW2381 : 'KW' '2381';
-KW2382 : 'KW' '2382';
-KW2383 : 'KW' '2383';
-KW2384 : 'KW' '2384';
-KW2385 : 'KW' '2385';
-KW2386 : 'KW' '2386';
-KW2387 : 'KW' '2387';
-KW2388 : 'KW' '2388';
-KW2389 : 'KW' '2389';
-KW2390 : 'KW' '2390';
-KW2391 : 'KW' '2391';
-KW2392 : 'KW' '2392';
-KW2393 : 'KW' '2393';
-KW2394 : 'KW' '2394';
-KW2395 : 'KW' '2395';
-KW2396 : 'KW' '2396';
-KW2397 : 'KW' '2397';
-KW2398 : 'KW' '2398';
-KW2399 : 'KW' '2399';
-KW2400 : 'KW' '2400';
-KW2401 : 'KW' '2401';
-KW2402 : 'KW' '2402';
-KW2403 : 'KW' '2403';
-KW2404 : 'KW' '2404';
-KW2405 : 'KW' '2405';
-KW2406 : 'KW' '2406';
-KW2407 : 'KW' '2407';
-KW2408 : 'KW' '2408';
-KW2409 : 'KW' '2409';
-KW2410 : 'KW' '2410';
-KW2411 : 'KW' '2411';
-KW2412 : 'KW' '2412';
-KW2413 : 'KW' '2413';
-KW2414 : 'KW' '2414';
-KW2415 : 'KW' '2415';
-KW2416 : 'KW' '2416';
-KW2417 : 'KW' '2417';
-KW2418 : 'KW' '2418';
-KW2419 : 'KW' '2419';
-KW2420 : 'KW' '2420';
-KW2421 : 'KW' '2421';
-KW2422 : 'KW' '2422';
-KW2423 : 'KW' '2423';
-KW2424 : 'KW' '2424';
-KW2425 : 'KW' '2425';
-KW2426 : 'KW' '2426';
-KW2427 : 'KW' '2427';
-KW2428 : 'KW' '2428';
-KW2429 : 'KW' '2429';
-KW2430 : 'KW' '2430';
-KW2431 : 'KW' '2431';
-KW2432 : 'KW' '2432';
-KW2433 : 'KW' '2433';
-KW2434 : 'KW' '2434';
-KW2435 : 'KW' '2435';
-KW2436 : 'KW' '2436';
-KW2437 : 'KW' '2437';
-KW2438 : 'KW' '2438';
-KW2439 : 'KW' '2439';
-KW2440 : 'KW' '2440';
-KW2441 : 'KW' '2441';
-KW2442 : 'KW' '2442';
-KW2443 : 'KW' '2443';
-KW2444 : 'KW' '2444';
-KW2445 : 'KW' '2445';
-KW2446 : 'KW' '2446';
-KW2447 : 'KW' '2447';
-KW2448 : 'KW' '2448';
-KW2449 : 'KW' '2449';
-KW2450 : 'KW' '2450';
-KW2451 : 'KW' '2451';
-KW2452 : 'KW' '2452';
-KW2453 : 'KW' '2453';
-KW2454 : 'KW' '2454';
-KW2455 : 'KW' '2455';
-KW2456 : 'KW' '2456';
-KW2457 : 'KW' '2457';
-KW2458 : 'KW' '2458';
-KW2459 : 'KW' '2459';
-KW2460 : 'KW' '2460';
-KW2461 : 'KW' '2461';
-KW2462 : 'KW' '2462';
-KW2463 : 'KW' '2463';
-KW2464 : 'KW' '2464';
-KW2465 : 'KW' '2465';
-KW2466 : 'KW' '2466';
-KW2467 : 'KW' '2467';
-KW2468 : 'KW' '2468';
-KW2469 : 'KW' '2469';
-KW2470 : 'KW' '2470';
-KW2471 : 'KW' '2471';
-KW2472 : 'KW' '2472';
-KW2473 : 'KW' '2473';
-KW2474 : 'KW' '2474';
-KW2475 : 'KW' '2475';
-KW2476 : 'KW' '2476';
-KW2477 : 'KW' '2477';
-KW2478 : 'KW' '2478';
-KW2479 : 'KW' '2479';
-KW2480 : 'KW' '2480';
-KW2481 : 'KW' '2481';
-KW2482 : 'KW' '2482';
-KW2483 : 'KW' '2483';
-KW2484 : 'KW' '2484';
-KW2485 : 'KW' '2485';
-KW2486 : 'KW' '2486';
-KW2487 : 'KW' '2487';
-KW2488 : 'KW' '2488';
-KW2489 : 'KW' '2489';
-KW2490 : 'KW' '2490';
-KW2491 : 'KW' '2491';
-KW2492 : 'KW' '2492';
-KW2493 : 'KW' '2493';
-KW2494 : 'KW' '2494';
-KW2495 : 'KW' '2495';
-KW2496 : 'KW' '2496';
-KW2497 : 'KW' '2497';
-KW2498 : 'KW' '2498';
-KW2499 : 'KW' '2499';
-KW2500 : 'KW' '2500';
-KW2501 : 'KW' '2501';
-KW2502 : 'KW' '2502';
-KW2503 : 'KW' '2503';
-KW2504 : 'KW' '2504';
-KW2505 : 'KW' '2505';
-KW2506 : 'KW' '2506';
-KW2507 : 'KW' '2507';
-KW2508 : 'KW' '2508';
-KW2509 : 'KW' '2509';
-KW2510 : 'KW' '2510';
-KW2511 : 'KW' '2511';
-KW2512 : 'KW' '2512';
-KW2513 : 'KW' '2513';
-KW2514 : 'KW' '2514';
-KW2515 : 'KW' '2515';
-KW2516 : 'KW' '2516';
-KW2517 : 'KW' '2517';
-KW2518 : 'KW' '2518';
-KW2519 : 'KW' '2519';
-KW2520 : 'KW' '2520';
-KW2521 : 'KW' '2521';
-KW2522 : 'KW' '2522';
-KW2523 : 'KW' '2523';
-KW2524 : 'KW' '2524';
-KW2525 : 'KW' '2525';
-KW2526 : 'KW' '2526';
-KW2527 : 'KW' '2527';
-KW2528 : 'KW' '2528';
-KW2529 : 'KW' '2529';
-KW2530 : 'KW' '2530';
-KW2531 : 'KW' '2531';
-KW2532 : 'KW' '2532';
-KW2533 : 'KW' '2533';
-KW2534 : 'KW' '2534';
-KW2535 : 'KW' '2535';
-KW2536 : 'KW' '2536';
-KW2537 : 'KW' '2537';
-KW2538 : 'KW' '2538';
-KW2539 : 'KW' '2539';
-KW2540 : 'KW' '2540';
-KW2541 : 'KW' '2541';
-KW2542 : 'KW' '2542';
-KW2543 : 'KW' '2543';
-KW2544 : 'KW' '2544';
-KW2545 : 'KW' '2545';
-KW2546 : 'KW' '2546';
-KW2547 : 'KW' '2547';
-KW2548 : 'KW' '2548';
-KW2549 : 'KW' '2549';
-KW2550 : 'KW' '2550';
-KW2551 : 'KW' '2551';
-KW2552 : 'KW' '2552';
-KW2553 : 'KW' '2553';
-KW2554 : 'KW' '2554';
-KW2555 : 'KW' '2555';
-KW2556 : 'KW' '2556';
-KW2557 : 'KW' '2557';
-KW2558 : 'KW' '2558';
-KW2559 : 'KW' '2559';
-KW2560 : 'KW' '2560';
-KW2561 : 'KW' '2561';
-KW2562 : 'KW' '2562';
-KW2563 : 'KW' '2563';
-KW2564 : 'KW' '2564';
-KW2565 : 'KW' '2565';
-KW2566 : 'KW' '2566';
-KW2567 : 'KW' '2567';
-KW2568 : 'KW' '2568';
-KW2569 : 'KW' '2569';
-KW2570 : 'KW' '2570';
-KW2571 : 'KW' '2571';
-KW2572 : 'KW' '2572';
-KW2573 : 'KW' '2573';
-KW2574 : 'KW' '2574';
-KW2575 : 'KW' '2575';
-KW2576 : 'KW' '2576';
-KW2577 : 'KW' '2577';
-KW2578 : 'KW' '2578';
-KW2579 : 'KW' '2579';
-KW2580 : 'KW' '2580';
-KW2581 : 'KW' '2581';
-KW2582 : 'KW' '2582';
-KW2583 : 'KW' '2583';
-KW2584 : 'KW' '2584';
-KW2585 : 'KW' '2585';
-KW2586 : 'KW' '2586';
-KW2587 : 'KW' '2587';
-KW2588 : 'KW' '2588';
-KW2589 : 'KW' '2589';
-KW2590 : 'KW' '2590';
-KW2591 : 'KW' '2591';
-KW2592 : 'KW' '2592';
-KW2593 : 'KW' '2593';
-KW2594 : 'KW' '2594';
-KW2595 : 'KW' '2595';
-KW2596 : 'KW' '2596';
-KW2597 : 'KW' '2597';
-KW2598 : 'KW' '2598';
-KW2599 : 'KW' '2599';
-KW2600 : 'KW' '2600';
-KW2601 : 'KW' '2601';
-KW2602 : 'KW' '2602';
-KW2603 : 'KW' '2603';
-KW2604 : 'KW' '2604';
-KW2605 : 'KW' '2605';
-KW2606 : 'KW' '2606';
-KW2607 : 'KW' '2607';
-KW2608 : 'KW' '2608';
-KW2609 : 'KW' '2609';
-KW2610 : 'KW' '2610';
-KW2611 : 'KW' '2611';
-KW2612 : 'KW' '2612';
-KW2613 : 'KW' '2613';
-KW2614 : 'KW' '2614';
-KW2615 : 'KW' '2615';
-KW2616 : 'KW' '2616';
-KW2617 : 'KW' '2617';
-KW2618 : 'KW' '2618';
-KW2619 : 'KW' '2619';
-KW2620 : 'KW' '2620';
-KW2621 : 'KW' '2621';
-KW2622 : 'KW' '2622';
-KW2623 : 'KW' '2623';
-KW2624 : 'KW' '2624';
-KW2625 : 'KW' '2625';
-KW2626 : 'KW' '2626';
-KW2627 : 'KW' '2627';
-KW2628 : 'KW' '2628';
-KW2629 : 'KW' '2629';
-KW2630 : 'KW' '2630';
-KW2631 : 'KW' '2631';
-KW2632 : 'KW' '2632';
-KW2633 : 'KW' '2633';
-KW2634 : 'KW' '2634';
-KW2635 : 'KW' '2635';
-KW2636 : 'KW' '2636';
-KW2637 : 'KW' '2637';
-KW2638 : 'KW' '2638';
-KW2639 : 'KW' '2639';
-KW2640 : 'KW' '2640';
-KW2641 : 'KW' '2641';
-KW2642 : 'KW' '2642';
-KW2643 : 'KW' '2643';
-KW2644 : 'KW' '2644';
-KW2645 : 'KW' '2645';
-KW2646 : 'KW' '2646';
-KW2647 : 'KW' '2647';
-KW2648 : 'KW' '2648';
-KW2649 : 'KW' '2649';
-KW2650 : 'KW' '2650';
-KW2651 : 'KW' '2651';
-KW2652 : 'KW' '2652';
-KW2653 : 'KW' '2653';
-KW2654 : 'KW' '2654';
-KW2655 : 'KW' '2655';
-KW2656 : 'KW' '2656';
-KW2657 : 'KW' '2657';
-KW2658 : 'KW' '2658';
-KW2659 : 'KW' '2659';
-KW2660 : 'KW' '2660';
-KW2661 : 'KW' '2661';
-KW2662 : 'KW' '2662';
-KW2663 : 'KW' '2663';
-KW2664 : 'KW' '2664';
-KW2665 : 'KW' '2665';
-KW2666 : 'KW' '2666';
-KW2667 : 'KW' '2667';
-KW2668 : 'KW' '2668';
-KW2669 : 'KW' '2669';
-KW2670 : 'KW' '2670';
-KW2671 : 'KW' '2671';
-KW2672 : 'KW' '2672';
-KW2673 : 'KW' '2673';
-KW2674 : 'KW' '2674';
-KW2675 : 'KW' '2675';
-KW2676 : 'KW' '2676';
-KW2677 : 'KW' '2677';
-KW2678 : 'KW' '2678';
-KW2679 : 'KW' '2679';
-KW2680 : 'KW' '2680';
-KW2681 : 'KW' '2681';
-KW2682 : 'KW' '2682';
-KW2683 : 'KW' '2683';
-KW2684 : 'KW' '2684';
-KW2685 : 'KW' '2685';
-KW2686 : 'KW' '2686';
-KW2687 : 'KW' '2687';
-KW2688 : 'KW' '2688';
-KW2689 : 'KW' '2689';
-KW2690 : 'KW' '2690';
-KW2691 : 'KW' '2691';
-KW2692 : 'KW' '2692';
-KW2693 : 'KW' '2693';
-KW2694 : 'KW' '2694';
-KW2695 : 'KW' '2695';
-KW2696 : 'KW' '2696';
-KW2697 : 'KW' '2697';
-KW2698 : 'KW' '2698';
-KW2699 : 'KW' '2699';
-KW2700 : 'KW' '2700';
-KW2701 : 'KW' '2701';
-KW2702 : 'KW' '2702';
-KW2703 : 'KW' '2703';
-KW2704 : 'KW' '2704';
-KW2705 : 'KW' '2705';
-KW2706 : 'KW' '2706';
-KW2707 : 'KW' '2707';
-KW2708 : 'KW' '2708';
-KW2709 : 'KW' '2709';
-KW2710 : 'KW' '2710';
-KW2711 : 'KW' '2711';
-KW2712 : 'KW' '2712';
-KW2713 : 'KW' '2713';
-KW2714 : 'KW' '2714';
-KW2715 : 'KW' '2715';
-KW2716 : 'KW' '2716';
-KW2717 : 'KW' '2717';
-KW2718 : 'KW' '2718';
-KW2719 : 'KW' '2719';
-KW2720 : 'KW' '2720';
-KW2721 : 'KW' '2721';
-KW2722 : 'KW' '2722';
-KW2723 : 'KW' '2723';
-KW2724 : 'KW' '2724';
-KW2725 : 'KW' '2725';
-KW2726 : 'KW' '2726';
-KW2727 : 'KW' '2727';
-KW2728 : 'KW' '2728';
-KW2729 : 'KW' '2729';
-KW2730 : 'KW' '2730';
-KW2731 : 'KW' '2731';
-KW2732 : 'KW' '2732';
-KW2733 : 'KW' '2733';
-KW2734 : 'KW' '2734';
-KW2735 : 'KW' '2735';
-KW2736 : 'KW' '2736';
-KW2737 : 'KW' '2737';
-KW2738 : 'KW' '2738';
-KW2739 : 'KW' '2739';
-KW2740 : 'KW' '2740';
-KW2741 : 'KW' '2741';
-KW2742 : 'KW' '2742';
-KW2743 : 'KW' '2743';
-KW2744 : 'KW' '2744';
-KW2745 : 'KW' '2745';
-KW2746 : 'KW' '2746';
-KW2747 : 'KW' '2747';
-KW2748 : 'KW' '2748';
-KW2749 : 'KW' '2749';
-KW2750 : 'KW' '2750';
-KW2751 : 'KW' '2751';
-KW2752 : 'KW' '2752';
-KW2753 : 'KW' '2753';
-KW2754 : 'KW' '2754';
-KW2755 : 'KW' '2755';
-KW2756 : 'KW' '2756';
-KW2757 : 'KW' '2757';
-KW2758 : 'KW' '2758';
-KW2759 : 'KW' '2759';
-KW2760 : 'KW' '2760';
-KW2761 : 'KW' '2761';
-KW2762 : 'KW' '2762';
-KW2763 : 'KW' '2763';
-KW2764 : 'KW' '2764';
-KW2765 : 'KW' '2765';
-KW2766 : 'KW' '2766';
-KW2767 : 'KW' '2767';
-KW2768 : 'KW' '2768';
-KW2769 : 'KW' '2769';
-KW2770 : 'KW' '2770';
-KW2771 : 'KW' '2771';
-KW2772 : 'KW' '2772';
-KW2773 : 'KW' '2773';
-KW2774 : 'KW' '2774';
-KW2775 : 'KW' '2775';
-KW2776 : 'KW' '2776';
-KW2777 : 'KW' '2777';
-KW2778 : 'KW' '2778';
-KW2779 : 'KW' '2779';
-KW2780 : 'KW' '2780';
-KW2781 : 'KW' '2781';
-KW2782 : 'KW' '2782';
-KW2783 : 'KW' '2783';
-KW2784 : 'KW' '2784';
-KW2785 : 'KW' '2785';
-KW2786 : 'KW' '2786';
-KW2787 : 'KW' '2787';
-KW2788 : 'KW' '2788';
-KW2789 : 'KW' '2789';
-KW2790 : 'KW' '2790';
-KW2791 : 'KW' '2791';
-KW2792 : 'KW' '2792';
-KW2793 : 'KW' '2793';
-KW2794 : 'KW' '2794';
-KW2795 : 'KW' '2795';
-KW2796 : 'KW' '2796';
-KW2797 : 'KW' '2797';
-KW2798 : 'KW' '2798';
-KW2799 : 'KW' '2799';
-KW2800 : 'KW' '2800';
-KW2801 : 'KW' '2801';
-KW2802 : 'KW' '2802';
-KW2803 : 'KW' '2803';
-KW2804 : 'KW' '2804';
-KW2805 : 'KW' '2805';
-KW2806 : 'KW' '2806';
-KW2807 : 'KW' '2807';
-KW2808 : 'KW' '2808';
-KW2809 : 'KW' '2809';
-KW2810 : 'KW' '2810';
-KW2811 : 'KW' '2811';
-KW2812 : 'KW' '2812';
-KW2813 : 'KW' '2813';
-KW2814 : 'KW' '2814';
-KW2815 : 'KW' '2815';
-KW2816 : 'KW' '2816';
-KW2817 : 'KW' '2817';
-KW2818 : 'KW' '2818';
-KW2819 : 'KW' '2819';
-KW2820 : 'KW' '2820';
-KW2821 : 'KW' '2821';
-KW2822 : 'KW' '2822';
-KW2823 : 'KW' '2823';
-KW2824 : 'KW' '2824';
-KW2825 : 'KW' '2825';
-KW2826 : 'KW' '2826';
-KW2827 : 'KW' '2827';
-KW2828 : 'KW' '2828';
-KW2829 : 'KW' '2829';
-KW2830 : 'KW' '2830';
-KW2831 : 'KW' '2831';
-KW2832 : 'KW' '2832';
-KW2833 : 'KW' '2833';
-KW2834 : 'KW' '2834';
-KW2835 : 'KW' '2835';
-KW2836 : 'KW' '2836';
-KW2837 : 'KW' '2837';
-KW2838 : 'KW' '2838';
-KW2839 : 'KW' '2839';
-KW2840 : 'KW' '2840';
-KW2841 : 'KW' '2841';
-KW2842 : 'KW' '2842';
-KW2843 : 'KW' '2843';
-KW2844 : 'KW' '2844';
-KW2845 : 'KW' '2845';
-KW2846 : 'KW' '2846';
-KW2847 : 'KW' '2847';
-KW2848 : 'KW' '2848';
-KW2849 : 'KW' '2849';
-KW2850 : 'KW' '2850';
-KW2851 : 'KW' '2851';
-KW2852 : 'KW' '2852';
-KW2853 : 'KW' '2853';
-KW2854 : 'KW' '2854';
-KW2855 : 'KW' '2855';
-KW2856 : 'KW' '2856';
-KW2857 : 'KW' '2857';
-KW2858 : 'KW' '2858';
-KW2859 : 'KW' '2859';
-KW2860 : 'KW' '2860';
-KW2861 : 'KW' '2861';
-KW2862 : 'KW' '2862';
-KW2863 : 'KW' '2863';
-KW2864 : 'KW' '2864';
-KW2865 : 'KW' '2865';
-KW2866 : 'KW' '2866';
-KW2867 : 'KW' '2867';
-KW2868 : 'KW' '2868';
-KW2869 : 'KW' '2869';
-KW2870 : 'KW' '2870';
-KW2871 : 'KW' '2871';
-KW2872 : 'KW' '2872';
-KW2873 : 'KW' '2873';
-KW2874 : 'KW' '2874';
-KW2875 : 'KW' '2875';
-KW2876 : 'KW' '2876';
-KW2877 : 'KW' '2877';
-KW2878 : 'KW' '2878';
-KW2879 : 'KW' '2879';
-KW2880 : 'KW' '2880';
-KW2881 : 'KW' '2881';
-KW2882 : 'KW' '2882';
-KW2883 : 'KW' '2883';
-KW2884 : 'KW' '2884';
-KW2885 : 'KW' '2885';
-KW2886 : 'KW' '2886';
-KW2887 : 'KW' '2887';
-KW2888 : 'KW' '2888';
-KW2889 : 'KW' '2889';
-KW2890 : 'KW' '2890';
-KW2891 : 'KW' '2891';
-KW2892 : 'KW' '2892';
-KW2893 : 'KW' '2893';
-KW2894 : 'KW' '2894';
-KW2895 : 'KW' '2895';
-KW2896 : 'KW' '2896';
-KW2897 : 'KW' '2897';
-KW2898 : 'KW' '2898';
-KW2899 : 'KW' '2899';
-KW2900 : 'KW' '2900';
-KW2901 : 'KW' '2901';
-KW2902 : 'KW' '2902';
-KW2903 : 'KW' '2903';
-KW2904 : 'KW' '2904';
-KW2905 : 'KW' '2905';
-KW2906 : 'KW' '2906';
-KW2907 : 'KW' '2907';
-KW2908 : 'KW' '2908';
-KW2909 : 'KW' '2909';
-KW2910 : 'KW' '2910';
-KW2911 : 'KW' '2911';
-KW2912 : 'KW' '2912';
-KW2913 : 'KW' '2913';
-KW2914 : 'KW' '2914';
-KW2915 : 'KW' '2915';
-KW2916 : 'KW' '2916';
-KW2917 : 'KW' '2917';
-KW2918 : 'KW' '2918';
-KW2919 : 'KW' '2919';
-KW2920 : 'KW' '2920';
-KW2921 : 'KW' '2921';
-KW2922 : 'KW' '2922';
-KW2923 : 'KW' '2923';
-KW2924 : 'KW' '2924';
-KW2925 : 'KW' '2925';
-KW2926 : 'KW' '2926';
-KW2927 : 'KW' '2927';
-KW2928 : 'KW' '2928';
-KW2929 : 'KW' '2929';
-KW2930 : 'KW' '2930';
-KW2931 : 'KW' '2931';
-KW2932 : 'KW' '2932';
-KW2933 : 'KW' '2933';
-KW2934 : 'KW' '2934';
-KW2935 : 'KW' '2935';
-KW2936 : 'KW' '2936';
-KW2937 : 'KW' '2937';
-KW2938 : 'KW' '2938';
-KW2939 : 'KW' '2939';
-KW2940 : 'KW' '2940';
-KW2941 : 'KW' '2941';
-KW2942 : 'KW' '2942';
-KW2943 : 'KW' '2943';
-KW2944 : 'KW' '2944';
-KW2945 : 'KW' '2945';
-KW2946 : 'KW' '2946';
-KW2947 : 'KW' '2947';
-KW2948 : 'KW' '2948';
-KW2949 : 'KW' '2949';
-KW2950 : 'KW' '2950';
-KW2951 : 'KW' '2951';
-KW2952 : 'KW' '2952';
-KW2953 : 'KW' '2953';
-KW2954 : 'KW' '2954';
-KW2955 : 'KW' '2955';
-KW2956 : 'KW' '2956';
-KW2957 : 'KW' '2957';
-KW2958 : 'KW' '2958';
-KW2959 : 'KW' '2959';
-KW2960 : 'KW' '2960';
-KW2961 : 'KW' '2961';
-KW2962 : 'KW' '2962';
-KW2963 : 'KW' '2963';
-KW2964 : 'KW' '2964';
-KW2965 : 'KW' '2965';
-KW2966 : 'KW' '2966';
-KW2967 : 'KW' '2967';
-KW2968 : 'KW' '2968';
-KW2969 : 'KW' '2969';
-KW2970 : 'KW' '2970';
-KW2971 : 'KW' '2971';
-KW2972 : 'KW' '2972';
-KW2973 : 'KW' '2973';
-KW2974 : 'KW' '2974';
-KW2975 : 'KW' '2975';
-KW2976 : 'KW' '2976';
-KW2977 : 'KW' '2977';
-KW2978 : 'KW' '2978';
-KW2979 : 'KW' '2979';
-KW2980 : 'KW' '2980';
-KW2981 : 'KW' '2981';
-KW2982 : 'KW' '2982';
-KW2983 : 'KW' '2983';
-KW2984 : 'KW' '2984';
-KW2985 : 'KW' '2985';
-KW2986 : 'KW' '2986';
-KW2987 : 'KW' '2987';
-KW2988 : 'KW' '2988';
-KW2989 : 'KW' '2989';
-KW2990 : 'KW' '2990';
-KW2991 : 'KW' '2991';
-KW2992 : 'KW' '2992';
-KW2993 : 'KW' '2993';
-KW2994 : 'KW' '2994';
-KW2995 : 'KW' '2995';
-KW2996 : 'KW' '2996';
-KW2997 : 'KW' '2997';
-KW2998 : 'KW' '2998';
-KW2999 : 'KW' '2999';
-KW3000 : 'KW' '3000';
-KW3001 : 'KW' '3001';
-KW3002 : 'KW' '3002';
-KW3003 : 'KW' '3003';
-KW3004 : 'KW' '3004';
-KW3005 : 'KW' '3005';
-KW3006 : 'KW' '3006';
-KW3007 : 'KW' '3007';
-KW3008 : 'KW' '3008';
-KW3009 : 'KW' '3009';
-KW3010 : 'KW' '3010';
-KW3011 : 'KW' '3011';
-KW3012 : 'KW' '3012';
-KW3013 : 'KW' '3013';
-KW3014 : 'KW' '3014';
-KW3015 : 'KW' '3015';
-KW3016 : 'KW' '3016';
-KW3017 : 'KW' '3017';
-KW3018 : 'KW' '3018';
-KW3019 : 'KW' '3019';
-KW3020 : 'KW' '3020';
-KW3021 : 'KW' '3021';
-KW3022 : 'KW' '3022';
-KW3023 : 'KW' '3023';
-KW3024 : 'KW' '3024';
-KW3025 : 'KW' '3025';
-KW3026 : 'KW' '3026';
-KW3027 : 'KW' '3027';
-KW3028 : 'KW' '3028';
-KW3029 : 'KW' '3029';
-KW3030 : 'KW' '3030';
-KW3031 : 'KW' '3031';
-KW3032 : 'KW' '3032';
-KW3033 : 'KW' '3033';
-KW3034 : 'KW' '3034';
-KW3035 : 'KW' '3035';
-KW3036 : 'KW' '3036';
-KW3037 : 'KW' '3037';
-KW3038 : 'KW' '3038';
-KW3039 : 'KW' '3039';
-KW3040 : 'KW' '3040';
-KW3041 : 'KW' '3041';
-KW3042 : 'KW' '3042';
-KW3043 : 'KW' '3043';
-KW3044 : 'KW' '3044';
-KW3045 : 'KW' '3045';
-KW3046 : 'KW' '3046';
-KW3047 : 'KW' '3047';
-KW3048 : 'KW' '3048';
-KW3049 : 'KW' '3049';
-KW3050 : 'KW' '3050';
-KW3051 : 'KW' '3051';
-KW3052 : 'KW' '3052';
-KW3053 : 'KW' '3053';
-KW3054 : 'KW' '3054';
-KW3055 : 'KW' '3055';
-KW3056 : 'KW' '3056';
-KW3057 : 'KW' '3057';
-KW3058 : 'KW' '3058';
-KW3059 : 'KW' '3059';
-KW3060 : 'KW' '3060';
-KW3061 : 'KW' '3061';
-KW3062 : 'KW' '3062';
-KW3063 : 'KW' '3063';
-KW3064 : 'KW' '3064';
-KW3065 : 'KW' '3065';
-KW3066 : 'KW' '3066';
-KW3067 : 'KW' '3067';
-KW3068 : 'KW' '3068';
-KW3069 : 'KW' '3069';
-KW3070 : 'KW' '3070';
-KW3071 : 'KW' '3071';
-KW3072 : 'KW' '3072';
-KW3073 : 'KW' '3073';
-KW3074 : 'KW' '3074';
-KW3075 : 'KW' '3075';
-KW3076 : 'KW' '3076';
-KW3077 : 'KW' '3077';
-KW3078 : 'KW' '3078';
-KW3079 : 'KW' '3079';
-KW3080 : 'KW' '3080';
-KW3081 : 'KW' '3081';
-KW3082 : 'KW' '3082';
-KW3083 : 'KW' '3083';
-KW3084 : 'KW' '3084';
-KW3085 : 'KW' '3085';
-KW3086 : 'KW' '3086';
-KW3087 : 'KW' '3087';
-KW3088 : 'KW' '3088';
-KW3089 : 'KW' '3089';
-KW3090 : 'KW' '3090';
-KW3091 : 'KW' '3091';
-KW3092 : 'KW' '3092';
-KW3093 : 'KW' '3093';
-KW3094 : 'KW' '3094';
-KW3095 : 'KW' '3095';
-KW3096 : 'KW' '3096';
-KW3097 : 'KW' '3097';
-KW3098 : 'KW' '3098';
-KW3099 : 'KW' '3099';
-KW3100 : 'KW' '3100';
-KW3101 : 'KW' '3101';
-KW3102 : 'KW' '3102';
-KW3103 : 'KW' '3103';
-KW3104 : 'KW' '3104';
-KW3105 : 'KW' '3105';
-KW3106 : 'KW' '3106';
-KW3107 : 'KW' '3107';
-KW3108 : 'KW' '3108';
-KW3109 : 'KW' '3109';
-KW3110 : 'KW' '3110';
-KW3111 : 'KW' '3111';
-KW3112 : 'KW' '3112';
-KW3113 : 'KW' '3113';
-KW3114 : 'KW' '3114';
-KW3115 : 'KW' '3115';
-KW3116 : 'KW' '3116';
-KW3117 : 'KW' '3117';
-KW3118 : 'KW' '3118';
-KW3119 : 'KW' '3119';
-KW3120 : 'KW' '3120';
-KW3121 : 'KW' '3121';
-KW3122 : 'KW' '3122';
-KW3123 : 'KW' '3123';
-KW3124 : 'KW' '3124';
-KW3125 : 'KW' '3125';
-KW3126 : 'KW' '3126';
-KW3127 : 'KW' '3127';
-KW3128 : 'KW' '3128';
-KW3129 : 'KW' '3129';
-KW3130 : 'KW' '3130';
-KW3131 : 'KW' '3131';
-KW3132 : 'KW' '3132';
-KW3133 : 'KW' '3133';
-KW3134 : 'KW' '3134';
-KW3135 : 'KW' '3135';
-KW3136 : 'KW' '3136';
-KW3137 : 'KW' '3137';
-KW3138 : 'KW' '3138';
-KW3139 : 'KW' '3139';
-KW3140 : 'KW' '3140';
-KW3141 : 'KW' '3141';
-KW3142 : 'KW' '3142';
-KW3143 : 'KW' '3143';
-KW3144 : 'KW' '3144';
-KW3145 : 'KW' '3145';
-KW3146 : 'KW' '3146';
-KW3147 : 'KW' '3147';
-KW3148 : 'KW' '3148';
-KW3149 : 'KW' '3149';
-KW3150 : 'KW' '3150';
-KW3151 : 'KW' '3151';
-KW3152 : 'KW' '3152';
-KW3153 : 'KW' '3153';
-KW3154 : 'KW' '3154';
-KW3155 : 'KW' '3155';
-KW3156 : 'KW' '3156';
-KW3157 : 'KW' '3157';
-KW3158 : 'KW' '3158';
-KW3159 : 'KW' '3159';
-KW3160 : 'KW' '3160';
-KW3161 : 'KW' '3161';
-KW3162 : 'KW' '3162';
-KW3163 : 'KW' '3163';
-KW3164 : 'KW' '3164';
-KW3165 : 'KW' '3165';
-KW3166 : 'KW' '3166';
-KW3167 : 'KW' '3167';
-KW3168 : 'KW' '3168';
-KW3169 : 'KW' '3169';
-KW3170 : 'KW' '3170';
-KW3171 : 'KW' '3171';
-KW3172 : 'KW' '3172';
-KW3173 : 'KW' '3173';
-KW3174 : 'KW' '3174';
-KW3175 : 'KW' '3175';
-KW3176 : 'KW' '3176';
-KW3177 : 'KW' '3177';
-KW3178 : 'KW' '3178';
-KW3179 : 'KW' '3179';
-KW3180 : 'KW' '3180';
-KW3181 : 'KW' '3181';
-KW3182 : 'KW' '3182';
-KW3183 : 'KW' '3183';
-KW3184 : 'KW' '3184';
-KW3185 : 'KW' '3185';
-KW3186 : 'KW' '3186';
-KW3187 : 'KW' '3187';
-KW3188 : 'KW' '3188';
-KW3189 : 'KW' '3189';
-KW3190 : 'KW' '3190';
-KW3191 : 'KW' '3191';
-KW3192 : 'KW' '3192';
-KW3193 : 'KW' '3193';
-KW3194 : 'KW' '3194';
-KW3195 : 'KW' '3195';
-KW3196 : 'KW' '3196';
-KW3197 : 'KW' '3197';
-KW3198 : 'KW' '3198';
-KW3199 : 'KW' '3199';
-KW3200 : 'KW' '3200';
-KW3201 : 'KW' '3201';
-KW3202 : 'KW' '3202';
-KW3203 : 'KW' '3203';
-KW3204 : 'KW' '3204';
-KW3205 : 'KW' '3205';
-KW3206 : 'KW' '3206';
-KW3207 : 'KW' '3207';
-KW3208 : 'KW' '3208';
-KW3209 : 'KW' '3209';
-KW3210 : 'KW' '3210';
-KW3211 : 'KW' '3211';
-KW3212 : 'KW' '3212';
-KW3213 : 'KW' '3213';
-KW3214 : 'KW' '3214';
-KW3215 : 'KW' '3215';
-KW3216 : 'KW' '3216';
-KW3217 : 'KW' '3217';
-KW3218 : 'KW' '3218';
-KW3219 : 'KW' '3219';
-KW3220 : 'KW' '3220';
-KW3221 : 'KW' '3221';
-KW3222 : 'KW' '3222';
-KW3223 : 'KW' '3223';
-KW3224 : 'KW' '3224';
-KW3225 : 'KW' '3225';
-KW3226 : 'KW' '3226';
-KW3227 : 'KW' '3227';
-KW3228 : 'KW' '3228';
-KW3229 : 'KW' '3229';
-KW3230 : 'KW' '3230';
-KW3231 : 'KW' '3231';
-KW3232 : 'KW' '3232';
-KW3233 : 'KW' '3233';
-KW3234 : 'KW' '3234';
-KW3235 : 'KW' '3235';
-KW3236 : 'KW' '3236';
-KW3237 : 'KW' '3237';
-KW3238 : 'KW' '3238';
-KW3239 : 'KW' '3239';
-KW3240 : 'KW' '3240';
-KW3241 : 'KW' '3241';
-KW3242 : 'KW' '3242';
-KW3243 : 'KW' '3243';
-KW3244 : 'KW' '3244';
-KW3245 : 'KW' '3245';
-KW3246 : 'KW' '3246';
-KW3247 : 'KW' '3247';
-KW3248 : 'KW' '3248';
-KW3249 : 'KW' '3249';
-KW3250 : 'KW' '3250';
-KW3251 : 'KW' '3251';
-KW3252 : 'KW' '3252';
-KW3253 : 'KW' '3253';
-KW3254 : 'KW' '3254';
-KW3255 : 'KW' '3255';
-KW3256 : 'KW' '3256';
-KW3257 : 'KW' '3257';
-KW3258 : 'KW' '3258';
-KW3259 : 'KW' '3259';
-KW3260 : 'KW' '3260';
-KW3261 : 'KW' '3261';
-KW3262 : 'KW' '3262';
-KW3263 : 'KW' '3263';
-KW3264 : 'KW' '3264';
-KW3265 : 'KW' '3265';
-KW3266 : 'KW' '3266';
-KW3267 : 'KW' '3267';
-KW3268 : 'KW' '3268';
-KW3269 : 'KW' '3269';
-KW3270 : 'KW' '3270';
-KW3271 : 'KW' '3271';
-KW3272 : 'KW' '3272';
-KW3273 : 'KW' '3273';
-KW3274 : 'KW' '3274';
-KW3275 : 'KW' '3275';
-KW3276 : 'KW' '3276';
-KW3277 : 'KW' '3277';
-KW3278 : 'KW' '3278';
-KW3279 : 'KW' '3279';
-KW3280 : 'KW' '3280';
-KW3281 : 'KW' '3281';
-KW3282 : 'KW' '3282';
-KW3283 : 'KW' '3283';
-KW3284 : 'KW' '3284';
-KW3285 : 'KW' '3285';
-KW3286 : 'KW' '3286';
-KW3287 : 'KW' '3287';
-KW3288 : 'KW' '3288';
-KW3289 : 'KW' '3289';
-KW3290 : 'KW' '3290';
-KW3291 : 'KW' '3291';
-KW3292 : 'KW' '3292';
-KW3293 : 'KW' '3293';
-KW3294 : 'KW' '3294';
-KW3295 : 'KW' '3295';
-KW3296 : 'KW' '3296';
-KW3297 : 'KW' '3297';
-KW3298 : 'KW' '3298';
-KW3299 : 'KW' '3299';
-KW3300 : 'KW' '3300';
-KW3301 : 'KW' '3301';
-KW3302 : 'KW' '3302';
-KW3303 : 'KW' '3303';
-KW3304 : 'KW' '3304';
-KW3305 : 'KW' '3305';
-KW3306 : 'KW' '3306';
-KW3307 : 'KW' '3307';
-KW3308 : 'KW' '3308';
-KW3309 : 'KW' '3309';
-KW3310 : 'KW' '3310';
-KW3311 : 'KW' '3311';
-KW3312 : 'KW' '3312';
-KW3313 : 'KW' '3313';
-KW3314 : 'KW' '3314';
-KW3315 : 'KW' '3315';
-KW3316 : 'KW' '3316';
-KW3317 : 'KW' '3317';
-KW3318 : 'KW' '3318';
-KW3319 : 'KW' '3319';
-KW3320 : 'KW' '3320';
-KW3321 : 'KW' '3321';
-KW3322 : 'KW' '3322';
-KW3323 : 'KW' '3323';
-KW3324 : 'KW' '3324';
-KW3325 : 'KW' '3325';
-KW3326 : 'KW' '3326';
-KW3327 : 'KW' '3327';
-KW3328 : 'KW' '3328';
-KW3329 : 'KW' '3329';
-KW3330 : 'KW' '3330';
-KW3331 : 'KW' '3331';
-KW3332 : 'KW' '3332';
-KW3333 : 'KW' '3333';
-KW3334 : 'KW' '3334';
-KW3335 : 'KW' '3335';
-KW3336 : 'KW' '3336';
-KW3337 : 'KW' '3337';
-KW3338 : 'KW' '3338';
-KW3339 : 'KW' '3339';
-KW3340 : 'KW' '3340';
-KW3341 : 'KW' '3341';
-KW3342 : 'KW' '3342';
-KW3343 : 'KW' '3343';
-KW3344 : 'KW' '3344';
-KW3345 : 'KW' '3345';
-KW3346 : 'KW' '3346';
-KW3347 : 'KW' '3347';
-KW3348 : 'KW' '3348';
-KW3349 : 'KW' '3349';
-KW3350 : 'KW' '3350';
-KW3351 : 'KW' '3351';
-KW3352 : 'KW' '3352';
-KW3353 : 'KW' '3353';
-KW3354 : 'KW' '3354';
-KW3355 : 'KW' '3355';
-KW3356 : 'KW' '3356';
-KW3357 : 'KW' '3357';
-KW3358 : 'KW' '3358';
-KW3359 : 'KW' '3359';
-KW3360 : 'KW' '3360';
-KW3361 : 'KW' '3361';
-KW3362 : 'KW' '3362';
-KW3363 : 'KW' '3363';
-KW3364 : 'KW' '3364';
-KW3365 : 'KW' '3365';
-KW3366 : 'KW' '3366';
-KW3367 : 'KW' '3367';
-KW3368 : 'KW' '3368';
-KW3369 : 'KW' '3369';
-KW3370 : 'KW' '3370';
-KW3371 : 'KW' '3371';
-KW3372 : 'KW' '3372';
-KW3373 : 'KW' '3373';
-KW3374 : 'KW' '3374';
-KW3375 : 'KW' '3375';
-KW3376 : 'KW' '3376';
-KW3377 : 'KW' '3377';
-KW3378 : 'KW' '3378';
-KW3379 : 'KW' '3379';
-KW3380 : 'KW' '3380';
-KW3381 : 'KW' '3381';
-KW3382 : 'KW' '3382';
-KW3383 : 'KW' '3383';
-KW3384 : 'KW' '3384';
-KW3385 : 'KW' '3385';
-KW3386 : 'KW' '3386';
-KW3387 : 'KW' '3387';
-KW3388 : 'KW' '3388';
-KW3389 : 'KW' '3389';
-KW3390 : 'KW' '3390';
-KW3391 : 'KW' '3391';
-KW3392 : 'KW' '3392';
-KW3393 : 'KW' '3393';
-KW3394 : 'KW' '3394';
-KW3395 : 'KW' '3395';
-KW3396 : 'KW' '3396';
-KW3397 : 'KW' '3397';
-KW3398 : 'KW' '3398';
-KW3399 : 'KW' '3399';
-KW3400 : 'KW' '3400';
-KW3401 : 'KW' '3401';
-KW3402 : 'KW' '3402';
-KW3403 : 'KW' '3403';
-KW3404 : 'KW' '3404';
-KW3405 : 'KW' '3405';
-KW3406 : 'KW' '3406';
-KW3407 : 'KW' '3407';
-KW3408 : 'KW' '3408';
-KW3409 : 'KW' '3409';
-KW3410 : 'KW' '3410';
-KW3411 : 'KW' '3411';
-KW3412 : 'KW' '3412';
-KW3413 : 'KW' '3413';
-KW3414 : 'KW' '3414';
-KW3415 : 'KW' '3415';
-KW3416 : 'KW' '3416';
-KW3417 : 'KW' '3417';
-KW3418 : 'KW' '3418';
-KW3419 : 'KW' '3419';
-KW3420 : 'KW' '3420';
-KW3421 : 'KW' '3421';
-KW3422 : 'KW' '3422';
-KW3423 : 'KW' '3423';
-KW3424 : 'KW' '3424';
-KW3425 : 'KW' '3425';
-KW3426 : 'KW' '3426';
-KW3427 : 'KW' '3427';
-KW3428 : 'KW' '3428';
-KW3429 : 'KW' '3429';
-KW3430 : 'KW' '3430';
-KW3431 : 'KW' '3431';
-KW3432 : 'KW' '3432';
-KW3433 : 'KW' '3433';
-KW3434 : 'KW' '3434';
-KW3435 : 'KW' '3435';
-KW3436 : 'KW' '3436';
-KW3437 : 'KW' '3437';
-KW3438 : 'KW' '3438';
-KW3439 : 'KW' '3439';
-KW3440 : 'KW' '3440';
-KW3441 : 'KW' '3441';
-KW3442 : 'KW' '3442';
-KW3443 : 'KW' '3443';
-KW3444 : 'KW' '3444';
-KW3445 : 'KW' '3445';
-KW3446 : 'KW' '3446';
-KW3447 : 'KW' '3447';
-KW3448 : 'KW' '3448';
-KW3449 : 'KW' '3449';
-KW3450 : 'KW' '3450';
-KW3451 : 'KW' '3451';
-KW3452 : 'KW' '3452';
-KW3453 : 'KW' '3453';
-KW3454 : 'KW' '3454';
-KW3455 : 'KW' '3455';
-KW3456 : 'KW' '3456';
-KW3457 : 'KW' '3457';
-KW3458 : 'KW' '3458';
-KW3459 : 'KW' '3459';
-KW3460 : 'KW' '3460';
-KW3461 : 'KW' '3461';
-KW3462 : 'KW' '3462';
-KW3463 : 'KW' '3463';
-KW3464 : 'KW' '3464';
-KW3465 : 'KW' '3465';
-KW3466 : 'KW' '3466';
-KW3467 : 'KW' '3467';
-KW3468 : 'KW' '3468';
-KW3469 : 'KW' '3469';
-KW3470 : 'KW' '3470';
-KW3471 : 'KW' '3471';
-KW3472 : 'KW' '3472';
-KW3473 : 'KW' '3473';
-KW3474 : 'KW' '3474';
-KW3475 : 'KW' '3475';
-KW3476 : 'KW' '3476';
-KW3477 : 'KW' '3477';
-KW3478 : 'KW' '3478';
-KW3479 : 'KW' '3479';
-KW3480 : 'KW' '3480';
-KW3481 : 'KW' '3481';
-KW3482 : 'KW' '3482';
-KW3483 : 'KW' '3483';
-KW3484 : 'KW' '3484';
-KW3485 : 'KW' '3485';
-KW3486 : 'KW' '3486';
-KW3487 : 'KW' '3487';
-KW3488 : 'KW' '3488';
-KW3489 : 'KW' '3489';
-KW3490 : 'KW' '3490';
-KW3491 : 'KW' '3491';
-KW3492 : 'KW' '3492';
-KW3493 : 'KW' '3493';
-KW3494 : 'KW' '3494';
-KW3495 : 'KW' '3495';
-KW3496 : 'KW' '3496';
-KW3497 : 'KW' '3497';
-KW3498 : 'KW' '3498';
-KW3499 : 'KW' '3499';
-KW3500 : 'KW' '3500';
-KW3501 : 'KW' '3501';
-KW3502 : 'KW' '3502';
-KW3503 : 'KW' '3503';
-KW3504 : 'KW' '3504';
-KW3505 : 'KW' '3505';
-KW3506 : 'KW' '3506';
-KW3507 : 'KW' '3507';
-KW3508 : 'KW' '3508';
-KW3509 : 'KW' '3509';
-KW3510 : 'KW' '3510';
-KW3511 : 'KW' '3511';
-KW3512 : 'KW' '3512';
-KW3513 : 'KW' '3513';
-KW3514 : 'KW' '3514';
-KW3515 : 'KW' '3515';
-KW3516 : 'KW' '3516';
-KW3517 : 'KW' '3517';
-KW3518 : 'KW' '3518';
-KW3519 : 'KW' '3519';
-KW3520 : 'KW' '3520';
-KW3521 : 'KW' '3521';
-KW3522 : 'KW' '3522';
-KW3523 : 'KW' '3523';
-KW3524 : 'KW' '3524';
-KW3525 : 'KW' '3525';
-KW3526 : 'KW' '3526';
-KW3527 : 'KW' '3527';
-KW3528 : 'KW' '3528';
-KW3529 : 'KW' '3529';
-KW3530 : 'KW' '3530';
-KW3531 : 'KW' '3531';
-KW3532 : 'KW' '3532';
-KW3533 : 'KW' '3533';
-KW3534 : 'KW' '3534';
-KW3535 : 'KW' '3535';
-KW3536 : 'KW' '3536';
-KW3537 : 'KW' '3537';
-KW3538 : 'KW' '3538';
-KW3539 : 'KW' '3539';
-KW3540 : 'KW' '3540';
-KW3541 : 'KW' '3541';
-KW3542 : 'KW' '3542';
-KW3543 : 'KW' '3543';
-KW3544 : 'KW' '3544';
-KW3545 : 'KW' '3545';
-KW3546 : 'KW' '3546';
-KW3547 : 'KW' '3547';
-KW3548 : 'KW' '3548';
-KW3549 : 'KW' '3549';
-KW3550 : 'KW' '3550';
-KW3551 : 'KW' '3551';
-KW3552 : 'KW' '3552';
-KW3553 : 'KW' '3553';
-KW3554 : 'KW' '3554';
-KW3555 : 'KW' '3555';
-KW3556 : 'KW' '3556';
-KW3557 : 'KW' '3557';
-KW3558 : 'KW' '3558';
-KW3559 : 'KW' '3559';
-KW3560 : 'KW' '3560';
-KW3561 : 'KW' '3561';
-KW3562 : 'KW' '3562';
-KW3563 : 'KW' '3563';
-KW3564 : 'KW' '3564';
-KW3565 : 'KW' '3565';
-KW3566 : 'KW' '3566';
-KW3567 : 'KW' '3567';
-KW3568 : 'KW' '3568';
-KW3569 : 'KW' '3569';
-KW3570 : 'KW' '3570';
-KW3571 : 'KW' '3571';
-KW3572 : 'KW' '3572';
-KW3573 : 'KW' '3573';
-KW3574 : 'KW' '3574';
-KW3575 : 'KW' '3575';
-KW3576 : 'KW' '3576';
-KW3577 : 'KW' '3577';
-KW3578 : 'KW' '3578';
-KW3579 : 'KW' '3579';
-KW3580 : 'KW' '3580';
-KW3581 : 'KW' '3581';
-KW3582 : 'KW' '3582';
-KW3583 : 'KW' '3583';
-KW3584 : 'KW' '3584';
-KW3585 : 'KW' '3585';
-KW3586 : 'KW' '3586';
-KW3587 : 'KW' '3587';
-KW3588 : 'KW' '3588';
-KW3589 : 'KW' '3589';
-KW3590 : 'KW' '3590';
-KW3591 : 'KW' '3591';
-KW3592 : 'KW' '3592';
-KW3593 : 'KW' '3593';
-KW3594 : 'KW' '3594';
-KW3595 : 'KW' '3595';
-KW3596 : 'KW' '3596';
-KW3597 : 'KW' '3597';
-KW3598 : 'KW' '3598';
-KW3599 : 'KW' '3599';
-KW3600 : 'KW' '3600';
-KW3601 : 'KW' '3601';
-KW3602 : 'KW' '3602';
-KW3603 : 'KW' '3603';
-KW3604 : 'KW' '3604';
-KW3605 : 'KW' '3605';
-KW3606 : 'KW' '3606';
-KW3607 : 'KW' '3607';
-KW3608 : 'KW' '3608';
-KW3609 : 'KW' '3609';
-KW3610 : 'KW' '3610';
-KW3611 : 'KW' '3611';
-KW3612 : 'KW' '3612';
-KW3613 : 'KW' '3613';
-KW3614 : 'KW' '3614';
-KW3615 : 'KW' '3615';
-KW3616 : 'KW' '3616';
-KW3617 : 'KW' '3617';
-KW3618 : 'KW' '3618';
-KW3619 : 'KW' '3619';
-KW3620 : 'KW' '3620';
-KW3621 : 'KW' '3621';
-KW3622 : 'KW' '3622';
-KW3623 : 'KW' '3623';
-KW3624 : 'KW' '3624';
-KW3625 : 'KW' '3625';
-KW3626 : 'KW' '3626';
-KW3627 : 'KW' '3627';
-KW3628 : 'KW' '3628';
-KW3629 : 'KW' '3629';
-KW3630 : 'KW' '3630';
-KW3631 : 'KW' '3631';
-KW3632 : 'KW' '3632';
-KW3633 : 'KW' '3633';
-KW3634 : 'KW' '3634';
-KW3635 : 'KW' '3635';
-KW3636 : 'KW' '3636';
-KW3637 : 'KW' '3637';
-KW3638 : 'KW' '3638';
-KW3639 : 'KW' '3639';
-KW3640 : 'KW' '3640';
-KW3641 : 'KW' '3641';
-KW3642 : 'KW' '3642';
-KW3643 : 'KW' '3643';
-KW3644 : 'KW' '3644';
-KW3645 : 'KW' '3645';
-KW3646 : 'KW' '3646';
-KW3647 : 'KW' '3647';
-KW3648 : 'KW' '3648';
-KW3649 : 'KW' '3649';
-KW3650 : 'KW' '3650';
-KW3651 : 'KW' '3651';
-KW3652 : 'KW' '3652';
-KW3653 : 'KW' '3653';
-KW3654 : 'KW' '3654';
-KW3655 : 'KW' '3655';
-KW3656 : 'KW' '3656';
-KW3657 : 'KW' '3657';
-KW3658 : 'KW' '3658';
-KW3659 : 'KW' '3659';
-KW3660 : 'KW' '3660';
-KW3661 : 'KW' '3661';
-KW3662 : 'KW' '3662';
-KW3663 : 'KW' '3663';
-KW3664 : 'KW' '3664';
-KW3665 : 'KW' '3665';
-KW3666 : 'KW' '3666';
-KW3667 : 'KW' '3667';
-KW3668 : 'KW' '3668';
-KW3669 : 'KW' '3669';
-KW3670 : 'KW' '3670';
-KW3671 : 'KW' '3671';
-KW3672 : 'KW' '3672';
-KW3673 : 'KW' '3673';
-KW3674 : 'KW' '3674';
-KW3675 : 'KW' '3675';
-KW3676 : 'KW' '3676';
-KW3677 : 'KW' '3677';
-KW3678 : 'KW' '3678';
-KW3679 : 'KW' '3679';
-KW3680 : 'KW' '3680';
-KW3681 : 'KW' '3681';
-KW3682 : 'KW' '3682';
-KW3683 : 'KW' '3683';
-KW3684 : 'KW' '3684';
-KW3685 : 'KW' '3685';
-KW3686 : 'KW' '3686';
-KW3687 : 'KW' '3687';
-KW3688 : 'KW' '3688';
-KW3689 : 'KW' '3689';
-KW3690 : 'KW' '3690';
-KW3691 : 'KW' '3691';
-KW3692 : 'KW' '3692';
-KW3693 : 'KW' '3693';
-KW3694 : 'KW' '3694';
-KW3695 : 'KW' '3695';
-KW3696 : 'KW' '3696';
-KW3697 : 'KW' '3697';
-KW3698 : 'KW' '3698';
-KW3699 : 'KW' '3699';
-KW3700 : 'KW' '3700';
-KW3701 : 'KW' '3701';
-KW3702 : 'KW' '3702';
-KW3703 : 'KW' '3703';
-KW3704 : 'KW' '3704';
-KW3705 : 'KW' '3705';
-KW3706 : 'KW' '3706';
-KW3707 : 'KW' '3707';
-KW3708 : 'KW' '3708';
-KW3709 : 'KW' '3709';
-KW3710 : 'KW' '3710';
-KW3711 : 'KW' '3711';
-KW3712 : 'KW' '3712';
-KW3713 : 'KW' '3713';
-KW3714 : 'KW' '3714';
-KW3715 : 'KW' '3715';
-KW3716 : 'KW' '3716';
-KW3717 : 'KW' '3717';
-KW3718 : 'KW' '3718';
-KW3719 : 'KW' '3719';
-KW3720 : 'KW' '3720';
-KW3721 : 'KW' '3721';
-KW3722 : 'KW' '3722';
-KW3723 : 'KW' '3723';
-KW3724 : 'KW' '3724';
-KW3725 : 'KW' '3725';
-KW3726 : 'KW' '3726';
-KW3727 : 'KW' '3727';
-KW3728 : 'KW' '3728';
-KW3729 : 'KW' '3729';
-KW3730 : 'KW' '3730';
-KW3731 : 'KW' '3731';
-KW3732 : 'KW' '3732';
-KW3733 : 'KW' '3733';
-KW3734 : 'KW' '3734';
-KW3735 : 'KW' '3735';
-KW3736 : 'KW' '3736';
-KW3737 : 'KW' '3737';
-KW3738 : 'KW' '3738';
-KW3739 : 'KW' '3739';
-KW3740 : 'KW' '3740';
-KW3741 : 'KW' '3741';
-KW3742 : 'KW' '3742';
-KW3743 : 'KW' '3743';
-KW3744 : 'KW' '3744';
-KW3745 : 'KW' '3745';
-KW3746 : 'KW' '3746';
-KW3747 : 'KW' '3747';
-KW3748 : 'KW' '3748';
-KW3749 : 'KW' '3749';
-KW3750 : 'KW' '3750';
-KW3751 : 'KW' '3751';
-KW3752 : 'KW' '3752';
-KW3753 : 'KW' '3753';
-KW3754 : 'KW' '3754';
-KW3755 : 'KW' '3755';
-KW3756 : 'KW' '3756';
-KW3757 : 'KW' '3757';
-KW3758 : 'KW' '3758';
-KW3759 : 'KW' '3759';
-KW3760 : 'KW' '3760';
-KW3761 : 'KW' '3761';
-KW3762 : 'KW' '3762';
-KW3763 : 'KW' '3763';
-KW3764 : 'KW' '3764';
-KW3765 : 'KW' '3765';
-KW3766 : 'KW' '3766';
-KW3767 : 'KW' '3767';
-KW3768 : 'KW' '3768';
-KW3769 : 'KW' '3769';
-KW3770 : 'KW' '3770';
-KW3771 : 'KW' '3771';
-KW3772 : 'KW' '3772';
-KW3773 : 'KW' '3773';
-KW3774 : 'KW' '3774';
-KW3775 : 'KW' '3775';
-KW3776 : 'KW' '3776';
-KW3777 : 'KW' '3777';
-KW3778 : 'KW' '3778';
-KW3779 : 'KW' '3779';
-KW3780 : 'KW' '3780';
-KW3781 : 'KW' '3781';
-KW3782 : 'KW' '3782';
-KW3783 : 'KW' '3783';
-KW3784 : 'KW' '3784';
-KW3785 : 'KW' '3785';
-KW3786 : 'KW' '3786';
-KW3787 : 'KW' '3787';
-KW3788 : 'KW' '3788';
-KW3789 : 'KW' '3789';
-KW3790 : 'KW' '3790';
-KW3791 : 'KW' '3791';
-KW3792 : 'KW' '3792';
-KW3793 : 'KW' '3793';
-KW3794 : 'KW' '3794';
-KW3795 : 'KW' '3795';
-KW3796 : 'KW' '3796';
-KW3797 : 'KW' '3797';
-KW3798 : 'KW' '3798';
-KW3799 : 'KW' '3799';
-KW3800 : 'KW' '3800';
-KW3801 : 'KW' '3801';
-KW3802 : 'KW' '3802';
-KW3803 : 'KW' '3803';
-KW3804 : 'KW' '3804';
-KW3805 : 'KW' '3805';
-KW3806 : 'KW' '3806';
-KW3807 : 'KW' '3807';
-KW3808 : 'KW' '3808';
-KW3809 : 'KW' '3809';
-KW3810 : 'KW' '3810';
-KW3811 : 'KW' '3811';
-KW3812 : 'KW' '3812';
-KW3813 : 'KW' '3813';
-KW3814 : 'KW' '3814';
-KW3815 : 'KW' '3815';
-KW3816 : 'KW' '3816';
-KW3817 : 'KW' '3817';
-KW3818 : 'KW' '3818';
-KW3819 : 'KW' '3819';
-KW3820 : 'KW' '3820';
-KW3821 : 'KW' '3821';
-KW3822 : 'KW' '3822';
-KW3823 : 'KW' '3823';
-KW3824 : 'KW' '3824';
-KW3825 : 'KW' '3825';
-KW3826 : 'KW' '3826';
-KW3827 : 'KW' '3827';
-KW3828 : 'KW' '3828';
-KW3829 : 'KW' '3829';
-KW3830 : 'KW' '3830';
-KW3831 : 'KW' '3831';
-KW3832 : 'KW' '3832';
-KW3833 : 'KW' '3833';
-KW3834 : 'KW' '3834';
-KW3835 : 'KW' '3835';
-KW3836 : 'KW' '3836';
-KW3837 : 'KW' '3837';
-KW3838 : 'KW' '3838';
-KW3839 : 'KW' '3839';
-KW3840 : 'KW' '3840';
-KW3841 : 'KW' '3841';
-KW3842 : 'KW' '3842';
-KW3843 : 'KW' '3843';
-KW3844 : 'KW' '3844';
-KW3845 : 'KW' '3845';
-KW3846 : 'KW' '3846';
-KW3847 : 'KW' '3847';
-KW3848 : 'KW' '3848';
-KW3849 : 'KW' '3849';
-KW3850 : 'KW' '3850';
-KW3851 : 'KW' '3851';
-KW3852 : 'KW' '3852';
-KW3853 : 'KW' '3853';
-KW3854 : 'KW' '3854';
-KW3855 : 'KW' '3855';
-KW3856 : 'KW' '3856';
-KW3857 : 'KW' '3857';
-KW3858 : 'KW' '3858';
-KW3859 : 'KW' '3859';
-KW3860 : 'KW' '3860';
-KW3861 : 'KW' '3861';
-KW3862 : 'KW' '3862';
-KW3863 : 'KW' '3863';
-KW3864 : 'KW' '3864';
-KW3865 : 'KW' '3865';
-KW3866 : 'KW' '3866';
-KW3867 : 'KW' '3867';
-KW3868 : 'KW' '3868';
-KW3869 : 'KW' '3869';
-KW3870 : 'KW' '3870';
-KW3871 : 'KW' '3871';
-KW3872 : 'KW' '3872';
-KW3873 : 'KW' '3873';
-KW3874 : 'KW' '3874';
-KW3875 : 'KW' '3875';
-KW3876 : 'KW' '3876';
-KW3877 : 'KW' '3877';
-KW3878 : 'KW' '3878';
-KW3879 : 'KW' '3879';
-KW3880 : 'KW' '3880';
-KW3881 : 'KW' '3881';
-KW3882 : 'KW' '3882';
-KW3883 : 'KW' '3883';
-KW3884 : 'KW' '3884';
-KW3885 : 'KW' '3885';
-KW3886 : 'KW' '3886';
-KW3887 : 'KW' '3887';
-KW3888 : 'KW' '3888';
-KW3889 : 'KW' '3889';
-KW3890 : 'KW' '3890';
-KW3891 : 'KW' '3891';
-KW3892 : 'KW' '3892';
-KW3893 : 'KW' '3893';
-KW3894 : 'KW' '3894';
-KW3895 : 'KW' '3895';
-KW3896 : 'KW' '3896';
-KW3897 : 'KW' '3897';
-KW3898 : 'KW' '3898';
-KW3899 : 'KW' '3899';
-KW3900 : 'KW' '3900';
-KW3901 : 'KW' '3901';
-KW3902 : 'KW' '3902';
-KW3903 : 'KW' '3903';
-KW3904 : 'KW' '3904';
-KW3905 : 'KW' '3905';
-KW3906 : 'KW' '3906';
-KW3907 : 'KW' '3907';
-KW3908 : 'KW' '3908';
-KW3909 : 'KW' '3909';
-KW3910 : 'KW' '3910';
-KW3911 : 'KW' '3911';
-KW3912 : 'KW' '3912';
-KW3913 : 'KW' '3913';
-KW3914 : 'KW' '3914';
-KW3915 : 'KW' '3915';
-KW3916 : 'KW' '3916';
-KW3917 : 'KW' '3917';
-KW3918 : 'KW' '3918';
-KW3919 : 'KW' '3919';
-KW3920 : 'KW' '3920';
-KW3921 : 'KW' '3921';
-KW3922 : 'KW' '3922';
-KW3923 : 'KW' '3923';
-KW3924 : 'KW' '3924';
-KW3925 : 'KW' '3925';
-KW3926 : 'KW' '3926';
-KW3927 : 'KW' '3927';
-KW3928 : 'KW' '3928';
-KW3929 : 'KW' '3929';
-KW3930 : 'KW' '3930';
-KW3931 : 'KW' '3931';
-KW3932 : 'KW' '3932';
-KW3933 : 'KW' '3933';
-KW3934 : 'KW' '3934';
-KW3935 : 'KW' '3935';
-KW3936 : 'KW' '3936';
-KW3937 : 'KW' '3937';
-KW3938 : 'KW' '3938';
-KW3939 : 'KW' '3939';
-KW3940 : 'KW' '3940';
-KW3941 : 'KW' '3941';
-KW3942 : 'KW' '3942';
-KW3943 : 'KW' '3943';
-KW3944 : 'KW' '3944';
-KW3945 : 'KW' '3945';
-KW3946 : 'KW' '3946';
-KW3947 : 'KW' '3947';
-KW3948 : 'KW' '3948';
-KW3949 : 'KW' '3949';
-KW3950 : 'KW' '3950';
-KW3951 : 'KW' '3951';
-KW3952 : 'KW' '3952';
-KW3953 : 'KW' '3953';
-KW3954 : 'KW' '3954';
-KW3955 : 'KW' '3955';
-KW3956 : 'KW' '3956';
-KW3957 : 'KW' '3957';
-KW3958 : 'KW' '3958';
-KW3959 : 'KW' '3959';
-KW3960 : 'KW' '3960';
-KW3961 : 'KW' '3961';
-KW3962 : 'KW' '3962';
-KW3963 : 'KW' '3963';
-KW3964 : 'KW' '3964';
-KW3965 : 'KW' '3965';
-KW3966 : 'KW' '3966';
-KW3967 : 'KW' '3967';
-KW3968 : 'KW' '3968';
-KW3969 : 'KW' '3969';
-KW3970 : 'KW' '3970';
-KW3971 : 'KW' '3971';
-KW3972 : 'KW' '3972';
-KW3973 : 'KW' '3973';
-KW3974 : 'KW' '3974';
-KW3975 : 'KW' '3975';
-KW3976 : 'KW' '3976';
-KW3977 : 'KW' '3977';
-KW3978 : 'KW' '3978';
-KW3979 : 'KW' '3979';
-KW3980 : 'KW' '3980';
-KW3981 : 'KW' '3981';
-KW3982 : 'KW' '3982';
-KW3983 : 'KW' '3983';
-KW3984 : 'KW' '3984';
-KW3985 : 'KW' '3985';
-KW3986 : 'KW' '3986';
-KW3987 : 'KW' '3987';
-KW3988 : 'KW' '3988';
-KW3989 : 'KW' '3989';
-KW3990 : 'KW' '3990';
-KW3991 : 'KW' '3991';
-KW3992 : 'KW' '3992';
-KW3993 : 'KW' '3993';
-KW3994 : 'KW' '3994';
-KW3995 : 'KW' '3995';
-KW3996 : 'KW' '3996';
-KW3997 : 'KW' '3997';
-KW3998 : 'KW' '3998';
-KW3999 : 'KW' '3999';
\ No newline at end of file
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeLexers/LexerDelegatorInvokesDelegateRule.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeLexers/LexerDelegatorInvokesDelegateRule.txt
new file mode 100644
index 0000000000..2113c646f6
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeLexers/LexerDelegatorInvokesDelegateRule.txt
@@ -0,0 +1,24 @@
+[type]
+CompositeLexer
+
+[grammar]
+lexer grammar M;
+import S;
+B : 'b';
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+lexer grammar S;
+A : 'a' {};
+C : 'c' ;
+
+[input]
+abc
+
+[output]
+S.A
+[@0,0:0='a',<3>,1:0]
+[@1,1:1='b',<1>,1:1]
+[@2,2:2='c',<4>,1:2]
+[@3,3:2='',<-1>,1:3]
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeLexers/LexerDelegatorRuleOverridesDelegate.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeLexers/LexerDelegatorRuleOverridesDelegate.txt
new file mode 100644
index 0000000000..74d6098a7c
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeLexers/LexerDelegatorRuleOverridesDelegate.txt
@@ -0,0 +1,22 @@
+[type]
+CompositeLexer
+
+[grammar]
+lexer grammar M;
+import S;
+A : 'a' B {} ;
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+lexer grammar S;
+A : 'a' {} ;
+B : 'b' {} ;
+
+[input]
+ab
+
+[output]
+M.A
+[@0,0:1='ab',<1>,1:0]
+[@1,2:1='',<-1>,1:2]
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/BringInLiteralsFromDelegate.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/BringInLiteralsFromDelegate.txt
new file mode 100644
index 0000000000..fa198f3065
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/BringInLiteralsFromDelegate.txt
@@ -0,0 +1,21 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+s : a ;
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar S;
+a : '=' 'a' {};
+
+[start]
+s
+
+[input]
+=a
+
+[output]
+"""S.a"""
\ No newline at end of file
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/CombinedImportsCombined.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/CombinedImportsCombined.txt
new file mode 100644
index 0000000000..80a446ac32
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/CombinedImportsCombined.txt
@@ -0,0 +1,25 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+s : x INT;
+
+[slaveGrammar]
+parser grammar S;
+tokens { A, B, C }
+x : 'x' INT {};
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+x 34 9
+
+[output]
+"""S.x
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatesSeeSameTokenType.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatesSeeSameTokenType.txt
new file mode 100644
index 0000000000..5e01124c22
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatesSeeSameTokenType.txt
@@ -0,0 +1,44 @@
+[notes]
+The lexer will create rules to match letters a, b, c.
+The associated token types A, B, C must have the same value
+and all import'd parsers. Since ANTLR regenerates all imports
+for use with the delegator M, it can generate the same token type
+mapping in each parser:
+public static final int C=6;
+public static final int EOF=-1;
+public static final int B=5;
+public static final int WS=7;
+public static final int A=4;
+
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S,T;
+s : x y ; // matches AA, which should be 'aa'
+B : 'b' ; // another order: B, A, C
+A : 'a' ;
+C : 'c' ;
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar T;
+tokens { C, B, A } // reverse order
+y : A {};
+
+[slaveGrammar]
+parser grammar S;
+tokens { A, B, C }
+x : A {};
+
+[start]
+s
+
+[input]
+aa
+
+[output]
+S.x
+T.y
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorAccessesDelegateMembers.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorAccessesDelegateMembers.txt
new file mode 100644
index 0000000000..d2dafa4117
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorAccessesDelegateMembers.txt
@@ -0,0 +1,26 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M; // uses no rules from the import
+import S;
+s : 'b' {} ; // gS is import pointer
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar S;
+@parser::members {
+
+}
+a : B;
+
+[start]
+s
+
+[input]
+b
+
+[output]
+"""foo
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesDelegateRule.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesDelegateRule.txt
new file mode 100644
index 0000000000..5b4ad9c2a1
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesDelegateRule.txt
@@ -0,0 +1,24 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+s : a ;
+B : 'b' ; // defines B from inherited token space
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar S;
+a : B {};
+
+[start]
+s
+
+[input]
+b
+
+[output]
+"""S.a
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesDelegateRuleWithArgs.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesDelegateRuleWithArgs.txt
new file mode 100644
index 0000000000..96fa718070
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesDelegateRuleWithArgs.txt
@@ -0,0 +1,24 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+s : label=a[3] {} ;
+B : 'b' ; // defines B from inherited token space
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar S;
+a[int x] returns [int y] : B {} {$y=1000;} ;
+
+[start]
+s
+
+[input]
+b
+
+[output]
+"""S.a1000
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesDelegateRuleWithReturnStruct.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesDelegateRuleWithReturnStruct.txt
new file mode 100644
index 0000000000..339a3f4740
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesDelegateRuleWithReturnStruct.txt
@@ -0,0 +1,23 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+s : a {} ;
+B : 'b' ; // defines B from inherited token space
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar S;
+a : B {} ;
+
+[start]
+s
+
+[input]
+b
+
+[output]
+"""S.ab"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesFirstVersionOfDelegateRule.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesFirstVersionOfDelegateRule.txt
new file mode 100644
index 0000000000..a0bab0812d
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorInvokesFirstVersionOfDelegateRule.txt
@@ -0,0 +1,29 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S,T;
+s : a ;
+B : 'b' ; // defines B from inherited token space
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar T;
+a : B {};
+
+[slaveGrammar]
+parser grammar S;
+a : b {};
+b : B;
+
+[start]
+s
+
+[input]
+b
+
+[output]
+"""S.a
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorRuleOverridesDelegate.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorRuleOverridesDelegate.txt
new file mode 100644
index 0000000000..d25532f56e
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorRuleOverridesDelegate.txt
@@ -0,0 +1,22 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+b : 'b'|'c';
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar S;
+a : b {};
+b : B ;
+
+[start]
+a
+
+[input]
+c
+
+[output]
+"""S.a"""
\ No newline at end of file
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorRuleOverridesDelegates.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorRuleOverridesDelegates.txt
new file mode 100644
index 0000000000..af5da57869
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorRuleOverridesDelegates.txt
@@ -0,0 +1,29 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S, T;
+b : 'b'|'c' {}|B|A;
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar T;
+tokens { A }
+b : 'b' {};
+
+[slaveGrammar]
+parser grammar S;
+a : b {};
+b : 'b' ;
+
+[start]
+a
+
+[input]
+c
+
+[output]
+M.b
+S.a
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorRuleOverridesLookaheadInDelegate.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorRuleOverridesLookaheadInDelegate.txt
new file mode 100644
index 0000000000..36725be26d
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/DelegatorRuleOverridesLookaheadInDelegate.txt
@@ -0,0 +1,29 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+prog : decl ;
+type_ : 'int' | 'float' ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip;
+
+[slaveGrammar]
+parser grammar S;
+type_ : 'int' ;
+decl : type_ ID ';'
+ | type_ ID init_ ';' {};
+init_ : '=' INT;
+
+[start]
+prog
+
+[input]
+float x = 3;
+
+[output]
+"""JavaDecl: floatx=3;
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/ImportLexerWithOnlyFragmentRules.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/ImportLexerWithOnlyFragmentRules.txt
new file mode 100644
index 0000000000..fc1d47f2f2
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/ImportLexerWithOnlyFragmentRules.txt
@@ -0,0 +1,32 @@
+[notes]
+This is a regression test for antlr/antlr4#248 "Including grammar with only
+fragments breaks generated lexer". https://github.com/antlr/antlr4/issues/248
+
+[type]
+CompositeParser
+
+[grammar]
+grammar Test;
+import Unicode;
+
+program : 'test' 'test';
+
+WS : (UNICODE_CLASS_Zs)+ -> skip;
+
+[slaveGrammar]
+"""lexer grammar Unicode;
+
+fragment
+UNICODE_CLASS_Zs : ' ' | ' ' | ' ' | ''
+ | ' '..' '
+ | ' ' | ' ' | ' '
+ ;
+
+"""
+
+[start]
+program
+
+[input]
+test test
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/ImportedGrammarWithEmptyOptions.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/ImportedGrammarWithEmptyOptions.txt
new file mode 100644
index 0000000000..00c1065461
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/ImportedGrammarWithEmptyOptions.txt
@@ -0,0 +1,21 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+s : a ;
+B : 'b' ;
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar S;
+options {}
+a : B ;
+
+[start]
+s
+
+[input]
+b
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/ImportedRuleWithAction.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/ImportedRuleWithAction.txt
new file mode 100644
index 0000000000..2fff024817
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/ImportedRuleWithAction.txt
@@ -0,0 +1,23 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+s : a;
+B : 'b';
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+parser grammar S;
+a @after {} : B;
+
+[start]
+s
+
+[input]
+b
+
+[skip]
+Go
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/KeywordVSIDOrder.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/KeywordVSIDOrder.txt
new file mode 100644
index 0000000000..80794c81fd
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/CompositeParsers/KeywordVSIDOrder.txt
@@ -0,0 +1,24 @@
+[type]
+CompositeParser
+
+[grammar]
+grammar M;
+import S;
+a : A {};
+A : 'abc' {};
+WS : (' '|'\n') -> skip ;
+
+[slaveGrammar]
+lexer grammar S;
+ID : 'a'..'z'+;
+
+[start]
+a
+
+[input]
+abc
+
+[output]
+M.A
+M.a: [@0,0:2='abc',<1>,1:0]
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/AmbigYieldsCtxSensitiveDFA.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/AmbigYieldsCtxSensitiveDFA.txt
new file mode 100644
index 0000000000..d9ab124449
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/AmbigYieldsCtxSensitiveDFA.txt
@@ -0,0 +1,27 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {}
+ : ID | ID {} ;
+ID : 'a'..'z'+;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+abc
+
+[output]
+Decision 0:
+s0-ID->:s1^=>1
+
+[errors]
+"""line 1:0 reportAttemptingFullContext d=0 (s), input='abc'
+"""
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/AmbiguityNoLoop.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/AmbiguityNoLoop.txt
new file mode 100644
index 0000000000..b2c0304a41
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/AmbiguityNoLoop.txt
@@ -0,0 +1,36 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+prog
+@init {}
+ : expr expr {}
+ | expr
+ ;
+expr: '@'
+ | ID '@'
+ | ID
+ ;
+ID : [a-z]+ ;
+WS : [ \r\n\t]+ -> skip ;
+
+[start]
+prog
+
+[input]
+a@
+
+[output]
+"""alt 1
+"""
+
+[errors]
+line 1:2 reportAttemptingFullContext d=0 (prog), input='a@'
+line 1:2 reportAmbiguity d=0 (prog): ambigAlts={1, 2}, input='a@'
+line 1:2 reportAttemptingFullContext d=1 (expr), input='a@'
+line 1:2 reportContextSensitivity d=1 (expr), input='a@'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/CtxSensitiveDFATwoDiffInput.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/CtxSensitiveDFATwoDiffInput.txt
new file mode 100644
index 0000000000..b07cc5e717
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/CtxSensitiveDFATwoDiffInput.txt
@@ -0,0 +1,34 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {}
+ : ('$' a | '@' b)+ ;
+a : e ID ;
+b : e INT ID ;
+e : INT | ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+$ 34 abc @ 34 abc
+
+[output]
+Decision 2:
+s0-INT->s1
+s1-ID->:s2^=>1
+
+[errors]
+line 1:5 reportAttemptingFullContext d=2 (e), input='34abc'
+line 1:2 reportContextSensitivity d=2 (e), input='34'
+line 1:14 reportAttemptingFullContext d=2 (e), input='34abc'
+line 1:14 reportContextSensitivity d=2 (e), input='34abc'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/CtxSensitiveDFA_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/CtxSensitiveDFA_1.txt
new file mode 100644
index 0000000000..7f4b51755f
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/CtxSensitiveDFA_1.txt
@@ -0,0 +1,32 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {}
+ : '$' a | '@' b ;
+a : e ID ;
+b : e INT ID ;
+e : INT | ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+$ 34 abc
+
+[output]
+Decision 1:
+s0-INT->s1
+s1-ID->:s2^=>1
+
+[errors]
+line 1:5 reportAttemptingFullContext d=1 (e), input='34abc'
+line 1:2 reportContextSensitivity d=1 (e), input='34'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/CtxSensitiveDFA_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/CtxSensitiveDFA_2.txt
new file mode 100644
index 0000000000..f2cfc226b9
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/CtxSensitiveDFA_2.txt
@@ -0,0 +1,32 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {}
+ : '$' a | '@' b ;
+a : e ID ;
+b : e INT ID ;
+e : INT | ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+@ 34 abc
+
+[output]
+Decision 1:
+s0-INT->s1
+s1-ID->:s2^=>1
+
+[errors]
+line 1:5 reportAttemptingFullContext d=1 (e), input='34abc'
+line 1:5 reportContextSensitivity d=1 (e), input='34abc'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/ExprAmbiguity_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/ExprAmbiguity_1.txt
new file mode 100644
index 0000000000..291be3b0c2
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/ExprAmbiguity_1.txt
@@ -0,0 +1,35 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s
+@init {}
+: expr[0] {};
+ expr[int _p]
+ : ID
+ (
+ {5 >= $_p}? '*' expr[6]
+ | {4 >= $_p}? '+' expr[5]
+ )*
+ ;
+ID : [a-zA-Z]+ ;
+WS : [ \r\n\t]+ -> skip ;
+
+[start]
+s
+
+[input]
+a+b
+
+[output]
+"""(expr a + (expr b))
+"""
+
+[errors]
+line 1:1 reportAttemptingFullContext d=1 (expr), input='+'
+line 1:2 reportContextSensitivity d=1 (expr), input='+b'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/ExprAmbiguity_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/ExprAmbiguity_2.txt
new file mode 100644
index 0000000000..fd26dfa50b
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/ExprAmbiguity_2.txt
@@ -0,0 +1,37 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s
+@init {}
+: expr[0] {};
+ expr[int _p]
+ : ID
+ (
+ {5 >= $_p}? '*' expr[6]
+ | {4 >= $_p}? '+' expr[5]
+ )*
+ ;
+ID : [a-zA-Z]+ ;
+WS : [ \r\n\t]+ -> skip ;
+
+[start]
+s
+
+[input]
+a+b*c
+
+[output]
+"""(expr a + (expr b * (expr c)))
+"""
+
+[errors]
+line 1:1 reportAttemptingFullContext d=1 (expr), input='+'
+line 1:2 reportContextSensitivity d=1 (expr), input='+b'
+line 1:3 reportAttemptingFullContext d=1 (expr), input='*'
+line 1:5 reportAmbiguity d=1 (expr): ambigAlts={1, 2}, input='*c'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_1.txt
new file mode 100644
index 0000000000..ee5a5ff28a
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_1.txt
@@ -0,0 +1,28 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s
+@init {}
+@after {}
+ : '{' stat* '}' ;
+stat: 'if' ID 'then' stat ('else' ID)?
+ | 'return'
+ ;
+ID : 'a'..'z'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+{ if x then return }
+
+[output]
+Decision 1:
+s0-'}'->:s1=>2
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_2.txt
new file mode 100644
index 0000000000..741ab3be3a
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_2.txt
@@ -0,0 +1,32 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s
+@init {}
+@after {}
+ : '{' stat* '}' ;
+stat: 'if' ID 'then' stat ('else' ID)?
+ | 'return'
+ ;
+ID : 'a'..'z'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+{ if x then return else foo }
+
+[output]
+Decision 1:
+s0-'else'->:s1^=>1
+
+[errors]
+line 1:19 reportAttemptingFullContext d=1 (stat), input='else'
+line 1:19 reportContextSensitivity d=1 (stat), input='else'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_3.txt
new file mode 100644
index 0000000000..481a446624
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_3.txt
@@ -0,0 +1,33 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s
+@init {}
+@after {}
+ : '{' stat* '}' ;
+stat: 'if' ID 'then' stat ('else' ID)?
+ | 'return'
+ ;
+ID : 'a'..'z'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+{ if x then if y then return else foo }
+
+[output]
+Decision 1:
+s0-'}'->:s2=>2
+s0-'else'->:s1^=>1
+
+[errors]
+line 1:29 reportAttemptingFullContext d=1 (stat), input='else'
+line 1:38 reportAmbiguity d=1 (stat): ambigAlts={1, 2}, input='elsefoo}'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_4.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_4.txt
new file mode 100644
index 0000000000..53278e4fc3
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_4.txt
@@ -0,0 +1,34 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s
+@init {}
+@after {}
+ : '{' stat* '}' ;
+stat: 'if' ID 'then' stat ('else' ID)?
+ | 'return'
+ ;
+ID : 'a'..'z'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+{ if x then if y then return else foo else bar }
+
+[output]
+Decision 1:
+s0-'else'->:s1^=>1
+
+[errors]
+line 1:29 reportAttemptingFullContext d=1 (stat), input='else'
+line 1:38 reportContextSensitivity d=1 (stat), input='elsefooelse'
+line 1:38 reportAttemptingFullContext d=1 (stat), input='else'
+line 1:38 reportContextSensitivity d=1 (stat), input='else'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_5.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_5.txt
new file mode 100644
index 0000000000..7a140928fa
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_5.txt
@@ -0,0 +1,36 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s
+@init {}
+@after {}
+ : '{' stat* '}' ;
+stat: 'if' ID 'then' stat ('else' ID)?
+ | 'return'
+ ;
+ID : 'a'..'z'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+{ if x then return else foo
+if x then if y then return else foo }
+
+[output]
+Decision 1:
+s0-'}'->:s2=>2
+s0-'else'->:s1^=>1
+
+[errors]
+line 1:19 reportAttemptingFullContext d=1 (stat), input='else'
+line 1:19 reportContextSensitivity d=1 (stat), input='else'
+line 2:27 reportAttemptingFullContext d=1 (stat), input='else'
+line 2:36 reportAmbiguity d=1 (stat): ambigAlts={1, 2}, input='elsefoo}'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_6.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_6.txt
new file mode 100644
index 0000000000..7a140928fa
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/FullContextIF_THEN_ELSEParse_6.txt
@@ -0,0 +1,36 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s
+@init {}
+@after {}
+ : '{' stat* '}' ;
+stat: 'if' ID 'then' stat ('else' ID)?
+ | 'return'
+ ;
+ID : 'a'..'z'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+{ if x then return else foo
+if x then if y then return else foo }
+
+[output]
+Decision 1:
+s0-'}'->:s2=>2
+s0-'else'->:s1^=>1
+
+[errors]
+line 1:19 reportAttemptingFullContext d=1 (stat), input='else'
+line 1:19 reportContextSensitivity d=1 (stat), input='else'
+line 2:27 reportAttemptingFullContext d=1 (stat), input='else'
+line 2:36 reportAmbiguity d=1 (stat): ambigAlts={1, 2}, input='elsefoo}'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/LoopsSimulateTailRecursion.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/LoopsSimulateTailRecursion.txt
new file mode 100644
index 0000000000..d708221f72
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/LoopsSimulateTailRecursion.txt
@@ -0,0 +1,41 @@
+[notes]
+Tests predictions for the following case involving closures.
+http://www.antlr.org/wiki/display/~admin/2011/12/29/Flaw+in+ANTLR+v3+LL(*)+analysis+algorithm
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+prog
+@init {}
+ : expr_or_assign*;
+expr_or_assign
+ : expr '++' {}
+ | expr {}
+ ;
+expr: expr_primary ('\<-' ID)?;
+expr_primary
+ : '(' ID ')'
+ | ID '(' ID ')'
+ | ID
+ ;
+ID : [a-z]+ ;
+
+[start]
+prog
+
+[input]
+a(i)<-x
+
+[output]
+"""pass: a(i)<-x
+"""
+
+[errors]
+line 1:3 reportAttemptingFullContext d=3 (expr_primary), input='a(i)'
+line 1:7 reportAmbiguity d=3 (expr_primary): ambigAlts={2, 3}, input='a(i)<-x'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/SLLSeesEOFInLLGrammar.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/SLLSeesEOFInLLGrammar.txt
new file mode 100644
index 0000000000..0908de123d
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/FullContextParsing/SLLSeesEOFInLLGrammar.txt
@@ -0,0 +1,32 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {}
+ : a;
+a : e ID ;
+b : e INT ID ;
+e : INT | ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\t'|'\n')+ -> skip ;
+
+[start]
+s
+
+[input]
+34 abc
+
+[output]
+Decision 0:
+s0-INT->s1
+s1-ID->:s2^=>1
+
+[errors]
+line 1:3 reportAttemptingFullContext d=0 (e), input='34abc'
+line 1:0 reportContextSensitivity d=0 (e), input='34'
+
+[flags]
+showDiagnosticErrors
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_1.txt
new file mode 100644
index 0000000000..8dd1e63929
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_1.txt
@@ -0,0 +1,33 @@
+[type]
+Parser
+
+[grammar]
+grammar Expr;
+prog: stat ;
+stat: expr NEWLINE # printExpr
+ | ID '=' expr NEWLINE# assign
+ | NEWLINE # blank
+ ;
+expr: expr ('*'|'/') expr # MulDiv
+ | expr ('+'|'-') expr # AddSub
+ | INT # int
+ | ID # id
+ | '(' expr ')' # parens
+ ;
+
+MUL : '*' ; // assigns token name to '*' used above in grammar
+DIV : '/' ;
+ADD : '+' ;
+SUB : '-' ;
+ID : [a-zA-Z]+ ; // match identifiers
+INT : [0-9]+ ;// match integers
+NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
+WS : [ \t]+ -> skip ; // toss out whitespace
+
+[start]
+prog
+
+[input]
+"""1
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_2.txt
new file mode 100644
index 0000000000..a017592e4a
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_2.txt
@@ -0,0 +1,33 @@
+[type]
+Parser
+
+[grammar]
+grammar Expr;
+prog: stat ;
+stat: expr NEWLINE # printExpr
+ | ID '=' expr NEWLINE# assign
+ | NEWLINE # blank
+ ;
+expr: expr ('*'|'/') expr # MulDiv
+ | expr ('+'|'-') expr # AddSub
+ | INT # int
+ | ID # id
+ | '(' expr ')' # parens
+ ;
+
+MUL : '*' ; // assigns token name to '*' used above in grammar
+DIV : '/' ;
+ADD : '+' ;
+SUB : '-' ;
+ID : [a-zA-Z]+ ; // match identifiers
+INT : [0-9]+ ;// match integers
+NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
+WS : [ \t]+ -> skip ; // toss out whitespace
+
+[start]
+prog
+
+[input]
+"""a = 5
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_3.txt
new file mode 100644
index 0000000000..4fc53bfe85
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_3.txt
@@ -0,0 +1,33 @@
+[type]
+Parser
+
+[grammar]
+grammar Expr;
+prog: stat ;
+stat: expr NEWLINE # printExpr
+ | ID '=' expr NEWLINE# assign
+ | NEWLINE # blank
+ ;
+expr: expr ('*'|'/') expr # MulDiv
+ | expr ('+'|'-') expr # AddSub
+ | INT # int
+ | ID # id
+ | '(' expr ')' # parens
+ ;
+
+MUL : '*' ; // assigns token name to '*' used above in grammar
+DIV : '/' ;
+ADD : '+' ;
+SUB : '-' ;
+ID : [a-zA-Z]+ ; // match identifiers
+INT : [0-9]+ ;// match integers
+NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
+WS : [ \t]+ -> skip ; // toss out whitespace
+
+[start]
+prog
+
+[input]
+"""b = 6
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_4.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_4.txt
new file mode 100644
index 0000000000..30ee4ed389
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_4.txt
@@ -0,0 +1,33 @@
+[type]
+Parser
+
+[grammar]
+grammar Expr;
+prog: stat ;
+stat: expr NEWLINE # printExpr
+ | ID '=' expr NEWLINE# assign
+ | NEWLINE # blank
+ ;
+expr: expr ('*'|'/') expr # MulDiv
+ | expr ('+'|'-') expr # AddSub
+ | INT # int
+ | ID # id
+ | '(' expr ')' # parens
+ ;
+
+MUL : '*' ; // assigns token name to '*' used above in grammar
+DIV : '/' ;
+ADD : '+' ;
+SUB : '-' ;
+ID : [a-zA-Z]+ ; // match identifiers
+INT : [0-9]+ ;// match integers
+NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
+WS : [ \t]+ -> skip ; // toss out whitespace
+
+[start]
+prog
+
+[input]
+"""a+b*2
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_5.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_5.txt
new file mode 100644
index 0000000000..98fba28371
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/AmbigLR_5.txt
@@ -0,0 +1,33 @@
+[type]
+Parser
+
+[grammar]
+grammar Expr;
+prog: stat ;
+stat: expr NEWLINE # printExpr
+ | ID '=' expr NEWLINE# assign
+ | NEWLINE # blank
+ ;
+expr: expr ('*'|'/') expr # MulDiv
+ | expr ('+'|'-') expr # AddSub
+ | INT # int
+ | ID # id
+ | '(' expr ')' # parens
+ ;
+
+MUL : '*' ; // assigns token name to '*' used above in grammar
+DIV : '/' ;
+ADD : '+' ;
+SUB : '-' ;
+ID : [a-zA-Z]+ ; // match identifiers
+INT : [0-9]+ ;// match integers
+NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
+WS : [ \t]+ -> skip ; // toss out whitespace
+
+[start]
+prog
+
+[input]
+"""(1+2)*3
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_1.txt
new file mode 100644
index 0000000000..ff41bcf1ad
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_1.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a
+
+[output]
+"""(s (declarator a) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_10.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_10.txt
new file mode 100644
index 0000000000..de50a048c6
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_10.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+(*a)[]
+
+[output]
+"""(s (declarator (declarator ( (declarator * (declarator a)) )) [ ]) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_2.txt
new file mode 100644
index 0000000000..c1baa1504f
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_2.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+*a
+
+[output]
+"""(s (declarator * (declarator a)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_3.txt
new file mode 100644
index 0000000000..3b6d324616
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_3.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+**a
+
+[output]
+"""(s (declarator * (declarator * (declarator a))) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_4.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_4.txt
new file mode 100644
index 0000000000..1f642b4d39
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_4.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a[3]
+
+[output]
+"""(s (declarator (declarator a) [ (e 3) ]) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_5.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_5.txt
new file mode 100644
index 0000000000..a64c3234ec
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_5.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+b[]
+
+[output]
+"""(s (declarator (declarator b) [ ]) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_6.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_6.txt
new file mode 100644
index 0000000000..afd017fce5
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_6.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+(a)
+
+[output]
+"""(s (declarator ( (declarator a) )) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_7.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_7.txt
new file mode 100644
index 0000000000..d62df17019
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_7.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a[]()
+
+[output]
+"""(s (declarator (declarator (declarator a) [ ]) ( )) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_8.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_8.txt
new file mode 100644
index 0000000000..b76e2fe79b
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_8.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a[][]
+
+[output]
+"""(s (declarator (declarator (declarator a) [ ]) [ ]) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_9.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_9.txt
new file mode 100644
index 0000000000..9f9a8e40ad
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Declarations_9.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : declarator EOF ; // must indicate EOF can follow
+declarator
+ : declarator '[' e ']'
+ | declarator '[' ']'
+ | declarator '(' ')'
+ | '*' declarator // binds less tight than suffixes
+ | '(' declarator ')'
+ | ID
+ ;
+e : INT ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+*a[]
+
+[output]
+"""(s (declarator * (declarator (declarator a) [ ])) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/DirectCallToLeftRecursiveRule_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/DirectCallToLeftRecursiveRule_1.txt
new file mode 100644
index 0000000000..9ccf4c3108
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/DirectCallToLeftRecursiveRule_1.txt
@@ -0,0 +1,25 @@
+[notes]
+This is a regression test for "Support direct calls to left-recursive
+rules". https://github.com/antlr/antlr4/issues/161
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+a @after {} : a ID
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+a
+
+[input]
+x
+
+[output]
+"""(a x)
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/DirectCallToLeftRecursiveRule_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/DirectCallToLeftRecursiveRule_2.txt
new file mode 100644
index 0000000000..2dccce6352
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/DirectCallToLeftRecursiveRule_2.txt
@@ -0,0 +1,25 @@
+[notes]
+This is a regression test for "Support direct calls to left-recursive
+rules". https://github.com/antlr/antlr4/issues/161
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+a @after {} : a ID
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+a
+
+[input]
+x y
+
+[output]
+"""(a (a x) y)
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/DirectCallToLeftRecursiveRule_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/DirectCallToLeftRecursiveRule_3.txt
new file mode 100644
index 0000000000..bc67fab7e8
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/DirectCallToLeftRecursiveRule_3.txt
@@ -0,0 +1,25 @@
+[notes]
+This is a regression test for "Support direct calls to left-recursive
+rules". https://github.com/antlr/antlr4/issues/161
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+a @after {} : a ID
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+a
+
+[input]
+x y z
+
+[output]
+"""(a (a (a x) y) z)
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_1.txt
new file mode 100644
index 0000000000..c65e2a0265
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_1.txt
@@ -0,0 +1,28 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+e : e '.' ID
+ | e '.' 'this'
+ | '-' e
+ | e '*' e
+ | e ('+'|'-') e
+ | INT
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a
+
+[output]
+"""(s (e a) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_2.txt
new file mode 100644
index 0000000000..61490cf815
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_2.txt
@@ -0,0 +1,28 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+e : e '.' ID
+ | e '.' 'this'
+ | '-' e
+ | e '*' e
+ | e ('+'|'-') e
+ | INT
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+1
+
+[output]
+"""(s (e 1) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_3.txt
new file mode 100644
index 0000000000..355cf4ffc3
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_3.txt
@@ -0,0 +1,28 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+e : e '.' ID
+ | e '.' 'this'
+ | '-' e
+ | e '*' e
+ | e ('+'|'-') e
+ | INT
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a-1
+
+[output]
+"""(s (e (e a) - (e 1)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_4.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_4.txt
new file mode 100644
index 0000000000..82823bc802
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_4.txt
@@ -0,0 +1,28 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+e : e '.' ID
+ | e '.' 'this'
+ | '-' e
+ | e '*' e
+ | e ('+'|'-') e
+ | INT
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a.b
+
+[output]
+"""(s (e (e a) . b) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_5.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_5.txt
new file mode 100644
index 0000000000..2fecad1eac
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_5.txt
@@ -0,0 +1,28 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+e : e '.' ID
+ | e '.' 'this'
+ | '-' e
+ | e '*' e
+ | e ('+'|'-') e
+ | INT
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a.this
+
+[output]
+"""(s (e (e a) . this) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_6.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_6.txt
new file mode 100644
index 0000000000..f36e03d1f6
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_6.txt
@@ -0,0 +1,28 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+e : e '.' ID
+ | e '.' 'this'
+ | '-' e
+ | e '*' e
+ | e ('+'|'-') e
+ | INT
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+-a
+
+[output]
+"""(s (e - (e a)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_7.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_7.txt
new file mode 100644
index 0000000000..69c9a28d60
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/Expressions_7.txt
@@ -0,0 +1,28 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+e : e '.' ID
+ | e '.' 'this'
+ | '-' e
+ | e '*' e
+ | e ('+'|'-') e
+ | INT
+ | ID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+-a+b
+
+[output]
+"""(s (e (e - (e a)) + (e b)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_1.txt
new file mode 100644
index 0000000000..f770f3cbfb
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_1.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a|b&c
+
+[output]
+"""(s (e (e a) | (e (e b) & (e c))) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_10.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_10.txt
new file mode 100644
index 0000000000..05bf8eb6fc
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_10.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a.f(x)==T.c
+
+[output]
+"""(s (e (e (e (e a) . f) ( (expressionList (e x)) )) == (e (e T) . c)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_11.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_11.txt
new file mode 100644
index 0000000000..d6ff972f3f
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_11.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a.f().g(x,1)
+
+[output]
+"""(s (e (e (e (e (e a) . f) ( )) . g) ( (expressionList (e x) , (e 1)) )) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_12.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_12.txt
new file mode 100644
index 0000000000..4fd312b0fd
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_12.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+new T[((n-1) * x) + 1]
+
+[output]
+"""(s (e new (typespec T) [ (e (e ( (e (e ( (e (e n) - (e 1)) )) * (e x)) )) + (e 1)) ]) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_2.txt
new file mode 100644
index 0000000000..ae082d450e
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_2.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+(a|b)&c
+
+[output]
+"""(s (e (e ( (e (e a) | (e b)) )) & (e c)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_3.txt
new file mode 100644
index 0000000000..da0aba1d89
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_3.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a > b
+
+[output]
+"""(s (e (e a) > (e b)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_4.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_4.txt
new file mode 100644
index 0000000000..f0b826c0d5
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_4.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a >> b
+
+[output]
+"""(s (e (e a) >> (e b)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_5.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_5.txt
new file mode 100644
index 0000000000..c6b0b80d6e
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_5.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a=b=c
+
+[output]
+"""(s (e (e a) = (e (e b) = (e c))) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_6.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_6.txt
new file mode 100644
index 0000000000..bff6065322
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_6.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a^b^c
+
+[output]
+"""(s (e (e a) ^ (e (e b) ^ (e c))) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_7.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_7.txt
new file mode 100644
index 0000000000..4728aa4b50
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_7.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+(T)x
+
+[output]
+"""(s (e ( (typespec T) ) (e x)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_8.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_8.txt
new file mode 100644
index 0000000000..0a5860edee
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_8.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+new A().b
+
+[output]
+"""(s (e (e new (typespec A) ( )) . b) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_9.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_9.txt
new file mode 100644
index 0000000000..1d85d91e86
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/JavaExpressions_9.txt
@@ -0,0 +1,72 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e EOF ; // must indicate EOF can follow
+expressionList
+ : e (',' e)*
+ ;
+e : '(' e ')'
+ | 'this'
+ | 'super'
+ | INT
+ | ID
+ | typespec '.' 'class'
+ | e '.' ID
+ | e '.' 'this'
+ | e '.' 'super' '(' expressionList? ')'
+ | e '.' 'new' ID '(' expressionList? ')'
+ | 'new' typespec ( '(' expressionList? ')' | ('[' e ']')+)
+ | e '[' e ']'
+ | '(' typespec ')' e
+ | e ('++' | '--')
+ | e '(' expressionList? ')'
+ | ('+'|'-'|'++'|'--') e
+ | ('~'|'!') e
+ | e ('*'|'/'|'%') e
+ | e ('+'|'-') e
+ | e ('\<\<' | '>>>' | '>>') e
+ | e ('\<=' | '>=' | '>' | '\<') e
+ | e 'instanceof' e
+ | e ('==' | '!=') e
+ | e '&' e
+ |\ e '^' e
+ | e '|' e
+ | e '&&' e
+ | e '||' e
+ | e '?' e ':' e
+ |\
+ e ('='
+ |'+='
+ |'-='
+ |'*='
+ |'/='
+ |'&='
+ |'|='
+ |'^='
+ |'>>='
+ |'>>>='
+ |'\<\<='
+ |'%=') e
+ ;
+typespec
+ : ID
+ | ID '[' ']'
+ | 'int'
+ | 'int' '[' ']'
+ ;
+ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+(T)t.f()
+
+[output]
+"""(s (e (e ( (typespec T) ) (e (e t) . f)) ( )) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/LabelsOnOpSubrule_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/LabelsOnOpSubrule_1.txt
new file mode 100644
index 0000000000..d7fe95127c
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/LabelsOnOpSubrule_1.txt
@@ -0,0 +1,23 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e;
+e : a=e op=('*'|'/') b=e {}
+ | INT {}
+ | '(' x=e ')' {}
+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+4
+
+[output]
+"""(s (e 4))
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/LabelsOnOpSubrule_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/LabelsOnOpSubrule_2.txt
new file mode 100644
index 0000000000..0ca7d3fd9c
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/LabelsOnOpSubrule_2.txt
@@ -0,0 +1,23 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e;
+e : a=e op=('*'|'/') b=e {}
+ | INT {}
+ | '(' x=e ')' {}
+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+1*2/3
+
+[output]
+"""(s (e (e (e 1) * (e 2)) / (e 3)))
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/LabelsOnOpSubrule_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/LabelsOnOpSubrule_3.txt
new file mode 100644
index 0000000000..20238f95a5
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/LabelsOnOpSubrule_3.txt
@@ -0,0 +1,23 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e;
+e : a=e op=('*'|'/') b=e {}
+ | INT {}
+ | '(' x=e ')' {}
+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+(1/2)*3
+
+[output]
+"""(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActionsPredicatesOptions_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActionsPredicatesOptions_1.txt
new file mode 100644
index 0000000000..c67586699b
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActionsPredicatesOptions_1.txt
@@ -0,0 +1,28 @@
+[notes]
+This is a regression test for antlr/antlr4#625 "Duplicate action breaks
+operator precedence" https://github.com/antlr/antlr4/issues/625
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e ;
+e : a=e op=('*'|'/') b=e {}{}?
+ | a=e op=('+'|'-') b=e {}\{}?\
+ | INT {}{}
+ | '(' x=e ')' {}{}
+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip;
+
+[start]
+s
+
+[input]
+4
+
+[output]
+"""(s (e 4))
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActionsPredicatesOptions_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActionsPredicatesOptions_2.txt
new file mode 100644
index 0000000000..61fabe9d85
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActionsPredicatesOptions_2.txt
@@ -0,0 +1,28 @@
+[notes]
+This is a regression test for antlr/antlr4#625 "Duplicate action breaks
+operator precedence" https://github.com/antlr/antlr4/issues/625
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e ;
+e : a=e op=('*'|'/') b=e {}{}?
+ | a=e op=('+'|'-') b=e {}\{}?\
+ | INT {}{}
+ | '(' x=e ')' {}{}
+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip;
+
+[start]
+s
+
+[input]
+1*2/3
+
+[output]
+"""(s (e (e (e 1) * (e 2)) / (e 3)))
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActionsPredicatesOptions_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActionsPredicatesOptions_3.txt
new file mode 100644
index 0000000000..689a65f174
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActionsPredicatesOptions_3.txt
@@ -0,0 +1,28 @@
+[notes]
+This is a regression test for antlr/antlr4#625 "Duplicate action breaks
+operator precedence" https://github.com/antlr/antlr4/issues/625
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e ;
+e : a=e op=('*'|'/') b=e {}{}?
+ | a=e op=('+'|'-') b=e {}\{}?\
+ | INT {}{}
+ | '(' x=e ')' {}{}
+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip;
+
+[start]
+s
+
+[input]
+(1/2)*3
+
+[output]
+"""(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActions_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActions_1.txt
new file mode 100644
index 0000000000..671b11ffda
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActions_1.txt
@@ -0,0 +1,27 @@
+[notes]
+This is a regression test for antlr/antlr4#625 "Duplicate action breaks
+operator precedence" https://github.com/antlr/antlr4/issues/625
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e ;
+e : a=e op=('*'|'/') b=e {}{}
+ | INT {}{}
+ | '(' x=e ')' {}{}
+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+4
+
+[output]
+"""(s (e 4))
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActions_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActions_2.txt
new file mode 100644
index 0000000000..752d000ccc
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActions_2.txt
@@ -0,0 +1,27 @@
+[notes]
+This is a regression test for antlr/antlr4#625 "Duplicate action breaks
+operator precedence" https://github.com/antlr/antlr4/issues/625
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e ;
+e : a=e op=('*'|'/') b=e {}{}
+ | INT {}{}
+ | '(' x=e ')' {}{}
+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+1*2/3
+
+[output]
+"""(s (e (e (e 1) * (e 2)) / (e 3)))
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActions_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActions_3.txt
new file mode 100644
index 0000000000..6fc361bce3
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleActions_3.txt
@@ -0,0 +1,27 @@
+[notes]
+This is a regression test for antlr/antlr4#625 "Duplicate action breaks
+operator precedence" https://github.com/antlr/antlr4/issues/625
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : e ;
+e : a=e op=('*'|'/') b=e {}{}
+ | INT {}{}
+ | '(' x=e ')' {}{}
+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+(1/2)*3
+
+[output]
+"""(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_1.txt
new file mode 100644
index 0000000000..629311487f
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_1.txt
@@ -0,0 +1,36 @@
+[notes]
+This is a regression test for antlr/antlr4#433 "Not all context accessor
+methods are generated when an alternative rule label is used for multiple
+alternatives". https://github.com/antlr/antlr4/issues/433
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : e {};
+e returns [int v]
+ : e '*' e {$v = (0)}, {})> * (1)}, {})>;} # binary
+ | e '+' e {$v = (0)}, {})> + (1)}, {})>;} # binary
+ | INT{$v = $INT.int;} # anInt
+ | '(' e ')' {$v = $e.v;} # parens
+ | left=e INC {$v = $left.v + 1;} # unary
+ | left=e DEC {$v = $left.v - 1;} # unary
+ | ID {} # anID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+INC : '++' ;
+DEC : '--' ;
+WS : (' '|'\n') -> skip;
+
+[start]
+s
+
+[input]
+4
+
+[output]
+"""4
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_2.txt
new file mode 100644
index 0000000000..31ee95f747
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_2.txt
@@ -0,0 +1,36 @@
+[notes]
+This is a regression test for antlr/antlr4#433 "Not all context accessor
+methods are generated when an alternative rule label is used for multiple
+alternatives". https://github.com/antlr/antlr4/issues/433
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : e {};
+e returns [int v]
+ : e '*' e {$v = (0)}, {})> * (1)}, {})>;} # binary
+ | e '+' e {$v = (0)}, {})> + (1)}, {})>;} # binary
+ | INT{$v = $INT.int;} # anInt
+ | '(' e ')' {$v = $e.v;} # parens
+ | left=e INC {$v = $left.v + 1;} # unary
+ | left=e DEC {$v = $left.v - 1;} # unary
+ | ID {} # anID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+INC : '++' ;
+DEC : '--' ;
+WS : (' '|'\n') -> skip;
+
+[start]
+s
+
+[input]
+1+2
+
+[output]
+"""3
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_3.txt
new file mode 100644
index 0000000000..3e2de3e588
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_3.txt
@@ -0,0 +1,36 @@
+[notes]
+This is a regression test for antlr/antlr4#433 "Not all context accessor
+methods are generated when an alternative rule label is used for multiple
+alternatives". https://github.com/antlr/antlr4/issues/433
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : e {};
+e returns [int v]
+ : e '*' e {$v = (0)}, {})> * (1)}, {})>;} # binary
+ | e '+' e {$v = (0)}, {})> + (1)}, {})>;} # binary
+ | INT{$v = $INT.int;} # anInt
+ | '(' e ')' {$v = $e.v;} # parens
+ | left=e INC {$v = $left.v + 1;} # unary
+ | left=e DEC {$v = $left.v - 1;} # unary
+ | ID {} # anID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+INC : '++' ;
+DEC : '--' ;
+WS : (' '|'\n') -> skip;
+
+[start]
+s
+
+[input]
+1+2*3
+
+[output]
+"""7
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_4.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_4.txt
new file mode 100644
index 0000000000..d3a5726520
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_4.txt
@@ -0,0 +1,36 @@
+[notes]
+This is a regression test for antlr/antlr4#433 "Not all context accessor
+methods are generated when an alternative rule label is used for multiple
+alternatives". https://github.com/antlr/antlr4/issues/433
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : e {};
+e returns [int v]
+ : e '*' e {$v = (0)}, {})> * (1)}, {})>;} # binary
+ | e '+' e {$v = (0)}, {})> + (1)}, {})>;} # binary
+ | INT{$v = $INT.int;} # anInt
+ | '(' e ')' {$v = $e.v;} # parens
+ | left=e INC {$v = $left.v + 1;} # unary
+ | left=e DEC {$v = $left.v - 1;} # unary
+ | ID {} # anID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+INC : '++' ;
+DEC : '--' ;
+WS : (' '|'\n') -> skip;
+
+[start]
+s
+
+[input]
+i++*3
+
+[output]
+"""12
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_5.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_5.txt
new file mode 100644
index 0000000000..4a313df433
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/MultipleAlternativesWithCommonLabel_5.txt
@@ -0,0 +1,36 @@
+[notes]
+This is a regression test for antlr/antlr4#433 "Not all context accessor
+methods are generated when an alternative rule label is used for multiple
+alternatives". https://github.com/antlr/antlr4/issues/433
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : e {};
+e returns [int v]
+ : e '*' e {$v = (0)}, {})> * (1)}, {})>;} # binary
+ | e '+' e {$v = (0)}, {})> + (1)}, {})>;} # binary
+ | INT{$v = $INT.int;} # anInt
+ | '(' e ')' {$v = $e.v;} # parens
+ | left=e INC {$v = $left.v + 1;} # unary
+ | left=e DEC {$v = $left.v - 1;} # unary
+ | ID {} # anID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+INC : '++' ;
+DEC : '--' ;
+WS : (' '|'\n') -> skip;
+
+[start]
+s
+
+[input]
+(99)+3
+
+[output]
+"""102
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrecedenceFilterConsidersContext.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrecedenceFilterConsidersContext.txt
new file mode 100644
index 0000000000..67d1bdde33
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrecedenceFilterConsidersContext.txt
@@ -0,0 +1,25 @@
+[notes]
+This is a regression test for antlr/antlr4#509 "Incorrect rule chosen in
+unambiguous grammar". https://github.com/antlr/antlr4/issues/509
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+prog
+@after {}
+: statement* EOF {};
+statement: letterA | statement letterA 'b' ;
+letterA: 'a';
+
+[start]
+prog
+
+[input]
+aa
+
+[output]
+"""(prog (statement (letterA a)) (statement (letterA a)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixAndOtherAlt_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixAndOtherAlt_1.txt
new file mode 100644
index 0000000000..30a38f6447
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixAndOtherAlt_1.txt
@@ -0,0 +1,25 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : expr EOF ;
+expr : literal
+ | op expr
+ | expr op expr
+ ;
+literal : '-'? Integer ;
+op : '+' | '-' ;
+Integer : [0-9]+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+-1
+
+[output]
+"""(s (expr (literal - 1)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixAndOtherAlt_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixAndOtherAlt_2.txt
new file mode 100644
index 0000000000..8002cdabb9
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixAndOtherAlt_2.txt
@@ -0,0 +1,25 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : expr EOF ;
+expr : literal
+ | op expr
+ | expr op expr
+ ;
+literal : '-'? Integer ;
+op : '+' | '-' ;
+Integer : [0-9]+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+-1 + -1
+
+[output]
+"""(s (expr (expr (literal - 1)) (op +) (expr (literal - 1))) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixOpWithActionAndLabel_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixOpWithActionAndLabel_1.txt
new file mode 100644
index 0000000000..1395ce3060
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixOpWithActionAndLabel_1.txt
@@ -0,0 +1,25 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : e {} ;
+e returns [ result]
+ : ID '=' e1=e {$result = ;}
+ | ID {$result = $ID.text;}
+ | e1=e '+' e2=e {$result = ;}
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a
+
+[output]
+"""a
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixOpWithActionAndLabel_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixOpWithActionAndLabel_2.txt
new file mode 100644
index 0000000000..54e8d888ff
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixOpWithActionAndLabel_2.txt
@@ -0,0 +1,25 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : e {} ;
+e returns [ result]
+ : ID '=' e1=e {$result = ;}
+ | ID {$result = $ID.text;}
+ | e1=e '+' e2=e {$result = ;}
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a+b
+
+[output]
+"""(a+b)
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixOpWithActionAndLabel_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixOpWithActionAndLabel_3.txt
new file mode 100644
index 0000000000..034019f7bc
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/PrefixOpWithActionAndLabel_3.txt
@@ -0,0 +1,25 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : e {} ;
+e returns [ result]
+ : ID '=' e1=e {$result = ;}
+ | ID {$result = $ID.text;}
+ | e1=e '+' e2=e {$result = ;}
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+a=b+c
+
+[output]
+"""((a=b)+c)
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_1.txt
new file mode 100644
index 0000000000..9cf6bb44ee
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_1.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : q=e {};
+e returns [int v]
+ : a=e op='*' b=e {$v = $a.v * $b.v;} # mult
+ | a=e '+' b=e {$v = $a.v + $b.v;} # add
+ | INT{$v = $INT.int;} # anInt
+ | '(' x=e ')' {$v = $x.v;} # parens
+ | x=e '++' {$v = $x.v+1;} # inc
+ | e '--' # dec
+ | ID {$v = 3;} # anID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+4
+
+[output]
+"""4
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_2.txt
new file mode 100644
index 0000000000..ba490abc13
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_2.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : q=e {};
+e returns [int v]
+ : a=e op='*' b=e {$v = $a.v * $b.v;} # mult
+ | a=e '+' b=e {$v = $a.v + $b.v;} # add
+ | INT{$v = $INT.int;} # anInt
+ | '(' x=e ')' {$v = $x.v;} # parens
+ | x=e '++' {$v = $x.v+1;} # inc
+ | e '--' # dec
+ | ID {$v = 3;} # anID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+1+2
+
+[output]
+"""3
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_3.txt
new file mode 100644
index 0000000000..10b39b825b
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_3.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : q=e {};
+e returns [int v]
+ : a=e op='*' b=e {$v = $a.v * $b.v;} # mult
+ | a=e '+' b=e {$v = $a.v + $b.v;} # add
+ | INT{$v = $INT.int;} # anInt
+ | '(' x=e ')' {$v = $x.v;} # parens
+ | x=e '++' {$v = $x.v+1;} # inc
+ | e '--' # dec
+ | ID {$v = 3;} # anID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+1+2*3
+
+[output]
+"""7
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_4.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_4.txt
new file mode 100644
index 0000000000..0d7f923820
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsAndLabels_4.txt
@@ -0,0 +1,29 @@
+[type]
+Parser
+
+[grammar]
+grammar T;
+s : q=e {};
+e returns [int v]
+ : a=e op='*' b=e {$v = $a.v * $b.v;} # mult
+ | a=e '+' b=e {$v = $a.v + $b.v;} # add
+ | INT{$v = $INT.int;} # anInt
+ | '(' x=e ')' {$v = $x.v;} # parens
+ | x=e '++' {$v = $x.v+1;} # inc
+ | e '--' # dec
+ | ID {$v = 3;} # anID
+ ;
+ID : 'a'..'z'+ ;
+INT : '0'..'9'+ ;
+WS : (' '|'\n') -> skip ;
+
+[start]
+s
+
+[input]
+i++*3
+
+[output]
+"""12
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_1.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_1.txt
new file mode 100644
index 0000000000..1cfb886d7d
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_1.txt
@@ -0,0 +1,34 @@
+[notes]
+This is a regression test for antlr/antlr4#677 "labels not working in grammar
+file". https://github.com/antlr/antlr4/issues/677
+This test treats `,` and `>>` as part of a single compound operator (similar
+to a ternary operator).
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : expr EOF;
+expr:
+ a=expr '*' a=expr #Factor
+ | b+=expr (',' b+=expr)* '>>' c=expr #Send
+ | ID #JustId //semantic check on modifiers
+;
+
+ID : ('a'..'z'|'A'..'Z'|'_')
+ ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
+;
+
+WS : [ \t\n]+ -> skip ;
+
+[start]
+s
+
+[input]
+a*b
+
+[output]
+"""(s (expr (expr a) * (expr b)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_2.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_2.txt
new file mode 100644
index 0000000000..06dc777133
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_2.txt
@@ -0,0 +1,34 @@
+[notes]
+This is a regression test for antlr/antlr4#677 "labels not working in grammar
+file". https://github.com/antlr/antlr4/issues/677
+This test treats `,` and `>>` as part of a single compound operator (similar
+to a ternary operator).
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : expr EOF;
+expr:
+ a=expr '*' a=expr #Factor
+ | b+=expr (',' b+=expr)* '>>' c=expr #Send
+ | ID #JustId //semantic check on modifiers
+;
+
+ID : ('a'..'z'|'A'..'Z'|'_')
+ ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
+;
+
+WS : [ \t\n]+ -> skip ;
+
+[start]
+s
+
+[input]
+a,c>>x
+
+[output]
+"""(s (expr (expr a) , (expr c) >> (expr x)) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_3.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_3.txt
new file mode 100644
index 0000000000..55fc5f9d47
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_3.txt
@@ -0,0 +1,34 @@
+[notes]
+This is a regression test for antlr/antlr4#677 "labels not working in grammar
+file". https://github.com/antlr/antlr4/issues/677
+This test treats `,` and `>>` as part of a single compound operator (similar
+to a ternary operator).
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {} : expr EOF;
+expr:
+ a=expr '*' a=expr #Factor
+ | b+=expr (',' b+=expr)* '>>' c=expr #Send
+ | ID #JustId //semantic check on modifiers
+;
+
+ID : ('a'..'z'|'A'..'Z'|'_')
+ ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
+;
+
+WS : [ \t\n]+ -> skip ;
+
+[start]
+s
+
+[input]
+x
+
+[output]
+"""(s (expr x) )
+"""
+
diff --git a/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_4.txt b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_4.txt
new file mode 100644
index 0000000000..ac7eddea64
--- /dev/null
+++ b/runtime-testsuite/resources/org/antlr/v4/test/runtime/descriptors/LeftRecursion/ReturnValueAndActionsList1_4.txt
@@ -0,0 +1,34 @@
+[notes]
+This is a regression test for antlr/antlr4#677 "labels not working in grammar
+file". https://github.com/antlr/antlr4/issues/677
+This test treats `,` and `>>` as part of a single compound operator (similar
+to a ternary operator).
+
+[type]
+Parser
+
+[grammar]
+grammar T;
+s @after {