forked from jasder/antlr
Merge branch 'master' into patch-1
This commit is contained in:
commit
3af2074061
|
@ -3,7 +3,7 @@ target/
|
||||||
# ... but not code generation targets
|
# ... but not code generation targets
|
||||||
!tool/src/org/antlr/v4/codegen/target/
|
!tool/src/org/antlr/v4/codegen/target/
|
||||||
|
|
||||||
# Node.js (npm and typings) cached dependencies
|
# Node.js (npm and typings) cached dependencies
|
||||||
node_modules/
|
node_modules/
|
||||||
typings/
|
typings/
|
||||||
|
|
||||||
|
@ -97,3 +97,7 @@ xcuserdata
|
||||||
# VSCode Java plugin temporary files
|
# VSCode Java plugin temporary files
|
||||||
javac-services.0.log
|
javac-services.0.log
|
||||||
javac-services.0.log.lck
|
javac-services.0.log.lck
|
||||||
|
test/
|
||||||
|
|
||||||
|
# Don't ignore python tests
|
||||||
|
!runtime/Python3/test/
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "runtime/PHP"]
|
||||||
|
path = runtime/PHP
|
||||||
|
url = https://github.com/antlr/antlr-php-runtime.git
|
64
.travis.yml
64
.travis.yml
|
@ -19,8 +19,9 @@ stages:
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- os: linux
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
compiler: clang
|
compiler: clang
|
||||||
jdk: openjdk7
|
jdk: openjdk8
|
||||||
env:
|
env:
|
||||||
- TARGET=cpp
|
- TARGET=cpp
|
||||||
- CXX=g++-5
|
- CXX=g++-5
|
||||||
|
@ -36,8 +37,9 @@ matrix:
|
||||||
- uuid-dev
|
- uuid-dev
|
||||||
- clang-3.7
|
- clang-3.7
|
||||||
- os: linux
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
compiler: clang
|
compiler: clang
|
||||||
jdk: openjdk7
|
jdk: openjdk8
|
||||||
env:
|
env:
|
||||||
- TARGET=cpp
|
- TARGET=cpp
|
||||||
- CXX=g++-5
|
- CXX=g++-5
|
||||||
|
@ -53,8 +55,9 @@ matrix:
|
||||||
- uuid-dev
|
- uuid-dev
|
||||||
- clang-3.7
|
- clang-3.7
|
||||||
- os: linux
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
compiler: clang
|
compiler: clang
|
||||||
jdk: openjdk7
|
jdk: openjdk8
|
||||||
env:
|
env:
|
||||||
- TARGET=cpp
|
- TARGET=cpp
|
||||||
- CXX=g++-5
|
- CXX=g++-5
|
||||||
|
@ -71,42 +74,42 @@ matrix:
|
||||||
- clang-3.7
|
- clang-3.7
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: clang
|
compiler: clang
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.2
|
||||||
env:
|
env:
|
||||||
- TARGET=cpp
|
- TARGET=cpp
|
||||||
- GROUP=LEXER
|
- GROUP=LEXER
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: clang
|
compiler: clang
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.2
|
||||||
env:
|
env:
|
||||||
- TARGET=cpp
|
- TARGET=cpp
|
||||||
- GROUP=PARSER
|
- GROUP=PARSER
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: clang
|
compiler: clang
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.2
|
||||||
env:
|
env:
|
||||||
- TARGET=cpp
|
- TARGET=cpp
|
||||||
- GROUP=RECURSION
|
- GROUP=RECURSION
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: clang
|
compiler: clang
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.2
|
||||||
env:
|
env:
|
||||||
- TARGET=swift
|
- TARGET=swift
|
||||||
- GROUP=LEXER
|
- GROUP=LEXER
|
||||||
stage: main-test
|
stage: main-test
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: clang
|
compiler: clang
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.2
|
||||||
env:
|
env:
|
||||||
- TARGET=swift
|
- TARGET=swift
|
||||||
- GROUP=PARSER
|
- GROUP=PARSER
|
||||||
stage: main-test
|
stage: main-test
|
||||||
- os: osx
|
- os: osx
|
||||||
compiler: clang
|
compiler: clang
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.2
|
||||||
env:
|
env:
|
||||||
- TARGET=swift
|
- TARGET=swift
|
||||||
- GROUP=RECURSION
|
- GROUP=RECURSION
|
||||||
|
@ -119,41 +122,49 @@ matrix:
|
||||||
- GROUP=ALL
|
- GROUP=ALL
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.2
|
||||||
env:
|
env:
|
||||||
- TARGET=dotnet
|
- TARGET=dotnet
|
||||||
- GROUP=LEXER
|
- GROUP=LEXER
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.2
|
||||||
env:
|
env:
|
||||||
- TARGET=dotnet
|
- TARGET=dotnet
|
||||||
- GROUP=PARSER
|
- GROUP=PARSER
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: osx
|
- os: osx
|
||||||
osx_image: xcode10.1
|
osx_image: xcode10.2
|
||||||
env:
|
env:
|
||||||
- TARGET=dotnet
|
- TARGET=dotnet
|
||||||
- GROUP=RECURSION
|
- GROUP=RECURSION
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: linux
|
- os: linux
|
||||||
|
dist: trusty
|
||||||
jdk: openjdk7
|
jdk: openjdk7
|
||||||
env: TARGET=java
|
env: TARGET=java
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: linux
|
- os: linux
|
||||||
jdk: openjdk8
|
jdk: openjdk8
|
||||||
env: TARGET=java
|
env: TARGET=java
|
||||||
stage: extended-test
|
|
||||||
- os: linux
|
|
||||||
jdk: oraclejdk8
|
|
||||||
env: TARGET=java
|
|
||||||
stage: smoke-test
|
stage: smoke-test
|
||||||
- os: linux
|
- os: linux
|
||||||
jdk: openjdk7
|
jdk: openjdk8
|
||||||
env: TARGET=csharp
|
env: TARGET=csharp
|
||||||
stage: main-test
|
stage: main-test
|
||||||
- os: linux
|
- os: linux
|
||||||
jdk: oraclejdk8
|
jdk: openjdk8
|
||||||
|
env: TARGET=dart
|
||||||
|
stage: main-test
|
||||||
|
- os: linux
|
||||||
|
language: php
|
||||||
|
php:
|
||||||
|
- 7.2
|
||||||
|
jdk: openjdk8
|
||||||
|
env: TARGET=php
|
||||||
|
stage: main-test
|
||||||
|
- os: linux
|
||||||
|
jdk: openjdk8
|
||||||
dist: trusty
|
dist: trusty
|
||||||
env:
|
env:
|
||||||
- TARGET=dotnet
|
- TARGET=dotnet
|
||||||
|
@ -167,31 +178,34 @@ matrix:
|
||||||
- GROUP=PARSER
|
- GROUP=PARSER
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: linux
|
- os: linux
|
||||||
jdk: oraclejdk8
|
jdk: openjdk8
|
||||||
dist: trusty
|
dist: trusty
|
||||||
env:
|
env:
|
||||||
- TARGET=dotnet
|
- TARGET=dotnet
|
||||||
- GROUP=RECURSION
|
- GROUP=RECURSION
|
||||||
stage: extended-test
|
stage: extended-test
|
||||||
- os: linux
|
- os: linux
|
||||||
jdk: openjdk7
|
jdk: openjdk8
|
||||||
env: TARGET=python2
|
env: TARGET=python2
|
||||||
stage: main-test
|
stage: main-test
|
||||||
- os: linux
|
- os: linux
|
||||||
jdk: openjdk7
|
jdk: openjdk8
|
||||||
env: TARGET=python3
|
env: TARGET=python3
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
sources:
|
sources:
|
||||||
- deadsnakes # source required so it finds the package definition below
|
- deadsnakes # source required so it finds the package definition below
|
||||||
packages:
|
packages:
|
||||||
- python3.6
|
- python3.7
|
||||||
stage: main-test
|
stage: main-test
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
jdk: openjdk8
|
jdk: openjdk8
|
||||||
env: TARGET=javascript
|
env: TARGET=javascript
|
||||||
stage: main-test
|
stage: main-test
|
||||||
|
before_install:
|
||||||
|
- nvm install 14 # otherwise it runs by default on node 8
|
||||||
|
- f="./.travis/before-install-linux-javascript.sh"; ! [ -x "$f" ] || "$f"
|
||||||
- os: linux
|
- os: linux
|
||||||
dist: trusty
|
dist: trusty
|
||||||
jdk: openjdk8
|
jdk: openjdk8
|
||||||
|
@ -204,7 +218,7 @@ before_install:
|
||||||
script:
|
script:
|
||||||
- |
|
- |
|
||||||
cd runtime-testsuite;
|
cd runtime-testsuite;
|
||||||
travis_wait 40 ../.travis/run-tests-$TARGET.sh;
|
travis_wait 40 ../.travis/run-tests-$TARGET.sh
|
||||||
rc=$?;
|
rc=$?
|
||||||
cat target/surefire-reports/*.dumpstream || true;
|
cat target/surefire-reports/*.dumpstream || true
|
||||||
exit $rc
|
exit $rc
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
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 update -qq
|
||||||
echo "deb http://download.mono-project.com/repo/debian wheezy/snapshots/3.12.1 main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
|
|
||||||
sudo apt-get install -qq mono-complete
|
sudo apt-get install -qq mono-complete
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
wget https://storage.googleapis.com/dart-archive/channels/stable/release/2.8.4/linux_packages/dart_2.8.4-1_amd64.deb
|
||||||
|
sudo dpkg -i ./dart_2.8.4-1_amd64.deb
|
||||||
|
sudo rm ./dart_2.8.4-1_amd64.deb
|
||||||
|
sudo apt-get install -f
|
|
@ -6,5 +6,5 @@ set -euo pipefail
|
||||||
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 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-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 417A0893
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install dotnet-dev-1.0.4
|
sudo apt-get --allow-unauthenticated install dotnet-dev-1.0.4
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,5 @@
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
|
||||||
sudo apt-get update -qq
|
|
||||||
eval "$(sudo gimme 1.7.3)"
|
eval "$(sudo gimme 1.7.3)"
|
||||||
( go version ; go env ) || true
|
( go version ; go env ) || true
|
||||||
|
|
|
@ -1,6 +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
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
# use v14 and check
|
||||||
sudo apt-get update -qq
|
echo node version: $(node --version)
|
||||||
curl -sL https://deb.nodesource.com/setup_0.12 | sudo -E bash -
|
|
||||||
sudo apt-get install -qq nodejs
|
|
||||||
node --version
|
|
||||||
|
|
|
@ -4,3 +4,7 @@ set -euo pipefail
|
||||||
|
|
||||||
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
|
||||||
sudo apt-get update -qq
|
sudo apt-get update -qq
|
||||||
|
|
||||||
|
php -v
|
||||||
|
|
||||||
|
mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V
|
|
@ -1,7 +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
|
|
||||||
python --version
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
python3 --version
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
mvn -q -Dparallel=classes -DthreadCount=4 -Dtest=dart.* test
|
|
@ -2,4 +2,8 @@
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=node.* test
|
cd ../runtime/JavaScript
|
||||||
|
npm install
|
||||||
|
npm link
|
||||||
|
cd ../../runtime-testsuite
|
||||||
|
mvn -q -Dparallel=methods -DthreadCount=1 -Dtest=javascript.* test
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/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
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
python --version
|
||||||
|
|
||||||
mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=python2.* test
|
mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=python2.* test
|
||||||
|
|
||||||
cd ../runtime/Python2/tests
|
cd ../runtime/Python2/tests
|
||||||
|
|
||||||
python run.py
|
python run.py
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
|
python3 --version
|
||||||
|
|
||||||
mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=python3.* test
|
mvn -q -Dparallel=methods -DthreadCount=4 -Dtest=python3.* test
|
||||||
|
|
||||||
cd ../runtime/Python3/test
|
cd ../runtime/Python3/test
|
||||||
|
|
||||||
python3.6 run.py
|
python3 run.py
|
||||||
|
|
|
@ -6,7 +6,7 @@ set -euo pipefail
|
||||||
# here since environment variables doesn't pass
|
# here since environment variables doesn't pass
|
||||||
# across scripts
|
# across scripts
|
||||||
if [ $TRAVIS_OS_NAME == "linux" ]; then
|
if [ $TRAVIS_OS_NAME == "linux" ]; then
|
||||||
export SWIFT_VERSION=swift-4.2.1
|
export SWIFT_VERSION=swift-5.0.1
|
||||||
export SWIFT_HOME=$(pwd)/swift/$SWIFT_VERSION-RELEASE-ubuntu16.04/usr/bin/
|
export SWIFT_HOME=$(pwd)/swift/$SWIFT_VERSION-RELEASE-ubuntu16.04/usr/bin/
|
||||||
export PATH=$SWIFT_HOME:$PATH
|
export PATH=$SWIFT_HOME:$PATH
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@ ANTLR project lead and supreme dictator for life
|
||||||
* [Janyou](https://github.com/janyou) (Swift target)
|
* [Janyou](https://github.com/janyou) (Swift target)
|
||||||
* [Ewan Mellor](https://github.com/ewanmellor), [Hanzhou Shi](https://github.com/hanjoes) (Swift target merging)
|
* [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)
|
* [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)
|
||||||
|
|
||||||
## Useful information
|
## Useful information
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-master</artifactId>
|
<artifactId>antlr4-master</artifactId>
|
||||||
<version>4.7.3-SNAPSHOT</version>
|
<version>4.8-2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>antlr4-maven-plugin</artifactId>
|
<artifactId>antlr4-maven-plugin</artifactId>
|
||||||
<packaging>maven-plugin</packaging>
|
<packaging>maven-plugin</packaging>
|
||||||
|
@ -120,7 +120,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-plugin-plugin</artifactId>
|
<artifactId>maven-plugin-plugin</artifactId>
|
||||||
<version>3.3</version>
|
<version>3.6.0</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- see http://jira.codehaus.org/browse/MNG-5346 -->
|
<!-- see http://jira.codehaus.org/browse/MNG-5346 -->
|
||||||
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
|
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
|
||||||
|
|
|
@ -4,6 +4,11 @@ cache:
|
||||||
- '%USERPROFILE%\.nuget\packages -> **\project.json'
|
- '%USERPROFILE%\.nuget\packages -> **\project.json'
|
||||||
image: Visual Studio 2017
|
image: Visual Studio 2017
|
||||||
build: off
|
build: off
|
||||||
|
install:
|
||||||
|
- git submodule update --init --recursive
|
||||||
|
- cinst -y php --params "/InstallDir:C:\tools\php"
|
||||||
|
- cinst -y composer
|
||||||
|
- cinst -y dart-sdk --version=2.8.4
|
||||||
build_script:
|
build_script:
|
||||||
- mvn -DskipTests install --batch-mode
|
- 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 /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
|
||||||
|
@ -11,7 +16,7 @@ build_script:
|
||||||
after_build:
|
after_build:
|
||||||
- msbuild /target:pack /property:Configuration=Release /verbosity:detailed runtime/CSharp/runtime/CSharp/Antlr4.dotnet.sln
|
- msbuild /target:pack /property:Configuration=Release /verbosity:detailed runtime/CSharp/runtime/CSharp/Antlr4.dotnet.sln
|
||||||
test_script:
|
test_script:
|
||||||
- mvn install -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
|
- mvn install -Dantlr-php-php="C:\tools\php\php.exe" -Dantlr-dart-dart="C:\tools\dart-sdk\bin\dart.exe" -Dantlr-dart-pub="C:\tools\dart-sdk\bin\pub.bat" -Dantlr-dart-dart2native="C:\tools\dart-sdk\bin\dart2native.bat" -Dantlr-python2-python="C:\Python27\python.exe" -Dantlr-python3-python="C:\Python35\python.exe" --batch-mode
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: 'runtime\**\*.nupkg'
|
- path: 'runtime\**\*.nupkg'
|
||||||
name: NuGet
|
name: NuGet
|
|
@ -1,5 +1,9 @@
|
||||||
ANTLR Project Contributors Certification of Origin and Rights
|
ANTLR Project Contributors Certification of Origin and Rights
|
||||||
|
|
||||||
|
NOTE: This tool is mature and Terence is mostly occupied elsewhere. We
|
||||||
|
can't accept any changes that could have widespread effects on thousands
|
||||||
|
of existing projects. Sorry!
|
||||||
|
|
||||||
All contributors to ANTLR v4 must formally agree to abide by this
|
All contributors to ANTLR v4 must formally agree to abide by this
|
||||||
certificate of origin by signing on the bottom with their github
|
certificate of origin by signing on the bottom with their github
|
||||||
userid, full name, email address (you can obscure your e-mail, but it
|
userid, full name, email address (you can obscure your e-mail, but it
|
||||||
|
@ -204,6 +208,7 @@ YYYY/MM/DD, github id, Full name, email
|
||||||
2018/07/03, jgoppert, James Goppert, james.goppert@gmail.com
|
2018/07/03, jgoppert, James Goppert, james.goppert@gmail.com
|
||||||
2018/07/27, Maksim Novikov, mnovikov.work@gmail.com
|
2018/07/27, Maksim Novikov, mnovikov.work@gmail.com
|
||||||
2018/08/03, ENDOH takanao, djmchl@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/10/18, edirgarcia, Edir García Lazo, edirgl@hotmail.com
|
||||||
2018/07/31, Lucas Henrqiue, lucashenrique580@gmail.com
|
2018/07/31, Lucas Henrqiue, lucashenrique580@gmail.com
|
||||||
2018/08/03, ENDOH takanao, djmchl@gmail.com
|
2018/08/03, ENDOH takanao, djmchl@gmail.com
|
||||||
|
@ -214,8 +219,64 @@ YYYY/MM/DD, github id, Full name, email
|
||||||
2018/11/29, hannemann-tamas, Ralf Hannemann-Tamas, ralf.ht@gmail.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/20, WalterCouto, Walter Couto, WalterCouto@users.noreply.github.com
|
||||||
2018/12/23, youkaichao, Kaichao You, youkaichao@gmail.com
|
2018/12/23, youkaichao, Kaichao You, youkaichao@gmail.com
|
||||||
|
2019/01/02, wkhemir, Wail Khemir, khemirwail@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/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/13, base698, Justin Thomas, justin.thomas1@gmail.com
|
||||||
2019/03/18, carlodri, Carlo Dri, carlo.dri@gmail.com
|
2019/03/18, carlodri, Carlo Dri, carlo.dri@gmail.com
|
||||||
2019/05/02, askingalot, Andy Collins, askingalot@gmail.com
|
2019/05/02, askingalot, Andy Collins, askingalot@gmail.com
|
||||||
2019/07/08, abhijithneilabraham,Abhijith Neil Abraham, abhijithneilabrahampk@gmail.com
|
2019/07/08, abhijithneilabraham,Abhijith Neil Abraham, abhijithneilabrahampk@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, 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/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/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
|
|
@ -14,7 +14,7 @@ For the 4.7.1 release, we discussed both approaches in [detail](https://github.c
|
||||||
|
|
||||||
## Case-insensitive grammars
|
## Case-insensitive grammars
|
||||||
|
|
||||||
As a prime example of a grammar that specifically describes case insensitive keywords, see the
|
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
|
[SQLite grammar](https://github.com/antlr/grammars-v4/blob/master/sqlite/SQLite.g4). To match a case insensitive keyword, there are rules such as
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -72,7 +72,8 @@ Lexer lexer = new SomeSQLLexer(upper);
|
||||||
|
|
||||||
Here are implementations of `CaseChangingCharStream` in various target languages:
|
Here are implementations of `CaseChangingCharStream` in various target languages:
|
||||||
|
|
||||||
* [Java](https://github.com/parrt/antlr4/blob/case-insensitivity-doc/doc/resources/CaseChangingCharStream.java)
|
* [C#](https://github.com/antlr/antlr4/blob/master/doc/resources/CaseChangingCharStream.cs)
|
||||||
* [JavaScript](https://github.com/parrt/antlr4/blob/case-insensitivity-doc/doc/resources/CaseInsensitiveInputStream.js)
|
* [Go](https://github.com/antlr/antlr4/blob/master/doc/resources/case_changing_stream.go)
|
||||||
* [Go](https://github.com/parrt/antlr4/blob/case-insensitivity-doc/doc/resources/case_changing_stream.go)
|
* [Java](https://github.com/antlr/antlr4/blob/master/doc/resources/CaseChangingCharStream.java)
|
||||||
* [C#](https://github.com/parrt/antlr4/blob/case-insensitivity-doc/doc/resources/CaseChangingCharStream.cs)
|
* [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)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# C++
|
# 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 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/beyond-the-loop/Antlr-cpp-cmake/).
|
||||||
|
|
||||||
## How to create a C++ lexer or parser?
|
## 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:
|
This is pretty much the same as creating a Java lexer or parser, except you need to specify the language target, for example:
|
||||||
|
@ -45,7 +45,7 @@ The generation step above created a listener and base listener class for you. Th
|
||||||
#include "MyGrammarParser.h"
|
#include "MyGrammarParser.h"
|
||||||
#include "MyGrammarBaseListener.h"
|
#include "MyGrammarBaseListener.h"
|
||||||
|
|
||||||
using namespace org::antlr::v4::runtime;
|
using namespace antlr4;
|
||||||
|
|
||||||
class TreeShapeListener : public MyGrammarBaseListener {
|
class TreeShapeListener : public MyGrammarBaseListener {
|
||||||
public:
|
public:
|
||||||
|
@ -65,7 +65,7 @@ int main(int argc, const char* argv[]) {
|
||||||
|
|
||||||
tree::ParseTree *tree = parser.key();
|
tree::ParseTree *tree = parser.key();
|
||||||
TreeShapeListener listener;
|
TreeShapeListener listener;
|
||||||
tree::ParseTreeWalker::DEFAULT->walk(&listener, tree);
|
tree::ParseTreeWalker::DEFAULT.walk(&listener, tree);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ Creating a new target involves the following key elements:
|
||||||
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 *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 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. 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. Create test files under [/runtime-testsuite/test/org/antlr/v4/test/runtime](https://github.com/antlr/antlr4/tree/master/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.
|
||||||
|
1. Create/edit shell scripts in [/.travis](https://github.com/antlr/antlr4/blob/master/.travis) and [/appveyor.yml](https://github.com/antlr/antlr4/blob/master/appveyor.yml) to run tests in CI pipelines.
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,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
|
IParseTree tree = parser.StartRule() - only repeated here for reference
|
||||||
KeyPrinter printer = new KeyPrinter();
|
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.
|
Further information can be found from The Definitive ANTLR Reference book.
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
# ANTLR4 Runtime for Dart
|
||||||
|
|
||||||
|
Notice: Dart target may generate code incompatible with Dart 2.9 sound null safety. Please set the minimum SDK constraint to 2.8.4 or lower if such violation is found. Contributions are welcomed.
|
||||||
|
|
||||||
|
### 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: <ANTLR version>
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 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<String> 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());
|
||||||
|
parser.buildParseTree = true;
|
||||||
|
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
|
||||||
|
```
|
|
@ -38,8 +38,8 @@ This is the main landing page for the ANTLR 4 FAQ. The links below will take you
|
||||||
|
|
||||||
## Translation
|
## Translation
|
||||||
|
|
||||||
* [ASTs vs parse trees](parse-trees.md)
|
* [ASTs vs parse trees](translation.md)
|
||||||
* [Decoupling input walking from output generation](parse-trees.md)
|
* [Decoupling input walking from output generation](translation.md)
|
||||||
|
|
||||||
## Actions and semantic predicates
|
## Actions and semantic predicates
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ For writing a compiler, either generate [LLVM-type static-single-assignment](htt
|
||||||
|
|
||||||
### XPath
|
### 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
|
### 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.
|
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)
|
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)
|
||||||
|
|
|
@ -6,46 +6,46 @@ Hi and welcome to the version 4 release of ANTLR! It's named after the fearless
|
||||||
|
|
||||||
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 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.
|
||||||
|
|
||||||
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.9-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
|
### UNIX
|
||||||
|
|
||||||
0. Install Java (version 1.6 or higher)
|
0. Install Java (version 1.7 or higher)
|
||||||
1. Download
|
1. Download
|
||||||
```
|
```
|
||||||
$ cd /usr/local/lib
|
$ 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.9-complete.jar
|
||||||
```
|
```
|
||||||
Or just download in browser from website:
|
Or just download in browser from website:
|
||||||
[https://www.antlr.org/download.html](https://www.antlr.org/download.html)
|
[https://www.antlr.org/download.html](https://www.antlr.org/download.html)
|
||||||
and put it somewhere rational like `/usr/local/lib`.
|
and put it somewhere rational like `/usr/local/lib`.
|
||||||
|
|
||||||
2. Add `antlr-4.7.1-complete.jar` to your `CLASSPATH`:
|
2. Add `antlr-4.9-complete.jar` to your `CLASSPATH`:
|
||||||
```
|
```
|
||||||
$ export CLASSPATH=".:/usr/local/lib/antlr-4.7.1-complete.jar:$CLASSPATH"
|
$ export CLASSPATH=".:/usr/local/lib/antlr-4.9-complete.jar.jar:$CLASSPATH"
|
||||||
```
|
```
|
||||||
It's also a good idea to put this in your `.bash_profile` or whatever your startup script is.
|
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`.
|
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 antlr4='java -Xmx500M -cp "/usr/local/lib/antlr-4.9-complete.jar.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 grun='java -Xmx500M -cp "/usr/local/lib/antlr-4.9-complete.jar.jar:$CLASSPATH" org.antlr.v4.gui.TestRig'
|
||||||
```
|
```
|
||||||
|
|
||||||
### WINDOWS
|
### WINDOWS
|
||||||
|
|
||||||
(*Thanks to Graham Wideman*)
|
(*Thanks to Graham Wideman*)
|
||||||
|
|
||||||
0. Install Java (version 1.6 or higher)
|
0. Install Java (version 1.7 or higher)
|
||||||
1. Download antlr-4.7.1-complete.jar (or whatever version) from [https://www.antlr.org/download/](https://www.antlr.org/download/)
|
1. Download antlr-4.9-complete.jar (or whatever version) from [https://www.antlr.org/download/](https://www.antlr.org/download/)
|
||||||
Save to your directory for 3rd party Java libraries, say `C:\Javalib`
|
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.9-complete.jar.jar` to CLASSPATH, either:
|
||||||
* Permanently: Using System Properties dialog > Environment variables > Create or append to `CLASSPATH` variable
|
* Permanently: Using System Properties dialog > Environment variables > Create or append to `CLASSPATH` variable
|
||||||
* Temporarily, at command line:
|
* Temporarily, at command line:
|
||||||
```
|
```
|
||||||
SET CLASSPATH=.;C:\Javalib\antlr-4.7.1-complete.jar;%CLASSPATH%
|
SET CLASSPATH=.;C:\Javalib\antlr-4.9-complete.jar;%CLASSPATH%
|
||||||
```
|
```
|
||||||
3. Create short convenient commands for the ANTLR Tool, and TestRig, using batch files or doskey commands:
|
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
|
* Batch files (in directory in system PATH) antlr4.bat and grun.bat
|
||||||
|
@ -71,7 +71,7 @@ Either launch org.antlr.v4.Tool directly:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ java org.antlr.v4.Tool
|
$ java org.antlr.v4.Tool
|
||||||
ANTLR Parser Generator Version 4.7.1
|
ANTLR Parser Generator Version 4.9
|
||||||
-o ___ specify output directory where all output is generated
|
-o ___ specify output directory where all output is generated
|
||||||
-lib ___ specify location of .tokens files
|
-lib ___ specify location of .tokens files
|
||||||
...
|
...
|
||||||
|
@ -80,8 +80,8 @@ ANTLR Parser Generator Version 4.7.1
|
||||||
or use -jar option on java:
|
or use -jar option on java:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ java -jar /usr/local/lib/antlr-4.7.1-complete.jar
|
$ java -jar /usr/local/lib/antlr-4.9-complete.jar
|
||||||
ANTLR Parser Generator Version 4.7.1
|
ANTLR Parser Generator Version 4.9
|
||||||
-o ___ specify output directory where all output is generated
|
-o ___ specify output directory where all output is generated
|
||||||
-lib ___ specify location of .tokens files
|
-lib ___ specify location of .tokens files
|
||||||
...
|
...
|
||||||
|
@ -112,8 +112,11 @@ Now test it:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ grun Hello r -tree
|
$ grun Hello r -tree
|
||||||
|
(Now enter something like the string below)
|
||||||
hello parrt
|
hello parrt
|
||||||
|
(now,do:)
|
||||||
^D
|
^D
|
||||||
|
(The output:)
|
||||||
(r hello parrt)
|
(r hello parrt)
|
||||||
(That ^D means EOF on unix; it's ^Z in Windows.) The -tree option prints the parse tree in LISP notation.
|
(That ^D means EOF on unix; it's ^Z in Windows.) The -tree option prints the parse tree in LISP notation.
|
||||||
It's nicer to look at parse trees visually.
|
It's nicer to look at parse trees visually.
|
||||||
|
@ -135,3 +138,4 @@ The book has lots and lots of examples that should be useful too. You can downlo
|
||||||
Also, there is a large collection of grammars for v4 at github:
|
Also, there is a large collection of grammars for v4 at github:
|
||||||
|
|
||||||
[https://github.com/antlr/grammars-v4](https://github.com/antlr/grammars-v4)
|
[https://github.com/antlr/grammars-v4](https://github.com/antlr/grammars-v4)
|
||||||
|
/
|
|
@ -65,7 +65,7 @@ Another common option to the ANTLR tool is `-visitor`, which generates a parse t
|
||||||
|
|
||||||
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. Suppose the gen'ed parser code is in the `parser` directory relative to this code:
|
||||||
|
|
||||||
```
|
```golang
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -11,11 +11,18 @@ In practice, this target has been extensively tested against:
|
||||||
* Chrome 39.0.2171
|
* Chrome 39.0.2171
|
||||||
* Explorer 11.0.3
|
* Explorer 11.0.3
|
||||||
|
|
||||||
The tests were conducted using Selenium. No issue was found, so you should find that the runtime works pretty much against any recent JavaScript engine.
|
The above tests were conducted using Selenium. No issue was found, so you should find that the runtime works pretty much against any recent JavaScript engine.
|
||||||
|
|
||||||
## Is NodeJS supported?
|
## Is NodeJS supported?
|
||||||
|
|
||||||
The runtime has also been extensively tested against Node.js 0.12.7. No issue was found.
|
The runtime has also been extensively tested against Node.js 14 LTS. No issue was found.
|
||||||
|
NodeJS together with a packaging tool is now the preferred development path, developers are encouraged to follow it.
|
||||||
|
|
||||||
|
## What about modules?
|
||||||
|
|
||||||
|
Starting with version 8.1, Antlr4 JavaScript runtime follows esm semantics (see https://tc39.es/ecma262/#sec-modules for details)
|
||||||
|
Generated lexers, parsers, listeners and visitors also follow this new standard.
|
||||||
|
If you have used previous versions of the runtime, you will need to migrate and make your parser a module.
|
||||||
|
|
||||||
## How to create a JavaScript lexer or parser?
|
## How to create a JavaScript lexer or parser?
|
||||||
|
|
||||||
|
@ -55,32 +62,20 @@ You can get [information on webpack here](https://webpack.github.io).
|
||||||
|
|
||||||
The steps to create your parsing code are the following:
|
The steps to create your parsing code are the following:
|
||||||
- generate your lexer, parser, listener and visitor using the antlr tool
|
- generate your lexer, parser, listener and visitor using the antlr tool
|
||||||
- write your parse tree handling code by providig your custom listener or visitor, and associated code, using 'require' to load antlr.
|
- write your parse tree handling code by providing your custom listener or visitor, and associated code, using 'require' to load antlr.
|
||||||
- create an index.js file with the entry point to your parsing code (or several if required).
|
- create an index.js file with the entry point to your parsing code (or several if required).
|
||||||
- test your parsing logic thoroughly using node.js
|
- test your parsing logic thoroughly using node.js
|
||||||
|
|
||||||
You are now ready to bundle your parsing code as follows:
|
You are now ready to bundle your parsing code as follows:
|
||||||
- following webpack specs, create a webpack.config file
|
- following webpack specs, create a webpack.config file
|
||||||
- in the webpack.config file, exclude node.js only modules using: node: { module: "empty", net: "empty", fs: "empty" }
|
- For Webpack version 5,
|
||||||
|
- in the `webpack.config` file, exclude node.js only modules using: `resolve: { fallback: { fs: false } }`
|
||||||
|
- For older versions of Webpack,
|
||||||
|
- in the `webpack.config` file, exclude node.js only modules using: `node: { module: "empty", net: "empty", fs: "empty" }`
|
||||||
- from the cmd line, navigate to the directory containing webpack.config and type: webpack
|
- from the cmd line, navigate to the directory containing webpack.config and type: webpack
|
||||||
|
|
||||||
This will produce a single js file containing all your parsing code. Easy to include in your web pages!
|
This will produce a single js file containing all your parsing code. Easy to include in your web pages!
|
||||||
|
|
||||||
If you can't use webpack, you can use the lib/require.js script which implements the Node.js 'require' function in brwsers.
|
|
||||||
|
|
||||||
This script is provided by Torben Haase, and is NOT part of ANTLR JavaScript runtime.
|
|
||||||
|
|
||||||
Assuming you have, at the root of your web site, both the 'antlr4' directory and a 'lib' directory with 'require.js' inside it, all you need to put in your HTML header is the following:
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<script src='lib/require.js'>
|
|
||||||
<script>
|
|
||||||
var antlr4 = require('antlr4/index');
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
This will load the runtime asynchronously.
|
|
||||||
|
|
||||||
## How do I run the generated lexer and/or parser?
|
## 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:
|
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:
|
||||||
|
@ -95,18 +90,18 @@ Let's suppose that your grammar is named, as above, "MyGrammar". Let's suppose t
|
||||||
Now a fully functioning script might look like the following:
|
Now a fully functioning script might look like the following:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var antlr4 = require('antlr4');
|
import antlr4 from 'antlr4';
|
||||||
var MyGrammarLexer = require('./MyGrammarLexer').MyGrammarLexer;
|
import MyGrammarLexer from './MyGrammarLexer.js');
|
||||||
var MyGrammarParser = require('./MyGrammarParser').MyGrammarParser;
|
import MyGrammarParser from './MyGrammarParser.js';
|
||||||
var MyGrammarListener = require('./MyGrammarListener').MyGrammarListener;
|
import MyGrammarListener from './MyGrammarListener.js';
|
||||||
|
|
||||||
var input = "your text to parse here"
|
const input = "your text to parse here"
|
||||||
var chars = new antlr4.InputStream(input);
|
const chars = new antlr4.InputStream(input);
|
||||||
var lexer = new MyGrammarLexer(chars);
|
const lexer = new MyGrammarLexer(chars);
|
||||||
var tokens = new antlr4.CommonTokenStream(lexer);
|
const tokens = new antlr4.CommonTokenStream(lexer);
|
||||||
var parser = new MyGrammarParser(tokens);
|
const parser = new MyGrammarParser(tokens);
|
||||||
parser.buildParseTrees = true;
|
parser.buildParseTrees = true;
|
||||||
var tree = parser.MyStartRule();
|
const tree = parser.MyStartRule();
|
||||||
```
|
```
|
||||||
|
|
||||||
This program will work. But it won't be useful unless you do one of the following:
|
This program will work. But it won't be useful unless you do one of the following:
|
||||||
|
@ -120,19 +115,19 @@ This program will work. But it won't be useful unless you do one of the followin
|
||||||
## How do I create and run a visitor?
|
## How do I create and run a visitor?
|
||||||
```javascript
|
```javascript
|
||||||
// test.js
|
// test.js
|
||||||
var antlr4 = require('antlr4');
|
import antlr4 from 'antlr4';
|
||||||
var MyGrammarLexer = require('./QueryLexer').QueryLexer;
|
import MyGrammarLexer from './QueryLexer.js';
|
||||||
var MyGrammarParser = require('./QueryParser').QueryParser;
|
import MyGrammarParser from './QueryParser.js';
|
||||||
var MyGrammarListener = require('./QueryListener').QueryListener;
|
import MyGrammarListener from './QueryListener.js';
|
||||||
|
|
||||||
|
|
||||||
var input = "field = 123 AND items in (1,2,3)"
|
const input = "field = 123 AND items in (1,2,3)"
|
||||||
var chars = new antlr4.InputStream(input);
|
const chars = new antlr4.InputStream(input);
|
||||||
var lexer = new MyGrammarLexer(chars);
|
const lexer = new MyGrammarLexer(chars);
|
||||||
var tokens = new antlr4.CommonTokenStream(lexer);
|
const tokens = new antlr4.CommonTokenStream(lexer);
|
||||||
var parser = new MyGrammarParser(tokens);
|
const parser = new MyGrammarParser(tokens);
|
||||||
parser.buildParseTrees = true;
|
parser.buildParseTrees = true;
|
||||||
var tree = parser.query();
|
const tree = parser.query();
|
||||||
|
|
||||||
class Visitor {
|
class Visitor {
|
||||||
visitChildren(ctx) {
|
visitChildren(ctx) {
|
||||||
|
@ -160,40 +155,37 @@ tree.accept(new Visitor());
|
||||||
Let's suppose your MyGrammar grammar comprises 2 rules: "key" and "value". The antlr4 tool will have generated the following listener:
|
Let's suppose your MyGrammar grammar comprises 2 rules: "key" and "value". The antlr4 tool will have generated the following listener:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
MyGrammarListener = function(ParseTreeListener) {
|
class MyGrammarListener extends ParseTreeListener {
|
||||||
// some code here
|
|
||||||
}
|
constructor() {
|
||||||
// some code here
|
super();
|
||||||
MyGrammarListener.prototype.enterKey = function(ctx) {};
|
}
|
||||||
MyGrammarListener.prototype.exitKey = function(ctx) {};
|
|
||||||
MyGrammarListener.prototype.enterValue = function(ctx) {};
|
enterKey(ctx) {}
|
||||||
MyGrammarListener.prototype.exitValue = function(ctx) {};
|
exitKey(ctx) {}
|
||||||
|
enterValue(ctx) {}
|
||||||
|
exitValue(ctx) {}
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
In order to provide custom behavior, you might want to create the following class:
|
In order to provide custom behavior, you might want to create the following class:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var KeyPrinter = function() {
|
class KeyPrinter extends MyGrammarListener {
|
||||||
MyGrammarListener.call(this); // inherit default listener
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
// continue inheriting default listener
|
// override default listener behavior
|
||||||
KeyPrinter.prototype = Object.create(MyGrammarListener.prototype);
|
exitKey(ctx) {
|
||||||
KeyPrinter.prototype.constructor = KeyPrinter;
|
console.log("Oh, a key!");
|
||||||
|
}
|
||||||
// override default listener behavior
|
}
|
||||||
KeyPrinter.prototype.exitKey = function(ctx) {
|
|
||||||
console.log("Oh, a key!");
|
|
||||||
};
|
|
||||||
```
|
```
|
||||||
|
|
||||||
In order to execute this listener, you would simply add the following lines to the above code:
|
In order to execute this listener, you would simply add the following lines to the above code:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
...
|
...
|
||||||
tree = parser.StartRule() // only repeated here for reference
|
tree = parser.StartRule() // only repeated here for reference
|
||||||
var printer = new KeyPrinter();
|
const printer = new KeyPrinter();
|
||||||
antlr4.tree.ParseTreeWalker.DEFAULT.walk(printer, tree);
|
antlr4.tree.ParseTreeWalker.DEFAULT.walk(printer, tree);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ fragment DIGIT : [0-9] ; // not a token by itself
|
||||||
|
|
||||||
## Lexical Modes
|
## Lexical Modes
|
||||||
|
|
||||||
Modes allow you to group lexical rules by context, such as inside and outside of XML tags. It’s like having multiple sublexers, one for context. The lexer can only return tokens matched by entering a rule in the current mode. Lexers start out in the so-called default mode. All rules are considered to be within the default mode unless you specify a mode command. Modes are not allowed within combined grammars, just lexer grammars. (See grammar `XMLLexer` from [Tokenizing XML](http://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference).)
|
Modes allow you to group lexical rules by context, such as inside and outside of XML tags. It’s like having multiple sublexers, one for each context. The lexer can only return tokens matched by entering a rule in the current mode. Lexers start out in the so-called default mode. All rules are considered to be within the default mode unless you specify a mode command. Modes are not allowed within combined grammars, just lexer grammars. (See grammar `XMLLexer` from [Tokenizing XML](http://pragprog.com/book/tpantlr2/the-definitive-antlr-4-reference).)
|
||||||
|
|
||||||
```
|
```
|
||||||
rules in default mode
|
rules in default mode
|
||||||
|
@ -58,7 +58,7 @@ Match that character or sequence of characters. E.g., ’while’ or ’=’.</t
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>[char set]</td><td>
|
<td>[char set]</td><td>
|
||||||
<p>Match one of the characters specified in the character set. Interpret <tt>x-y</tt> as the set of characters between range <tt>x</tt> and <tt>y</tt>, inclusively. The following escaped characters are interpreted as single special characters: <tt>\n</tt>, <tt>\r</tt>, <tt>\b</tt>, <tt>\t</tt>, <tt>\f</tt>, <tt>\uXXXX</tt>, and <tt>\u{XXXXXX}</tt>. To get <tt>]</tt>, <tt>\</tt>, or <tt>-</tt> you must escape them with <tt>\</tt>.</p>
|
<p>Match one of the characters specified in the character set. Interpret <tt>x-y</tt> as the set of characters between range <tt>x</tt> and <tt>y</tt>, inclusively. The following escaped characters are interpreted as single special characters: <tt>\n</tt>, <tt>\r</tt>, <tt>\b</tt>, <tt>\t</tt>, <tt>\f</tt>, <tt>\uXXXX</tt>, and <tt>\u{XXXXXX}</tt>. To get <tt>]</tt> or <tt>\</tt> you must escape them with <tt>\</tt>. To get <tt>-</tt> you must escape it with <tt>\</tt> too, except for the case when <tt>-</tt> is the first or last character in the set.</p>
|
||||||
|
|
||||||
<p>You can also include all characters matching Unicode properties (general category, boolean, or enumerated including scripts and blocks) with <tt>\p{PropertyName}</tt> or <tt>\p{EnumProperty=Value}</tt>. (You can invert the test with <tt>\P{PropertyName}</tt> or <tt>\P{EnumProperty=Value}</tt>).</p>
|
<p>You can also include all characters matching Unicode properties (general category, boolean, or enumerated including scripts and blocks) with <tt>\p{PropertyName}</tt> or <tt>\p{EnumProperty=Value}</tt>. (You can invert the test with <tt>\P{PropertyName}</tt> or <tt>\P{EnumProperty=Value}</tt>).</p>
|
||||||
|
|
||||||
|
@ -90,6 +90,8 @@ UNICODE_ID : [\p{Alpha}\p{General_Category=Other_Letter}] [\p{Alnum}\p{General_C
|
||||||
EMOJI : [\u{1F4A9}\u{1F926}] ; // note Unicode code points > U+FFFF
|
EMOJI : [\u{1F4A9}\u{1F926}] ; // note Unicode code points > U+FFFF
|
||||||
|
|
||||||
DASHBRACK : [\-\]]+ ; // match - or ] one or more times
|
DASHBRACK : [\-\]]+ ; // match - or ] one or more times
|
||||||
|
|
||||||
|
DASH : [---] ; // match a single -, i.e., "any character" between - and - (note first and last - not escaped)
|
||||||
</pre>
|
</pre>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -123,7 +125,7 @@ ESC : '\\' . ; // match any escaped \x character
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>{«action»}</td><td>
|
<td>{«action»}</td><td>
|
||||||
Lexer actions can appear anywhere as of 4.2, not just at the end of the outermost alternative. The lexer executes the actions at the appropriate input position, according to the placement of the action within the rule. To execute a single action for a role that has multiple alternatives, you can enclose the alts in parentheses and put the action afterwards:
|
Lexer actions can appear anywhere as of 4.2, not just at the end of the outermost alternative. The lexer executes the actions at the appropriate input position, according to the placement of the action within the rule. To execute a single action for a rule that has multiple alternatives, you can enclose the alts in parentheses and put the action afterwards:
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
END : ('endif'|'end') {System.out.println("found an end");} ;
|
END : ('endif'|'end') {System.out.println("found an end");} ;
|
||||||
|
@ -244,7 +246,8 @@ The mode commands alter the mode stack and hence the mode of the lexer. The 'mor
|
||||||
```
|
```
|
||||||
// Default "mode": Everything OUTSIDE of a tag
|
// Default "mode": Everything OUTSIDE of a tag
|
||||||
COMMENT : '<!--' .*? '-->' ;
|
COMMENT : '<!--' .*? '-->' ;
|
||||||
CDATA : '<![CDATA[' .*? ']]>' ;OPEN : '<' -> pushMode(INSIDE) ;
|
CDATA : '<![CDATA[' .*? ']]>' ;
|
||||||
|
OPEN : '<' -> pushMode(INSIDE) ;
|
||||||
...
|
...
|
||||||
XMLDeclOpen : '<?xml' S -> pushMode(INSIDE) ;
|
XMLDeclOpen : '<?xml' S -> pushMode(INSIDE) ;
|
||||||
SPECIAL_OPEN: '<?' Name -> more, pushMode(PROC_INSTR) ;
|
SPECIAL_OPEN: '<?' Name -> more, pushMode(PROC_INSTR) ;
|
||||||
|
|
|
@ -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:
|
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
|
ID, LPAREN, RIGHT_CURLY // token names/lexer rules
|
||||||
expr, simpleDeclarator, d2, header_file // rule names
|
expr, simpleDeclarator, d2, header_file // parser rule names
|
||||||
```
|
```
|
||||||
|
|
||||||
Like Java, ANTLR accepts Unicode characters in ANTLR names:
|
Like Java, ANTLR accepts Unicode characters in ANTLR names:
|
||||||
|
@ -96,7 +96,7 @@ The recognizers that ANTLR generates assume a character vocabulary containing al
|
||||||
|
|
||||||
## Actions
|
## 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).
|
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).
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
# ANTLR4 Runtime for PHP
|
||||||
|
|
||||||
|
### 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 PHP 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 Composer:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
composer require antlr4-php-runtime
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 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 PHP parser, run the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
antlr4 -Dlanguage=PHP 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=PHP JSON.g4`. The result of this is a
|
||||||
|
collection of `.php` files in the `parser` directory including:
|
||||||
|
```
|
||||||
|
JsonParser.php
|
||||||
|
JsonBaseListener.php
|
||||||
|
JsonLexer.php
|
||||||
|
JsonListener.php
|
||||||
|
```
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace JsonParser;
|
||||||
|
|
||||||
|
use Antlr\Antlr4\Runtime\CommonTokenStream;
|
||||||
|
use Antlr\Antlr4\Runtime\Error\Listeners\DiagnosticErrorListener;
|
||||||
|
use Antlr\Antlr4\Runtime\InputStream;
|
||||||
|
use Antlr\Antlr4\Runtime\ParserRuleContext;
|
||||||
|
use Antlr\Antlr4\Runtime\Tree\ErrorNode;
|
||||||
|
use Antlr\Antlr4\Runtime\Tree\ParseTreeListener;
|
||||||
|
use Antlr\Antlr4\Runtime\Tree\ParseTreeWalker;
|
||||||
|
use Antlr\Antlr4\Runtime\Tree\TerminalNode;
|
||||||
|
|
||||||
|
final class TreeShapeListener implements ParseTreeListener {
|
||||||
|
public function visitTerminal(TerminalNode $node) : void {}
|
||||||
|
public function visitErrorNode(ErrorNode $node) : void {}
|
||||||
|
public function exitEveryRule(ParserRuleContext $ctx) : void {}
|
||||||
|
|
||||||
|
public function enterEveryRule(ParserRuleContext $ctx) : void {
|
||||||
|
echo $ctx->getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = InputStream::fromPath($argv[1]);
|
||||||
|
$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);
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a `example.json` file:
|
||||||
|
```json
|
||||||
|
{"a":1}
|
||||||
|
```
|
||||||
|
|
||||||
|
Parse the input file:
|
||||||
|
|
||||||
|
```
|
||||||
|
php json.php example.json
|
||||||
|
```
|
||||||
|
|
||||||
|
The expected output is:
|
||||||
|
|
||||||
|
```
|
||||||
|
{"a":1}
|
||||||
|
{"a":1}
|
||||||
|
"a":1
|
||||||
|
1
|
||||||
|
```
|
|
@ -9,17 +9,41 @@ Create a pre-release or full release at github; [Example 4.5-rc-1](https://githu
|
||||||
Wack any existing tag as mvn will create one and it fails if already there.
|
Wack any existing tag as mvn will create one and it fails if already there.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git tag -d 4.7
|
$ git tag -d 4.8
|
||||||
$ git push origin :refs/tags/4.7
|
$ git push origin :refs/tags/4.8
|
||||||
$ git push upstream :refs/tags/4.7
|
$ git push upstream :refs/tags/4.8
|
||||||
```
|
```
|
||||||
|
|
||||||
### Create release candidate tag
|
### Create release candidate tag
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ git tag -a 4.7-rc1 -m 'heading towards 4.7'
|
$ git tag -a 4.8-rc1 -m 'heading towards 4.8'
|
||||||
$ git push origin 4.7-rc1
|
$ git push origin 4.8-rc1
|
||||||
$ git push upstream 4.7-rc1
|
$ git push upstream 4.8-rc1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Update submodules
|
||||||
|
|
||||||
|
Make sure you tell git to pull in the submodule (for every clone you do of antlr4):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git submodule init
|
||||||
|
```
|
||||||
|
|
||||||
|
Also bump version to 4.8 in `runtime/PHP/src/RuntimeMetaData.php`.
|
||||||
|
|
||||||
|
Update the runtime submodules by running the following command:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git submodule update --recursive
|
||||||
|
git submodule update --remote --merge # might only need this last one but do both
|
||||||
|
```
|
||||||
|
|
||||||
|
Make sure these changes go back to antlr4 repo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add runtime/PHP
|
||||||
|
git commit -m "Update PHP Runtime to latest version"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Bump version
|
## Bump version
|
||||||
|
@ -33,7 +57,7 @@ Edit the repository looking for 4.5 or whatever and update it. Bump version in t
|
||||||
* runtime/Python3/src/antlr4/Recognizer.py
|
* runtime/Python3/src/antlr4/Recognizer.py
|
||||||
* runtime/CSharp/runtime/CSharp/Antlr4.Runtime/Properties/AssemblyInfo.cs
|
* runtime/CSharp/runtime/CSharp/Antlr4.Runtime/Properties/AssemblyInfo.cs
|
||||||
* runtime/CSharp/runtime/CSharp/Antlr4.Runtime/Antlr4.Runtime.dotnet.csproj
|
* runtime/CSharp/runtime/CSharp/Antlr4.Runtime/Antlr4.Runtime.dotnet.csproj
|
||||||
* runtime/JavaScript/src/antlr4/package.json
|
* runtime/JavaScript/package.json
|
||||||
* runtime/JavaScript/src/antlr4/Recognizer.js
|
* runtime/JavaScript/src/antlr4/Recognizer.js
|
||||||
* runtime/Cpp/VERSION
|
* runtime/Cpp/VERSION
|
||||||
* runtime/Cpp/runtime/src/RuntimeMetaData.cpp
|
* runtime/Cpp/runtime/src/RuntimeMetaData.cpp
|
||||||
|
@ -41,6 +65,8 @@ Edit the repository looking for 4.5 or whatever and update it. Bump version in t
|
||||||
* runtime/Cpp/demo/generate.cmd
|
* runtime/Cpp/demo/generate.cmd
|
||||||
* runtime/Go/antlr/recognizer.go
|
* runtime/Go/antlr/recognizer.go
|
||||||
* runtime/Swift/Antlr4/org/antlr/v4/runtime/RuntimeMetaData.swift
|
* runtime/Swift/Antlr4/org/antlr/v4/runtime/RuntimeMetaData.swift
|
||||||
|
* runtime/Dart/lib/src/runtime_meta_data.dart
|
||||||
|
* runtime/Dart/pubspec.yaml
|
||||||
* tool/src/org/antlr/v4/codegen/target/GoTarget.java
|
* 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/CppTarget.java
|
||||||
* tool/src/org/antlr/v4/codegen/target/CSharpTarget.java
|
* tool/src/org/antlr/v4/codegen/target/CSharpTarget.java
|
||||||
|
@ -59,6 +85,10 @@ find tool runtime -type f -exec grep -l '4\.6' {} \;
|
||||||
|
|
||||||
Commit to repository.
|
Commit to repository.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
## Maven Repository Settings
|
## Maven Repository Settings
|
||||||
|
|
||||||
First, make sure you have maven set up to communicate with staging servers etc... Create file `~/.m2/settings.xml` with appropriate username/password for staging server and gpg.keyname/passphrase for signing. Make sure it has strict visibility privileges to just you. On unix, it looks like:
|
First, make sure you have maven set up to communicate with staging servers etc... Create file `~/.m2/settings.xml` with appropriate username/password for staging server and gpg.keyname/passphrase for signing. Make sure it has strict visibility privileges to just you. On unix, it looks like:
|
||||||
|
@ -106,7 +136,7 @@ Here is the file template
|
||||||
|
|
||||||
## Maven deploy snapshot
|
## Maven deploy snapshot
|
||||||
|
|
||||||
The goal is to get a snapshot, such as `4.7-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.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).
|
||||||
|
|
||||||
Do this:
|
Do this:
|
||||||
|
|
||||||
|
@ -114,15 +144,15 @@ Do this:
|
||||||
$ mvn deploy -DskipTests
|
$ mvn deploy -DskipTests
|
||||||
...
|
...
|
||||||
[INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ antlr4-tool-testsuite ---
|
[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.7-SNAPSHOT/maven-metadata.xml
|
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.7-SNAPSHOT/antlr4-tool-testsuite-4.7-20161211.173752-1.jar
|
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.7-SNAPSHOT/antlr4-tool-testsuite-4.7-20161211.173752-1.jar (3 KB at 3.4 KB/sec)
|
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.7-SNAPSHOT/antlr4-tool-testsuite-4.7-20161211.173752-1.pom
|
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.7-SNAPSHOT/antlr4-tool-testsuite-4.7-20161211.173752-1.pom (3 KB at 6.5 KB/sec)
|
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
|
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)
|
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.7-SNAPSHOT/maven-metadata.xml
|
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.7-SNAPSHOT/maven-metadata.xml (774 B at 1.8 KB/sec)
|
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
|
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)
|
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/maven-metadata.xml (388 B at 0.9 KB/sec)
|
||||||
[INFO] ------------------------------------------------------------------------
|
[INFO] ------------------------------------------------------------------------
|
||||||
|
@ -192,18 +222,18 @@ It will start out by asking you the version number:
|
||||||
|
|
||||||
```
|
```
|
||||||
...
|
...
|
||||||
What is the release version for "ANTLR 4"? (org.antlr:antlr4-master) 4.7: : 4.7
|
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.7: :
|
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.7: :
|
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.7: :
|
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.7: :
|
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.7: :
|
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.7: : 4.7
|
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.7.1-SNAPSHOT:
|
What is the new development version for "ANTLR 4"? (org.antlr:antlr4-master) 4.8.1-SNAPSHOT:
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
Maven will go through your pom.xml files to update versions from 4.7-SNAPSHOT to 4.7 for release and then to 4.7.1-SNAPSHOT after release, which is done with:
|
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:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mvn release:perform -Darguments="-DskipTests"
|
mvn release:perform -Darguments="-DskipTests"
|
||||||
|
@ -217,16 +247,18 @@ 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:
|
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:
|
||||||
|
|
||||||
[http://repo1.maven.org/maven2/org/antlr/antlr4-runtime/](http://repo1.maven.org/maven2/org/antlr/antlr4-runtime/)
|
[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
|
Copy the jars to antlr.org site and update download/index.html
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cp ~/.m2/repository/org/antlr/antlr4-runtime/4.7/antlr4-runtime-4.7.jar ~/antlr/sites/website-antlr4/download/antlr-runtime-4.7.jar
|
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.7/antlr4-4.7-complete.jar ~/antlr/sites/website-antlr4/download/antlr-4.7-complete.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
|
cd ~/antlr/sites/website-antlr4/download
|
||||||
git add antlr-4.7-complete.jar
|
git add antlr-4.8-complete.jar
|
||||||
git add antlr-runtime-4.7.jar
|
git add antlr-runtime-4.8.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
Update on site:
|
Update on site:
|
||||||
|
@ -238,7 +270,7 @@ Update on site:
|
||||||
* scripts/topnav.js
|
* scripts/topnav.js
|
||||||
|
|
||||||
```
|
```
|
||||||
git commit -a -m 'add 4.7 jars'
|
git commit -a -m 'add 4.8 jars'
|
||||||
git push origin gh-pages
|
git push origin gh-pages
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -247,16 +279,14 @@ git push origin gh-pages
|
||||||
### JavaScript
|
### JavaScript
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd runtime/JavaScript/src
|
cd runtime/JavaScript
|
||||||
zip -r /tmp/antlr-javascript-runtime-4.7.zip antlr4
|
|
||||||
cp /tmp/antlr-javascript-runtime-4.7.zip ~/antlr/sites/website-antlr4/download
|
|
||||||
# git add, commit, push
|
# git add, commit, push
|
||||||
```
|
```
|
||||||
|
|
||||||
**Push to npm**
|
**Push to npm**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd runtime/JavaScript/src
|
cd runtime/JavaScript
|
||||||
npm login
|
npm login
|
||||||
npm publish antlr4
|
npm publish antlr4
|
||||||
```
|
```
|
||||||
|
@ -264,11 +294,8 @@ npm publish antlr4
|
||||||
Move target to website
|
Move target to website
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pushd ~/antlr/sites/website-antlr4/download
|
npm run build
|
||||||
git add antlr-javascript-runtime-4.7.zip
|
cp /dist/antlr4.js ~/antlr/sites/website-antlr4/download
|
||||||
git commit -a -m 'update JS runtime'
|
|
||||||
git push origin gh-pages
|
|
||||||
popd
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### CSharp
|
### CSharp
|
||||||
|
@ -309,7 +336,7 @@ Copyright (C) Microsoft Corporation. All rights reserved.
|
||||||
Restore completed in 427.62 ms for C:\Code\antlr4-fork\runtime\CSharp\runtime\CSharp\Antlr4.Runtime\Antlr4.Runtime.dotnet.csproj.
|
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\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
|
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.7.2.nupkg'.
|
Successfully created package 'C:\Code\antlr4-fork\runtime\CSharp\runtime\CSharp\Antlr4.Runtime\lib\Release\Antlr4.Runtime.Standard.4.8.2.nupkg'.
|
||||||
```
|
```
|
||||||
|
|
||||||
**Publishing to NuGet**
|
**Publishing to NuGet**
|
||||||
|
@ -371,7 +398,7 @@ There are links to the artifacts in [download.html](http://www.antlr.org/downloa
|
||||||
|
|
||||||
The C++ target is the most complex one, because it addresses multiple platforms, which require individual handling. We have 4 scenarios to cover:
|
The C++ target is the most complex one, because it addresses multiple platforms, which require individual handling. We have 4 scenarios to cover:
|
||||||
|
|
||||||
* **Windows**: static and dynamic libraries for the VC++ runtime 2013 or 2015 (corresponding to Visual Studio 2013 or 2015) + header files. All that in 32 and 64bit, debug + release.
|
* **Windows**: static and dynamic libraries for the VC++ runtime 2017 or 2019 (corresponding to Visual Studio 2017 or 2019) + header files. All that in 32 and 64bit, debug + release.
|
||||||
* **MacOS**: static and dynamic release libraries + header files.
|
* **MacOS**: static and dynamic release libraries + header files.
|
||||||
* **iOS**: no prebuilt binaries, but just a zip of the source, including the XCode project to build everything from source.
|
* **iOS**: no prebuilt binaries, but just a zip of the source, including the XCode project to build everything from source.
|
||||||
* **Linux**: no prebuilt binaries, but just a zip of the source code, including the cmake file to build everything from source there.
|
* **Linux**: no prebuilt binaries, but just a zip of the source code, including the cmake file to build everything from source there.
|
||||||
|
@ -385,7 +412,7 @@ On a Mac (with XCode 7+ installed):
|
||||||
```bash
|
```bash
|
||||||
cd runtime/Cpp
|
cd runtime/Cpp
|
||||||
./deploy-macos.sh
|
./deploy-macos.sh
|
||||||
cp antlr4-cpp-runtime-macos.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.7-macos.zip
|
cp antlr4-cpp-runtime-macos.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.8-macos.zip
|
||||||
```
|
```
|
||||||
|
|
||||||
On any Mac or Linux machine:
|
On any Mac or Linux machine:
|
||||||
|
@ -393,15 +420,15 @@ On any Mac or Linux machine:
|
||||||
```bash
|
```bash
|
||||||
cd runtime/Cpp
|
cd runtime/Cpp
|
||||||
./deploy-source.sh
|
./deploy-source.sh
|
||||||
cp antlr4-cpp-runtime-source.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.7-source.zip
|
cp antlr4-cpp-runtime-source.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.8-source.zip
|
||||||
```
|
```
|
||||||
|
|
||||||
On a Windows machine the build scripts checks if VS 2013 and/or VS 2015 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).
|
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
|
```bash
|
||||||
cd runtime/Cpp
|
cd runtime/Cpp
|
||||||
deploy-windows.cmd
|
deploy-windows.cmd Community
|
||||||
cp runtime\bin\vs-2015\x64\Release DLL\antlr4-cpp-runtime-vs2015.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.7-vs2015.zip
|
cp antlr4-cpp-runtime-vs2019.zip ~/antlr/sites/website-antlr4/download/antlr4-cpp-runtime-4.8-vs2019.zip
|
||||||
```
|
```
|
||||||
|
|
||||||
Move target to website (**_rename to a specific ANTLR version first if needed_**):
|
Move target to website (**_rename to a specific ANTLR version first if needed_**):
|
||||||
|
@ -409,14 +436,27 @@ Move target to website (**_rename to a specific ANTLR version first if needed_**
|
||||||
```bash
|
```bash
|
||||||
pushd ~/antlr/sites/website-antlr4/download
|
pushd ~/antlr/sites/website-antlr4/download
|
||||||
# vi index.html
|
# vi index.html
|
||||||
git add antlr4cpp-runtime-4.7-macos.zip
|
git add antlr4cpp-runtime-4.8-macos.zip
|
||||||
git add antlr4cpp-runtime-4.7-windows.zip
|
git add antlr4cpp-runtime-4.8-windows.zip
|
||||||
git add antlr4cpp-runtime-4.7-source.zip
|
git add antlr4cpp-runtime-4.8-source.zip
|
||||||
git commit -a -m 'update C++ runtime'
|
git commit -a -m 'update C++ runtime'
|
||||||
git push origin gh-pages
|
git push origin gh-pages
|
||||||
popd
|
popd
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Dart
|
||||||
|
|
||||||
|
Push to pub.dev
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd runtime/Dart
|
||||||
|
pub publish
|
||||||
|
```
|
||||||
|
|
||||||
|
It will warn that no change log found for the new version.
|
||||||
|
If there are changes relevant to dart in this release, edit [CHANGELOG.md](https://github.com/antlr/antlr4/blob/master/runtime/Dart/CHANGELOG.md) to describe the changes.
|
||||||
|
Otherwise enter `N` to ignore the warning.
|
||||||
|
|
||||||
## Update javadoc for runtime and tool
|
## Update javadoc for runtime and tool
|
||||||
|
|
||||||
First, gen javadoc:
|
First, gen javadoc:
|
||||||
|
@ -433,9 +473,9 @@ cd ~/antlr/sites/website-antlr4/api
|
||||||
git checkout gh-pages
|
git checkout gh-pages
|
||||||
git pull origin gh-pages
|
git pull origin gh-pages
|
||||||
cd Java
|
cd Java
|
||||||
jar xvf ~/.m2/repository/org/antlr/antlr4-runtime/4.7/antlr4-runtime-4.7-javadoc.jar
|
jar xvf ~/.m2/repository/org/antlr/antlr4-runtime/4.8/antlr4-runtime-4.8-javadoc.jar
|
||||||
cd ../JavaTool
|
cd ../JavaTool
|
||||||
jar xvf ~/.m2/repository/org/antlr/antlr4/4.7/antlr4-4.7-javadoc.jar
|
jar xvf ~/.m2/repository/org/antlr/antlr4/4.8/antlr4-4.8-javadoc.jar
|
||||||
git commit -a -m 'freshen api doc'
|
git commit -a -m 'freshen api doc'
|
||||||
git push origin gh-pages
|
git push origin gh-pages
|
||||||
```
|
```
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
//
|
||||||
|
/* 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;
|
|
@ -0,0 +1,13 @@
|
||||||
|
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())
|
|
@ -1,54 +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 CaseInsensitiveInputStream(stream, upper) {
|
|
||||||
this._stream = stream;
|
|
||||||
this._case = upper ? String.toUpperCase : String.toLowerCase;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
CaseInsensitiveInputStream.prototype.LA = function (offset) {
|
|
||||||
c = this._stream.LA(i);
|
|
||||||
if (c <= 0) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
return this._case.call(String.fromCodePoint(c))
|
|
||||||
};
|
|
||||||
|
|
||||||
CaseInsensitiveInputStream.prototype.reset = function() {
|
|
||||||
return this._stream.reset();
|
|
||||||
};
|
|
||||||
|
|
||||||
CaseInsensitiveInputStream.prototype.consume = function() {
|
|
||||||
return this._stream.consume();
|
|
||||||
};
|
|
||||||
|
|
||||||
CaseInsensitiveInputStream.prototype.LT = function(offset) {
|
|
||||||
return this._stream.LT(offset);
|
|
||||||
};
|
|
||||||
|
|
||||||
CaseInsensitiveInputStream.prototype.mark = function() {
|
|
||||||
return this._stream.mark();
|
|
||||||
};
|
|
||||||
|
|
||||||
CaseInsensitiveInputStream.prototype.release = function(marker) {
|
|
||||||
return this._stream.release(marker);
|
|
||||||
};
|
|
||||||
|
|
||||||
CaseInsensitiveInputStream.prototype.seek = function(_index) {
|
|
||||||
return this._stream.getText(start, stop);
|
|
||||||
};
|
|
||||||
|
|
||||||
CaseInsensitiveInputStream.prototype.getText = function(start, stop) {
|
|
||||||
return this._stream.getText(start, stop);
|
|
||||||
};
|
|
||||||
|
|
||||||
CaseInsensitiveInputStream.prototype.toString = function() {
|
|
||||||
return this._stream.toString();
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.CaseInsensitiveInputStream = CaseInsensitiveInputStream;
|
|
|
@ -1,13 +1,15 @@
|
||||||
package antlr
|
package antlr_resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/antlr/antlr4/runtime/Go/antlr"
|
||||||
)
|
)
|
||||||
|
|
||||||
// CaseChangingStream wraps an existing CharStream, but upper cases, or
|
// CaseChangingStream wraps an existing CharStream, but upper cases, or
|
||||||
// lower cases the input before it is tokenized.
|
// lower cases the input before it is tokenized.
|
||||||
type CaseChangingStream struct {
|
type CaseChangingStream struct {
|
||||||
CharStream
|
antlr.CharStream
|
||||||
|
|
||||||
upper bool
|
upper bool
|
||||||
}
|
}
|
||||||
|
@ -15,10 +17,8 @@ type CaseChangingStream struct {
|
||||||
// NewCaseChangingStream returns a new CaseChangingStream that forces
|
// NewCaseChangingStream returns a new CaseChangingStream that forces
|
||||||
// all tokens read from the underlying stream to be either upper case
|
// all tokens read from the underlying stream to be either upper case
|
||||||
// or lower case based on the upper argument.
|
// or lower case based on the upper argument.
|
||||||
func NewCaseChangingStream(in CharStream, upper bool) *CaseChangingStream {
|
func NewCaseChangingStream(in antlr.CharStream, upper bool) *CaseChangingStream {
|
||||||
return &CaseChangingStream{
|
return &CaseChangingStream{in, upper}
|
||||||
in, upper,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// LA gets the value of the symbol at offset from the current position
|
// LA gets the value of the symbol at offset from the current position
|
||||||
|
|
|
@ -9,12 +9,14 @@ This page lists the available and upcoming ANTLR runtimes. Please note that you
|
||||||
* [Go](go-target.md)
|
* [Go](go-target.md)
|
||||||
* [C++](cpp-target.md)
|
* [C++](cpp-target.md)
|
||||||
* [Swift](swift-target.md)
|
* [Swift](swift-target.md)
|
||||||
|
* [PHP](php-target.md)
|
||||||
|
* [Dart](dart-target.md)
|
||||||
|
|
||||||
## Target feature parity
|
## 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.
|
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|
|
|Feature|Java|C♯|Python2|Python3|JavaScript|Go|C++|Swift|PHP|Dart
|
||||||
|---|---|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|---|---|---|---|
|
||||||
|Ambiguous tree construction|4.5.1|-|-|-|-|-|-|-|
|
|Ambiguous tree construction|4.5.1|-|-|-|-|-|-|-|-|-|
|
||||||
|
|
||||||
|
|
4
pom.xml
4
pom.xml
|
@ -13,7 +13,7 @@
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-master</artifactId>
|
<artifactId>antlr4-master</artifactId>
|
||||||
<version>4.7.3-SNAPSHOT</version>
|
<version>4.8-2-SNAPSHOT</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<name>ANTLR 4</name>
|
<name>ANTLR 4</name>
|
||||||
|
@ -151,7 +151,7 @@
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.6.0</version>
|
<version>3.8.1</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>${maven.compiler.source}</source>
|
<source>${maven.compiler.source}</source>
|
||||||
<target>${maven.compiler.target}</target>
|
<target>${maven.compiler.target}</target>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-master</artifactId>
|
<artifactId>antlr4-master</artifactId>
|
||||||
<version>4.7.3-SNAPSHOT</version>
|
<version>4.8-2-SNAPSHOT</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>antlr4-runtime-test-annotations</artifactId>
|
<artifactId>antlr4-runtime-test-annotations</artifactId>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-master</artifactId>
|
<artifactId>antlr4-master</artifactId>
|
||||||
<version>4.7.3-SNAPSHOT</version>
|
<version>4.8-2-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>antlr4-runtime-testsuite</artifactId>
|
<artifactId>antlr4-runtime-testsuite</artifactId>
|
||||||
<name>ANTLR 4 Runtime Tests (2nd generation)</name>
|
<name>ANTLR 4 Runtime Tests (2nd generation)</name>
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>ST4</artifactId>
|
<artifactId>ST4</artifactId>
|
||||||
<version>4.1</version>
|
<version>4.3</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -59,18 +59,6 @@
|
||||||
<version>4.12</version>
|
<version>4.12</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.seleniumhq.selenium</groupId>
|
|
||||||
<artifactId>selenium-java</artifactId>
|
|
||||||
<version>2.46.0</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
|
||||||
<artifactId>jetty-server</artifactId>
|
|
||||||
<version>[9.3.24.v20180605,)</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.glassfish</groupId>
|
<groupId>org.glassfish</groupId>
|
||||||
<artifactId>javax.json</artifactId>
|
<artifactId>javax.json</artifactId>
|
||||||
|
@ -108,14 +96,16 @@
|
||||||
<!-- SUREFIRE-951: file.encoding cannot be set via systemPropertyVariables -->
|
<!-- SUREFIRE-951: file.encoding cannot be set via systemPropertyVariables -->
|
||||||
<argLine>-Dfile.encoding=UTF-8</argLine>
|
<argLine>-Dfile.encoding=UTF-8</argLine>
|
||||||
<includes>
|
<includes>
|
||||||
<include>**/csharp/Test*.java</include>
|
<include>**/csharp/Test*.java</include>
|
||||||
<include>**/java/Test*.java</include>
|
<include>**/java/Test*.java</include>
|
||||||
<include>**/go/Test*.java</include>
|
<include>**/go/Test*.java</include>
|
||||||
<include>**/javascript/node/Test*.java</include>
|
<include>**/javascript/Test*.java</include>
|
||||||
<include>**/python2/Test*.java</include>
|
<include>**/python2/Test*.java</include>
|
||||||
<include>**/python3/Test*.java</include>
|
<include>**/python3/Test*.java</include>
|
||||||
<include>${antlr.tests.swift}</include>
|
<include>**/php/Test*.java</include>
|
||||||
</includes>
|
<include>**/dart/Test*.java</include>
|
||||||
|
<include>${antlr.tests.swift}</include>
|
||||||
|
</includes>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.antlr</groupId>
|
<groupId>org.antlr</groupId>
|
||||||
<artifactId>antlr4-master</artifactId>
|
<artifactId>antlr4-master</artifactId>
|
||||||
<version>4.7.3-SNAPSHOT</version>
|
<version>4.8-2-SNAPSHOT</version>
|
||||||
<relativePath>../../pom.xml</relativePath>
|
<relativePath>../../pom.xml</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>antlr4-runtime-test-annotation-processors</artifactId>
|
<artifactId>antlr4-runtime-test-annotation-processors</artifactId>
|
||||||
|
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "((<t>)<v>)"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + <b>"
|
Append(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "Object <s> = <v>;"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= "System.Collections.IList __ttt__ = <v>;" // just use static type system
|
AssertIsList(v) ::= "System.Collections.IList __ttt__ = <v>;" // just use static type system
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%int <n> = <v>;%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%bool <n> = <v>;%>
|
InitBooleanMember(n,v) ::= <%bool <n> = <v>;%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "int <n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%this.<n>%>
|
GetMember(n) ::= <%this.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + this.<n>%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%this.<n> == <v>%>
|
MemberEquals(n,v) ::= <%this.<n> == <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> == <v>%>
|
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> == <v>%>
|
||||||
|
@ -94,6 +98,8 @@ bool Property() {
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
public override IToken NextToken() {
|
public override IToken NextToken() {
|
||||||
|
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "<v>"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + <b>"
|
Append(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "var <s> = <v>;"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array";}>>
|
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array";}>>
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "<n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%this.<n>%>
|
GetMember(n) ::= <%this.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + this.<n>%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
||||||
|
@ -70,7 +74,7 @@ LANotEquals(i, v) ::= <%this._input.LA(<i>)!=<v>%>
|
||||||
|
|
||||||
TokenStartColumnEquals(i) ::= <%this._tokenStartColumn===<i>%>
|
TokenStartColumnEquals(i) ::= <%this._tokenStartColumn===<i>%>
|
||||||
|
|
||||||
ImportListener(X) ::= <<var <X>Listener = require('./<X>Listener').<X>Listener;>>
|
ImportListener(X) ::= ""
|
||||||
|
|
||||||
GetExpectedTokenNames() ::= "this.getExpectedTokens().toString(this.literalNames)"
|
GetExpectedTokenNames() ::= "this.getExpectedTokens().toString(this.literalNames)"
|
||||||
|
|
||||||
|
@ -92,6 +96,8 @@ this.Property = function() {
|
||||||
}
|
}
|
||||||
>>
|
>>
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
||||||
|
|
|
@ -9,19 +9,20 @@ Assert(s) ::= ""
|
||||||
Cast(t,v) ::= "dynamic_cast\<<t> *>(<v>)" // Should actually use a more specific name. We may have to use other casts as well.
|
Cast(t,v) ::= "dynamic_cast\<<t> *>(<v>)" // Should actually use a more specific name. We may have to use other casts as well.
|
||||||
Append(a,b) ::= "<a> + <b>->toString()"
|
Append(a,b) ::= "<a> + <b>->toString()"
|
||||||
Concat(a,b) ::= "<a><b>"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
AppendStr(a,b) ::= "<a> + <b>"
|
||||||
DeclareLocal(s,v) ::= "<s> = <v>"
|
|
||||||
|
|
||||||
AssertIsList(v) ::= "assert(<v>.size() >= 0);" // Use a method that exists only on a list (vector actually).
|
AssertIsList(v) ::= "assert(<v>.size() >= 0);" // Use a method that exists only on a list (vector actually).
|
||||||
AssignLocal(s,v) ::= "<s> = <v>;"
|
AssignLocal(s,v) ::= "<s> = <v>;"
|
||||||
|
|
||||||
InitIntMember(n,v) ::= "int <n> = <v>;"
|
InitIntMember(n,v) ::= "int <n> = <v>;"
|
||||||
InitBooleanMember(n,v) ::= "bool <n> = <v>;"
|
InitBooleanMember(n,v) ::= "bool <n> = <v>;"
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
IntArg(n) ::= "int <n>"
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= "<n>"
|
GetMember(n) ::= "<n>"
|
||||||
SetMember(n,v) ::= "<n> = <v>;"
|
SetMember(n,v) ::= "<n> = <v>;"
|
||||||
AddMember(n,v) ::= "<n> += <v>;"
|
AddMember(n,v) ::= "<n> += <v>;"
|
||||||
PlusMember(v,n) ::= "<v> + <n>"
|
|
||||||
MemberEquals(n,v) ::= "<n> == <v>"
|
MemberEquals(n,v) ::= "<n> == <v>"
|
||||||
ModMemberEquals(n,m,v) ::= "<n> % <m> == <v>"
|
ModMemberEquals(n,m,v) ::= "<n> % <m> == <v>"
|
||||||
ModMemberNotEquals(n,m,v) ::= "<n> % <m> != <v>"
|
ModMemberNotEquals(n,m,v) ::= "<n> % <m> != <v>"
|
||||||
|
@ -68,6 +69,8 @@ bool Property() {
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<call>"
|
ParserPropertyCall(p, call) ::= "<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
protected:
|
protected:
|
||||||
class PositionAdjustingLexerATNSimulator : public antlr4::atn::LexerATNSimulator {
|
class PositionAdjustingLexerATNSimulator : public antlr4::atn::LexerATNSimulator {
|
||||||
|
|
|
@ -0,0 +1,318 @@
|
||||||
|
writeln(s) ::= <<print(<s>);>>
|
||||||
|
write(s) ::= <<stdout.write(<s>);>>
|
||||||
|
writeList(s) ::= <<print(<s; separator="+">);>>
|
||||||
|
|
||||||
|
False() ::= "false"
|
||||||
|
|
||||||
|
True() ::= "true"
|
||||||
|
|
||||||
|
Not(v) ::= "!<v>"
|
||||||
|
|
||||||
|
Assert(s) ::= <<assert(<s>);>>
|
||||||
|
|
||||||
|
Cast(t,v) ::= "(<v> as <t>)"
|
||||||
|
|
||||||
|
Append(a,b) ::= "<a>.toString() + <b>.toString()"
|
||||||
|
|
||||||
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
|
||||||
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
|
AssertIsList(v) ::= "assert (<v> is List);" // just use static type system
|
||||||
|
|
||||||
|
AssignLocal(s,v) ::= "<s> = <v>;"
|
||||||
|
|
||||||
|
InitIntMember(n,v) ::= <%int <n> = <v>;%>
|
||||||
|
|
||||||
|
InitBooleanMember(n,v) ::= <%bool <n> = <v>;%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "int <n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
|
GetMember(n) ::= <%this.<n>%>
|
||||||
|
|
||||||
|
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
|
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
||||||
|
|
||||||
|
MemberEquals(n,v) ::= <%this.<n> == <v>%>
|
||||||
|
|
||||||
|
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> == <v>%>
|
||||||
|
|
||||||
|
ModMemberNotEquals(n,m,v) ::= <%this.<n> % <m> != <v>%>
|
||||||
|
|
||||||
|
DumpDFA() ::= "this.dumpDFA();"
|
||||||
|
|
||||||
|
Pass() ::= ""
|
||||||
|
|
||||||
|
StringList() ::= "List\<String>"
|
||||||
|
|
||||||
|
BuildParseTrees() ::= "buildParseTree = true;"
|
||||||
|
|
||||||
|
BailErrorStrategy() ::= <%errorHandler = new BailErrorStrategy();%>
|
||||||
|
|
||||||
|
ToStringTree(s) ::= <%<s>.toStringTree(parser: this)%>
|
||||||
|
|
||||||
|
Column() ::= "this.charPositionInLine"
|
||||||
|
|
||||||
|
Text() ::= "this.text"
|
||||||
|
|
||||||
|
ValEquals(a,b) ::= <%<a>==<b>%>
|
||||||
|
|
||||||
|
TextEquals(a) ::= <%this.text == "<a>"%>
|
||||||
|
|
||||||
|
PlusText(a) ::= <%"<a>" + this.text%>
|
||||||
|
|
||||||
|
InputText() ::= "tokenStream.text"
|
||||||
|
|
||||||
|
LTEquals(i, v) ::= <%tokenStream.LT(<i>).text == <v>%>
|
||||||
|
|
||||||
|
LANotEquals(i, v) ::= <%tokenStream.LA(<i>)!=<v>%>
|
||||||
|
|
||||||
|
TokenStartColumnEquals(i) ::= <%this.tokenStartCharPositionInLine==<i>%>
|
||||||
|
|
||||||
|
ImportListener(X) ::= ""
|
||||||
|
|
||||||
|
GetExpectedTokenNames() ::= "this.expectedTokens.toString(vocabulary: this.vocabulary)"
|
||||||
|
|
||||||
|
RuleInvocationStack() ::= "ruleInvocationStack"
|
||||||
|
|
||||||
|
LL_EXACT_AMBIG_DETECTION() ::= <<interpreter.predictionMode = PredictionMode.LL_EXACT_AMBIG_DETECTION;>>
|
||||||
|
|
||||||
|
ParserToken(parser, token) ::= <%<parser>.TOKEN_<token>%>
|
||||||
|
|
||||||
|
Production(p) ::= <%<p>%>
|
||||||
|
|
||||||
|
Result(r) ::= <%<r>%>
|
||||||
|
|
||||||
|
ParserPropertyMember() ::= <<
|
||||||
|
@members {
|
||||||
|
bool Property() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= <<
|
||||||
|
class PositionAdjustingLexerATNSimulator extends LexerATNSimulator {
|
||||||
|
PositionAdjustingLexerATNSimulator(Lexer recog, ATN atn,
|
||||||
|
List\<DFA> decisionToDFA, PredictionContextCache sharedContextCache)
|
||||||
|
: super(atn, decisionToDFA, sharedContextCache, recog: recog);
|
||||||
|
|
||||||
|
void resetAcceptPosition(CharStream input, int index, int line,
|
||||||
|
int charPositionInLine) {
|
||||||
|
input.seek(index);
|
||||||
|
this.line = line;
|
||||||
|
this.charPositionInLine = charPositionInLine;
|
||||||
|
consume(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
PositionAdjustingLexer() ::= <<
|
||||||
|
@override
|
||||||
|
Token nextToken() {
|
||||||
|
if (!(super.interpreter is PositionAdjustingLexerATNSimulator)) {
|
||||||
|
interpreter = new PositionAdjustingLexerATNSimulator(
|
||||||
|
this, _ATN, _decisionToDFA, _sharedContextCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Token emit() {
|
||||||
|
switch (type) {
|
||||||
|
case TOKEN_TOKENS:
|
||||||
|
handleAcceptPositionForKeyword("tokens");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TOKEN_LABEL:
|
||||||
|
handleAcceptPositionForIdentifier();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handleAcceptPositionForIdentifier() {
|
||||||
|
String tokenText = text;
|
||||||
|
int identifierLength = 0;
|
||||||
|
while (identifierLength \< tokenText.length &&
|
||||||
|
isIdentifierChar(tokenText[identifierLength])) {
|
||||||
|
identifierLength++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputStream.index > tokenStartCharIndex + identifierLength) {
|
||||||
|
int offset = identifierLength - 1;
|
||||||
|
interpreter.resetAcceptPosition(inputStream, tokenStartCharIndex + offset,
|
||||||
|
tokenStartLine, tokenStartCharPositionInLine + offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handleAcceptPositionForKeyword(String keyword) {
|
||||||
|
if (inputStream.index > tokenStartCharIndex + keyword.length) {
|
||||||
|
int offset = keyword.length - 1;
|
||||||
|
interpreter.resetAcceptPosition(inputStream, tokenStartCharIndex + offset,
|
||||||
|
tokenStartLine, tokenStartCharPositionInLine + offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
PositionAdjustingLexerATNSimulator get interpreter {
|
||||||
|
return super.interpreter as PositionAdjustingLexerATNSimulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isIdentifierChar(String c) {
|
||||||
|
return isLetterOrDigit(c) || c == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ZERO = 48;
|
||||||
|
static const LOWER_A = 97;
|
||||||
|
static const LOWER_Z = 122;
|
||||||
|
static const UPPER_A = 65;
|
||||||
|
static const UPPER_Z = 90;
|
||||||
|
|
||||||
|
static bool isLetterOrDigit(String char) => isLetter(char) || isDigit(char);
|
||||||
|
|
||||||
|
// Note: this is intentially ASCII only
|
||||||
|
static bool isLetter(String char) {
|
||||||
|
if (char == null) return false;
|
||||||
|
var cc = char.codeUnitAt(0);
|
||||||
|
return cc >= LOWER_A && cc \<= LOWER_Z || cc >= UPPER_A && cc \<= UPPER_Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isDigit(String char) {
|
||||||
|
if (char == null) return false;
|
||||||
|
var cc = char.codeUnitAt(0);
|
||||||
|
return cc >= ZERO && cc \< ZERO + 10;
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
BasicListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener {
|
||||||
|
void visitTerminal(TerminalNode node) {
|
||||||
|
print(node.symbol.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
WalkListener(s) ::= <<
|
||||||
|
ParseTreeWalker walker = new ParseTreeWalker();
|
||||||
|
walker.walk(new LeafListener(), <s>);
|
||||||
|
>>
|
||||||
|
|
||||||
|
TreeNodeWithAltNumField(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class MyRuleNode extends ParserRuleContext {
|
||||||
|
int altNum;
|
||||||
|
|
||||||
|
MyRuleNode(ParserRuleContext parent, int invokingStateNumber)
|
||||||
|
: super(parent, invokingStateNumber);
|
||||||
|
|
||||||
|
@override int get altNumber {
|
||||||
|
return altNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override void set altNumber(int altNum) {
|
||||||
|
this.altNum = altNum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
TokenGetterListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener {
|
||||||
|
void exitA(AContext ctx) {
|
||||||
|
if (ctx.childCount==2)
|
||||||
|
stdout.write("${ctx.INT(0).symbol.text} ${ctx.INT(1).symbol.text} ${ctx.INTs()}");
|
||||||
|
else
|
||||||
|
print(ctx.ID().symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
RuleGetterListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener {
|
||||||
|
void exitA(AContext ctx) {
|
||||||
|
if (ctx.childCount==2) {
|
||||||
|
stdout.write("${ctx.b(0).start.text} ${ctx.b(1).start.text} ${ctx.bs()[0].start.text}");
|
||||||
|
} else
|
||||||
|
print(ctx.b(0).start.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
|
||||||
|
LRListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener {
|
||||||
|
void exitE(EContext ctx) {
|
||||||
|
if (ctx.childCount==3) {
|
||||||
|
stdout.write("${ctx.e(0).start.text} ${ctx.e(1).start.text} ${ctx.es()[0].start.text}\n");
|
||||||
|
} else
|
||||||
|
print(ctx.INT().symbol.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
LRWithLabelsListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener {
|
||||||
|
void exitCall(CallContext ctx) {
|
||||||
|
stdout.write("${ctx.e().start.text} ${ctx.eList()}");
|
||||||
|
}
|
||||||
|
void exitInt(IntContext ctx) {
|
||||||
|
print(ctx.INT().symbol.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
DeclareContextListGettersFunction() ::= <<
|
||||||
|
void foo() {
|
||||||
|
SContext s = null;
|
||||||
|
List\<AContext> a = s.as();
|
||||||
|
List\<BContext> b = s.bs();
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
Declare_foo() ::= <<
|
||||||
|
void foo() {print("foo");}
|
||||||
|
>>
|
||||||
|
|
||||||
|
Invoke_foo() ::= "foo();"
|
||||||
|
|
||||||
|
Declare_pred() ::= <<bool pred(bool v) {
|
||||||
|
print("eval=\$v");
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
Invoke_pred(v) ::= <<this.pred(<v>)>>
|
||||||
|
|
||||||
|
ParserTokenType(t) ::= "Parser.<t>"
|
||||||
|
ContextRuleFunction(ctx, rule) ::= "<ctx>.<rule>"
|
||||||
|
StringType() ::= "String"
|
||||||
|
ContextMember(ctx, subctx, member) ::= "<ctx>.<subctx>.<member>"
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "<v>"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + <b>"
|
Append(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "var <s> = <v>;"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array";}>>
|
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array";}>>
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "<n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%this.<n>%>
|
GetMember(n) ::= <%this.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + this.<n>%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
||||||
|
@ -98,6 +102,8 @@ this.Property = function() {
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
||||||
|
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "<v>"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + <b>"
|
Append(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "var <s> = <v>;"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array"}>>
|
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array"}>>
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "<n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%this.<n>%>
|
GetMember(n) ::= <%this.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + this.<n>%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
||||||
|
@ -72,11 +76,7 @@ LANotEquals(i, v) ::= <%this._input.LA(<i>)!=<v>%>
|
||||||
|
|
||||||
TokenStartColumnEquals(i) ::= <%this._tokenStartColumn===<i>%>
|
TokenStartColumnEquals(i) ::= <%this._tokenStartColumn===<i>%>
|
||||||
|
|
||||||
ImportListener(X) ::= <<
|
ImportListener(X) ::= ""
|
||||||
@parser::header {
|
|
||||||
var <X>Listener = require('./<X>Listener').<X>Listener;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
GetExpectedTokenNames() ::= "this.getExpectedTokens().toString(this.literalNames)"
|
GetExpectedTokenNames() ::= "this.getExpectedTokens().toString(this.literalNames)"
|
||||||
|
|
||||||
|
@ -100,6 +100,8 @@ this.Property = function() {
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
||||||
|
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "(<v>)"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + fmt.Sprint(<b>)"
|
Append(a,b) ::= "<a> + fmt.Sprint(<b>)"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
DeclareLocal(s, v) ::= "var <s> = <v>"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= ""
|
AssertIsList(v) ::= ""
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n, v) ::= <%var <n> int = <v>; var _ int = <n>; %>
|
||||||
|
|
||||||
InitBooleanMember(n, v) ::= <%var <n> bool = <v>; var _ bool = <n>; %>
|
InitBooleanMember(n, v) ::= <%var <n> bool = <v>; var _ bool = <n>; %>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "int <n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%<n>%>
|
GetMember(n) ::= <%<n>%>
|
||||||
|
|
||||||
SetMember(n, v) ::= <%<n> = <v>;%>
|
SetMember(n, v) ::= <%<n> = <v>;%>
|
||||||
|
|
||||||
AddMember(n, v) ::= <%<n> += <v>;%>
|
AddMember(n, v) ::= <%<n> += <v>;%>
|
||||||
|
|
||||||
PlusMember(v, n) ::= <%<v> + fmt.Sprint(<n>)%>
|
|
||||||
|
|
||||||
MemberEquals(n, v) ::= <%<n> == <v>%>
|
MemberEquals(n, v) ::= <%<n> == <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n, m, v) ::= <%<n> % <m> == <v>%>
|
ModMemberEquals(n, m, v) ::= <%<n> % <m> == <v>%>
|
||||||
|
@ -94,9 +98,13 @@ func (p *TParser) Property() bool {
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
func (p *PositionAdjustingLexer) NextToken() antlr.Token {
|
func (p *PositionAdjustingLexer) NextToken() antlr.Token {
|
||||||
if _, ok := p.Interpreter.(*PositionAdjustingLexerATNSimulator); !ok {
|
if _, ok := p.Interpreter.(*PositionAdjustingLexerATNSimulator); !ok {
|
||||||
|
lexerDeserializer := antlr.NewATNDeserializer(nil)
|
||||||
|
lexerAtn := lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn)
|
||||||
p.Interpreter = NewPositionAdjustingLexerATNSimulator(p, lexerAtn, p.Interpreter.DecisionToDFA(), p.Interpreter.SharedContextCache())
|
p.Interpreter = NewPositionAdjustingLexerATNSimulator(p, lexerAtn, p.Interpreter.DecisionToDFA(), p.Interpreter.SharedContextCache())
|
||||||
p.Virt = p
|
p.Virt = p
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "((<t>)<v>)"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + <b>"
|
Append(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "Object <s> = <v>;"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= "List\<?> __ttt__ = <v>;" // just use static type system
|
AssertIsList(v) ::= "List\<?> __ttt__ = <v>;" // just use static type system
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%int <n> = <v>;%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%boolean <n> = <v>;%>
|
InitBooleanMember(n,v) ::= <%boolean <n> = <v>;%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "int <n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%this.<n>%>
|
GetMember(n) ::= <%this.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + this.<n>%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%this.<n> == <v>%>
|
MemberEquals(n,v) ::= <%this.<n> == <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> == <v>%>
|
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> == <v>%>
|
||||||
|
@ -94,6 +98,8 @@ boolean Property() {
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "<v>"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + <b>"
|
Append(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "var <s> = <v>;"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array";}>>
|
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array";}>>
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "<n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%this.<n>%>
|
GetMember(n) ::= <%this.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + this.<n>%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
||||||
|
@ -70,11 +74,7 @@ LANotEquals(i, v) ::= <%this._input.LA(<i>)!=<v>%>
|
||||||
|
|
||||||
TokenStartColumnEquals(i) ::= <%this._tokenStartColumn===<i>%>
|
TokenStartColumnEquals(i) ::= <%this._tokenStartColumn===<i>%>
|
||||||
|
|
||||||
ImportListener(X) ::= <<
|
ImportListener(X) ::= ""
|
||||||
@parser::header {
|
|
||||||
var <X>Listener = require('./<X>Listener').<X>Listener;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
GetExpectedTokenNames() ::= "this.getExpectedTokens().toString(this.literalNames)"
|
GetExpectedTokenNames() ::= "this.getExpectedTokens().toString(this.literalNames)"
|
||||||
|
|
||||||
|
@ -98,6 +98,8 @@ this.Property = function() {
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
||||||
|
@ -182,18 +184,21 @@ walker.walk(new this.LeafListener(), <s>);
|
||||||
|
|
||||||
TreeNodeWithAltNumField(X) ::= <<
|
TreeNodeWithAltNumField(X) ::= <<
|
||||||
@parser::header {
|
@parser::header {
|
||||||
MyRuleNode = function(parent, invokingState) {
|
class MyRuleNode extends antlr4.ParserRuleContext {
|
||||||
antlr4.ParserRuleContext.call(this, parent, invokingState);
|
constructor(parent, invokingState) {
|
||||||
|
super(parent, invokingState);
|
||||||
|
this.altNum = 0;
|
||||||
|
}
|
||||||
|
|
||||||
this.altNum = 0;
|
getAltNumber() {
|
||||||
return this;
|
return this.altNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
setAltNumber(altNumber){
|
||||||
|
this.altNum = altNumber;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
MyRuleNode.prototype = Object.create(antlr4.ParserRuleContext.prototype);
|
|
||||||
MyRuleNode.prototype.constructor = MyRuleNode;
|
|
||||||
MyRuleNode.prototype.getAltNumber = function() { return this.altNum; }
|
|
||||||
MyRuleNode.prototype.setAltNumber = function(altNumber) { this.altNum = altNumber; }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
>>
|
>>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,272 @@
|
||||||
|
writeln(s) ::= <<echo <s> . \PHP_EOL;>>
|
||||||
|
write(s) ::= <<echo <s>;>>
|
||||||
|
writeList(s) ::= <<echo <s; separator=".">;>>
|
||||||
|
|
||||||
|
False() ::= "false"
|
||||||
|
True() ::= "true"
|
||||||
|
Not(v) ::= "!<v>"
|
||||||
|
Assert(s) ::= <<assert(<s>);>>
|
||||||
|
Cast(t,v) ::= "<v>"
|
||||||
|
Append(a,b) ::= "<a> . <b>"
|
||||||
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
|
DeclareLocal(s,v) ::= "<s> = <v>;"
|
||||||
|
|
||||||
|
AssertIsList(v) ::= "assert(\is_array(<v>));" // just use static type system
|
||||||
|
AssignLocal(s,v) ::= "<s> = <v>;"
|
||||||
|
|
||||||
|
InitIntMember(n,v) ::= <%public \$<n> = <v>;%>
|
||||||
|
InitBooleanMember(n,v) ::= <%public \$<n> = <v>;%>
|
||||||
|
InitIntVar(n,v) ::= <%\$<n> = <v>;%>
|
||||||
|
IntArg(n) ::= "int <n>"
|
||||||
|
VarRef(n) ::= "$<n>"
|
||||||
|
|
||||||
|
GetMember(n) ::= <%\$this-><n>%>
|
||||||
|
SetMember(n,v) ::= <%\$this-><n> = <v>;%>
|
||||||
|
AddMember(n,v) ::= <%\$this-><n> += <v>;%>
|
||||||
|
PlusMember(v,n) ::= <%<v> + \$this-><n>%>
|
||||||
|
MemberEquals(n,v) ::= <%\$this-><n> == <v>%>
|
||||||
|
ModMemberEquals(n,m,v) ::= <%\$this-><n> % <m> == <v>%>
|
||||||
|
ModMemberNotEquals(n,m,v) ::= <%\$this-><n> % <m> !== <v>%>
|
||||||
|
|
||||||
|
DumpDFA() ::= "\$this->dumpDFA();"
|
||||||
|
Pass() ::= ""
|
||||||
|
|
||||||
|
StringList() ::= ""
|
||||||
|
BuildParseTrees() ::= "\$this->setBuildParseTree(true);"
|
||||||
|
BailErrorStrategy() ::= <%\$this->setErrorHandler(new Antlr\\Antlr4\\Runtime\\Error\\BailErrorStrategy());%>
|
||||||
|
|
||||||
|
ToStringTree(s) ::= <%<s>->toStringTree(\$this->getRuleNames())%>
|
||||||
|
Column() ::= "\$this->getCharPositionInLine()"
|
||||||
|
Text() ::= "\$this->getText()"
|
||||||
|
ValEquals(a,b) ::= <%<a>===<b>%>
|
||||||
|
TextEquals(a) ::= <%\$this->getText() === "<a>"%>
|
||||||
|
PlusText(a) ::= <%"<a>" . \$this->getText()%>
|
||||||
|
InputText() ::= "\$this->input->getText()"
|
||||||
|
LTEquals(i, v) ::= <%\$this->input->LT(<i>)->getText() === <v>%>
|
||||||
|
LANotEquals(i, v) ::= <%\$this->input->LA(<i>) !== <v>%>
|
||||||
|
TokenStartColumnEquals(i) ::= <%\$this->tokenStartCharPositionInLine === <i>%>
|
||||||
|
|
||||||
|
ImportListener(X) ::= ""
|
||||||
|
|
||||||
|
GetExpectedTokenNames() ::= "\$this->getExpectedTokens()->toStringVocabulary(\$this->getVocabulary())"
|
||||||
|
|
||||||
|
RuleInvocationStack() ::= "'[' . \implode(', ', \$this->getRuleInvocationStack()) . ']'"
|
||||||
|
|
||||||
|
LL_EXACT_AMBIG_DETECTION() ::= <<\$this->interp->setPredictionMode(Antlr\\Antlr4\\Runtime\\Atn\\PredictionMode::LL_EXACT_AMBIG_DETECTION);>>
|
||||||
|
|
||||||
|
|
||||||
|
ParserToken(parser, token) ::= <%<parser>::<token>%>
|
||||||
|
|
||||||
|
Production(p) ::= <%<p>%>
|
||||||
|
|
||||||
|
Result(r) ::= <%<r>%>
|
||||||
|
|
||||||
|
ParserPropertyMember() ::= <<
|
||||||
|
@members {
|
||||||
|
public function Property() : bool
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
ParserPropertyCall(p, call) ::= "<p>-><call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= <<
|
||||||
|
class PositionAdjustingLexerATNSimulator extends LexerATNSimulator {
|
||||||
|
public function resetAcceptPosition(CharStream \$input, int \$index, int \$line, int \$charPositionInLine) : void {
|
||||||
|
\$input->seek(\$index);
|
||||||
|
\$this->line = \$line;
|
||||||
|
\$this->charPositionInLine = \$charPositionInLine;
|
||||||
|
\$this->consume(\$input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
PositionAdjustingLexer() ::= <<
|
||||||
|
public function nextToken() : Antlr\\Antlr4\\Runtime\\Token
|
||||||
|
{
|
||||||
|
if (!\$this->interp instanceof PositionAdjustingLexerATNSimulator) {
|
||||||
|
\$this->interp = new PositionAdjustingLexerATNSimulator(\$this, self::\$atn, self::\$decisionToDFA, self::\$sharedContextCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function emit() : Antlr\\Antlr4\\Runtime\\Token
|
||||||
|
{
|
||||||
|
switch (\$this->type) {
|
||||||
|
case self::TOKENS:
|
||||||
|
\$this->handleAcceptPositionForKeyword('tokens');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case self::LABEL:
|
||||||
|
\$this->handleAcceptPositionForIdentifier();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handleAcceptPositionForIdentifier() : bool
|
||||||
|
{
|
||||||
|
\$tokenText = \$this->getText();
|
||||||
|
\$identifierLength = 0;
|
||||||
|
while (\$identifierLength \< \strlen(\$tokenText) && self::isIdentifierChar(\$tokenText[\$identifierLength])) {
|
||||||
|
\$identifierLength++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\$this->getInputStream()->getIndex() > \$this->tokenStartCharIndex + \$identifierLength) {
|
||||||
|
\$offset = \$identifierLength - 1;
|
||||||
|
\$this->getInterpreter()->resetAcceptPosition(\$this->getInputStream(), \$this->tokenStartCharIndex + \$offset, \$this->tokenStartLine, \$this->tokenStartCharPositionInLine + \$offset);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function handleAcceptPositionForKeyword(string \$keyword) : bool
|
||||||
|
{
|
||||||
|
if (\$this->getInputStream()->getIndex() > \$this->tokenStartCharIndex + \strlen(\$keyword)) {
|
||||||
|
\$offset = \strlen(\$keyword) - 1;
|
||||||
|
\$this->getInterpreter()->resetAcceptPosition(\$this->getInputStream(), \$this->tokenStartCharIndex + \$offset, \$this->tokenStartLine, \$this->tokenStartCharPositionInLine + \$offset);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function isIdentifierChar(string \$c) : bool
|
||||||
|
{
|
||||||
|
return \ctype_alnum(\$c) || \$c === '_';
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
BasicListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener
|
||||||
|
{
|
||||||
|
public function visitTerminal(Antlr\\Antlr4\\Runtime\\Tree\\TerminalNode \$node) : void
|
||||||
|
{
|
||||||
|
echo \$node->getSymbol()->getText() . \PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
WalkListener(s) ::= <<
|
||||||
|
\$walker = new Antlr\\Antlr4\\Runtime\\Tree\\ParseTreeWalker();
|
||||||
|
\$walker->walk(new LeafListener(), <s>);
|
||||||
|
>>
|
||||||
|
|
||||||
|
TreeNodeWithAltNumField(X) ::= <<
|
||||||
|
@parser::contexts {
|
||||||
|
class MyRuleNode extends ParserRuleContext
|
||||||
|
{
|
||||||
|
public \$altNum;
|
||||||
|
|
||||||
|
public function getAltNumber() : int
|
||||||
|
{
|
||||||
|
return \$this->altNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAltNumber(int \$altNum) : void
|
||||||
|
{
|
||||||
|
\$this->altNum = \$altNum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
TokenGetterListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener {
|
||||||
|
public function exitA(Context\\AContext \$ctx) : void {
|
||||||
|
if (\$ctx->getChildCount() === 2) {
|
||||||
|
echo \sprintf('%s %s [%s]',\$ctx->INT(0)->getSymbol()->getText(), \$ctx->INT(1)->getSymbol()->getText(), \implode(', ', \$ctx->INT())) . \PHP_EOL;
|
||||||
|
} else {
|
||||||
|
echo \$ctx->ID()->getSymbol() . \PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
RuleGetterListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener {
|
||||||
|
public function exitA(Context\\AContext \$ctx) : void
|
||||||
|
{
|
||||||
|
if (\$ctx->getChildCount() === 2) {
|
||||||
|
echo \sprintf('%s %s %s', \$ctx->b(0)->start->getText(), \$ctx->b(1)->start->getText(),\$ctx->b()[0]->start->getText()) . \PHP_EOL;
|
||||||
|
} else {
|
||||||
|
echo \$ctx->b(0)->start->getText() . \PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
|
||||||
|
LRListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener {
|
||||||
|
public function exitE(Context\\EContext \$ctx) : void
|
||||||
|
{
|
||||||
|
if (\$ctx->getChildCount() === 3) {
|
||||||
|
echo \sprintf('%s %s %s', \$ctx->e(0)->start->getText(), \$ctx->e(1)->start->getText(), \$ctx->e()[0]->start->getText()) . \PHP_EOL;
|
||||||
|
} else {
|
||||||
|
echo \$ctx->INT()->getSymbol()->getText() . \PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
LRWithLabelsListener(X) ::= <<
|
||||||
|
@parser::definitions {
|
||||||
|
class LeafListener extends TBaseListener
|
||||||
|
{
|
||||||
|
public function exitCall(Context\\CallContext \$ctx) : void {
|
||||||
|
echo \sprintf('%s %s',\$ctx->e()->start->getText(),\$ctx->eList()) . \PHP_EOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exitInt(Context\\IntContext \$ctx) : void {
|
||||||
|
echo \$ctx->INT()->getSymbol()->getText() . \PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
DeclareContextListGettersFunction() ::= <<
|
||||||
|
public function foo() : void {
|
||||||
|
\$s = null;
|
||||||
|
\$a = \$s->a();
|
||||||
|
\$b = \$s->b();
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
Declare_foo() ::= <<
|
||||||
|
public function foo() : void {
|
||||||
|
echo 'foo' . \PHP_EOL;
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
Invoke_foo() ::= "\$this->foo();"
|
||||||
|
|
||||||
|
Declare_pred() ::= <<public function pred(bool \$v) : bool {
|
||||||
|
echo "eval=".(\$v ? 'true' : 'false') . \PHP_EOL;
|
||||||
|
return \$v;
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
Invoke_pred(v) ::= "\$this->pred(<v>)"
|
||||||
|
|
||||||
|
ParserTokenType(t) ::= "Parser::<t>"
|
||||||
|
ContextRuleFunction(ctx, rule) ::= "<ctx>-><rule>"
|
||||||
|
StringType() ::= ""
|
||||||
|
ContextMember(ctx, subctx, member) ::= "<ctx>-><subctx>-><member>"
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "<v>"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + str(<b>)"
|
Append(a,b) ::= "<a> + str(<b>)"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "<s> = <v>"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= "assert isinstance(v, (list, tuple))"
|
AssertIsList(v) ::= "assert isinstance(v, (list, tuple))"
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%<n> = <v>%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%<n> = <v>%>
|
InitBooleanMember(n,v) ::= <%<n> = <v>%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "<n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%self.<n>%>
|
GetMember(n) ::= <%self.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%self.<n> = <v>%>
|
SetMember(n,v) ::= <%self.<n> = <v>%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%self.<n> += <v>%>
|
AddMember(n,v) ::= <%self.<n> += <v>%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + str(self.<n>)%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%self.<n> == <v>%>
|
MemberEquals(n,v) ::= <%self.<n> == <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%self.<n> % <m> == <v>%>
|
ModMemberEquals(n,m,v) ::= <%self.<n> % <m> == <v>%>
|
||||||
|
@ -94,6 +98,8 @@ def Property(self):
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
def resetAcceptPosition(self, index, line, column):
|
def resetAcceptPosition(self, index, line, column):
|
||||||
|
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "<v>"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + str(<b>)"
|
Append(a,b) ::= "<a> + str(<b>)"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "<s> = <v>"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= "assert isinstance(v, (list, tuple))"
|
AssertIsList(v) ::= "assert isinstance(v, (list, tuple))"
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%<n> = <v>%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%<n> = <v>%>
|
InitBooleanMember(n,v) ::= <%<n> = <v>%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "<n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%self.<n>%>
|
GetMember(n) ::= <%self.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%self.<n> = <v>%>
|
SetMember(n,v) ::= <%self.<n> = <v>%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%self.<n> += <v>%>
|
AddMember(n,v) ::= <%self.<n> += <v>%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + str(self.<n>)%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%self.<n> == <v>%>
|
MemberEquals(n,v) ::= <%self.<n> == <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%self.<n> % <m> == <v>%>
|
ModMemberEquals(n,m,v) ::= <%self.<n> % <m> == <v>%>
|
||||||
|
@ -99,6 +103,8 @@ def Property(self):
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
def resetAcceptPosition(self, index, line, column):
|
def resetAcceptPosition(self, index, line, column):
|
||||||
|
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "<v>"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + <b>"
|
Append(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "var <s> = <v>;"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array";}>>
|
AssertIsList(v) ::= <<if ( !(v instanceof Array) ) {throw "value is not an array";}>>
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
InitBooleanMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "<n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%this.<n>%>
|
GetMember(n) ::= <%this.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + this.<n>%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
MemberEquals(n,v) ::= <%this.<n> === <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> === <v>%>
|
||||||
|
@ -70,11 +74,7 @@ LANotEquals(i, v) ::= <%this._input.LA(<i>)!=<v>%>
|
||||||
|
|
||||||
TokenStartColumnEquals(i) ::= <%this._tokenStartColumn===<i>%>
|
TokenStartColumnEquals(i) ::= <%this._tokenStartColumn===<i>%>
|
||||||
|
|
||||||
ImportListener(X) ::= <<
|
ImportListener(X) ::= ""
|
||||||
@parser::header {
|
|
||||||
var <X>Listener = require('./<X>Listener').<X>Listener;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
GetExpectedTokenNames() ::= "this.getExpectedTokens().toString(this.literalNames)"
|
GetExpectedTokenNames() ::= "this.getExpectedTokens().toString(this.literalNames)"
|
||||||
|
|
||||||
|
@ -98,6 +98,8 @@ this.Property = function() {
|
||||||
|
|
||||||
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
ParserPropertyCall(p, call) ::= "<p>.<call>"
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
PositionAdjustingLexer.prototype.resetAcceptPosition = function(index, line, column) {
|
||||||
|
|
|
@ -14,9 +14,9 @@ Cast(t,v) ::= "((<v> as! <t>))"
|
||||||
|
|
||||||
Append(a,b) ::= "<a> + <b>"
|
Append(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
Concat(a,b) ::= "<a><b>"
|
AppendStr(a,b) ::= <%<Append(a,b)>%>
|
||||||
|
|
||||||
DeclareLocal(s,v) ::= "var <s> = <v>"
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
AssertIsList(v) ::= "var __ttt__ = <v>;" // just use static type system
|
AssertIsList(v) ::= "var __ttt__ = <v>;" // just use static type system
|
||||||
|
|
||||||
|
@ -26,14 +26,18 @@ InitIntMember(n,v) ::= <%var <n> = <v>%>
|
||||||
|
|
||||||
InitBooleanMember(n,v) ::= <%var <n> = <v>%>
|
InitBooleanMember(n,v) ::= <%var <n> = <v>%>
|
||||||
|
|
||||||
|
InitIntVar(n,v) ::= <%<InitIntMember(n,v)>%>
|
||||||
|
|
||||||
|
IntArg(n) ::= "int <n>"
|
||||||
|
|
||||||
|
VarRef(n) ::= "<n>"
|
||||||
|
|
||||||
GetMember(n) ::= <%self.<n>%>
|
GetMember(n) ::= <%self.<n>%>
|
||||||
|
|
||||||
SetMember(n,v) ::= <%self.<n> = <v>%>
|
SetMember(n,v) ::= <%self.<n> = <v>%>
|
||||||
|
|
||||||
AddMember(n,v) ::= <%self.<n> += <v>%>
|
AddMember(n,v) ::= <%self.<n> += <v>%>
|
||||||
|
|
||||||
PlusMember(v,n) ::= <%<v> + self.<n>%>
|
|
||||||
|
|
||||||
MemberEquals(n,v) ::= <%self.<n> == <v>%>
|
MemberEquals(n,v) ::= <%self.<n> == <v>%>
|
||||||
|
|
||||||
ModMemberEquals(n,m,v) ::= <%self.<n> % <m> == <v>%>
|
ModMemberEquals(n,m,v) ::= <%self.<n> % <m> == <v>%>
|
||||||
|
@ -96,6 +100,8 @@ ParserPropertyCall(parser, property) ::= <<
|
||||||
<parser>.<property>
|
<parser>.<property>
|
||||||
>>
|
>>
|
||||||
|
|
||||||
|
PositionAdjustingLexerDef() ::= ""
|
||||||
|
|
||||||
PositionAdjustingLexer() ::= <<
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
override
|
override
|
||||||
|
@ -123,7 +129,7 @@ open func emit() -> Token {
|
||||||
private func handleAcceptPositionForIdentifier() -> Bool {
|
private func handleAcceptPositionForIdentifier() -> Bool {
|
||||||
let tokenText = getText()
|
let tokenText = getText()
|
||||||
var identifierLength = 0
|
var identifierLength = 0
|
||||||
while ((identifierLength \< tokenText.characters.count) && isIdentifierChar(tokenText[tokenText.characters.index(tokenText.startIndex, offsetBy: identifierLength)])) {
|
while ((identifierLength \< tokenText.count) && isIdentifierChar(tokenText[tokenText.index(tokenText.startIndex, offsetBy: identifierLength)])) {
|
||||||
identifierLength += 1
|
identifierLength += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,8 +143,8 @@ private func handleAcceptPositionForIdentifier() -> Bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleAcceptPositionForKeyword(_ keyword:String) -> Bool {
|
private func handleAcceptPositionForKeyword(_ keyword:String) -> Bool {
|
||||||
if getInputStream()!.index() > _tokenStartCharIndex + keyword.characters.count {
|
if getInputStream()!.index() > _tokenStartCharIndex + keyword.count {
|
||||||
let offset = keyword.characters.count - 1
|
let offset = keyword.count - 1
|
||||||
(getInterpreter() as! PositionAdjustingLexerATNSimulator).resetAcceptPosition(getInputStream()!, _tokenStartCharIndex + offset, _tokenStartLine, _tokenStartCharPositionInLine + offset)
|
(getInterpreter() as! PositionAdjustingLexerATNSimulator).resetAcceptPosition(getInputStream()!, _tokenStartCharIndex + offset, _tokenStartLine, _tokenStartCharPositionInLine + offset)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,14 +46,14 @@ import static org.junit.Assume.assumeFalse;
|
||||||
public abstract class BaseRuntimeTest {
|
public abstract class BaseRuntimeTest {
|
||||||
public final static String[] Targets = {
|
public final static String[] Targets = {
|
||||||
"Cpp",
|
"Cpp",
|
||||||
"Java",
|
|
||||||
"Go",
|
|
||||||
"CSharp",
|
"CSharp",
|
||||||
|
"Dart",
|
||||||
|
"Go",
|
||||||
|
"Java",
|
||||||
|
"Node",
|
||||||
|
"PHP",
|
||||||
"Python2", "Python3",
|
"Python2", "Python3",
|
||||||
"Node", "Safari", "Firefox", "Explorer", "Chrome"
|
"Swift"
|
||||||
};
|
|
||||||
public final static String[] JavaScriptTargets = {
|
|
||||||
"Node", "Safari", "Firefox", "Explorer", "Chrome"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -96,10 +96,17 @@ public abstract class BaseRuntimeTest {
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
// From http://junit.sourceforge.net/javadoc/org/junit/Assume.html
|
// From http://junit.sourceforge.net/javadoc/org/junit/Assume.html
|
||||||
// "The default JUnit runner treats tests with failing assumptions as ignored"
|
// "The default JUnit runner treats tests with failing assumptions as ignored"
|
||||||
assumeFalse(descriptor.ignore(descriptor.getTarget()));
|
assumeFalse(checkIgnored());
|
||||||
delegate.testSetUp();
|
delegate.testSetUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean checkIgnored() {
|
||||||
|
boolean ignored = !TestContext.isSupportedTarget(descriptor.getTarget()) || descriptor.ignore(descriptor.getTarget());
|
||||||
|
if(ignored)
|
||||||
|
System.out.println("Ignore " + descriptor);
|
||||||
|
return ignored;
|
||||||
|
}
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public final TestRule testWatcher = new TestWatcher() {
|
public final TestRule testWatcher = new TestWatcher() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,9 +120,10 @@ public abstract class BaseRuntimeTest {
|
||||||
public void testOne() throws Exception {
|
public void testOne() throws Exception {
|
||||||
// System.out.println(delegate.getTmpDir());
|
// System.out.println(delegate.getTmpDir());
|
||||||
if ( descriptor.ignore(descriptor.getTarget()) ) {
|
if ( descriptor.ignore(descriptor.getTarget()) ) {
|
||||||
System.out.printf("Ignore "+descriptor);
|
System.out.println("Ignore " + descriptor);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( descriptor.getTestType().contains("Parser") ) {
|
if ( descriptor.getTestType().contains("Parser") ) {
|
||||||
testParser(descriptor);
|
testParser(descriptor);
|
||||||
}
|
}
|
||||||
|
@ -273,6 +281,8 @@ public abstract class BaseRuntimeTest {
|
||||||
// ---- support ----
|
// ---- support ----
|
||||||
|
|
||||||
public static RuntimeTestDescriptor[] getRuntimeTestDescriptors(Class<?> clazz, String targetName) {
|
public static RuntimeTestDescriptor[] getRuntimeTestDescriptors(Class<?> clazz, String targetName) {
|
||||||
|
if(!TestContext.isSupportedTarget(targetName))
|
||||||
|
return new RuntimeTestDescriptor[0];
|
||||||
Class<?>[] nestedClasses = clazz.getClasses();
|
Class<?>[] nestedClasses = clazz.getClasses();
|
||||||
List<RuntimeTestDescriptor> descriptors = new ArrayList<RuntimeTestDescriptor>();
|
List<RuntimeTestDescriptor> descriptors = new ArrayList<RuntimeTestDescriptor>();
|
||||||
for (Class<?> nestedClass : nestedClasses) {
|
for (Class<?> nestedClass : nestedClasses) {
|
||||||
|
@ -280,8 +290,10 @@ public abstract class BaseRuntimeTest {
|
||||||
if ( RuntimeTestDescriptor.class.isAssignableFrom(nestedClass) && !Modifier.isAbstract(modifiers) ) {
|
if ( RuntimeTestDescriptor.class.isAssignableFrom(nestedClass) && !Modifier.isAbstract(modifiers) ) {
|
||||||
try {
|
try {
|
||||||
RuntimeTestDescriptor d = (RuntimeTestDescriptor) nestedClass.newInstance();
|
RuntimeTestDescriptor d = (RuntimeTestDescriptor) nestedClass.newInstance();
|
||||||
d.setTarget(targetName);
|
if(!d.ignore(targetName)) {
|
||||||
descriptors.add(d);
|
d.setTarget(targetName);
|
||||||
|
descriptors.add(d);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace(System.err);
|
e.printStackTrace(System.err);
|
||||||
}
|
}
|
||||||
|
@ -300,6 +312,16 @@ public abstract class BaseRuntimeTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String readFile(String dir, String fileName) {
|
||||||
|
try {
|
||||||
|
return String.copyValueOf(Utils.readFile(dir+"/"+fileName, "UTF-8"));
|
||||||
|
}
|
||||||
|
catch (IOException ioe) {
|
||||||
|
System.err.println("can't read file");
|
||||||
|
ioe.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected static void assertCorrectOutput(RuntimeTestDescriptor descriptor, RuntimeTestSupport delegate, String actualOutput) {
|
protected static void assertCorrectOutput(RuntimeTestDescriptor descriptor, RuntimeTestSupport delegate, String actualOutput) {
|
||||||
String actualParseErrors = delegate.getParseErrors();
|
String actualParseErrors = delegate.getParseErrors();
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package org.antlr.v4.test.runtime;
|
||||||
|
|
||||||
|
public abstract class TestContext {
|
||||||
|
|
||||||
|
public static boolean isTravisCI() {
|
||||||
|
return "true".equals(String.valueOf(System.getenv("TRAVIS")).toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAppVeyorCI() {
|
||||||
|
return "true".equals(String.valueOf(System.getenv("APPVEYOR")).toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSupportedTarget(String target) {
|
||||||
|
if(isAppVeyorCI())
|
||||||
|
return !target.matches("Swift|Node");
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.explorer;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.CompositeLexersDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.CompositeLexersDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestCompositeLexers extends BaseRuntimeTest {
|
public class TestCompositeLexers extends BaseRuntimeTest {
|
||||||
public TestCompositeLexers(RuntimeTestDescriptor descriptor) {
|
public TestCompositeLexers(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseExplorerTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(CompositeLexersDescriptors.class, "Explorer");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(CompositeLexersDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.firefox;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.CompositeParsersDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.CompositeParsersDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestCompositeParsers extends BaseRuntimeTest {
|
public class TestCompositeParsers extends BaseRuntimeTest {
|
||||||
public TestCompositeParsers(RuntimeTestDescriptor descriptor) {
|
public TestCompositeParsers(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseFirefoxTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(CompositeParsersDescriptors.class, "Firefox");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(CompositeParsersDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.explorer;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.FullContextParsingDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.FullContextParsingDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestFullContextParsing extends BaseRuntimeTest {
|
public class TestFullContextParsing extends BaseRuntimeTest {
|
||||||
public TestFullContextParsing(RuntimeTestDescriptor descriptor) {
|
public TestFullContextParsing(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseExplorerTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(FullContextParsingDescriptors.class, "Explorer");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(FullContextParsingDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.explorer;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.LeftRecursionDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.LeftRecursionDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestLeftRecursion extends BaseRuntimeTest {
|
public class TestLeftRecursion extends BaseRuntimeTest {
|
||||||
public TestLeftRecursion(RuntimeTestDescriptor descriptor) {
|
public TestLeftRecursion(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseExplorerTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(LeftRecursionDescriptors.class, "Explorer");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(LeftRecursionDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.firefox;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.LexerErrorsDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.LexerErrorsDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestLexerErrors extends BaseRuntimeTest {
|
public class TestLexerErrors extends BaseRuntimeTest {
|
||||||
public TestLexerErrors(RuntimeTestDescriptor descriptor) {
|
public TestLexerErrors(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseFirefoxTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(LexerErrorsDescriptors.class, "Firefox");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(LexerErrorsDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.firefox;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.LexerExecDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.LexerExecDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestLexerExec extends BaseRuntimeTest {
|
public class TestLexerExec extends BaseRuntimeTest {
|
||||||
public TestLexerExec(RuntimeTestDescriptor descriptor) {
|
public TestLexerExec(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseFirefoxTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(LexerExecDescriptors.class, "Firefox");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(LexerExecDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.firefox;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.ListenersDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.ListenersDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestListeners extends BaseRuntimeTest {
|
public class TestListeners extends BaseRuntimeTest {
|
||||||
public TestListeners(RuntimeTestDescriptor descriptor) {
|
public TestListeners(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseFirefoxTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(ListenersDescriptors.class, "Firefox");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(ListenersDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.firefox;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.ParseTreesDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.ParseTreesDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestParseTrees extends BaseRuntimeTest {
|
public class TestParseTrees extends BaseRuntimeTest {
|
||||||
public TestParseTrees(RuntimeTestDescriptor descriptor) {
|
public TestParseTrees(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseFirefoxTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(ParseTreesDescriptors.class, "Firefox");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(ParseTreesDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.chrome;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.ParserErrorsDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.ParserErrorsDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestParserErrors extends BaseRuntimeTest {
|
public class TestParserErrors extends BaseRuntimeTest {
|
||||||
public TestParserErrors(RuntimeTestDescriptor descriptor) {
|
public TestParserErrors(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseChromeTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(ParserErrorsDescriptors.class, "Chrome");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(ParserErrorsDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.firefox;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.ParserExecDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.ParserExecDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestParserExec extends BaseRuntimeTest {
|
public class TestParserExec extends BaseRuntimeTest {
|
||||||
public TestParserExec(RuntimeTestDescriptor descriptor) {
|
public TestParserExec(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseFirefoxTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(ParserExecDescriptors.class, "Firefox");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(ParserExecDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.firefox;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.PerformanceDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.PerformanceDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestPerformance extends BaseRuntimeTest {
|
public class TestPerformance extends BaseRuntimeTest {
|
||||||
public TestPerformance(RuntimeTestDescriptor descriptor) {
|
public TestPerformance(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseFirefoxTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(PerformanceDescriptors.class, "Firefox");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(PerformanceDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.firefox;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.SemPredEvalLexerDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.SemPredEvalLexerDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestSemPredEvalLexer extends BaseRuntimeTest {
|
public class TestSemPredEvalLexer extends BaseRuntimeTest {
|
||||||
public TestSemPredEvalLexer(RuntimeTestDescriptor descriptor) {
|
public TestSemPredEvalLexer(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseFirefoxTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(SemPredEvalLexerDescriptors.class, "Firefox");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(SemPredEvalLexerDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.explorer;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.SemPredEvalParserDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.SemPredEvalParserDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestSemPredEvalParser extends BaseRuntimeTest {
|
public class TestSemPredEvalParser extends BaseRuntimeTest {
|
||||||
public TestSemPredEvalParser(RuntimeTestDescriptor descriptor) {
|
public TestSemPredEvalParser(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseExplorerTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(SemPredEvalParserDescriptors.class, "Explorer");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(SemPredEvalParserDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,22 +4,23 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.explorer;
|
package org.antlr.v4.test.runtime.dart;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
||||||
import org.antlr.v4.test.runtime.descriptors.SetsDescriptors;
|
import org.antlr.v4.test.runtime.descriptors.SetsDescriptors;
|
||||||
|
import org.antlr.v4.test.runtime.dart.BaseDartTest;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
@RunWith(Parameterized.class)
|
@RunWith(Parameterized.class)
|
||||||
public class TestSets extends BaseRuntimeTest {
|
public class TestSets extends BaseRuntimeTest {
|
||||||
public TestSets(RuntimeTestDescriptor descriptor) {
|
public TestSets(RuntimeTestDescriptor descriptor) {
|
||||||
super(descriptor,new BaseExplorerTest());
|
super(descriptor,new BaseDartTest());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Parameterized.Parameters(name="{0}")
|
@Parameterized.Parameters(name="{0}")
|
||||||
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
|
||||||
return BaseRuntimeTest.getRuntimeTestDescriptors(SetsDescriptors.class, "Explorer");
|
return BaseRuntimeTest.getRuntimeTestDescriptors(SetsDescriptors.class, "Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -418,7 +418,7 @@ public class CompositeParsersDescriptors {
|
||||||
parser grammar S;
|
parser grammar S;
|
||||||
type_ : 'int' ;
|
type_ : 'int' ;
|
||||||
decl : type_ ID ';'
|
decl : type_ ID ';'
|
||||||
| type_ ID init_ ';' {<write("\"JavaDecl: \" + $text")>};
|
| type_ ID init_ ';' {<AppendStr("\"JavaDecl: \"","$text"):writeln()>};
|
||||||
init_ : '=' INT;
|
init_ : '=' INT;
|
||||||
*/
|
*/
|
||||||
@CommentHasStringValue
|
@CommentHasStringValue
|
||||||
|
@ -532,7 +532,7 @@ public class CompositeParsersDescriptors {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
parser grammar S;
|
parser grammar S;
|
||||||
a @after {<InitIntMember("x","0")>} : B;
|
a @after {<InitIntVar("x","0")>} : B;
|
||||||
*/
|
*/
|
||||||
@CommentHasStringValue
|
@CommentHasStringValue
|
||||||
public String slaveGrammarS;
|
public String slaveGrammarS;
|
||||||
|
|
|
@ -372,7 +372,7 @@ public class FullContextParsingDescriptors {
|
||||||
: expr_or_assign*;
|
: expr_or_assign*;
|
||||||
expr_or_assign
|
expr_or_assign
|
||||||
: expr '++' {<writeln("\"fail.\"")>}
|
: expr '++' {<writeln("\"fail.\"")>}
|
||||||
| expr {<writeln("\"pass: \"+$expr.text")>}
|
| expr {<AppendStr("\"pass: \"","$expr.text"):writeln()>}
|
||||||
;
|
;
|
||||||
expr: expr_primary ('\<-' ID)?;
|
expr: expr_primary ('\<-' ID)?;
|
||||||
expr_primary
|
expr_primary
|
||||||
|
|
|
@ -529,8 +529,8 @@ public class LeftRecursionDescriptors {
|
||||||
| e '+' e {$v = <Cast("BinaryContext","$ctx"):ContextMember({<Production("e")>(0)}, {<Result("v")>})> + <Cast("BinaryContext","$ctx"):ContextMember({<Production("e")>(1)}, {<Result("v")>})>;} # binary
|
| e '+' e {$v = <Cast("BinaryContext","$ctx"):ContextMember({<Production("e")>(0)}, {<Result("v")>})> + <Cast("BinaryContext","$ctx"):ContextMember({<Production("e")>(1)}, {<Result("v")>})>;} # binary
|
||||||
| INT {$v = $INT.int;} # anInt
|
| INT {$v = $INT.int;} # anInt
|
||||||
| '(' e ')' {$v = $e.v;} # parens
|
| '(' e ')' {$v = $e.v;} # parens
|
||||||
| left=e INC {<Cast("UnaryContext","$ctx"):Concat(".INC() != null"):Assert()>$v = $left.v + 1;} # unary
|
| left=e INC {<ContextRuleFunction(Cast("UnaryContext","$ctx"), "INC()"):Concat(" != null"):Assert()>$v = $left.v + 1;} # unary
|
||||||
| left=e DEC {<Cast("UnaryContext","$ctx"):Concat(".DEC() != null"):Assert()>$v = $left.v - 1;} # unary
|
| left=e DEC {<ContextRuleFunction(Cast("UnaryContext","$ctx"), "DEC()"):Concat(" != null"):Assert()>$v = $left.v - 1;} # unary
|
||||||
| ID {<AssignLocal("$v","3")>} # anID
|
| ID {<AssignLocal("$v","3")>} # anID
|
||||||
;
|
;
|
||||||
ID : 'a'..'z'+ ;
|
ID : 'a'..'z'+ ;
|
||||||
|
@ -636,9 +636,9 @@ public class LeftRecursionDescriptors {
|
||||||
grammar T;
|
grammar T;
|
||||||
s : e {<writeln("$e.result")>} ;
|
s : e {<writeln("$e.result")>} ;
|
||||||
e returns [<StringType()> result]
|
e returns [<StringType()> result]
|
||||||
: ID '=' e1=e {$result = "(" + $ID.text + "=" + $e1.result + ")";}
|
: ID '=' e1=e {$result = <AppendStr("\"(\"", AppendStr("$ID.text", AppendStr("\"=\"", AppendStr("$e1.result", "\")\""))))>;}
|
||||||
| ID {$result = $ID.text;}
|
| ID {$result = $ID.text;}
|
||||||
| e1=e '+' e2=e {$result = "(" + $e1.result + "+" + $e2.result + ")";}
|
| e1=e '+' e2=e {$result = <AppendStr("\"(\"", AppendStr("$e1.result", AppendStr("\"+\"", AppendStr("$e2.result", "\")\""))))>;}
|
||||||
;
|
;
|
||||||
ID : 'a'..'z'+ ;
|
ID : 'a'..'z'+ ;
|
||||||
INT : '0'..'9'+ ;
|
INT : '0'..'9'+ ;
|
||||||
|
|
|
@ -766,6 +766,10 @@ public class LexerExecDescriptors {
|
||||||
/**
|
/**
|
||||||
lexer grammar PositionAdjustingLexer;
|
lexer grammar PositionAdjustingLexer;
|
||||||
|
|
||||||
|
@definitions {
|
||||||
|
<PositionAdjustingLexerDef()>
|
||||||
|
}
|
||||||
|
|
||||||
@members {
|
@members {
|
||||||
<PositionAdjustingLexer()>
|
<PositionAdjustingLexer()>
|
||||||
}
|
}
|
||||||
|
@ -1047,10 +1051,39 @@ public class LexerExecDescriptors {
|
||||||
grammar = new String(Files.readAllBytes(Paths.get(stuff.toURI())));
|
grammar = new String(Files.readAllBytes(Paths.get(stuff.toURI())));
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
System.err.println("Cannot find grammar org/antlr/v4/test/runtime/LarseLexer.g4");
|
System.err.println("Cannot find grammar org/antlr/v4/test/runtime/LargeLexer.g4");
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Pair<>(grammarName, grammar);
|
return new Pair<>(grammarName, grammar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a regression test for antlr/antlr4#2709 "PHP target generates
|
||||||
|
* invalid output when $ is used as part of the literal in lexer rule"
|
||||||
|
* https://github.com/antlr/antlr4/issues/2709
|
||||||
|
*/
|
||||||
|
public static class EscapeTargetStringLiteral extends BaseLexerTestDescriptor {
|
||||||
|
/**
|
||||||
|
[@0,0:-1='<EOF>',<-1>,1:0]
|
||||||
|
*/
|
||||||
|
@CommentHasStringValue
|
||||||
|
public String output;
|
||||||
|
|
||||||
|
public String errors = null;
|
||||||
|
public String startRule = "";
|
||||||
|
public String grammarName = "L";
|
||||||
|
|
||||||
|
/**
|
||||||
|
lexer grammar L;
|
||||||
|
ACTION_WITH_DOLLAR: '$ACTION';
|
||||||
|
*/
|
||||||
|
@CommentHasStringValue
|
||||||
|
public String grammar;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean ignore(String targetName) {
|
||||||
|
return !targetName.equals("PHP");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class ParseTreesDescriptors {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean ignore(String targetName) {
|
public boolean ignore(String targetName) {
|
||||||
return !targetName.matches("Java|Python2|Python3|Node|Swift|CSharp");
|
return !targetName.matches("Java|Python2|Python3|Node|Swift|CSharp|Dart");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -639,7 +639,7 @@ public class ParserErrorsDescriptors {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean ignore(String targetName) {
|
public boolean ignore(String targetName) {
|
||||||
return !"Java".equals(targetName) && !"Swift".equals(targetName);
|
return !"Java".equals(targetName) && !"Swift".equals(targetName) && !"Dart".equals(targetName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -889,4 +889,32 @@ public class ParserExecDescriptors {
|
||||||
@CommentHasStringValue
|
@CommentHasStringValue
|
||||||
public String grammar;
|
public String grammar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a regression test for antlr/antlr4#2728
|
||||||
|
* It should generate correct code for grammars with more than 65 tokens.
|
||||||
|
* https://github.com/antlr/antlr4/pull/2728#issuecomment-622940562
|
||||||
|
*/
|
||||||
|
public static class TokenOffset extends BaseParserTestDescriptor {
|
||||||
|
public String input = "12 34 56 66";
|
||||||
|
public String output = "12345666\n";
|
||||||
|
|
||||||
|
public String errors = null;
|
||||||
|
public String startRule = "a";
|
||||||
|
public String grammarName = "L";
|
||||||
|
|
||||||
|
/**
|
||||||
|
grammar L;
|
||||||
|
a : ('1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'|'10'|'11'|'12'|'13'|'14'|'15'|'16'
|
||||||
|
|'17'|'18'|'19'|'20'|'21'|'22'|'23'|'24'|'25'|'26'|'27'|'28'|'29'|'30'|'31'|'32'
|
||||||
|
|'33'|'34'|'35'|'36'|'37'|'38'|'39'|'40'|'41'|'42'|'43'|'44'|'45'|'46'|'47'|'48'
|
||||||
|
|'49'|'50'|'51'|'52'|'53'|'54'|'55'|'56'|'57'|'58'|'59'|'60'|'61'|'62'|'63'|'64'
|
||||||
|
|'65'|'66')+ {
|
||||||
|
<writeln("$text")>
|
||||||
|
};
|
||||||
|
WS : (' '|'\n') -> skip;
|
||||||
|
*/
|
||||||
|
@CommentHasStringValue
|
||||||
|
public String grammar;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ public class PerformanceDescriptors {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean ignore(String targetName) {
|
public boolean ignore(String targetName) {
|
||||||
return !Arrays.asList("Java", "CSharp", "Python2", "Python3", "Node", "Cpp", "Swift").contains(targetName);
|
return !Arrays.asList("Java", "CSharp", "Python2", "Python3", "Node", "Cpp", "Swift", "Dart").contains(targetName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ public class PerformanceDescriptors {
|
||||||
@Override
|
@Override
|
||||||
public boolean ignore(String targetName) {
|
public boolean ignore(String targetName) {
|
||||||
// passes, but still too slow in Python and JavaScript
|
// passes, but still too slow in Python and JavaScript
|
||||||
return !Arrays.asList("Java", "CSharp", "Cpp", "Swift").contains(targetName);
|
return !Arrays.asList("Java", "CSharp", "Cpp", "Swift", "Dart").contains(targetName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,8 +144,8 @@ public class SemPredEvalParserDescriptors {
|
||||||
/**
|
/**
|
||||||
grammar T;
|
grammar T;
|
||||||
s : b[2] ';' | b[2] '.' ; // decision in s drills down to ctx-dependent pred in a;
|
s : b[2] ';' | b[2] '.' ; // decision in s drills down to ctx-dependent pred in a;
|
||||||
b[int i] : a[i] ;
|
b[<IntArg("i")>] : a[<VarRef("i")>] ;
|
||||||
a[int i]
|
a[<IntArg("i")>]
|
||||||
: {<ValEquals("$i","1")>}? ID {<writeln("\"alt 1\"")>}
|
: {<ValEquals("$i","1")>}? ID {<writeln("\"alt 1\"")>}
|
||||||
| {<ValEquals("$i","2")>}? ID {<writeln("\"alt 2\"")>}
|
| {<ValEquals("$i","2")>}? ID {<writeln("\"alt 2\"")>}
|
||||||
;
|
;
|
||||||
|
@ -310,7 +310,7 @@ public class SemPredEvalParserDescriptors {
|
||||||
grammar T;
|
grammar T;
|
||||||
@parser::members {<InitBooleanMember("enumKeyword",True())>}
|
@parser::members {<InitBooleanMember("enumKeyword",True())>}
|
||||||
primary
|
primary
|
||||||
: ID {<writeln("\"ID \"+$ID.text")>}
|
: ID {<AppendStr("\"ID \"", "$ID.text"):writeln()>}
|
||||||
| {<GetMember("enumKeyword"):Not()>}? 'enum' {<writeln("\"enum\"")>}
|
| {<GetMember("enumKeyword"):Not()>}? 'enum' {<writeln("\"enum\"")>}
|
||||||
;
|
;
|
||||||
ID : [a-z]+ ;
|
ID : [a-z]+ ;
|
||||||
|
|
|
@ -0,0 +1,533 @@
|
||||||
|
/*
|
||||||
|
* 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.javascript;
|
||||||
|
|
||||||
|
import org.antlr.v4.Tool;
|
||||||
|
import org.antlr.v4.automata.ATNFactory;
|
||||||
|
import org.antlr.v4.automata.ATNPrinter;
|
||||||
|
import org.antlr.v4.automata.LexerATNFactory;
|
||||||
|
import org.antlr.v4.automata.ParserATNFactory;
|
||||||
|
import org.antlr.v4.codegen.CodeGenerator;
|
||||||
|
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||||
|
import org.antlr.v4.runtime.CharStream;
|
||||||
|
import org.antlr.v4.runtime.CommonToken;
|
||||||
|
import org.antlr.v4.runtime.CommonTokenStream;
|
||||||
|
import org.antlr.v4.runtime.IntStream;
|
||||||
|
import org.antlr.v4.runtime.Lexer;
|
||||||
|
import org.antlr.v4.runtime.RuleContext;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
import org.antlr.v4.runtime.TokenSource;
|
||||||
|
import org.antlr.v4.runtime.TokenStream;
|
||||||
|
import org.antlr.v4.runtime.WritableToken;
|
||||||
|
import org.antlr.v4.runtime.atn.ATN;
|
||||||
|
import org.antlr.v4.runtime.atn.ATNDeserializer;
|
||||||
|
import org.antlr.v4.runtime.atn.ATNSerializer;
|
||||||
|
import org.antlr.v4.runtime.atn.ATNState;
|
||||||
|
import org.antlr.v4.runtime.atn.LexerATNSimulator;
|
||||||
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
|
import org.antlr.v4.runtime.misc.IntegerList;
|
||||||
|
import org.antlr.v4.runtime.misc.Interval;
|
||||||
|
import org.antlr.v4.semantics.SemanticPipeline;
|
||||||
|
import org.antlr.v4.test.runtime.ErrorQueue;
|
||||||
|
import org.antlr.v4.test.runtime.RuntimeTestSupport;
|
||||||
|
import org.antlr.v4.test.runtime.StreamVacuum;
|
||||||
|
import org.antlr.v4.test.runtime.TestContext;
|
||||||
|
import org.antlr.v4.tool.ANTLRMessage;
|
||||||
|
import org.antlr.v4.tool.DOTGenerator;
|
||||||
|
import org.antlr.v4.tool.Grammar;
|
||||||
|
import org.antlr.v4.tool.GrammarSemanticsMessage;
|
||||||
|
import org.antlr.v4.tool.LexerGrammar;
|
||||||
|
import org.antlr.v4.tool.Rule;
|
||||||
|
import org.stringtemplate.v4.ST;
|
||||||
|
import org.stringtemplate.v4.STGroup;
|
||||||
|
import org.stringtemplate.v4.STGroupString;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString;
|
||||||
|
import static org.antlr.v4.test.runtime.BaseRuntimeTest.writeFile;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class BaseNodeTest implements RuntimeTestSupport {
|
||||||
|
// -J-Dorg.antlr.v4.test.BaseTest.level=FINE
|
||||||
|
// private static final Logger LOGGER =
|
||||||
|
// Logger.getLogger(BaseTest.class.getName());
|
||||||
|
|
||||||
|
public static final String newline = System.getProperty("line.separator");
|
||||||
|
public static final String pathSep = System.getProperty("path.separator");
|
||||||
|
|
||||||
|
public String tmpdir = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If error during parser execution, store stderr here; can't return stdout
|
||||||
|
* and stderr. This doesn't trap errors from running antlr.
|
||||||
|
*/
|
||||||
|
protected String stderrDuringParse;
|
||||||
|
|
||||||
|
/** Errors found while running antlr */
|
||||||
|
protected StringBuilder antlrToolErrors;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testSetUp() throws Exception {
|
||||||
|
// new output dir for each test
|
||||||
|
String prop = System.getProperty("antlr-javascript-test-dir");
|
||||||
|
if (prop != null && prop.length() > 0) {
|
||||||
|
tmpdir = prop;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmpdir = new File(System.getProperty("java.io.tmpdir"), getClass()
|
||||||
|
.getSimpleName()+"-"+Thread.currentThread().getName()+"-"+System.currentTimeMillis())
|
||||||
|
.getAbsolutePath();
|
||||||
|
}
|
||||||
|
File dir = new File(tmpdir);
|
||||||
|
if (dir.exists())
|
||||||
|
this.eraseFiles(dir);
|
||||||
|
antlrToolErrors = new StringBuilder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void testTearDown() throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTmpDir() {
|
||||||
|
return tmpdir;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getStdout() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getParseErrors() {
|
||||||
|
return stderrDuringParse;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getANTLRToolErrors() {
|
||||||
|
if ( antlrToolErrors.length()==0 ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return antlrToolErrors.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ATN createATN(Grammar g, boolean useSerializer) {
|
||||||
|
if (g.atn == null) {
|
||||||
|
semanticProcess(g);
|
||||||
|
assertEquals(0, g.tool.getNumErrors());
|
||||||
|
|
||||||
|
ParserATNFactory f;
|
||||||
|
if (g.isLexer()) {
|
||||||
|
f = new LexerATNFactory((LexerGrammar) g);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
f = new ParserATNFactory(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
g.atn = f.createATN();
|
||||||
|
assertEquals(0, g.tool.getNumErrors());
|
||||||
|
}
|
||||||
|
|
||||||
|
ATN atn = g.atn;
|
||||||
|
if (useSerializer) {
|
||||||
|
char[] serialized = ATNSerializer.getSerializedAsChars(atn);
|
||||||
|
return new ATNDeserializer().deserialize(serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
return atn;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void semanticProcess(Grammar g) {
|
||||||
|
if (g.ast != null && !g.ast.hasErrors) {
|
||||||
|
System.out.println(g.ast.toStringTree());
|
||||||
|
Tool antlr = new Tool();
|
||||||
|
SemanticPipeline sem = new SemanticPipeline(g);
|
||||||
|
sem.process();
|
||||||
|
if (g.getImportedGrammars() != null) { // process imported grammars
|
||||||
|
// (if any)
|
||||||
|
for (Grammar imp : g.getImportedGrammars()) {
|
||||||
|
antlr.processNonCombinedGrammar(imp, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String execLexer(String grammarFileName, String grammarStr,
|
||||||
|
String lexerName, String input) {
|
||||||
|
return execLexer(grammarFileName, grammarStr, lexerName, input, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String execLexer(String grammarFileName, String grammarStr,
|
||||||
|
String lexerName, String input, boolean showDFA) {
|
||||||
|
boolean success = rawGenerateAndBuildRecognizer(grammarFileName,
|
||||||
|
grammarStr, null, lexerName, "-no-listener");
|
||||||
|
assertTrue(success);
|
||||||
|
writeFile(tmpdir, "input", input);
|
||||||
|
writeLexerTestFile(lexerName, showDFA);
|
||||||
|
writeFile(tmpdir, "package.json", "{\"type\": \"module\"}");
|
||||||
|
String output = execModule("Test.js");
|
||||||
|
if ( output!=null && output.length()==0 ) {
|
||||||
|
output = null;
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String execParser(String grammarFileName, String grammarStr,
|
||||||
|
String parserName, String lexerName, String listenerName,
|
||||||
|
String visitorName, String startRuleName, String input,
|
||||||
|
boolean showDiagnosticErrors)
|
||||||
|
{
|
||||||
|
boolean success = rawGenerateAndBuildRecognizer(grammarFileName,
|
||||||
|
grammarStr, parserName, lexerName, "-visitor");
|
||||||
|
assertTrue(success);
|
||||||
|
writeFile(tmpdir, "input", input);
|
||||||
|
rawBuildRecognizerTestFile(parserName, lexerName, listenerName,
|
||||||
|
visitorName, startRuleName, showDiagnosticErrors);
|
||||||
|
writeFile(tmpdir, "package.json", "{\"type\": \"module\"}");
|
||||||
|
return execRecognizer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return true if all is well */
|
||||||
|
protected boolean rawGenerateAndBuildRecognizer(String grammarFileName,
|
||||||
|
String grammarStr, String parserName, String lexerName,
|
||||||
|
String... extraOptions) {
|
||||||
|
return rawGenerateAndBuildRecognizer(grammarFileName, grammarStr,
|
||||||
|
parserName, lexerName, false, extraOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return true if all is well */
|
||||||
|
protected boolean rawGenerateAndBuildRecognizer(String grammarFileName,
|
||||||
|
String grammarStr, String parserName, String lexerName,
|
||||||
|
boolean defaultListener, String... extraOptions) {
|
||||||
|
ErrorQueue equeue = antlrOnString(getTmpDir(), "JavaScript", grammarFileName, grammarStr,
|
||||||
|
defaultListener, extraOptions);
|
||||||
|
if (!equeue.errors.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> files = new ArrayList<String>();
|
||||||
|
if (lexerName != null) {
|
||||||
|
files.add(lexerName + ".js");
|
||||||
|
}
|
||||||
|
if (parserName != null) {
|
||||||
|
files.add(parserName + ".js");
|
||||||
|
Set<String> optionsSet = new HashSet<String>(
|
||||||
|
Arrays.asList(extraOptions));
|
||||||
|
if (!optionsSet.contains("-no-listener")) {
|
||||||
|
files.add(grammarFileName.substring(0,
|
||||||
|
grammarFileName.lastIndexOf('.'))
|
||||||
|
+ "Listener.js");
|
||||||
|
}
|
||||||
|
if (optionsSet.contains("-visitor")) {
|
||||||
|
files.add(grammarFileName.substring(0,
|
||||||
|
grammarFileName.lastIndexOf('.'))
|
||||||
|
+ "Visitor.js");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true; // allIsWell: no compile
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void rawBuildRecognizerTestFile(String parserName,
|
||||||
|
String lexerName, String listenerName, String visitorName,
|
||||||
|
String parserStartRuleName, boolean debug) {
|
||||||
|
this.stderrDuringParse = null;
|
||||||
|
if (parserName == null) {
|
||||||
|
writeLexerTestFile(lexerName, false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
writeParserTestFile(parserName, lexerName, listenerName,
|
||||||
|
visitorName, parserStartRuleName, debug);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String execRecognizer() {
|
||||||
|
return execModule("Test.js");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String execModule(String fileName) {
|
||||||
|
try {
|
||||||
|
String npmPath = locateNpm();
|
||||||
|
if(!TestContext.isTravisCI()) {
|
||||||
|
installRuntime(npmPath);
|
||||||
|
registerRuntime(npmPath);
|
||||||
|
}
|
||||||
|
String modulePath = new File(new File(tmpdir), fileName)
|
||||||
|
.getAbsolutePath();
|
||||||
|
linkRuntime(npmPath);
|
||||||
|
String nodejsPath = locateNodeJS();
|
||||||
|
String inputPath = new File(new File(tmpdir), "input")
|
||||||
|
.getAbsolutePath();
|
||||||
|
ProcessBuilder builder = new ProcessBuilder(nodejsPath, modulePath,
|
||||||
|
inputPath);
|
||||||
|
builder.environment().put("NODE_PATH", tmpdir);
|
||||||
|
builder.directory(new File(tmpdir));
|
||||||
|
Process process = builder.start();
|
||||||
|
StreamVacuum stdoutVacuum = new StreamVacuum(
|
||||||
|
process.getInputStream());
|
||||||
|
StreamVacuum stderrVacuum = new StreamVacuum(
|
||||||
|
process.getErrorStream());
|
||||||
|
stdoutVacuum.start();
|
||||||
|
stderrVacuum.start();
|
||||||
|
// TODO switch to jdk 8
|
||||||
|
process.waitFor();
|
||||||
|
// if(!process.waitFor(1L, TimeUnit.MINUTES))
|
||||||
|
// process.destroyForcibly();
|
||||||
|
stdoutVacuum.join();
|
||||||
|
stderrVacuum.join();
|
||||||
|
String output = stdoutVacuum.toString();
|
||||||
|
if ( output.length()==0 ) {
|
||||||
|
output = null;
|
||||||
|
}
|
||||||
|
if (stderrVacuum.toString().length() > 0) {
|
||||||
|
this.stderrDuringParse = stderrVacuum.toString();
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println("can't exec recognizer");
|
||||||
|
e.printStackTrace(System.err);
|
||||||
|
System.err.println();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installRuntime(String npmPath) throws IOException, InterruptedException {
|
||||||
|
String runtimePath = locateRuntime();
|
||||||
|
ProcessBuilder builder = new ProcessBuilder(npmPath, "install");
|
||||||
|
builder.directory(new File(runtimePath));
|
||||||
|
builder.redirectError(new File(tmpdir, "error.txt"));
|
||||||
|
builder.redirectOutput(new File(tmpdir, "output.txt"));
|
||||||
|
Process process = builder.start();
|
||||||
|
// TODO switch to jdk 8
|
||||||
|
process.waitFor();
|
||||||
|
// if(!process.waitFor(30L, TimeUnit.SECONDS))
|
||||||
|
// process.destroyForcibly();
|
||||||
|
int error = process.exitValue();
|
||||||
|
if(error!=0)
|
||||||
|
throw new IOException("'npm install' failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerRuntime(String npmPath) throws IOException, InterruptedException {
|
||||||
|
String runtimePath = locateRuntime();
|
||||||
|
ProcessBuilder builder = new ProcessBuilder(npmPath, "link");
|
||||||
|
builder.directory(new File(runtimePath));
|
||||||
|
builder.redirectError(new File(tmpdir, "error.txt"));
|
||||||
|
builder.redirectOutput(new File(tmpdir, "output.txt"));
|
||||||
|
Process process = builder.start();
|
||||||
|
// TODO switch to jdk 8
|
||||||
|
process.waitFor();
|
||||||
|
// if(!process.waitFor(30L, TimeUnit.SECONDS))
|
||||||
|
// process.destroyForcibly();
|
||||||
|
int error = process.exitValue();
|
||||||
|
if(error!=0)
|
||||||
|
throw new IOException("'npm link' failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void linkRuntime(String npmPath) throws IOException, InterruptedException {
|
||||||
|
ProcessBuilder builder = new ProcessBuilder(npmPath, "link", "antlr4");
|
||||||
|
builder.directory(new File(tmpdir));
|
||||||
|
builder.redirectError(new File(tmpdir, "error.txt"));
|
||||||
|
builder.redirectOutput(new File(tmpdir, "output.txt"));
|
||||||
|
Process process = builder.start();
|
||||||
|
// TODO switch to jdk 8
|
||||||
|
process.waitFor();
|
||||||
|
// if(!process.waitFor(30L, TimeUnit.SECONDS))
|
||||||
|
// process.destroyForcibly();
|
||||||
|
int error = process.exitValue();
|
||||||
|
if(error!=0)
|
||||||
|
throw new IOException("'npm link antlr4' failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canExecute(String tool) {
|
||||||
|
try {
|
||||||
|
ProcessBuilder builder = new ProcessBuilder(tool, "--version");
|
||||||
|
builder.redirectErrorStream(true);
|
||||||
|
Process process = builder.start();
|
||||||
|
StreamVacuum vacuum = new StreamVacuum(process.getInputStream());
|
||||||
|
vacuum.start();
|
||||||
|
// TODO switch to jdk 8
|
||||||
|
process.waitFor();
|
||||||
|
// if(!process.waitFor(30L, TimeUnit.SECONDS))
|
||||||
|
// process.destroyForcibly();
|
||||||
|
vacuum.join();
|
||||||
|
return process.exitValue() == 0;
|
||||||
|
} catch (Exception e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String locateNpm() {
|
||||||
|
// typically /usr/local/bin/npm
|
||||||
|
String prop = System.getProperty("antlr-javascript-npm");
|
||||||
|
if ( prop!=null && prop.length()!=0 ) {
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
return "npm"; // everywhere
|
||||||
|
}
|
||||||
|
|
||||||
|
private String locateNodeJS() {
|
||||||
|
// typically /usr/local/bin/node
|
||||||
|
String prop = System.getProperty("antlr-javascript-nodejs");
|
||||||
|
if ( prop!=null && prop.length()!=0 ) {
|
||||||
|
return prop;
|
||||||
|
}
|
||||||
|
if (canExecute("nodejs")) {
|
||||||
|
return "nodejs"; // nodejs on Debian without node-legacy package
|
||||||
|
}
|
||||||
|
return "node"; // everywhere else
|
||||||
|
}
|
||||||
|
|
||||||
|
private String locateRuntime() {
|
||||||
|
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
|
||||||
|
final URL runtimeSrc = loader.getResource("JavaScript");
|
||||||
|
if ( runtimeSrc==null ) {
|
||||||
|
throw new RuntimeException("Cannot find JavaScript runtime");
|
||||||
|
}
|
||||||
|
if(isWindows()){
|
||||||
|
return runtimeSrc.getPath().replaceFirst("/", "");
|
||||||
|
}
|
||||||
|
return runtimeSrc.getPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWindows() {
|
||||||
|
return System.getProperty("os.name").toLowerCase().contains("windows");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void writeParserTestFile(String parserName, String lexerName,
|
||||||
|
String listenerName, String visitorName,
|
||||||
|
String parserStartRuleName, boolean debug) {
|
||||||
|
ST outputFileST = new ST(
|
||||||
|
"import antlr4 from 'antlr4';\n"
|
||||||
|
+ "import <lexerName> from './<lexerName>.js';\n"
|
||||||
|
+ "import <parserName> from './<parserName>.js';\n"
|
||||||
|
+ "import <listenerName> from './<listenerName>.js';\n"
|
||||||
|
+ "import <visitorName> from './<visitorName>.js';\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "class TreeShapeListener extends antlr4.tree.ParseTreeListener {\n" +
|
||||||
|
" enterEveryRule(ctx) {\n" +
|
||||||
|
" for (let i = 0; i \\< ctx.getChildCount; i++) {\n" +
|
||||||
|
" const child = ctx.getChild(i)\n" +
|
||||||
|
" const parent = child.parentCtx\n" +
|
||||||
|
" if (parent.getRuleContext() !== ctx || !(parent instanceof antlr4.tree.RuleNode)) {\n" +
|
||||||
|
" throw `Invalid parse tree shape detected.`\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "function main(argv) {\n"
|
||||||
|
+ " var input = new antlr4.FileStream(argv[2], true);\n"
|
||||||
|
+ " var lexer = new <lexerName>(input);\n"
|
||||||
|
+ " var stream = new antlr4.CommonTokenStream(lexer);\n"
|
||||||
|
+ "<createParser>"
|
||||||
|
+ " parser.buildParseTrees = true;\n"
|
||||||
|
+ " const printer = function() {\n"
|
||||||
|
+ " this.println = function(s) { console.log(s); }\n"
|
||||||
|
+ " this.print = function(s) { process.stdout.write(s); }\n"
|
||||||
|
+ " return this;\n"
|
||||||
|
+ " };\n"
|
||||||
|
+ " parser.printer = new printer();\n"
|
||||||
|
+ " var tree = parser.<parserStartRuleName>();\n"
|
||||||
|
+ " antlr4.tree.ParseTreeWalker.DEFAULT.walk(new TreeShapeListener(), tree);\n"
|
||||||
|
+ "}\n" + "\n" + "main(process.argv);\n" + "\n");
|
||||||
|
ST createParserST = new ST(
|
||||||
|
" var parser = new <parserName>(stream);\n");
|
||||||
|
if (debug) {
|
||||||
|
createParserST = new ST(
|
||||||
|
" var parser = new <parserName>(stream);\n"
|
||||||
|
+ " parser.addErrorListener(new antlr4.error.DiagnosticErrorListener());\n");
|
||||||
|
}
|
||||||
|
outputFileST.add("createParser", createParserST);
|
||||||
|
outputFileST.add("parserName", parserName);
|
||||||
|
outputFileST.add("lexerName", lexerName);
|
||||||
|
outputFileST.add("listenerName", listenerName);
|
||||||
|
outputFileST.add("visitorName", visitorName);
|
||||||
|
outputFileST.add("parserStartRuleName", parserStartRuleName);
|
||||||
|
writeFile(tmpdir, "Test.js", outputFileST.render());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void writeLexerTestFile(String lexerName, boolean showDFA) {
|
||||||
|
ST outputFileST = new ST(
|
||||||
|
"import antlr4 from 'antlr4';\n"
|
||||||
|
+ "import <lexerName> from './<lexerName>.js';\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "function main(argv) {\n"
|
||||||
|
+ " var input = new antlr4.FileStream(argv[2], true);\n"
|
||||||
|
+ " var lexer = new <lexerName>(input);\n"
|
||||||
|
+ " var stream = new antlr4.CommonTokenStream(lexer);\n"
|
||||||
|
+ " stream.fill();\n"
|
||||||
|
+ " for(var i=0; i\\<stream.tokens.length; i++) {\n"
|
||||||
|
+ " console.log(stream.tokens[i].toString());\n"
|
||||||
|
+ " }\n"
|
||||||
|
+ (showDFA ? " process.stdout.write(lexer._interp.decisionToDFA[antlr4.Lexer.DEFAULT_MODE].toLexerString());\n"
|
||||||
|
: "") + "}\n" + "\n" + "main(process.argv);\n"
|
||||||
|
+ "\n");
|
||||||
|
outputFileST.add("lexerName", lexerName);
|
||||||
|
writeFile(tmpdir, "Test.js", outputFileST.render());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void eraseFiles(File dir) {
|
||||||
|
String[] files = dir.list();
|
||||||
|
for (int i = 0; files != null && i < files.length; i++) {
|
||||||
|
new File(dir, files[i]).delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void eraseTempDir() {
|
||||||
|
boolean doErase = true;
|
||||||
|
String propName = "antlr-javascript-erase-test-dir";
|
||||||
|
String prop = System.getProperty(propName);
|
||||||
|
if (prop != null && prop.length() > 0)
|
||||||
|
doErase = Boolean.getBoolean(prop);
|
||||||
|
if (doErase) {
|
||||||
|
File tmpdirF = new File(tmpdir);
|
||||||
|
if (tmpdirF.exists()) {
|
||||||
|
eraseFiles(tmpdirF);
|
||||||
|
tmpdirF.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Sort a list */
|
||||||
|
public <T extends Comparable<? super T>> List<T> sort(List<T> data) {
|
||||||
|
List<T> dup = new ArrayList<T>(data);
|
||||||
|
Collections.sort(dup);
|
||||||
|
return dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return map sorted by key */
|
||||||
|
public <K extends Comparable<? super K>, V> LinkedHashMap<K, V> sort(
|
||||||
|
Map<K, V> data) {
|
||||||
|
LinkedHashMap<K, V> dup = new LinkedHashMap<K, V>();
|
||||||
|
List<K> keys = new ArrayList<K>(data.keySet());
|
||||||
|
Collections.sort(keys);
|
||||||
|
for (K k : keys) {
|
||||||
|
dup.put(k, data.get(k));
|
||||||
|
}
|
||||||
|
return dup;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
|
@ -4,7 +4,7 @@
|
||||||
* can be found in the LICENSE.txt file in the project root.
|
* can be found in the LICENSE.txt file in the project root.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.antlr.v4.test.runtime.javascript.node;
|
package org.antlr.v4.test.runtime.javascript;
|
||||||
|
|
||||||
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
import org.antlr.v4.test.runtime.BaseRuntimeTest;
|
||||||
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue