diff --git a/.editorconfig b/.editorconfig
index 53b65e9f3..daa6da0fb 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,5 +1,8 @@
root = true
+[*]
+tab_width = 4
+
[*.{java,stg}]
charset = utf-8
insert_final_newline = true
diff --git a/.travis.yml b/.travis.yml
index d27ee56b3..d9969b6eb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,30 +2,26 @@ sudo: true
language: java
+cache:
+ directories:
+ - $HOME/.m2
+ - $HOME/Library/Caches/Homebrew
+
+stages:
+ - smoke-test
+ - main-test
+ - extended-test
+
matrix:
include:
- os: linux
compiler: clang
- jdk: oraclejdk7
+ jdk: openjdk7
env:
- TARGET=cpp
- CXX=g++-5
- - GROUP=ALL
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - llvm-toolchain-precise-3.7
- packages:
- - g++-5
- - uuid-dev
- - clang-3.7
- - os: osx
- compiler: clang
- osx_image: xcode8.1
- env:
- - TARGET=cpp
- GROUP=LEXER
+ stage: main-test
addons:
apt:
sources:
@@ -35,106 +31,150 @@ matrix:
- g++-5
- uuid-dev
- clang-3.7
- - os: osx
- compiler: clang
- osx_image: xcode8.1
- env:
- - TARGET=cpp
- - GROUP=PARSER
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - llvm-toolchain-precise-3.7
- packages:
- - g++-5
- - uuid-dev
- - clang-3.7
- - os: osx
- compiler: clang
- osx_image: xcode8.1
- env:
- - TARGET=cpp
- - GROUP=RECURSION
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - llvm-toolchain-precise-3.7
- packages:
- - g++-5
- - uuid-dev
- - clang-3.7
- - os: osx
- compiler: clang
- osx_image: xcode8.1
- env:
- - TARGET=swift
- - GROUP=LEXER
- - os: osx
- compiler: clang
- osx_image: xcode8.1
- env:
- - TARGET=swift
- - GROUP=PARSER
- - os: osx
- compiler: clang
- osx_image: xcode8.1
- env:
- - TARGET=swift
- - GROUP=RECURSION
- os: linux
+ compiler: clang
+ jdk: openjdk7
+ env:
+ - TARGET=cpp
+ - CXX=g++-5
+ - GROUP=PARSER
+ stage: main-test
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ - llvm-toolchain-precise-3.7
+ packages:
+ - g++-5
+ - uuid-dev
+ - clang-3.7
+ - os: linux
+ compiler: clang
+ jdk: openjdk7
+ env:
+ - TARGET=cpp
+ - CXX=g++-5
+ - GROUP=RECURSION
+ stage: main-test
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ - llvm-toolchain-precise-3.7
+ packages:
+ - g++-5
+ - uuid-dev
+ - clang-3.7
+ - os: osx
+ compiler: clang
+ osx_image: xcode9
+ env:
+ - TARGET=cpp
+ - GROUP=LEXER
+ stage: extended-test
+ - os: osx
+ compiler: clang
+ osx_image: xcode9
+ env:
+ - TARGET=cpp
+ - GROUP=PARSER
+ stage: extended-test
+ - os: osx
+ compiler: clang
+ osx_image: xcode9
+ env:
+ - TARGET=cpp
+ - GROUP=RECURSION
+ stage: extended-test
+ - os: osx
+ compiler: clang
+ osx_image: xcode9
+ env:
+ - TARGET=swift
+ - GROUP=LEXER
+ stage: main-test
+ - os: osx
+ compiler: clang
+ osx_image: xcode9
+ env:
+ - TARGET=swift
+ - GROUP=PARSER
+ stage: main-test
+ - os: osx
+ compiler: clang
+ osx_image: xcode9
+ env:
+ - TARGET=swift
+ - GROUP=RECURSION
+ stage: main-test
+ - os: linux
+ dist: trusty
compiler: clang
env:
- TARGET=swift
- GROUP=ALL
+ stage: extended-test
- os: osx
- osx_image: xcode8.2
+ osx_image: xcode9
env:
- TARGET=dotnet
- GROUP=LEXER
+ stage: extended-test
- os: osx
- osx_image: xcode8.2
+ osx_image: xcode9
env:
- TARGET=dotnet
- GROUP=PARSER
+ stage: extended-test
- os: osx
- osx_image: xcode8.2
+ osx_image: xcode9
env:
- TARGET=dotnet
- GROUP=RECURSION
+ stage: extended-test
- os: linux
- jdk: oraclejdk7
+ jdk: openjdk7
env: TARGET=java
+ stage: extended-test
+ - os: linux
+ jdk: openjdk8
+ env: TARGET=java
+ stage: extended-test
- os: linux
jdk: oraclejdk8
env: TARGET=java
+ stage: smoke-test
- os: linux
- jdk: oraclejdk7
+ jdk: openjdk7
env: TARGET=csharp
+ stage: extended-test
- os: linux
jdk: oraclejdk8
dist: trusty
env:
- TARGET=dotnet
- GROUP=LEXER
+ stage: main-test
- os: linux
- jdk: oraclejdk8
+ jdk: openjdk8
dist: trusty
env:
- TARGET=dotnet
- GROUP=PARSER
+ stage: main-test
- os: linux
jdk: oraclejdk8
dist: trusty
env:
- TARGET=dotnet
- GROUP=RECURSION
+ stage: main-test
- os: linux
- jdk: oraclejdk7
+ jdk: openjdk7
env: TARGET=python2
+ stage: extended-test
- os: linux
- jdk: oraclejdk7
+ jdk: openjdk7
env: TARGET=python3
addons:
apt:
@@ -142,16 +182,20 @@ matrix:
- deadsnakes # source required so it finds the package definition below
packages:
- python3.5
+ stage: main-test
- os: linux
- jdk: oraclejdk7
+ dist: trusty
+ jdk: openjdk8
env: TARGET=javascript
+ stage: main-test
- os: linux
- jdk: oraclejdk7
+ dist: trusty
+ jdk: openjdk8
env: TARGET=go
+ stage: main-test
before_install:
- - ./.travis/before-install-$TRAVIS_OS_NAME-$TARGET.sh
+ - f="./.travis/before-install-$TRAVIS_OS_NAME-$TARGET.sh"; ! [ -x "$f" ] || "$f"
script:
- - cd runtime-testsuite; ../.travis/run-tests-$TARGET.sh
-
+ - cd runtime-testsuite; travis_wait 40 ../.travis/run-tests-$TARGET.sh
diff --git a/.travis/before-install-linux-swift.sh b/.travis/before-install-linux-swift.sh
index 607f04449..1a2b2a555 100755
--- a/.travis/before-install-linux-swift.sh
+++ b/.travis/before-install-linux-swift.sh
@@ -1,14 +1,12 @@
set -euo pipefail
-# make sure we use trusty repositories (travis by default uses precise)
-curl https://repogen.simplylinux.ch/txt/trusty/sources_c4aa56bd26c0f54f391d8fae3e687ef5f6e97c26.txt | sudo tee /etc/apt/sources.list
-
# install dependencies
# some packages below will be update, swift assumes newer versions
# of, for example, sqlite3 and libicu, without the update some
# tools will not work
sudo apt-get update
-sudo apt-get install clang libicu-dev libxml2 sqlite3
+sudo apt-get install clang-3.6 libxml2
+sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-3.6 100
# This would fix a know linker issue mentioned in:
# https://bugs.swift.org/browse/SR-2299
diff --git a/.travis/before-install-osx-cpp.sh b/.travis/before-install-osx-cpp.sh
deleted file mode 100755
index 48152d221..000000000
--- a/.travis/before-install-osx-cpp.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-thisdir=$(dirname "$0")
-
-brew update
-brew install cmake
-
-# Work around apparent rvm bug that is in Travis's Xcode image.
-# https://github.com/direnv/direnv/issues/210
-# https://github.com/travis-ci/travis-ci/issues/6307
-shell_session_update() { :; }
diff --git a/.travis/before-install-osx-dotnet.sh b/.travis/before-install-osx-dotnet.sh
index 428016fa6..c784ba091 100755
--- a/.travis/before-install-osx-dotnet.sh
+++ b/.travis/before-install-osx-dotnet.sh
@@ -4,9 +4,7 @@ set -euo pipefail
thisdir=$(dirname "$0")
-# pre-requisites for dotnet core
-brew update
-brew install openssl
+# OpenSSL setup for dotnet core
mkdir -p /usr/local/lib
ln -s /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib /usr/local/lib/
ln -s /usr/local/opt/openssl/lib/libssl.1.0.0.dylib /usr/local/lib/
@@ -19,9 +17,3 @@ sudo installer -pkg /tmp/dotnet-dev-osx-x64.1.0.4.pkg -target /
# make the link
ln -s /usr/local/share/dotnet/dotnet /usr/local/bin/
-
-# Work around apparent rvm bug that is in Travis's Xcode image.
-# https://github.com/direnv/direnv/issues/210
-# https://github.com/travis-ci/travis-ci/issues/6307
-shell_session_update() { :; }
-
diff --git a/.travis/before-install-osx-swift.sh b/.travis/before-install-osx-swift.sh
deleted file mode 100755
index 145a505c6..000000000
--- a/.travis/before-install-osx-swift.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-
-thisdir=$(dirname "$0")
-
-brew update
-
-# Work around apparent rvm bug that is in Travis's Xcode image.
-# https://github.com/direnv/direnv/issues/210
-# https://github.com/travis-ci/travis-ci/issues/6307
-shell_session_update() { :; }
diff --git a/.travis/run-tests-swift.sh b/.travis/run-tests-swift.sh
index 56d2cec65..8c63070aa 100755
--- a/.travis/run-tests-swift.sh
+++ b/.travis/run-tests-swift.sh
@@ -4,7 +4,7 @@
# here since environment variables doesn't pass
# across scripts
if [ $TRAVIS_OS_NAME == "linux" ]; then
- export SWIFT_VERSION=swift-3.1.1
+ export SWIFT_VERSION=swift-4.0
export SWIFT_HOME=$(pwd)/swift/$SWIFT_VERSION-RELEASE-ubuntu14.04/usr/bin/
export PATH=$SWIFT_HOME:$PATH
diff --git a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java
index dcdc0a29d..c0926fe6c 100644
--- a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java
+++ b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/Antlr4Mojo.java
@@ -395,7 +395,7 @@ public class Antlr4Mojo extends AbstractMojo {
String tokensFileName = grammarFile.getName().split("\\.")[0] + ".tokens";
File outputFile = new File(outputDirectory, tokensFileName);
if ( (! outputFile.exists()) ||
- outputFile.lastModified() < grammarFile.lastModified() ||
+ outputFile.lastModified() <= grammarFile.lastModified() ||
dependencies.isDependencyChanged(grammarFile)) {
grammarFilesToProcess.add(grammarFile);
}
@@ -412,10 +412,7 @@ public class Antlr4Mojo extends AbstractMojo {
// Iterate each grammar file we were given and add it into the tool's list of
// grammars to process.
for (File grammarFile : grammarFiles) {
- if (!buildContext.hasDelta(grammarFile)) {
- continue;
- }
-
+ buildContext.refresh(grammarFile);
buildContext.removeMessages(grammarFile);
getLog().debug("Grammar file '" + grammarFile.getPath() + "' detected.");
diff --git a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/GrammarDependencies.java b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/GrammarDependencies.java
index 2e9e2472c..d21d1ab7f 100644
--- a/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/GrammarDependencies.java
+++ b/antlr4-maven-plugin/src/main/java/org/antlr/mojo/antlr4/GrammarDependencies.java
@@ -216,14 +216,14 @@ class GrammarDependencies {
return;
for (GrammarAST importDecl : grammar.getAllChildrenWithType(ANTLRParser.IMPORT)) {
- Tree id = importDecl.getFirstChildWithType(ANTLRParser.ID);
+ for (Tree id: importDecl.getAllChildrenWithType(ANTLRParser.ID)) {
+ // missing id is not valid, but we don't want to prevent the root cause from
+ // being reported by the ANTLR tool
+ if (id != null) {
+ String grammarPath = getRelativePath(grammarFile);
- // missing id is not valid, but we don't want to prevent the root cause from
- // being reported by the ANTLR tool
- if (id != null) {
- String grammarPath = getRelativePath(grammarFile);
-
- graph.addEdge(id.getText() + ".g4", grammarPath);
+ graph.addEdge(id.getText() + ".g4", grammarPath);
+ }
}
}
diff --git a/antlr4-maven-plugin/src/test/java/org/antlr/mojo/antlr4/Antlr4MojoTest.java b/antlr4-maven-plugin/src/test/java/org/antlr/mojo/antlr4/Antlr4MojoTest.java
index d90728922..da38c582a 100644
--- a/antlr4-maven-plugin/src/test/java/org/antlr/mojo/antlr4/Antlr4MojoTest.java
+++ b/antlr4-maven-plugin/src/test/java/org/antlr/mojo/antlr4/Antlr4MojoTest.java
@@ -202,6 +202,7 @@ public class Antlr4MojoTest {
Path genHello = generatedSources.resolve("test/HelloParser.java");
Path baseGrammar = antlrDir.resolve("imports/TestBaseLexer.g4");
+ Path baseGrammar2 = antlrDir.resolve("imports/TestBaseLexer2.g4");
Path lexerGrammar = antlrDir.resolve("test/TestLexer.g4");
Path parserGrammar = antlrDir.resolve("test/TestParser.g4");
@@ -222,21 +223,20 @@ public class Antlr4MojoTest {
assertTrue(Files.exists(genHello));
assertTrue(Files.exists(genTestParser));
assertTrue(Files.exists(genTestLexer));
+ byte[] origTestLexerSum = checksum(genTestLexer);
+ byte[] origTestParserSum = checksum(genTestParser);
+ byte[] origHelloSum = checksum(genHello);
////////////////////////////////////////////////////////////////////////
// 2nd - nothing has been modified, no grammars have to be processed
////////////////////////////////////////////////////////////////////////
{
- byte[] testLexerSum = checksum(genTestLexer);
- byte[] testParserSum = checksum(genTestParser);
- byte[] helloSum = checksum(genHello);
-
maven.executeMojo(session, project, exec);
- assertTrue(Arrays.equals(testLexerSum, checksum(genTestLexer)));
- assertTrue(Arrays.equals(testParserSum, checksum(genTestParser)));
- assertTrue(Arrays.equals(helloSum, checksum(genHello)));
+ assertTrue(Arrays.equals(origTestLexerSum, checksum(genTestLexer)));
+ assertTrue(Arrays.equals(origTestParserSum, checksum(genTestParser)));
+ assertTrue(Arrays.equals(origHelloSum, checksum(genHello)));
}
////////////////////////////////////////////////////////////////////////
@@ -245,50 +245,71 @@ public class Antlr4MojoTest {
// modify the grammar to make checksum comparison detect a change
try(Change change = Change.of(baseGrammar, "DOT: '.' ;")) {
- byte[] testLexerSum = checksum(genTestLexer);
- byte[] testParserSum = checksum(genTestParser);
- byte[] helloSum = checksum(genHello);
-
maven.executeMojo(session, project, exec);
- assertFalse(Arrays.equals(testLexerSum, checksum(genTestLexer)));
- assertFalse(Arrays.equals(testParserSum, checksum(genTestParser)));
- assertTrue(Arrays.equals(helloSum, checksum(genHello)));
+ assertFalse(Arrays.equals(origTestLexerSum, checksum(genTestLexer)));
+ assertFalse(Arrays.equals(origTestParserSum, checksum(genTestParser)));
+ assertTrue(Arrays.equals(origHelloSum, checksum(genHello)));
}
+ // Restore file and confirm it was restored.
+ maven.executeMojo(session, project, exec);
+ assertTrue(Arrays.equals(origTestLexerSum, checksum(genTestLexer)));
+ assertTrue(Arrays.equals(origTestParserSum, checksum(genTestParser)));
+ assertTrue(Arrays.equals(origHelloSum, checksum(genHello)));
////////////////////////////////////////////////////////////////////////
- // 4th - the lexer grammar changed, the parser grammar has to be processed as well
+ // 4th - the second imported grammar changed, every dependency has to be processed
////////////////////////////////////////////////////////////////////////
// modify the grammar to make checksum comparison detect a change
- try(Change change = Change.of(lexerGrammar)) {
- byte[] testLexerSum = checksum(genTestLexer);
- byte[] testParserSum = checksum(genTestParser);
- byte[] helloSum = checksum(genHello);
-
+ try(Change change = Change.of(baseGrammar2, "BANG: '!' ;")) {
maven.executeMojo(session, project, exec);
- assertFalse(Arrays.equals(testLexerSum, checksum(genTestLexer)));
- assertFalse(Arrays.equals(testParserSum, checksum(genTestParser)));
- assertTrue(Arrays.equals(helloSum, checksum(genHello)));
+ assertFalse(Arrays.equals(origTestLexerSum, checksum(genTestLexer)));
+ assertFalse(Arrays.equals(origTestParserSum, checksum(genTestParser)));
+ assertTrue(Arrays.equals(origHelloSum, checksum(genHello)));
}
+ // Restore file and confirm it was restored.
+ maven.executeMojo(session, project, exec);
+ assertTrue(Arrays.equals(origTestLexerSum, checksum(genTestLexer)));
+ assertTrue(Arrays.equals(origTestParserSum, checksum(genTestParser)));
+ assertTrue(Arrays.equals(origHelloSum, checksum(genHello)));
////////////////////////////////////////////////////////////////////////
- // 5th - the parser grammar changed, no other grammars have to be processed
+ // 5th - the lexer grammar changed, the parser grammar has to be processed as well
+ ////////////////////////////////////////////////////////////////////////
+
+ // modify the grammar to make checksum comparison detect a change
+ try(Change change = Change.of(lexerGrammar, "FOO: 'foo' ;")) {
+ maven.executeMojo(session, project, exec);
+
+ assertFalse(Arrays.equals(origTestLexerSum, checksum(genTestLexer)));
+ assertFalse(Arrays.equals(origTestParserSum, checksum(genTestParser)));
+ assertTrue(Arrays.equals(origHelloSum, checksum(genHello)));
+ }
+ // Restore file and confirm it was restored.
+ maven.executeMojo(session, project, exec);
+ assertTrue(Arrays.equals(origTestLexerSum, checksum(genTestLexer)));
+ assertTrue(Arrays.equals(origTestParserSum, checksum(genTestParser)));
+ assertTrue(Arrays.equals(origHelloSum, checksum(genHello)));
+
+ ////////////////////////////////////////////////////////////////////////
+ // 6th - the parser grammar changed, no other grammars have to be processed
////////////////////////////////////////////////////////////////////////
// modify the grammar to make checksum comparison detect a change
try(Change change = Change.of(parserGrammar, " t : WS* ;")) {
- byte[] testLexerSum = checksum(genTestLexer);
- byte[] testParserSum = checksum(genTestParser);
- byte[] helloSum = checksum(genHello);
-
maven.executeMojo(session, project, exec);
- assertTrue(Arrays.equals(testLexerSum, checksum(genTestLexer)));
- assertFalse(Arrays.equals(testParserSum, checksum(genTestParser)));
- assertTrue(Arrays.equals(helloSum, checksum(genHello)));
+ assertTrue(Arrays.equals(origTestLexerSum, checksum(genTestLexer)));
+ assertFalse(Arrays.equals(origTestParserSum, checksum(genTestParser)));
+ assertTrue(Arrays.equals(origHelloSum, checksum(genHello)));
}
+ // Restore file and confirm it was restored.
+ maven.executeMojo(session, project, exec);
+ assertTrue(Arrays.equals(origTestLexerSum, checksum(genTestLexer)));
+ assertTrue(Arrays.equals(origTestParserSum, checksum(genTestParser)));
+ assertTrue(Arrays.equals(origHelloSum, checksum(genHello)));
}
@Test
diff --git a/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer.g4 b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer.g4
index 5fcc6d353..6c3164de3 100644
--- a/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer.g4
+++ b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer.g4
@@ -10,7 +10,4 @@ fragment
Whitespace : ' ' | '\n' | '\t' | '\r' ;
fragment
-Hexdigit : [a-fA-F0-9] ;
-
-fragment
-Digit : [0-9] ;
+Hexdigit : [a-fA-F0-9] ;
\ No newline at end of file
diff --git a/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer2.g4 b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer2.g4
new file mode 100644
index 000000000..18aa0c4f3
--- /dev/null
+++ b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/imports/TestBaseLexer2.g4
@@ -0,0 +1,4 @@
+lexer grammar TestBaseLexer2;
+
+fragment
+Digit : [0-9] ;
diff --git a/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestLexer.g4 b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestLexer.g4
index 668b76496..b9c07b3df 100644
--- a/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestLexer.g4
+++ b/antlr4-maven-plugin/src/test/projects/importsStandard/src/main/antlr4/test/TestLexer.g4
@@ -1,6 +1,6 @@
lexer grammar TestLexer;
-import TestBaseLexer;
+import TestBaseLexer, TestBaseLexer2;
WS : Whitespace+ -> skip;
-TEXT : ~[<&]+ ; // match any 16 bit char other than < and &
\ No newline at end of file
+TEXT : ~[<&]+ ; // match any 16 bit char other than < and &
diff --git a/appveyor.yml b/appveyor.yml
index 57184557b..61ef31a41 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,4 +1,4 @@
-version: '4.6-SNAPSHOT+AppVeyor.{build}'
+version: '4.7.1-SNAPSHOT+AppVeyor.{build}'
os: Windows Server 2012
build_script:
- mvn -DskipTests install -q --batch-mode
diff --git a/contributors.txt b/contributors.txt
index 63d6d57f5..867396142 100644
--- a/contributors.txt
+++ b/contributors.txt
@@ -150,4 +150,19 @@ YYYY/MM/DD, github id, Full name, email
2017/05/29, kosak, Corey Kosak, kosak@kosak.com
2017/06/11, erikbra, Erik A. Brandstadmoen, erik@brandstadmoen.net
2017/06/10, jm-mikkelsen, Jan Martin Mikkelsen, janm@transactionware.com
-2017/06/25, alimg, Alim Gökkaya, alim.gokkaya@gmail.com
\ No newline at end of file
+2017/06/25, alimg, Alim Gökkaya, alim.gokkaya@gmail.com
+2017/06/28, jBugman, Sergey Parshukov, codedby@bugman.me
+2017/07/09, neatnerd, Mike Arshinskiy, neatnerd@users.noreply.github.com
+2017/07/11, dhalperi, Daniel Halperin, daniel@halper.in
+2017/07/17, vaibhavaingankar09, Vaibhav Vaingankar, vbhvvaingankar9@gmail.com
+2017/07/23, venkatperi, Venkat Peri, venkatperi@gmail.com
+2017/07/27, shirou, WAKAYAMA Shirou, shirou.faw@gmail.com
+2017/07/09, neatnerd, Mike Arshinskiy, neatnerd@users.noreply.github.com
+2017/07/27, matthauck, Matt Hauck, matthauck@gmail.com
+2017/07/27, shirou, WAKAYAMA Shirou, shirou.faw@gmail.com
+2017/08/20, tiagomazzutti, Tiago Mazzutti, tiagomzt@gmail.com
+2017/08/29, Eddy Reyes, eddy@mindsight.io
+2017/09/09, brauliobz, Bráulio Bezerra, brauliobezerra@gmail.com
+2017/09/11, sachinjain024, Sachin Jain, sachinjain024@gmail.com
+2017/10/06, bramp, Andrew Brampton, brampton@gmail.com
+2017/10/15, simkimsia, Sim Kim Sia, kimcity@gmail.com
\ No newline at end of file
diff --git a/doc/getting-started.md b/doc/getting-started.md
index eaf2141fb..30acdb65a 100644
--- a/doc/getting-started.md
+++ b/doc/getting-started.md
@@ -6,7 +6,7 @@ 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.
-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.5.3-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.7-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.
@@ -16,16 +16,18 @@ If you are going to integrate ANTLR into your existing build system using mvn, a
1. Download
```
$ cd /usr/local/lib
-$ curl -O http://www.antlr.org/download/antlr-4.5.3-complete.jar
+$ curl -O http://www.antlr.org/download/antlr-4.7-complete.jar
```
Or just download in browser from website:
[http://www.antlr.org/download.html](http://www.antlr.org/download.html)
and put it somewhere rational like `/usr/local/lib`.
+
2. Add `antlr-4.5.3-complete.jar` to your `CLASSPATH`:
```
$ export CLASSPATH=".:/usr/local/lib/antlr-4.5.3-complete.jar:$CLASSPATH"
```
It's also a good idea to put this in your `.bash_profile` or whatever your startup script is.
+
3. Create aliases for the ANTLR Tool, and `TestRig`.
```
$ alias antlr4='java -Xmx500M -cp "/usr/local/lib/antlr-4.5.3-complete.jar:$CLASSPATH" org.antlr.v4.Tool'
@@ -39,11 +41,11 @@ $ alias grun='java org.antlr.v4.gui.TestRig'
0. Install Java (version 1.6 or higher)
1. Download antlr-4.5.3-complete.jar (or whatever version) from [http://www.antlr.org/download/](http://www.antlr.org/download/)
Save to your directory for 3rd party Java libraries, say `C:\Javalib`
-2. Add `antlr-4.5-complete.jar` to CLASSPATH, either:
+2. Add `antlr-4.5.3-complete.jar` to CLASSPATH, either:
* Permanently: Using System Properties dialog > Environment variables > Create or append to `CLASSPATH` variable
* Temporarily, at command line:
```
-SET CLASSPATH=.;C:\Javalib\antlr-4.5.3-complete.jar;%CLASSPATH%
+SET CLASSPATH=.;C:\Javalib\antlr-4.7-complete.jar;%CLASSPATH%
```
3. Create short convenient commands for the ANTLR Tool, and TestRig, using batch files or doskey commands:
* Batch files (in directory in system PATH) antlr4.bat and grun.bat
@@ -65,7 +67,7 @@ Either launch org.antlr.v4.Tool directly:
```
$ java org.antlr.v4.Tool
-ANTLR Parser Generator Version 4.5.3
+ANTLR Parser Generator Version 4.7
-o ___ specify output directory where all output is generated
-lib ___ specify location of .tokens files
...
@@ -74,8 +76,8 @@ ANTLR Parser Generator Version 4.5.3
or use -jar option on java:
```
-$ java -jar /usr/local/lib/antlr-4.5.3-complete.jar
-ANTLR Parser Generator Version 4.5.3
+$ java -jar /usr/local/lib/antlr-4.7-complete.jar
+ANTLR Parser Generator Version 4.7
-o ___ specify output directory where all output is generated
-lib ___ specify location of .tokens files
...
diff --git a/doc/images/gen_spm_module.png b/doc/images/gen_spm_module.png
new file mode 100644
index 000000000..0798c37b6
Binary files /dev/null and b/doc/images/gen_spm_module.png differ
diff --git a/doc/swift-target.md b/doc/swift-target.md
index 69eb88e4d..4f4e6e7c1 100644
--- a/doc/swift-target.md
+++ b/doc/swift-target.md
@@ -1,9 +1,15 @@
# ANTLR4 Language Target, Runtime for Swift
+## Performance Note
+
+To use ANTLR4 Swift target in production environment, make sure to turn on compiler optimizations by following [these instructions](https://github.com/apple/swift-package-manager/blob/master/Documentation/Usage.md#build-configurations) if you use SwiftPM to build your project. If you are using Xcode to build your project, it's unlikely you will not use `release` build for production build.
+
+Conclusion is, you need to turn on `release` mode (which will have all the optimization pre configured for you) so the ANTLR4 Swift target can have reasonable parsing speed.
+
## Install ANTLR4
Make sure you have the ANTLR
-installed.[The getting started guide](getting-started.md) should get
+installed. [The getting started guide](getting-started.md) should get
you started.
## Create a Swift lexer or parser
@@ -18,82 +24,120 @@ For a full list of antlr4 tool options, please visit the
## Build your Swift project with ANTLR runtime
-The following instructions are assuming Xcode as the IDE:
+### Note
-* __Add parser/lexer to project__. Make sure the parsers/lexers
+We use __boot.py__ script located at the root of the Swift runtime folder
+`antlr4/runtime/Swift` to provide additional support for both Xcode-based
+projects and SPM-based projects. Below sections are organized for both of
+the flavors. If you want to quickly get started, try:
+
+```
+python boot.py --help
+```
+
+for information about this script.
+
+### Xcode Projects
+
+Note that even if you are otherwise using ANTLR from a binary distribution,
+you should compile the ANTLR Swift runtime from source, because the Swift
+language does not yet have a stable ABI.
+
+ANTLR uses Swift Package Manager to generate Xcode project files. Note that
+Swift Package Manager does not currently support iOS, watchOS, or tvOS, so
+if you wish to use those platforms, you will need to alter the project build
+settings manually as appropriate.
+
+#### Download source code for ANTLR
+
+```
+git clone https://github.com/antlr/antlr4
+```
+
+#### Generate Xcode project for ANTLR runtime
+
+The `boot.py` script includes a wrapper around `swift package
+generate-xcodeproj`. Use this to generate `Antlr4.xcodeproj` for the ANTLR
+Swift runtime. (using _swift package generate-xcodeproj_ is not recommended)
+since the project is dependent on some parser files generated by _boot.py_.
+
+```
+cd antlr4/runtime/Swift
+python boot.py --gen-xcodeproj
+```
+
+#### Import ANTLR Swift runtime into your project
+
+Open your own project in Xcode.
+
+Open Finder in the `runtime/Swift` directory:
+
+```
+# From antlr4/runtime/Swift
+open .
+```
+
+Drag `Antlr4.xcodeproj` into your project.
+
+After this is done, your Xcode project navigator will be something like the
+screenshot below. In this example, your own project is "Smalltalk", and you
+will be able to see `Antlr4.xcodeproj` shown as a contained project.
+
+
+
+#### Edit the build settings if necessary
+
+Swift Package Manager currently does not support iOS, watchOS, or tvOS. If
+you wish to build for those platforms, you will need to alter the project
+build settings manually.
+
+#### Add generated parser and lexer to project
+
+Make sure the parsers/lexers
generated in __step 2__ are added to the project. To do this, you can
drag the generated files from Finder to the Xcode IDE. Remember to
check __Copy items if needed__ to make sure the files are actually
moved into the project folder instead of symbolic links (see the
screenshot below). After moving you will be able to see your files in
-the project navigator. But when you open one of the files, you will
-see Xcode complaining the module "Antlr4" could not be found at the
-import statement. This is expected, since we still need the ANTLR
-Swift runtime for those missing symbols.
+the project navigator. Make sure that the Target Membership settings
+are correct for your project.
-* __Download ANTLR runtime__. Due to unstable ABI of Swift language,
-there will not be a single "library" for the Swift ANTLR runtime for
-now. To get Swift ANTLR runtime, clone the ANTLR repository. Open it
-in finder. From the root directory of the repo, go to runtime/Swift
-folder. You will see the Xcode project manifest file:
-__Antlr4.xcodeproj__.
+#### Add the ANTLR Swift runtime as a dependency
-* __Import ANTLR Swift runtime into project__. Drag Antlr4.xcodeproj
-into your project, after this is done, your Xcode project navigator
-will be something like the screenshot below. In this case, your own
-project is "Smalltalk", and you will be able to see the
-Antlr4.xcodeproj shown as a contained project. The error message will
-still be there, that's because we still need to tell Xcode how to find
-the runtime.
-
-
-
-* __Build ANTLR runtime__. By expanding the "Products" folder in the
-inner project (Antlr4.xcodeproj), you will see two Antlr4.framework
-files. ".framework" file is the swift version of ".jar", ".a" as in
-JAVA, C/C++ Initially those two files should be red, that's because
-they are not built. To build, click the "target selection" button
-right next to your Xcode run button. And in the drop down select the
-target you want to build. And you will see the two Antlr4.framework
-files are for iOS and OSX, as shown below. After target selection,
-press "CMD+B", and Xcode will build the framework for you. Then you
-will see one of the frameworks become black.
-
-
-
-* __Add dependencies__. Simply adding ANTLR Swift runtime and build
-the artifact is not enough. You still need to specify
-dependencies. Click your own project (Smalltalk), and you will see
-project setting page. Go to "Build Phase", and inside it make sure
-your ANTLR Swift runtime framework is added to both "__Target
-Dependencies__" and "__Link Binary With Libraries__" sections, as
-shown below. After correctly added dependencies, the error message for
-importing library will be gone.
+Select your own project in Xcode and go to the Build Phases settings panel.
+Add the ANTLR runtime under __Target Dependencies__ and __Link Binary With
+Libraries__.
-## Example playground
+#### Build your project
-The Swift runtime includes an Xcode playground to get started with.
+The runtime and generated grammar should now build correctly.
-First go to the ANTLR4 repository, and open
-`runtime/Swift/Antlr4.xcworkspace` in Xcode. Select "Antlr4 OSX > My
-Mac" as the build target, and build the project as normal. The
-playground should then be active.
+### Swift Package Manager Projects
-The playground includes a simple grammar called "Hello", and an
-example for walking the parse tree. You should see in the playground
-output that it is printing messages for each node in the parse tree as
-it walks.
+Since we cannot have a separate repository for Swift target (see issue [#1774](https://github.com/antlr/antlr4/issues/1774)),
+and Swift is currently not ABI stable. We currently support support SPM-based
+projects by creating temporary local repository.
-The grammar is defined in the playground's `Resources/Hello.g4`. The
-parser was generated from the grammar using ANTLR like this:
+For people using [Swift Package Manager](https://swift.org/package-manager/),
+the __boot.py__ script supports generating local repository that can be used
+as a dependency to your project. Simply run:
-```
-antlr4 -Dlanguage=Swift -visitor -o ../Sources/Autogen Hello.g4
+```
+python boot.py --gen-spm-module
```
-The example tree walker is in Sources/HelloWalker.swift.
-
+The prompt will show something like below:
+
+
+
+Put the SPM directive that contains the url to temporary repository to your
+project's Package.swift. And run `swift build` in your project.
+
+The project is generated in your system's `/tmp/` directory, if you find it
+inconvenient, consider copy that generated ANTLR repository to some place
+that won't be cleaned automatically and update `url` parameter in your
+`Package.swift` file.
diff --git a/runtime-testsuite/test/org/antlr/v4/runtime/TestCodePointCharStream.java b/runtime-testsuite/test/org/antlr/v4/runtime/TestCodePointCharStream.java
index 25c4c0919..c40c4048c 100644
--- a/runtime-testsuite/test/org/antlr/v4/runtime/TestCodePointCharStream.java
+++ b/runtime-testsuite/test/org/antlr/v4/runtime/TestCodePointCharStream.java
@@ -23,6 +23,7 @@ public class TestCodePointCharStream {
CodePointCharStream s = CharStreams.fromString("");
assertEquals(0, s.size());
assertEquals(0, s.index());
+ assertEquals("", s.toString());
}
@Test
diff --git a/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserErrorsDescriptors.java b/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserErrorsDescriptors.java
index 0b53e994e..26352d317 100644
--- a/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserErrorsDescriptors.java
+++ b/runtime-testsuite/test/org/antlr/v4/test/runtime/descriptors/ParserErrorsDescriptors.java
@@ -618,4 +618,28 @@ public class ParserErrorsDescriptors {
public String grammar;
}
+
+ public static class ExtraneousInput extends BaseParserTestDescriptor {
+ public String input = "baa";
+ public String output = null;
+ public String errors = "line 1:0 mismatched input 'b' expecting {
This action is implemented by calling {@link Lexer//pushMode} with the // value provided by {@link //getMode}.
func (l *LexerPushModeAction) execute(lexer Lexer) { - lexer.pushMode(l.mode) + lexer.PushMode(l.mode) } func (l *LexerPushModeAction) hash() int { @@ -190,7 +190,7 @@ var LexerPopModeActionINSTANCE = NewLexerPopModeAction() //This action is implemented by calling {@link Lexer//popMode}.
func (l *LexerPopModeAction) execute(lexer Lexer) { - lexer.popMode() + lexer.PopMode() } func (l *LexerPopModeAction) String() string { @@ -242,7 +242,7 @@ func NewLexerModeAction(mode int) *LexerModeAction { //This action is implemented by calling {@link Lexer//mode} with the // value provided by {@link //getMode}.
func (l *LexerModeAction) execute(lexer Lexer) { - lexer.setMode(l.mode) + lexer.SetMode(l.mode) } func (l *LexerModeAction) hash() int { @@ -341,7 +341,7 @@ func NewLexerChannelAction(channel int) *LexerChannelAction { //This action is implemented by calling {@link Lexer//setChannel} with the // value provided by {@link //getChannel}.
func (l *LexerChannelAction) execute(lexer Lexer) { - lexer.setChannel(l.channel) + lexer.SetChannel(l.channel) } func (l *LexerChannelAction) hash() int { diff --git a/runtime/Go/antlr/testing_assert_test.go b/runtime/Go/antlr/testing_assert_test.go new file mode 100644 index 000000000..f3ca0d341 --- /dev/null +++ b/runtime/Go/antlr/testing_assert_test.go @@ -0,0 +1,98 @@ +// 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. + +// These assert functions are borrowed from https://github.com/stretchr/testify/ (MIT License) + +package antlr + +import ( + "fmt" + "reflect" + "testing" +) + +type assert struct { + t *testing.T +} + +func assertNew(t *testing.T) *assert { + return &assert{ + t: t, + } +} + +func (a *assert) Equal(expected, actual interface{}) bool { + if !objectsAreEqual(expected, actual) { + return a.Fail(fmt.Sprintf("Not equal:\n"+ + "expected: %#v\n"+ + " actual: %#v\n", expected, actual)) + } + return true +} + +func objectsAreEqual(expected, actual interface{}) bool { + if expected == nil || actual == nil { + return expected == actual + } + return reflect.DeepEqual(expected, actual) +} + +func (a *assert) Nil(object interface{}) bool { + if isNil(object) { + return true + } + return a.Fail(fmt.Sprintf("Expected nil, but got: %#v", object)) +} + +func (a *assert) NotNil(object interface{}) bool { + if !isNil(object) { + return true + } + return a.Fail("Expected value not to be nil.") +} + +// isNil checks if a specified object is nil or not, without Failing. +func isNil(object interface{}) bool { + if object == nil { + return true + } + + value := reflect.ValueOf(object) + kind := value.Kind() + if kind >= reflect.Chan && kind <= reflect.Slice && value.IsNil() { + return true + } + + return false +} + +func (a *assert) Panics(f func()) bool { + if funcDidPanic, panicValue := didPanic(f); !funcDidPanic { + return a.Fail(fmt.Sprintf("func %#v should panic\n\r\tPanic value:\t%v", f, panicValue)) + } + + return true +} + +// Fail reports a failure through +func (a *assert) Fail(failureMessage string) bool { + a.t.Errorf("%s", failureMessage) + return false +} + +// didPanic returns true if the function passed to it panics. Otherwise, it returns false. +func didPanic(f func()) (bool, interface{}) { + didPanic := false + var message interface{} + func() { + defer func() { + if message = recover(); message != nil { + didPanic = true + } + }() + // call the target function + f() + }() + return didPanic, message +} diff --git a/runtime/Go/antlr/testing_lexer_b_test.go b/runtime/Go/antlr/testing_lexer_b_test.go new file mode 100644 index 000000000..4ab9b340d --- /dev/null +++ b/runtime/Go/antlr/testing_lexer_b_test.go @@ -0,0 +1,107 @@ +// 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 antlr + +/* +LexerB is a lexer for testing purpose. + +This file is generated from this grammer. + +lexer grammar LexerB; + +ID : 'a'..'z'+; +INT : '0'..'9'+; +SEMI : ';'; +ASSIGN : '='; +PLUS : '+'; +MULT : '*'; +WS : ' '+; +*/ + +var lexerB_serializedLexerAtn = []uint16{ + 3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 9, 40, 8, + 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, + 7, 4, 8, 9, 8, 3, 2, 6, 2, 19, 10, 2, 13, 2, 14, 2, 20, 3, 3, 6, 3, 24, + 10, 3, 13, 3, 14, 3, 25, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, + 3, 8, 6, 8, 37, 10, 8, 13, 8, 14, 8, 38, 2, 2, 9, 3, 3, 5, 4, 7, 5, 9, + 6, 11, 7, 13, 8, 15, 9, 3, 2, 2, 2, 42, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, + 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, + 2, 2, 2, 15, 3, 2, 2, 2, 3, 18, 3, 2, 2, 2, 5, 23, 3, 2, 2, 2, 7, 27, 3, + 2, 2, 2, 9, 29, 3, 2, 2, 2, 11, 31, 3, 2, 2, 2, 13, 33, 3, 2, 2, 2, 15, + 36, 3, 2, 2, 2, 17, 19, 4, 99, 124, 2, 18, 17, 3, 2, 2, 2, 19, 20, 3, 2, + 2, 2, 20, 18, 3, 2, 2, 2, 20, 21, 3, 2, 2, 2, 21, 4, 3, 2, 2, 2, 22, 24, + 4, 50, 59, 2, 23, 22, 3, 2, 2, 2, 24, 25, 3, 2, 2, 2, 25, 23, 3, 2, 2, + 2, 25, 26, 3, 2, 2, 2, 26, 6, 3, 2, 2, 2, 27, 28, 7, 61, 2, 2, 28, 8, 3, + 2, 2, 2, 29, 30, 7, 63, 2, 2, 30, 10, 3, 2, 2, 2, 31, 32, 7, 45, 2, 2, + 32, 12, 3, 2, 2, 2, 33, 34, 7, 44, 2, 2, 34, 14, 3, 2, 2, 2, 35, 37, 7, + 34, 2, 2, 36, 35, 3, 2, 2, 2, 37, 38, 3, 2, 2, 2, 38, 36, 3, 2, 2, 2, 38, + 39, 3, 2, 2, 2, 39, 16, 3, 2, 2, 2, 6, 2, 20, 25, 38, 2, +} + +var lexerB_lexerDeserializer = NewATNDeserializer(nil) +var lexerB_lexerAtn = lexerB_lexerDeserializer.DeserializeFromUInt16(lexerB_serializedLexerAtn) + +var lexerB_lexerChannelNames = []string{ + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", +} + +var lexerB_lexerModeNames = []string{ + "DEFAULT_MODE", +} + +var lexerB_lexerLiteralNames = []string{ + "", "", "", "';'", "'='", "'+'", "'*'", +} + +var lexerB_lexerSymbolicNames = []string{ + "", "ID", "INT", "SEMI", "ASSIGN", "PLUS", "MULT", "WS", +} + +var lexerB_lexerRuleNames = []string{ + "ID", "INT", "SEMI", "ASSIGN", "PLUS", "MULT", "WS", +} + +type LexerB struct { + *BaseLexer + channelNames []string + modeNames []string + // TODO: EOF string +} + +var lexerB_lexerDecisionToDFA = make([]*DFA, len(lexerB_lexerAtn.DecisionToState)) + +func init() { + for index, ds := range lexerB_lexerAtn.DecisionToState { + lexerB_lexerDecisionToDFA[index] = NewDFA(ds, index) + } +} + +func NewLexerB(input CharStream) *LexerB { + l := new(LexerB) + + l.BaseLexer = NewBaseLexer(input) + l.Interpreter = NewLexerATNSimulator(l, lexerB_lexerAtn, lexerB_lexerDecisionToDFA, NewPredictionContextCache()) + + l.channelNames = lexerB_lexerChannelNames + l.modeNames = lexerB_lexerModeNames + l.RuleNames = lexerB_lexerRuleNames + l.LiteralNames = lexerB_lexerLiteralNames + l.SymbolicNames = lexerB_lexerSymbolicNames + l.GrammarFileName = "LexerB.g4" + // TODO: l.EOF = TokenEOF + + return l +} + +// LexerB tokens. +const ( + LexerBID = 1 + LexerBINT = 2 + LexerBSEMI = 3 + LexerBASSIGN = 4 + LexerBPLUS = 5 + LexerBMULT = 6 + LexerBWS = 7 +) diff --git a/runtime/Go/antlr/testing_util_test.go b/runtime/Go/antlr/testing_util_test.go new file mode 100644 index 000000000..20428831b --- /dev/null +++ b/runtime/Go/antlr/testing_util_test.go @@ -0,0 +1,30 @@ +package antlr + +import ( + "fmt" + "strings" +) + +// newTestCommonToken create common token with tokentype, text and channel +// notice: test purpose only +func newTestCommonToken(tokenType int, text string, channel int) *CommonToken { + t := new(CommonToken) + t.BaseToken = new(BaseToken) + t.tokenType = tokenType + t.channel = channel + t.text = text + t.line = 0 + t.column = -1 + return t +} + +// tokensToString returnes []Tokens string +// notice: test purpose only +func tokensToString(tokens []Token) string { + buf := make([]string, len(tokens)) + for i, token := range tokens { + buf[i] = fmt.Sprintf("%v", token) + } + + return "[" + strings.Join(buf, ", ") + "]" +} diff --git a/runtime/Go/antlr/tokenstream_rewriter.go b/runtime/Go/antlr/tokenstream_rewriter.go new file mode 100644 index 000000000..96a03f02a --- /dev/null +++ b/runtime/Go/antlr/tokenstream_rewriter.go @@ -0,0 +1,649 @@ +// 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 antlr + +import ( +"bytes" +"fmt" +) + + +// +// Useful for rewriting out a buffered input token stream after doing some +// augmentation or other manipulations on it. + +//+// You can insert stuff, replace, and delete chunks. Note that the operations +// are done lazily--only if you convert the buffer to a {@link String} with +// {@link TokenStream#getText()}. This is very efficient because you are not +// moving data around all the time. As the buffer of tokens is converted to +// strings, the {@link #getText()} method(s) scan the input token stream and +// check to see if there is an operation at the current index. If so, the +// operation is done and then normal {@link String} rendering continues on the +// buffer. This is like having multiple Turing machine instruction streams +// (programs) operating on a single input tape. :)
+//+ +// This rewriter makes no modifications to the token stream. It does not ask the +// stream to fill itself up nor does it advance the input cursor. The token +// stream {@link TokenStream#index()} will return the same value before and +// after any {@link #getText()} call.
+ +//+// The rewriter only works on tokens that you have in the buffer and ignores the +// current input cursor. If you are buffering tokens on-demand, calling +// {@link #getText()} halfway through the input will only do rewrites for those +// tokens in the first half of the file.
+ +//+// Since the operations are done lazily at {@link #getText}-time, operations do +// not screw up the token index values. That is, an insert operation at token +// index {@code i} does not change the index values for tokens +// {@code i}+1..n-1.
+ +//+// Because operations never actually alter the buffer, you may always get the +// original token stream back without undoing anything. Since the instructions +// are queued up, you can easily simulate transactions and roll back any changes +// if there is an error just by removing instructions. For example,
+ +//+// CharStream input = new ANTLRFileStream("input"); +// TLexer lex = new TLexer(input); +// CommonTokenStream tokens = new CommonTokenStream(lex); +// T parser = new T(tokens); +// TokenStreamRewriter rewriter = new TokenStreamRewriter(tokens); +// parser.startRule(); +//+ +//
+// Then in the rules, you can execute (assuming rewriter is visible):
+ +//+// Token t,u; +// ... +// rewriter.insertAfter(t, "text to put after t");} +// rewriter.insertAfter(u, "text after u");} +// System.out.println(rewriter.getText()); +//+ +//
+// You can also have multiple "instruction streams" and get multiple rewrites +// from a single pass over the input. Just name the instruction streams and use +// that name again when printing the buffer. This could be useful for generating +// a C file and also its header file--all from the same buffer:
+ +//+// rewriter.insertAfter("pass1", t, "text to put after t");} +// rewriter.insertAfter("pass2", u, "text after u");} +// System.out.println(rewriter.getText("pass1")); +// System.out.println(rewriter.getText("pass2")); +//+ +//
+// If you don't use named rewrite streams, a "default" stream is used as the +// first example shows.
+ + + +const( + Default_Program_Name = "default" + Program_Init_Size = 100 + Min_Token_Index = 0 +) + +// Define the rewrite operation hierarchy + +type RewriteOperation interface { + // Execute the rewrite operation by possibly adding to the buffer. + // Return the index of the next token to operate on. + Execute(buffer *bytes.Buffer) int + String() string + GetInstructionIndex() int + GetIndex() int + GetText() string + GetOpName() string + GetTokens() TokenStream + SetInstructionIndex(val int) + SetIndex(int) + SetText(string) + SetOpName(string) + SetTokens(TokenStream) +} + +type BaseRewriteOperation struct { + //Current index of rewrites list + instruction_index int + //Token buffer index + index int + //Substitution text + text string + //Actual operation name + op_name string + //Pointer to token steam + tokens TokenStream +} + +func (op *BaseRewriteOperation)GetInstructionIndex() int{ + return op.instruction_index +} + +func (op *BaseRewriteOperation)GetIndex() int{ + return op.index +} + +func (op *BaseRewriteOperation)GetText() string{ + return op.text +} + +func (op *BaseRewriteOperation)GetOpName() string{ + return op.op_name +} + +func (op *BaseRewriteOperation)GetTokens() TokenStream{ + return op.tokens +} + +func (op *BaseRewriteOperation)SetInstructionIndex(val int){ + op.instruction_index = val +} + +func (op *BaseRewriteOperation)SetIndex(val int) { + op.index = val +} + +func (op *BaseRewriteOperation)SetText(val string){ + op.text = val +} + +func (op *BaseRewriteOperation)SetOpName(val string){ + op.op_name = val +} + +func (op *BaseRewriteOperation)SetTokens(val TokenStream) { + op.tokens = val +} + + +func (op *BaseRewriteOperation) Execute(buffer *bytes.Buffer) int{ + return op.index +} + +func (op *BaseRewriteOperation) String() string { + return fmt.Sprintf("<%s@%d:\"%s\">", + op.op_name, + op.tokens.Get(op.GetIndex()), + op.text, + ) + +} + + +type InsertBeforeOp struct { + BaseRewriteOperation +} + +func NewInsertBeforeOp(index int, text string, stream TokenStream) *InsertBeforeOp{ + return &InsertBeforeOp{BaseRewriteOperation:BaseRewriteOperation{ + index:index, + text:text, + op_name:"InsertBeforeOp", + tokens:stream, + }} +} + +func (op *InsertBeforeOp) Execute(buffer *bytes.Buffer) int{ + buffer.WriteString(op.text) + if op.tokens.Get(op.index).GetTokenType() != TokenEOF{ + buffer.WriteString(op.tokens.Get(op.index).GetText()) + } + return op.index+1 +} + +func (op *InsertBeforeOp) String() string { + return op.BaseRewriteOperation.String() +} + +// Distinguish between insert after/before to do the "insert afters" +// first and then the "insert befores" at same index. Implementation +// of "insert after" is "insert before index+1". + +type InsertAfterOp struct { + BaseRewriteOperation +} + +func NewInsertAfterOp(index int, text string, stream TokenStream) *InsertAfterOp{ + return &InsertAfterOp{BaseRewriteOperation:BaseRewriteOperation{ + index:index+1, + text:text, + tokens:stream, + }} +} + +func (op *InsertAfterOp) Execute(buffer *bytes.Buffer) int { + buffer.WriteString(op.text) + if op.tokens.Get(op.index).GetTokenType() != TokenEOF{ + buffer.WriteString(op.tokens.Get(op.index).GetText()) + } + return op.index+1 +} + +func (op *InsertAfterOp) String() string { + return op.BaseRewriteOperation.String() +} + +// I'm going to try replacing range from x..y with (y-x)+1 ReplaceOp +// instructions. +type ReplaceOp struct{ + BaseRewriteOperation + LastIndex int +} + +func NewReplaceOp(from, to int, text string, stream TokenStream)*ReplaceOp { + return &ReplaceOp{ + BaseRewriteOperation:BaseRewriteOperation{ + index:from, + text:text, + op_name:"ReplaceOp", + tokens:stream, + }, + LastIndex:to, + } +} + +func (op *ReplaceOp)Execute(buffer *bytes.Buffer) int{ + if op.text != ""{ + buffer.WriteString(op.text) + } + return op.LastIndex +1 +} + +func (op *ReplaceOp) String() string { + if op.text == "" { + return fmt.Sprintf("a
a", "DistinguishBetweenInsertAfterAndInsertBeforeToPreserverOrder2", + func(r *TokenStreamRewriter){ + r.InsertBeforeDefault(0, "") + r.InsertBeforeDefault(0, "") + r.InsertAfterDefault(0, "
") + r.InsertAfterDefault(0, "") + r.InsertBeforeDefault(1, "") + r.InsertAfterDefault(1,"") + }), + NewLexerTest("ab", "a
")
+ r.InsertBeforeDefault(0, "")
+ r.InsertBeforeDefault(0, " The implementation for {@link TokenTagToken} returns a string of the form
# {@code tokenName:type}. The {@link org.antlr.v4.runtime.RecognitionException} is non-null for all syntax errors except
+ ///
+ /// The _RecognitionException_ is non-null for all syntax errors except
/// when we discover mismatched token errors that we can recover from
/// in-line, without returning from the surrounding rule (via the single
- /// token insertion and deletion mechanism). Each full-context prediction which does not result in a syntax error
- /// will call either {@link #reportContextSensitivity} or
- /// {@link #reportAmbiguity}. When {@code ambigAlts} is not null, it contains the set of potentially
+ ///
+ /// Each full-context prediction which does not result in a syntax error
+ /// will call either _#reportContextSensitivity_ or
+ /// _#reportAmbiguity_.
+ ///
+ /// When `ambigAlts` is not null, it contains the set of potentially
/// viable alternatives identified by the prediction algorithm. When
- /// {@code ambigAlts} is null, use {@link org.antlr.v4.runtime.atn.ATNConfigSet#getAlts} to obtain the
- /// represented alternatives from the {@code configs} argument. When {@code exact} is {@code true}, all of the potentially
+ /// `ambigAlts` is null, use _org.antlr.v4.runtime.atn.ATNConfigSet#getAlts_ to obtain the
+ /// represented alternatives from the `configs` argument.
+ ///
+ /// When `exact` is `true`, __all__ of the potentially
/// viable alternatives are truly viable, i.e. this is reporting an exact
- /// ambiguity. When {@code exact} is {@code false}, at least two of
+ /// ambiguity. When `exact` is `false`, __at least two__ of
/// the potentially viable alternatives are viable for the current input, but
/// the prediction algorithm terminated as soon as it determined that at
- /// least the minimum potentially viable alternative is truly
- /// viable. When the {@link org.antlr.v4.runtime.atn.PredictionMode#LL_EXACT_AMBIG_DETECTION} prediction
+ /// least the __minimum__ potentially viable alternative is truly
+ /// viable.
+ ///
+ /// When the _org.antlr.v4.runtime.atn.PredictionMode#LL_EXACT_AMBIG_DETECTION_ prediction
/// mode is used, the parser is required to identify exact ambiguities so
- /// {@code exact} will always be {@code true}. This method is not used by lexers. If one or more configurations in {@code configs} contains a semantic
+ ///
+ /// If one or more configurations in `configs` contains a semantic
/// predicate, the predicates are evaluated before this method is called. The
/// subset of alternatives which are still viable after predicates are
- /// evaluated is reported in {@code conflictingAlts}. This method is not used by lexers. Each full-context prediction which does not result in a syntax error
- /// will call either {@link #reportContextSensitivity} or
- /// {@link #reportAmbiguity}. For prediction implementations that only evaluate full-context
+ ///
+ /// Each full-context prediction which does not result in a syntax error
+ /// will call either _#reportContextSensitivity_ or
+ /// _#reportAmbiguity_.
+ ///
+ /// For prediction implementations that only evaluate full-context
/// predictions when an SLL conflict is found (including the default
- /// {@link org.antlr.v4.runtime.atn.ParserATNSimulator} implementation), this method reports cases
+ /// _org.antlr.v4.runtime.atn.ParserATNSimulator_ implementation), this method reports cases
/// where SLL conflicts were resolved to unique full-context predictions,
/// i.e. the decision was context-sensitive. This report does not necessarily
/// indicate a problem, and it may appear even in completely unambiguous
- /// grammars. {@code configs} may have more than one represented alternative if the
+ /// grammars.
+ ///
+ /// `configs` may have more than one represented alternative if the
/// full-context prediction algorithm does not evaluate predicates before
/// beginning the full-context prediction. In all cases, the final prediction
- /// is passed as the {@code prediction} argument. Note that the definition of "context sensitivity" in this method
- /// differs from the concept in {@link org.antlr.v4.runtime.atn.DecisionInfo#contextSensitivities}.
+ /// is passed as the `prediction` argument.
+ ///
+ /// Note that the definition of "context sensitivity" in this method
+ /// differs from the concept in _org.antlr.v4.runtime.atn.DecisionInfo#contextSensitivities_.
/// This method reports all instances where an SLL conflict occurred but LL
/// parsing produced a unique result, whether or not that unique result
- /// matches the minimum alternative in the SLL conflicting set. This method is not used by lexers. TODO: what to do about lexers This method handles the consumption of any tokens - the caller should
- /// not call {@link org.antlr.v4.runtime.Parser#consume} after a successful recovery. Note that the calling code will not report an error if this method
+ ///
+ /// This method handles the consumption of any tokens - the caller should
+ /// __not__ call _org.antlr.v4.runtime.Parser#consume_ after a successful recovery.
+ ///
+ /// Note that the calling code will not report an error if this method
/// returns successfully. The error strategy implementation is responsible
- /// for calling {@link org.antlr.v4.runtime.Parser#notifyErrorListeners} as appropriate. The generated code currently contains calls to {@link #sync} after
- /// entering the decision state of a closure block ({@code (...)*} or
- /// {@code (...)+}). For an implementation based on Jim Idle's "magic sync" mechanism, see
- /// {@link org.antlr.v4.runtime.DefaultErrorStrategy#sync}. If you need encoding, pass in stream/reader with correct encoding.
-/// This error strategy is useful in the following scenarios.
-/// {@code myparser.setErrorHandler(new BailErrorStrategy());}
-/// This token stream ignores the value of {@link org.antlr.v4.runtime.Token#getChannel}. If your
+///
+///
+/// This token stream ignores the value of _org.antlr.v4.runtime.Token#getChannel_. If your
/// parser requires the token stream filter tokens to only those on a particular
-/// channel, such as {@link org.antlr.v4.runtime.Token#DEFAULT_CHANNEL} or
-/// {@link org.antlr.v4.runtime.Token#HIDDEN_CHANNEL}, use a filtering token stream such a
-/// {@link org.antlr.v4.runtime.CommonTokenStream}. This field is set to -1 when the stream is first constructed or when
- /// {@link #setTokenSource} is called, indicating that the first token has
+ ///
+ /// The index into _#tokens_ of the current token (next token to
+ /// _#consume_). _#tokens_`[`_#p_`]` should be
+ /// _#LT LT(1)_.
+ ///
+ /// This field is set to -1 when the stream is first constructed or when
+ /// _#setTokenSource_ is called, indicating that the first token has
/// not yet been fetched from the token source. For additional information,
- /// see the documentation of {@link org.antlr.v4.runtime.IntStream} for a description of
- /// Initializing Methods. For example, {@link org.antlr.v4.runtime.CommonTokenStream} overrides this method to ensure that
- /// the seek target is always an on-channel token.
- /// If {@code i} specifies an index at or after the EOF token, the EOF token
+ /// channel. Return `i` if `tokens[i]` is on channel. Return -1
+ /// if there are no tokens on channel between `i` and 0.
+ ///
+ ///
+ /// If `i` specifies an index at or after the EOF token, the EOF token
/// index is returned. This is due to the fact that the EOF token is treated
- /// as though it were on every channel.
+ ///
+ /// This is the backing field for _#getTokenSource_ and
+ /// _#getInputStream_.
+ ///
+ ///
/// These properties share a field to reduce the memory footprint of
- /// {@link org.antlr.v4.runtime.CommonToken}. Tokens created by a {@link org.antlr.v4.runtime.CommonTokenFactory} from
+ /// _org.antlr.v4.runtime.CommonToken_. Tokens created by a _org.antlr.v4.runtime.CommonTokenFactory_ from
/// the same source and input stream share a reference to the same
- /// {@link org.antlr.v4.runtime.misc.Pair} containing these values.
- /// If {@code oldToken} is also a {@link org.antlr.v4.runtime.CommonToken} instance, the newly
- /// constructed token will share a reference to the {@link #text} field and
- /// the {@link org.antlr.v4.runtime.misc.Pair} stored in {@link #source}. Otherwise, {@link #text} will
- /// be assigned the result of calling {@link #getText}, and {@link #source}
- /// will be constructed from the result of {@link org.antlr.v4.runtime.Token#getTokenSource} and
- /// {@link org.antlr.v4.runtime.Token#getInputStream}.
+ ///
+ /// The default _org.antlr.v4.runtime.CommonTokenFactory_ instance.
+ ///
+ ///
/// This token factory does not explicitly copy token text when constructing
- /// tokens.
- /// The default value is {@code false} to avoid the performance and memory
- /// overhead of copying text for every token unless explicitly requested.
- /// When {@code copyText} is {@code false}, the {@link #DEFAULT} instance
- /// should be used instead of constructing a new instance.
- /// The {@link #DEFAULT} instance should be used instead of calling this
- /// directly.
+/// _org.antlr.v4.runtime.Token#getChannel_ returns a particular value).
+///
+///
/// This token stream provides access to all tokens by index or when calling
-/// methods like {@link #getText}. The channel filtering is only used for code
-/// accessing tokens via the lookahead methods {@link #LA}, {@link #LT}, and
-/// {@link #LB}.
+/// methods like _#getText_. The channel filtering is only used for code
+/// accessing tokens via the lookahead methods _#LA_, _#LT_, and
+/// _#LB_.
+///
+///
/// By default, tokens are placed on the default channel
-/// ({@link org.antlr.v4.runtime.Token#DEFAULT_CHANNEL}), but may be reassigned by using the
-/// {@code ->channel(HIDDEN)} lexer command, or by using an embedded action to
-/// call {@link org.antlr.v4.runtime.Lexer#setChannel}.
-///
-/// Note: lexer rules which use the {@code ->skip} lexer command or call
-/// {@link org.antlr.v4.runtime.Lexer#skip} do not produce tokens at all, so input text matched by
+/// (_org.antlr.v4.runtime.Token#DEFAULT_CHANNEL_), but may be reassigned by using the
+/// `->channel(HIDDEN)` lexer command, or by using an embedded action to
+/// call _org.antlr.v4.runtime.Lexer#setChannel_.
+///
+///
+///
+/// Note: lexer rules which use the `->skip` lexer command or call
+/// _org.antlr.v4.runtime.Lexer#skip_ do not produce tokens at all, so input text matched by
/// such a rule will not be available as part of the token stream, regardless of
-/// channel.
- /// The default value is {@link org.antlr.v4.runtime.Token#DEFAULT_CHANNEL}, which matches the
- /// default channel assigned to tokens created by the lexer.
- /// This implementation prints messages to {@link System#err} containing the
- /// values of {@code line}, {@code charPositionInLine}, and {@code msg} using
- /// the following format. The default implementation simply calls {@link #endErrorCondition} to
- /// ensure that the handler is not in error recovery mode. The default implementation simply calls {@link #endErrorCondition}. The default implementation returns immediately if the handler is already
- /// in error recovery mode. Otherwise, it calls {@link #beginErrorCondition}
- /// and dispatches the reporting task based on the runtime type of {@code e}
- /// according to the following table. The default implementation resynchronizes the parser by consuming tokens
+ ///
+ /// The default implementation resynchronizes the parser by consuming tokens
/// until we find one in the resynchronization set--loosely the set of tokens
- /// that can follow the current rule. Implements Jim Idle's magic sync mechanism in closures and optional
- /// subrules. E.g., If the sub rule is optional ({@code (...)?}, {@code (...)*}, or block
+ ///
+ /// If the sub rule is optional (`(...)?`, `(...)*`, or block
/// with an empty alternative), then the expected set includes what follows
- /// the subrule. During loop iteration, it consumes until it sees a token that can start a
+ /// the subrule.
+ ///
+ /// During loop iteration, it consumes until it sees a token that can start a
/// sub rule or what follows loop. Yes, that is pretty aggressive. We opt to
- /// stay in the loop as long as possible. ORIGINS Previous versions of ANTLR did a poor job of their recovery within loops.
+ /// stay in the loop as long as possible.
+ ///
+ /// __ORIGINS__
+ ///
+ /// Previous versions of ANTLR did a poor job of their recovery within loops.
/// A single mismatch token or missing token would force the parser to bail
- /// out of the entire rules surrounding the loop. So, for rule This functionality cost a little bit of effort because the parser has to
+ ///
+ /// This functionality cost a little bit of effort because the parser has to
/// compare token set at the start of the loop and at each iteration. If for
/// some reason speed is suffering for you, you can turn off this
- /// functionality by simply overriding this method as a blank { }. This method is called when {@link #singleTokenDeletion} identifies
+ /// `recognizer` is in error recovery mode.
+ ///
+ /// This method is called when _#singleTokenDeletion_ identifies
/// single-token deletion as a viable recovery strategy for a mismatched
- /// input error. The default implementation simply returns if the handler is already in
- /// error recovery mode. Otherwise, it calls {@link #beginErrorCondition} to
+ /// input error.
+ ///
+ /// The default implementation simply returns if the handler is already in
+ /// error recovery mode. Otherwise, it calls _#beginErrorCondition_ to
/// enter error recovery mode, followed by calling
- /// {@link org.antlr.v4.runtime.Parser#notifyErrorListeners}. This method is called when {@link #singleTokenInsertion} identifies
+ /// method returns, `recognizer` is in error recovery mode.
+ ///
+ /// This method is called when _#singleTokenInsertion_ identifies
/// single-token insertion as a viable recovery strategy for a mismatched
- /// input error. The default implementation simply returns if the handler is already in
- /// error recovery mode. Otherwise, it calls {@link #beginErrorCondition} to
+ /// input error.
+ ///
+ /// The default implementation simply returns if the handler is already in
+ /// error recovery mode. Otherwise, it calls _#beginErrorCondition_ to
/// enter error recovery mode, followed by calling
- /// {@link org.antlr.v4.runtime.Parser#notifyErrorListeners}. The default implementation attempts to recover from the mismatched input
+ ///
+ ///
+ ///
+ /// The default implementation attempts to recover from the mismatched input
/// by using single token insertion and deletion as described below. If the
/// recovery attempt fails, this method throws an
- /// {@link org.antlr.v4.runtime.InputMismatchException}. EXTRA TOKEN (single token deletion) {@code LA(1)} is not what we are looking for. If {@code LA(2)} has the
- /// right token, however, then assume {@code LA(1)} is some extra spurious
+ /// _org.antlr.v4.runtime.InputMismatchException_.
+ ///
+ /// __EXTRA TOKEN__ (single token deletion)
+ ///
+ /// `LA(1)` is not what we are looking for. If `LA(2)` has the
+ /// right token, however, then assume `LA(1)` is some extra spurious
/// token and delete it. Then consume and return the next token (which was
- /// the {@code LA(2)} token) as the successful result of the match operation. This recovery strategy is implemented by {@link #singleTokenDeletion}. MISSING TOKEN (single token insertion) If current token (at {@code LA(1)}) is consistent with what could come
- /// after the expected {@code LA(1)} token, then assume the token is missing
- /// and use the parser's {@link org.antlr.v4.runtime.TokenFactory} to create it on the fly. The
+ /// the `LA(2)` token) as the successful result of the match operation.
+ ///
+ /// This recovery strategy is implemented by _#singleTokenDeletion_.
+ ///
+ /// __MISSING TOKEN__ (single token insertion)
+ ///
+ /// If current token (at `LA(1)`) is consistent with what could come
+ /// after the expected `LA(1)` token, then assume the token is missing
+ /// and use the parser's _org.antlr.v4.runtime.TokenFactory_ to create it on the fly. The
/// "insertion" is performed by returning the created token as the successful
- /// result of the match operation. This recovery strategy is implemented by {@link #singleTokenInsertion}. EXAMPLE For example, Input {@code i=(3;} is clearly missing the {@code ')'}. When
- /// the parser returns from the nested call to {@code expr}, it will have
- /// call chain: This method determines whether or not single-token insertion is viable by
- /// checking if the {@code LA(1)} input symbol could be successfully matched
- /// if it were instead the {@code LA(2)} symbol. If this method returns
- /// {@code true}, the caller is responsible for creating and inserting a
- /// token with the correct type to produce this behavior. If the single-token deletion is successful, this method calls
- /// {@link #reportUnwantedToken} to report the error, followed by
- /// {@link org.antlr.v4.runtime.Parser#consume} to actually "delete" the extraneous token. Then,
- /// before returning {@link #reportMatch} is called to signal a successful
- /// match. Initializing Methods: Some methods in this interface have
+/// For more information on marked ranges, see _#mark_.
+///
+/// __Initializing Methods:__ Some methods in this interface have
/// unspecified behavior if no call to an initializing method has occurred after
-/// the stream was constructed. The following is a list of initializing methods: This method is guaranteed to succeed if any of the following are true: If {@code i} represents a position at or beyond the end of the stream,
- /// this method returns {@link #EOF}. The return value is unspecified if {@code i<0} and fewer than {@code -i}
- /// calls to {@link #consume consume()} have occurred from the beginning of
- /// the stream before calling this method. The returned mark is an opaque handle (type {@code int}) which is passed
- /// to {@link #release release()} when the guarantees provided by the marked
+ ///
+ /// The returned mark is an opaque handle (type `int`) which is passed
+ /// to _#release release()_ when the guarantees provided by the marked
/// range are no longer necessary. When calls to
- /// {@code mark()}/{@code release()} are nested, the marks must be released
+ /// `mark()`/`release()` are nested, the marks must be released
/// in reverse order of which they were obtained. Since marked regions are
/// used during performance-critical sections of prediction, the specific
/// behavior of invalid usage is unspecified (i.e. a mark is not released, or
/// a mark is released twice, or marks are not released in reverse order from
- /// which they were created). The behavior of this method is unspecified if no call to an
- /// {@link org.antlr.v4.runtime.IntStream initializing method} has occurred after this stream was
- /// constructed. This method does not change the current position in the input stream. The following example shows the use of {@link #mark mark()},
- /// {@link #release release(mark)}, {@link #index index()}, and
- /// {@link #seek seek(index)} as part of an operation to safely work within a
+ /// which they were created).
+ ///
+ /// The behavior of this method is unspecified if no call to an
+ /// _org.antlr.v4.runtime.IntStream initializing method_ has occurred after this stream was
+ /// constructed.
+ ///
+ /// This method does not change the current position in the input stream.
+ ///
+ /// The following example shows the use of _#mark mark()_,
+ /// _#release release(mark)_, _#index index()_, and
+ /// _#seek seek(index)_ as part of an operation to safely work within a
/// marked region, then restore the stream position to its original value and
- /// release the mark. For more information and an example, see {@link #mark}. The behavior of this method is unspecified if no call to an
- /// {@link org.antlr.v4.runtime.IntStream initializing method} has occurred after this stream was
- /// constructed.
-/// {@link org.antlr.v4.runtime.ParserRuleContext} does not include field storage for the rule index
+///
+/// This class extends _org.antlr.v4.runtime.ParserRuleContext_ by allowing the value of
+/// _#getRuleIndex_ to be explicitly set for the context.
+///
+///
+/// _org.antlr.v4.runtime.ParserRuleContext_ does not include field storage for the rule index
/// since the context classes created by the code generator override the
-/// {@link #getRuleIndex} method to return the correct value for that context.
+/// _#getRuleIndex_ method to return the correct value for that context.
/// Since the parser interpreter does not use the context classes generated for a
/// parser, this class (with slightly more memory overhead per node) is used to
-/// provide equivalent functionality. If the final token in the list is an {@link org.antlr.v4.runtime.Token#EOF} token, it will be used
-/// as the EOF token for every call to {@link #nextToken} after the end of the
-/// list is reached. Otherwise, an EOF token will be created. If the symbol type does not match,
- * {@link org.antlr.v4.runtime.ANTLRErrorStrategy#recoverInline} is called on the current error
- * strategy to attempt recovery. If {@link #getBuildParseTree} is
- * {@code true} and the token index of the symbol returned by
- * {@link org.antlr.v4.runtime.ANTLRErrorStrategy#recoverInline} is -1, the symbol is added to
- * the parse tree by calling {@link #createErrorNode(ParserRuleContext, Token)} then
- * {@link ParserRuleContext#addErrorNode(ErrorNode)}. If the symbol type does not match,
- * {@link org.antlr.v4.runtime.ANTLRErrorStrategy#recoverInline} is called on the current error
- * strategy to attempt recovery. If {@link #getBuildParseTree} is
- * {@code true} and the token index of the symbol returned by
- * {@link org.antlr.v4.runtime.ANTLRErrorStrategy#recoverInline} is -1, the symbol is added to
- * the parse tree by calling {@link #createErrorNode(ParserRuleContext, Token)} then
- * {@link ParserRuleContext#addErrorNode(ErrorNode)}. Note that if we are not building parse trees, rule contexts only point
- * upwards. When a rule exits, it returns the context but that gets garbage
- * collected if nobody holds a reference. It points upwards but nobody
- * points at it. When we build parse trees, we are adding all of these contexts to
- * {@link org.antlr.v4.runtime.ParserRuleContext#children} list. Contexts are then not candidates
- * for garbage collection. To support output-preserving grammar transformations (including but not
- * limited to left-recursion removal, automated left-factoring, and
- * optimized code generation), calls to listener methods during the parse
- * may differ substantially from calls made by
- * {@link org.antlr.v4.runtime.tree.ParseTreeWalker#DEFAULT} used after the parse is complete. In
- * particular, rule entry and exit events may occur in a different order
- * during the parse than after the parser. In addition, calls to certain
- * rule entry methods may be omitted. With the following specific exceptions, calls to listener events are
- * deterministic, i.e. for identical input the calls to listener
- * methods will be the same. If {@code listener} is {@code null} or has not been added as a parse
- * listener, this method does nothing. E.g., given the following input with {@code A} being the current
- * lookahead symbol, this function moves the cursor to {@code B} and returns
- * {@code A}. If the state number is not known, this method returns -1. If the set of expected tokens is not known and could not be computed,
- * this method returns {@code null}. If the context is not available, this method returns {@code null}. If the input stream is not available, this method returns {@code null}. If the recognizer is not available, this method returns {@code null}. Used for XPath and tree pattern compilation. Used for XPath and tree pattern compilation. For interpreters, we don't know their serialized ATN despite having
- * created the interpreter from it.
- * Since tokens on hidden channels (e.g. whitespace or comments) are not
- * added to the parse trees, they will not appear in the output of this
- * method.
- */
+ /// Return the combined text of all child nodes. This method only considers
+ /// tokens which have been added to the parse tree.
+ ///
+ /// Since tokens on hidden channels (e.g. whitespace or comments) are not
+ /// added to the parse trees, they will not appear in the output of this
+ /// method.
+ ///
open override func getText() -> String {
let length = getChildCount()
@@ -159,62 +159,61 @@ open class RuleContext: RuleNode {
return visitor.visitChildren(self)
}
- /*
- /** Call this method to view a parse tree in a dialog box visually. */
- public func inspect(parser : Parser) -> Future
- * The runtime version information is provided by {@link #VERSION} and
- * {@link #getRuntimeVersion()}. Detailed information about these values is
- * provided in the documentation for each member.
- * The runtime version check is implemented by {@link #checkVersion}. Detailed
- * information about incorporating this call into user code, as well as its use
- * in generated code, is provided in the documentation for the method.
- * Version strings x.y and x.y.z are considered "compatible" and no error
- * would be generated. Likewise, version strings x.y-SNAPSHOT and x.y.z are
- * considered "compatible" because the major and minor components x.y
- * are the same in each.
- * To trap any error messages issued by this code, use System.setErr()
- * in your main() startup code.
- *
- * This compile-time constant value allows generated parsers and other
- * libraries to include a literal reference to the version of the ANTLR 4
- * runtime library the code was compiled against. At each release, we
- * change this value. Version numbers are assumed to have the form
- *
- * major.minor.patch.revision-suffix,
- *
- * with the individual components defined as follows.
- * This method provides runtime access to the {@link #VERSION} field, as
- * opposed to directly referencing the field as a compile-time constant.
- * The version check is designed to detect the following two specific
- * scenarios.
- * Starting with ANTLR 4.3, the code generator emits a call to this method
- * using two constants in each generated lexer and parser: a hard-coded
- * constant indicating the version of the tool used to generate the parser
- * and a reference to the compile-time constant {@link #VERSION}. At
- * runtime, this method is called during the initialization of the generated
- * parser to detect mismatched versions, and notify the registered listeners
- * prior to creating instances of the parser.
- * This method does not perform any detection or filtering of semantic
- * changes between tool and runtime versions. It simply checks for a
- * version match and emits an error to stderr if a difference
- * is detected.
- * Note that some breaking changes between releases could result in other
- * types of runtime exceptions, such as a {@link LinkageError}, prior to
- * calling this method. In these cases, the underlying version mismatch will
- * not be reported here. This method is primarily intended to
- * notify users of potential semantic changes between releases that do not
- * result in binary compatibility problems which would be detected by the
- * class loader. As with semantic changes, changes that break binary
- * compatibility between releases are mentioned in the release notes
- * accompanying the affected release.
- * Additional note for target developers: The version check
- * implemented by this class is designed to address specific compatibility
- * concerns that may arise during the execution of Java applications. Other
- * targets should consider the implementation of this method in the context
- * of that target's known execution environment, which may or may not
- * resemble the design provided for the Java target.
- * The non-negative numbers less than {@link #MIN_USER_CHANNEL_VALUE} are
- * assigned to the predefined channels {@link #DEFAULT_CHANNEL} and
- * {@link #HIDDEN_CHANNEL}. Errors from the lexer are never passed to the parser. Either you want to keep
- * going or you do not upon token recognition error. If you do not want to
- * continue lexing then you do not want to continue parsing. Just throw an
- * exception not under {@link org.antlr.v4.runtime.RecognitionException} and Java will naturally toss
- * you all the way out of the recognizers. If you want to continue lexing then
- * you should not throw an exception to the parser--it has already requested a
- * token. Keep lexing until you get a valid one. Just report errors and keep
- * going, looking for a valid token. The preconditions for this method are the same as the preconditions of
- * {@link org.antlr.v4.runtime.IntStream#seek}. If the behavior of {@code seek(index)} is
- * unspecified for the current state and given {@code index}, then the
- * behavior of this method is also unspecified. The symbol referred to by {@code index} differs from {@code seek()} only
- * in the case of filtering streams where {@code index} lies before the end
- * of the stream. Unlike {@code seek()}, this method does not adjust
- * {@code index} to point to a non-ignored symbol. If {@code ctx.getSourceInterval()} does not return a valid interval of
- * tokens provided by this stream, the behavior is unspecified. If the specified {@code start} or {@code stop} token was not provided by
- * this stream, or if the {@code stop} occurred before the {@code start}
- * token, the behavior is unspecified. For streams which ensure that the {@link org.antlr.v4.runtime.Token#getTokenIndex} method is
- * accurate for all of its provided tokens, this method behaves like the
- * following code. Other streams may implement this method in other ways
- * provided the behavior is consistent with this at a high level.
- * You can insert stuff, replace, and delete chunks. Note that the operations
- * are done lazily--only if you convert the buffer to a {@link String} with
- * {@link org.antlr.v4.runtime.TokenStream#getText()}. This is very efficient because you are not
- * moving data around all the time. As the buffer of tokens is converted to
- * strings, the {@link #getText()} method(s) scan the input token stream and
- * check to see if there is an operation at the current index. If so, the
- * operation is done and then normal {@link String} rendering continues on the
- * buffer. This is like having multiple Turing machine instruction streams
- * (programs) operating on a single input tape. :)
- * This rewriter makes no modifications to the token stream. It does not ask the
- * stream to fill itself up nor does it advance the input cursor. The token
- * stream {@link org.antlr.v4.runtime.TokenStream#index()} will return the same value before and
- * after any {@link #getText()} call.
- * The rewriter only works on tokens that you have in the buffer and ignores the
- * current input cursor. If you are buffering tokens on-demand, calling
- * {@link #getText()} halfway through the input will only do rewrites for those
- * tokens in the first half of the file.
- * Since the operations are done lazily at {@link #getText}-time, operations do
- * not screw up the token index values. That is, an insert operation at token
- * index {@code i} does not change the index values for tokens
- * {@code i}+1..n-1.
- * Because operations never actually alter the buffer, you may always get the
- * original token stream back without undoing anything. Since the instructions
- * are queued up, you can easily simulate transactions and roll back any changes
- * if there is an error just by removing instructions. For example,
- * Then in the rules, you can execute (assuming rewriter is visible):
- * You can also have multiple "instruction streams" and get multiple rewrites
- * from a single pass over the input. Just name the instruction streams and use
- * that name again when printing the buffer. This could be useful for generating
- * a C file and also its header file--all from the same buffer:
- * If you don't use named rewrite streams, a "default" stream is used as the
- * first example shows. This is not the buffer capacity, that's {@code tokens.length}. The {@code LT(1)} token is {@code tokens[p]}. If {@code p == n}, we are
- * out of buffered tokens. This value is used to set the token indexes if the stream provides tokens
- * that implement {@link org.antlr.v4.runtime.WritableToken}. The specific marker value used for this class allows for some level of
- * protection against misuse where {@code seek()} is called on a mark or
- * {@code release()} is called in the wrong order.
- * No literal or symbol names are assigned to token types, so
- * {@link #getDisplayName(int)} returns the numeric value for all tokens
- * except {@link org.antlr.v4.runtime.Token#EOF}. The resulting vocabulary instance returns {@code null} for
- * {@link #getLiteralName(int)} and {@link #getSymbolicName(int)}, and the
- * value from {@code tokenNames} for the display names. If {@code context} is {@code null}, it is treated as
- /// {@link org.antlr.v4.runtime.ParserRuleContext#EMPTY}.
+ ///
+ ///
/// closure() tracks the depth of how far we dip into the outer context:
/// depth > 0. Note that it may not be totally accurate depth since I
- /// don't ever decrement. TODO: make it a boolean then
- /// For memory efficiency, the {@link #isPrecedenceFilterSuppressed} method
+ /// don't ever decrement. TODO: make it a boolean then
+ ///
+ ///
+ /// For memory efficiency, the _#isPrecedenceFilterSuppressed_ method
/// is also backed by this field. Since the field is publicly accessible, the
/// highest bit which would not cause the value to become negative is used to
/// store this field. This choice minimizes the risk that code which only
/// compares this value to 0 would be affected by the new purpose of the
- /// flag. It also ensures the performance of the existing {@link org.antlr.v4.runtime.atn.ATNConfig}
+ /// flag. It also ensures the performance of the existing _org.antlr.v4.runtime.atn.ATNConfig_
/// constructors as well as certain operations like
- /// {@link org.antlr.v4.runtime.atn.ATNConfigSet#add(org.antlr.v4.runtime.atn.ATNConfig, DoubleKeyMap)} method are
- /// completely unaffected by the change. This method updates {@link #dipsIntoOuterContext} and
- /// {@link #hasSemanticContext} when necessary. This cache makes a huge difference in memory and a little bit in speed.
+ ///
+ /// This cache makes a huge difference in memory and a little bit in speed.
/// For the Java grammar on java.*, it dropped the memory requirements
/// at the end from 25M to 16M. We don't store any of the full context
/// graphs in the DFA because they are limited to local context only,
/// but apparently there's a lot of repetition there as well. We optimize
/// the config contexts before storing the config set in the DFA states
- /// by literally rebuilding them with cached subgraphs only. I tried a cache for use during closure operations, that was
+ /// by literally rebuilding them with cached subgraphs only.
+ ///
+ /// I tried a cache for use during closure operations, that was
/// whacked after each adaptivePredict(). It cost a little bit
/// more time I think and doesn't save on the overall footprint
- /// so it's not worth the complexity.
+///
+///
/// This event may be reported during SLL prediction in cases where the
/// conflicting SLL configuration set provides sufficient information to
/// determine that the SLL conflict is truly an ambiguity. For example, if none
/// of the ATN configurations in the conflicting SLL configuration set have
/// traversed a global follow transition (i.e.
-/// {@link org.antlr.v4.runtime.atn.ATNConfig#reachesIntoOuterContext} is 0 for all configurations), then
+/// _org.antlr.v4.runtime.atn.ATNConfig#reachesIntoOuterContext_ is 0 for all configurations), then
/// the result of SLL prediction for that input is known to be equivalent to the
-/// result of LL prediction for that input.
+/// result of LL prediction for that input.
+///
+///
/// In some cases, the minimum represented alternative in the conflicting LL
/// configuration set is not equal to the minimum represented alternative in the
/// conflicting SLL configuration set. Grammars and inputs which result in this
-/// scenario are unable to use {@link org.antlr.v4.runtime.atn.PredictionMode#SLL}, which in turn means
+/// scenario are unable to use _org.antlr.v4.runtime.atn.PredictionMode#SLL_, which in turn means
/// they cannot use the two-stage parsing strategy to improve parsing performance
-/// for that input.
+///
+///
/// In some cases, the unique alternative identified by LL prediction is not
/// equal to the minimum represented alternative in the conflicting SLL
/// configuration set. Grammars and inputs which result in this scenario are
-/// unable to use {@link org.antlr.v4.runtime.atn.PredictionMode#SLL}, which in turn means they cannot use
+/// unable to use _org.antlr.v4.runtime.atn.PredictionMode#SLL_, which in turn means they cannot use
/// the two-stage parsing strategy to improve parsing performance for that
-/// input.
+///
+///
/// Parsing performance in ANTLR 4 is heavily influenced by both static factors
/// (e.g. the form of the rules in the grammar) and dynamic factors (e.g. the
/// choice of input and the state of the DFA cache at the time profiling
/// operations are started). For best results, gather and use aggregate
/// statistics from a large sample of inputs representing the inputs expected in
-/// production before using the results to make changes in the grammar.
+ ///
+ ///
/// The value of this field contains the sum of differential results obtained
- /// by {@link System#nanoTime()}, and is not adjusted to compensate for JIT
+ /// by _System#nanoTime()_, and is not adjusted to compensate for JIT
/// and/or garbage collection overhead. For best accuracy, use a modern JVM
/// implementation that provides precise results from
- /// {@link System#nanoTime()}, and perform profiling in a separate process
+ /// _System#nanoTime()_, and perform profiling in a separate process
/// which is warmed up by parsing the input prior to profiling. If desired,
- /// call {@link org.antlr.v4.runtime.atn.ATNSimulator#clearDFA} to reset the DFA cache to its initial
- /// state before starting the profiling measurement pass.
-///
-///
-/// Implementations of this interface report syntax errors by calling
-/// {@link org.antlr.v4.runtime.Parser#notifyErrorListeners}.
-///
-///
-///
-///
-///
- ///
+ /// _#fetchedEOF_ and _#p_ instead of calling _#LA_.
+ ///
+ /// * _#fetch_: The check to prevent adding multiple EOF symbols into
+ /// _#tokens_ is trivial with this field.
+ ///
internal var fetchedEOF: Bool = false
public init(_ tokenSource: TokenSource) {
@@ -69,7 +80,6 @@ public class BufferedTokenStream: TokenStream {
return 0
}
-
public func release(_ marker: Int) {
// no resources to release
}
@@ -108,8 +118,6 @@ public class BufferedTokenStream: TokenStream {
if try !skipEofCheck && LA(1) == BufferedTokenStream.EOF {
throw ANTLRError.illegalState(msg: "cannot consume EOF")
- //RuntimeException("cannot consume EOF")
- //throw ANTLRError.IllegalState /* throw IllegalStateException("cannot consume EOF"); */
}
if try sync(p + 1) {
@@ -117,11 +125,13 @@ public class BufferedTokenStream: TokenStream {
}
}
- /// Make sure index {@code i} in tokens has a token.
- ///
- /// - returns: {@code true} if a token is located at index {@code i}, otherwise
- /// {@code false}.
+ ///
+ /// Make sure index `i` in tokens has a token.
+ ///
+ /// - returns: `true` if a token is located at index `i`, otherwise
+ /// `false`.
/// - seealso: #get(int i)
+ ///
@discardableResult
internal func sync(_ i: Int) throws -> Bool {
assert(i >= 0, "Expected: i>=0")
@@ -135,9 +145,11 @@ public class BufferedTokenStream: TokenStream {
return true
}
- /// Add {@code n} elements to buffer.
- ///
+ ///
+ /// Add `n` elements to buffer.
+ ///
/// - returns: The actual number of elements added to the buffer.
+ ///
internal func fetch(_ n: Int) throws -> Int {
if fetchedEOF {
return 0
@@ -159,7 +171,6 @@ public class BufferedTokenStream: TokenStream {
return n
}
-
public func get(_ i: Int) throws -> Token {
if i < 0 || i >= tokens.count {
let index = tokens.count - 1
@@ -168,7 +179,9 @@ public class BufferedTokenStream: TokenStream {
return tokens[i] //tokens[i]
}
+ ///
/// Get all tokens from start..stop inclusively
+ ///
public func get(_ start: Int,_ stop: Int) throws -> Array
- /// line line:charPositionInLine msg
- ///
- override
- public func syntaxError
- ///
-
+ ///
+ ///
+ /// The default implementation returns immediately if the handler is already
+ /// in error recovery mode. Otherwise, it calls _#beginErrorCondition_
+ /// and dispatches the reporting task based on the runtime type of `e`
+ /// according to the following table.
+ ///
+ /// * _org.antlr.v4.runtime.NoViableAltException_: Dispatches the call to
+ /// _#reportNoViableAlternative_
+ /// * _org.antlr.v4.runtime.InputMismatchException_: Dispatches the call to
+ /// _#reportInputMismatch_
+ /// * _org.antlr.v4.runtime.FailedPredicateException_: Dispatches the call to
+ /// _#reportFailedPredicate_
+ /// * All other types: calls _org.antlr.v4.runtime.Parser#notifyErrorListeners_ to report
+ /// the exception
+ ///
public func reportError(_ recognizer: Parser,
_ e: AnyObject) {
// if we've already reported an error and have not matched a token
@@ -94,7 +98,6 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
return // don't report spurious errors
}
beginErrorCondition(recognizer)
- //TODO: exception handler
if (e is NoViableAltException) {
try! reportNoViableAlternative(recognizer, e as! NoViableAltException);
} else {
@@ -112,12 +115,11 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
}
}
- /// {@inheritDoc}
- ///
- ///
+ ///
+ /// Implements Jim Idle's magic sync mechanism in closures and optional
+ /// subrules. E.g.,
+ ///
+ ///
/// a : sync ( stuff sync )* ;
/// sync : {consume to what can follow sync} ;
- ///
- ///
- /// At the start of a sub rule upon error, {@link #sync} performs single
+ ///
+ ///
+ /// At the start of a sub rule upon error, _#sync_ performs single
/// token deletion, if possible. If it can't do that, it bails on the current
/// rule and uses the default error recovery, which consumes until the
/// resynchronization set of the current rule.
- ///
- ///
+ /// out of the entire rules surrounding the loop. So, for rule
+ ///
+ ///
/// classDef : 'class' ID '{' member* '}'
- ///
- ///
+ ///
+ ///
/// input with an extra token between members would force the parser to
/// consume until it found the next class definition rather than the next
/// member definition of the current class.
- ///
- ///
+ /// result of the match operation.
+ ///
+ /// This recovery strategy is implemented by _#singleTokenInsertion_.
+ ///
+ /// __EXAMPLE__
+ ///
+ /// For example, Input `i=(3;` is clearly missing the `')'`. When
+ /// the parser returns from the nested call to `expr`, it will have
+ /// call chain:
+ ///
+ ///
/// stat → expr → atom
- ///
- ///
- /// and it will be trying to match the {@code ')'} at this point in the
+ ///
+ ///
+ /// and it will be trying to match the `')'` at this point in the
/// derivation:
- ///
- ///
+ ///
+ ///
/// => ID '=' '(' INT ')' ('+' atom)* ';'
/// ^
- ///
- ///
- /// The attempt to match {@code ')'} will fail when it sees {@code ';'} and
- /// call {@link #recoverInline}. To recover, it sees that {@code LA(1)==';'}
- /// is in the set of tokens that can follow the {@code ')'} token reference
- /// in rule {@code atom}. It can assume that you forgot the {@code ')'}.
+ ///
+ ///
+ /// The attempt to match `')'` will fail when it sees `';'` and
+ /// call _#recoverInline_. To recover, it sees that `LA(1)==';'`
+ /// is in the set of tokens that can follow the `')'` token reference
+ /// in rule `atom`. It can assume that you forgot the `')'`.
+ ///
public func recoverInline(_ recognizer: Parser) throws -> Token {
// SINGLE TOKEN DELETION
@@ -422,21 +438,23 @@ public class DefaultErrorStrategy: ANTLRErrorStrategy {
//throwException() /* throw InputMismatchException(recognizer); */
}
+ ///
/// This method implements the single-token insertion inline error recovery
- /// strategy. It is called by {@link #recoverInline} if the single-token
+ /// strategy. It is called by _#recoverInline_ if the single-token
/// deletion strategy fails to recover from the mismatched input. If this
- /// method returns {@code true}, {@code recognizer} will be in error recovery
+ /// method returns `true`, `recognizer` will be in error recovery
/// mode.
- ///
- ///
-///
-///
+/// this situation occurs.
+///
/// - Sam Harwell
+///
import Foundation
public class DiagnosticErrorListener: BaseErrorListener {
- /// When {@code true}, only exactly known ambiguities are reported.
+ ///
+ /// When `true`, only exactly known ambiguities are reported.
+ ///
internal final var exactOnly: Bool
- /// Initializes a new instance of {@link org.antlr.v4.runtime.DiagnosticErrorListener} which only
+ ///
+ /// Initializes a new instance of _org.antlr.v4.runtime.DiagnosticErrorListener_ which only
/// reports exact ambiguities.
+ ///
public convenience override init() {
self.init(true)
}
- /// Initializes a new instance of {@link org.antlr.v4.runtime.DiagnosticErrorListener}, specifying
+ ///
+ /// Initializes a new instance of _org.antlr.v4.runtime.DiagnosticErrorListener_, specifying
/// whether all ambiguities or only exact ambiguities are reported.
- ///
- /// - parameter exactOnly: {@code true} to report only exact ambiguities, otherwise
- /// {@code false} to report all ambiguities.
+ ///
+ /// - parameter exactOnly: `true` to report only exact ambiguities, otherwise
+ /// `false` to report all ambiguities.
+ ///
public init(_ exactOnly: Bool) {
self.exactOnly = exactOnly
}
@@ -106,15 +114,17 @@ public class DiagnosticErrorListener: BaseErrorListener {
return "\(decision) (\(ruleName))"
}
+ ///
/// Computes the set of conflicting or ambiguous alternatives from a
/// configuration set, if that information was not already provided by the
/// parser.
- ///
+ ///
/// - parameter reportedAlts: The set of conflicting or ambiguous alternatives, as
/// reported by the parser.
/// - parameter configs: The conflicting or ambiguous configuration set.
- /// - returns: Returns {@code reportedAlts} if it is not {@code null}, otherwise
- /// returns the set of alternatives represented in {@code configs}.
+ /// - returns: Returns `reportedAlts` if it is not `null`, otherwise
+ /// returns the set of alternatives represented in `configs`.
+ ///
internal func getConflictingAlts(_ reportedAlts: BitSet?, _ configs: ATNConfigSet) throws -> BitSet {
if reportedAlts != nil {
return reportedAlts!
diff --git a/runtime/Swift/Sources/Antlr4/FailedPredicateException.swift b/runtime/Swift/Sources/Antlr4/FailedPredicateException.swift
index 529ce372f..5df39b506 100644
--- a/runtime/Swift/Sources/Antlr4/FailedPredicateException.swift
+++ b/runtime/Swift/Sources/Antlr4/FailedPredicateException.swift
@@ -1,12 +1,16 @@
+///
/// 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.
+///
+///
/// A semantic predicate failed during validation. Validation of predicates
/// occurs when normally parsing the alternative just like matching a token.
/// Disambiguating predicate evaluation occurs when we test a predicate during
/// prediction.
+///
public class FailedPredicateException: RecognitionException
-///
-
+/// the stream was constructed. The following is a list of initializing methods:
+///
+/// * _#LA_
+/// * _#consume_
+/// * _#size_
+///
public protocol IntStream: class {
- /// The value returned by {@link #LA LA()} when the end of the stream is
- /// reached.
- //let EOF : Int = -1;
-
- /// The value returned by {@link #getSourceName} when the actual name of the
- /// underlying source is not known.
- //let UNKNOWN_SOURCE_NAME : String = "
- ///
- ///
- /// Note that calling this method does not guarantee that {@code index()} is
+ ///
+ /// * __Forward movement:__ The value of _#index index()_
+ /// before calling this method is less than the value of `index()`
+ /// after calling this method.
+ /// * __Ordered lookahead:__ The value of `LA(1)` before
+ /// calling this method becomes the value of `LA(-1)` after calling
+ /// this method.
+ ///
+ /// Note that calling this method does not guarantee that `index()` is
/// incremented by exactly 1, as that would preclude the ability to implement
- /// filtering streams (e.g. {@link org.antlr.v4.runtime.CommonTokenStream} which distinguishes
+ /// filtering streams (e.g. _org.antlr.v4.runtime.CommonTokenStream_ which distinguishes
/// between "on-channel" and "off-channel" tokens).
- ///
- /// - IllegalStateException if an attempt is made to consume the the
- /// end of the stream (i.e. if {@code LA(1)==}{@link #EOF EOF} before calling
- /// {@code consume}).
+ ///
+ /// - throws: _ANTLRError.illegalState_ if an attempt is made to consume the the
+ /// end of the stream (i.e. if `LA(1)==`_#EOF EOF_ before calling
+ /// `consume`).
+ ///
func consume() throws
- /// Gets the value of the symbol at offset {@code i} from the current
- /// position. When {@code i==1}, this method returns the value of the current
+ ///
+ /// Gets the value of the symbol at offset `i` from the current
+ /// position. When `i==1`, this method returns the value of the current
/// symbol in the stream (which is the next symbol to be consumed). When
- /// {@code i==-1}, this method returns the value of the previously read
+ /// `i==-1`, this method returns the value of the previously read
/// symbol in the stream. It is not valid to call this method with
- /// {@code i==0}, but the specific behavior is unspecified because this
+ /// `i==0`, but the specific behavior is unspecified because this
/// method is frequently called from performance-critical code.
- ///
- ///
- ///
- ///
- ///
+ /// release the mark.
+ ///
/// IntStream stream = ...;
/// int index = -1;
/// int mark = stream.mark();
@@ -124,70 +119,78 @@ public protocol IntStream: class {
/// }
/// stream.release(mark);
/// }
- ///
- ///
+ ///
+ ///
/// - returns: An opaque marker which should be passed to
- /// {@link #release release()} when the marked range is no longer required.
+ /// _#release release()_ when the marked range is no longer required.
+ ///
func mark() -> Int
+ ///
/// This method releases a marked range created by a call to
- /// {@link #mark mark()}. Calls to {@code release()} must appear in the
- /// reverse order of the corresponding calls to {@code mark()}. If a mark is
+ /// _#mark mark()_. Calls to `release()` must appear in the
+ /// reverse order of the corresponding calls to `mark()`. If a mark is
/// released twice, or if marks are not released in reverse order of the
- /// corresponding calls to {@code mark()}, the behavior is unspecified.
- ///
- ///
- ///
- ///
- /// This operation is guaranteed to not throw an exception if {@code index}
+ /// adjust `index` forward the minimum amount required for the
+ /// operation to target a non-ignored symbol.
+ /// * `LA(1)` returns _#EOF_
+ ///
+ /// This operation is guaranteed to not throw an exception if `index`
/// lies within a marked region. For more information on marked regions, see
- /// {@link #mark}. The behavior of this method is unspecified if no call to
- /// an {@link org.antlr.v4.runtime.IntStream initializing method} has occurred after this stream
+ /// _#mark_. The behavior of this method is unspecified if no call to
+ /// an _org.antlr.v4.runtime.IntStream initializing method_ has occurred after this stream
/// was constructed.
- ///
+ ///
/// - parameter index: The absolute index to seek to.
- ///
- /// - IllegalArgumentException if {@code index} is less than 0
- /// - UnsupportedOperationException if the stream does not support
+ ///
+ /// - throws: _ANTLRError.illegalArgument_ if `index` is less than 0
+ /// - throws: _ANTLRError.unsupportedOperation_ if the stream does not support
/// seeking to the specified index
+ ///
func seek(_ index: Int) throws
+ ///
/// Returns the total number of symbols in the stream, including a single EOF
/// symbol.
- ///
- /// - UnsupportedOperationException if the size of the stream is
+ ///
+ /// - throws: _ANTLRError.unsupportedOperation_ if the size of the stream is
/// unknown.
+ ///
func size() -> Int
+ ///
/// Gets the name of the underlying symbol source. This method returns a
/// non-null, non-empty string. If such a name is not known, this method
- /// returns {@link #UNKNOWN_SOURCE_NAME}.
-
+ /// returns _#UNKNOWN_SOURCE_NAME_.
+ ///
func getSourceName() -> String
}
diff --git a/runtime/Swift/Sources/Antlr4/InterpreterRuleContext.swift b/runtime/Swift/Sources/Antlr4/InterpreterRuleContext.swift
index ea4789386..b881a94ea 100644
--- a/runtime/Swift/Sources/Antlr4/InterpreterRuleContext.swift
+++ b/runtime/Swift/Sources/Antlr4/InterpreterRuleContext.swift
@@ -1,33 +1,41 @@
+///
/// 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.
+///
-/// This class extends {@link org.antlr.v4.runtime.ParserRuleContext} by allowing the value of
-/// {@link #getRuleIndex} to be explicitly set for the context.
-///
-///
- *
- *
- * @param listener the listener to add
- *
- * @throws NullPointerException if {@code} listener is {@code null}
- */
+ ///
+ /// Registers `listener` to receive events during the parsing process.
+ ///
+ /// To support output-preserving grammar transformations (including but not
+ /// limited to left-recursion removal, automated left-factoring, and
+ /// optimized code generation), calls to listener methods during the parse
+ /// may differ substantially from calls made by
+ /// _org.antlr.v4.runtime.tree.ParseTreeWalker#DEFAULT_ used after the parse is complete. In
+ /// particular, rule entry and exit events may occur in a different order
+ /// during the parse than after the parser. In addition, calls to certain
+ /// rule entry methods may be omitted.
+ ///
+ /// With the following specific exceptions, calls to listener events are
+ /// __deterministic__, i.e. for identical input the calls to listener
+ /// methods will be the same.
+ ///
+ /// * Alterations to the grammar used to generate code may change the
+ /// behavior of the listener calls.
+ /// * Alterations to the command line options passed to ANTLR 4 when
+ /// generating the parser may change the behavior of the listener calls.
+ /// * Changing the version of the ANTLR Tool used to generate the parser
+ /// may change the behavior of the listener calls.
+ ///
+ /// - Parameter listener: the listener to add
+ ///
public func addParseListener(_ listener: ParseTreeListener) {
if _parseListeners == nil {
_parseListeners = Array
- * ParseTree t = parser.expr();
- * ParseTreePattern p = parser.compileParseTreePattern("<ID>+0", MyParser.RULE_expr);
- * ParseTreeMatch m = p.match(t);
- * String id = m.get("ID");
- *
- */
+ ///
+ /// The preferred method of getting a tree pattern. For example, here's a
+ /// sample use:
+ ///
+ ///
+ /// ParseTree t = parser.expr();
+ /// ParseTreePattern p = parser.compileParseTreePattern("<ID>+0", MyParser.RULE_expr);
+ /// ParseTreeMatch m = p.match(t);
+ /// String id = m.get("ID");
+ ///
+ ///
public func compileParseTreePattern(_ pattern: String, _ patternRuleIndex: Int) throws -> ParseTreePattern {
if let tokenStream = getTokenStream() {
let tokenSource: TokenSource = tokenStream.getTokenSource()
@@ -475,10 +479,10 @@ open class Parser: Recognizer
- * A B
- * ^
- *
- *
- * If the parser is not in error recovery mode, the consumed symbol is added
- * to the parse tree using {@link ParserRuleContext#addChild(TerminalNode)}, and
- * {@link org.antlr.v4.runtime.tree.ParseTreeListener#visitTerminal} is called on any parse listeners.
- * If the parser is in error recovery mode, the consumed symbol is
- * added to the parse tree using {@link #createErrorNode(ParserRuleContext, Token)} then
- * {@link ParserRuleContext#addErrorNode(ErrorNode)} and
- * {@link org.antlr.v4.runtime.tree.ParseTreeListener#visitErrorNode} is called on any parse
- * listeners.
- */
+ ///
+ /// Consume and return the |: #getCurrentToken current symbol:|.
+ ///
+ /// E.g., given the following input with `A` being the current
+ /// lookahead symbol, this function moves the cursor to `B` and returns
+ /// `A`.
+ ///
+ ///
+ /// A B
+ /// ^
+ ///
+ ///
+ /// If the parser is not in error recovery mode, the consumed symbol is added
+ /// to the parse tree using _ParserRuleContext#addChild(TerminalNode)_, and
+ /// _org.antlr.v4.runtime.tree.ParseTreeListener#visitTerminal_ is called on any parse listeners.
+ /// If the parser __is__ in error recovery mode, the consumed symbol is
+ /// added to the parse tree using _#createErrorNode(ParserRuleContext, Token)_ then
+ /// _ParserRuleContext#addErrorNode(ErrorNode)_ and
+ /// _org.antlr.v4.runtime.tree.ParseTreeListener#visitErrorNode_ is called on any parse
+ /// listeners.
+ ///
@discardableResult
public func consume() throws -> Token {
let o: Token = try getCurrentToken()
@@ -592,20 +596,20 @@ open class Parser: Recognizer
- * return getExpectedTokens().contains(symbol);
- *
- *
- * @param symbol the symbol type to check
- * @return {@code true} if {@code symbol} can follow the current state in
- * the ATN, otherwise {@code false}.
- */
+ ///
+ /// Checks whether or not `symbol` can follow the current state in the
+ /// ATN. The behavior of this method is equivalent to the following, but is
+ /// implemented such that the complete context-sensitive follow set does not
+ /// need to be explicitly constructed.
+ ///
+ ///
+ /// return getExpectedTokens().contains(symbol);
+ ///
+ ///
+ /// - Parameter symbol: the symbol type to check
+ /// - Returns: `true` if `symbol` can follow the current state in
+ /// the ATN, otherwise `false`.
+ ///
public func isExpectedToken(_ symbol: Int) throws -> Bool {
// return getInterpreter().atn.nextTokens(_ctx);
let atn: ATN = getInterpreter().atn
@@ -921,13 +927,13 @@ open class Parser: Recognizer
- *
- */
+ ///
+ /// A compile-time constant containing the current version of the ANTLR 4
+ /// runtime library.
+ ///
+ /// This compile-time constant value allows generated parsers and other
+ /// libraries to include a literal reference to the version of the ANTLR 4
+ /// runtime library the code was compiled against. At each release, we
+ /// change this value.
+ ///
+ /// Version numbers are assumed to have the form
+ ///
+ /// __major__.__minor__.__patch__.__revision__-__suffix__,
+ ///
+ /// with the individual components defined as follows.
+ ///
+ /// * __major__ is a required non-negative integer, and is equal to
+ /// `4` for ANTLR 4.
+ /// * __minor__ is a required non-negative integer.
+ /// * __patch__ is an optional non-negative integer. When
+ /// patch is omitted, the `.` (dot) appearing before it is
+ /// also omitted.
+ /// * __revision__ is an optional non-negative integer, and may only
+ /// be included when __patch__ is also included. When __revision__
+ /// is omitted, the `.` (dot) appearing before it is also omitted.
+ /// * __suffix__ is an optional string. When __suffix__ is
+ /// omitted, the `-` (hyphen-minus) appearing before it is also
+ /// omitted.
+ ///
public static let VERSION: String = "4.7"
- /**
- * Gets the currently executing version of the ANTLR 4 runtime library.
- *
- *
- *
- *
- *
- * TokenStream stream = ...;
- * String text = "";
- * for (int i = interval.a; i <= interval.b; i++) {
- * text += stream.get(i).getText();
- * }
- *
- *
- * @param interval The interval of tokens within this stream to get text
- * for.
- * @return The text of all tokens within the specified interval in this
- * stream.
- *
- * @throws NullPointerException if {@code interval} is {@code null}
- */
+ ///
+ /// Return the text of all tokens within the specified `interval`. This
+ /// method behaves like the following code (including potential exceptions
+ /// for violating preconditions of _#get_, but may be optimized by the
+ /// specific implementation.
+ ///
+ ///
+ /// TokenStream stream = ...;
+ /// String text = "";
+ /// for (int i = interval.a; i <= interval.b; i++) {
+ /// text += stream.get(i).getText();
+ /// }
+ ///
+ ///
+ /// - Parameter interval: The interval of tokens within this stream to get text
+ /// for.
+ /// - Returns: The text of all tokens within the specified interval in this
+ /// stream.
+ ///
+ ///
func getText(_ interval: Interval) throws -> String
- /**
- * Return the text of all tokens in the stream. This method behaves like the
- * following code, including potential exceptions from the calls to
- * {@link org.antlr.v4.runtime.IntStream#size} and {@link #getText(org.antlr.v4.runtime.misc.Interval)}, but may be
- * optimized by the specific implementation.
- *
- *
- * TokenStream stream = ...;
- * String text = stream.getText(new Interval(0, stream.size()));
- *
- *
- * @return The text of all tokens in the stream.
- */
+ ///
+ /// Return the text of all tokens in the stream. This method behaves like the
+ /// following code, including potential exceptions from the calls to
+ /// _org.antlr.v4.runtime.IntStream#size_ and _#getText(org.antlr.v4.runtime.misc.Interval)_, but may be
+ /// optimized by the specific implementation.
+ ///
+ ///
+ /// TokenStream stream = ...;
+ /// String text = stream.getText(new Interval(0, stream.size()));
+ ///
+ ///
+ /// - Returns: The text of all tokens in the stream.
+ ///
func getText() throws -> String
- /**
- * Return the text of all tokens in the source interval of the specified
- * context. This method behaves like the following code, including potential
- * exceptions from the call to {@link #getText(org.antlr.v4.runtime.misc.Interval)}, but may be
- * optimized by the specific implementation.
- *
- *
- * TokenStream stream = ...;
- * String text = stream.getText(ctx.getSourceInterval());
- *
- *
- * @param ctx The context providing the source interval of tokens to get
- * text for.
- * @return The text of all tokens within the source interval of {@code ctx}.
- */
+ ///
+ /// Return the text of all tokens in the source interval of the specified
+ /// context. This method behaves like the following code, including potential
+ /// exceptions from the call to _#getText(org.antlr.v4.runtime.misc.Interval)_, but may be
+ /// optimized by the specific implementation.
+ ///
+ /// If `ctx.getSourceInterval()` does not return a valid interval of
+ /// tokens provided by this stream, the behavior is unspecified.
+ ///
+ ///
+ /// TokenStream stream = ...;
+ /// String text = stream.getText(ctx.getSourceInterval());
+ ///
+ ///
+ /// - Parameter ctx: The context providing the source interval of tokens to get
+ /// text for.
+ /// - Returns: The text of all tokens within the source interval of `ctx`.
+ ///
func getText(_ ctx: RuleContext) throws -> String
- /**
- * Return the text of all tokens in this stream between {@code start} and
- * {@code stop} (inclusive).
- *
- *
- * TokenStream stream = ...;
- * String text = "";
- * for (int i = start.getTokenIndex(); i <= stop.getTokenIndex(); i++) {
- * text += stream.get(i).getText();
- * }
- *
- *
- * @param start The first token in the interval to get text for.
- * @param stop The last token in the interval to get text for (inclusive).
- * @return The text of all tokens lying between the specified {@code start}
- * and {@code stop} tokens.
- *
- * @throws UnsupportedOperationException if this stream does not support
- * this method for the specified tokens
- */
+ ///
+ /// Return the text of all tokens in this stream between `start` and
+ /// `stop` (inclusive).
+ ///
+ /// If the specified `start` or `stop` token was not provided by
+ /// this stream, or if the `stop` occurred before the `start`
+ /// token, the behavior is unspecified.
+ ///
+ /// For streams which ensure that the _org.antlr.v4.runtime.Token#getTokenIndex_ method is
+ /// accurate for all of its provided tokens, this method behaves like the
+ /// following code. Other streams may implement this method in other ways
+ /// provided the behavior is consistent with this at a high level.
+ ///
+ ///
+ /// TokenStream stream = ...;
+ /// String text = "";
+ /// for (int i = start.getTokenIndex(); i <= stop.getTokenIndex(); i++) {
+ /// text += stream.get(i).getText();
+ /// }
+ ///
+ ///
+ /// - Parameter start: The first token in the interval to get text for.
+ /// - Parameter stop: The last token in the interval to get text for (inclusive).
+ /// - Throws: ANTLRError.unsupportedOperation if this stream does not support
+ /// this method for the specified tokens
+ /// - Returns: The text of all tokens lying between the specified `start`
+ /// and `stop` tokens.
+ ///
+ ///
func getText(_ start: Token?, _ stop: Token?) throws -> String
}
diff --git a/runtime/Swift/Sources/Antlr4/TokenStreamRewriter.swift b/runtime/Swift/Sources/Antlr4/TokenStreamRewriter.swift
index 9423ba7b7..2a74c3681 100644
--- a/runtime/Swift/Sources/Antlr4/TokenStreamRewriter.swift
+++ b/runtime/Swift/Sources/Antlr4/TokenStreamRewriter.swift
@@ -4,82 +4,82 @@
*/
-/**
- * Useful for rewriting out a buffered input token stream after doing some
- * augmentation or other manipulations on it.
- *
- *
- * CharStream input = new ANTLRFileStream("input");
- * TLexer lex = new TLexer(input);
- * CommonTokenStream tokens = new CommonTokenStream(lex);
- * T parser = new T(tokens);
- * TokenStreamRewriter rewriter = new TokenStreamRewriter(tokens);
- * parser.startRule();
- *
- *
- *
- * Token t,u;
- * ...
- * rewriter.insertAfter(t, "text to put after t");}
- * rewriter.insertAfter(u, "text after u");}
- * System.out.println(rewriter.getText());
- *
- *
- *
- * rewriter.insertAfter("pass1", t, "text to put after t");}
- * rewriter.insertAfter("pass2", u, "text after u");}
- * System.out.println(rewriter.getText("pass1"));
- * System.out.println(rewriter.getText("pass2"));
- *
- *
- *
-///
-///
-///
-/// Basic Blocks
-///
-/// Rule
-///
-///
-///
-/// Block of 1 or more alternatives
-///
-///
-///
-/// Greedy Loops
-///
-/// Greedy Closure: {@code (...)*}
-///
-///
-///
-/// Greedy Positive Closure: {@code (...)+}
-///
-///
-///
-/// Greedy Optional: {@code (...)?}
-///
-///
-///
-/// Non-Greedy Loops
-///
-/// Non-Greedy Closure: {@code (...)*?}
-///
-///
-///
-/// Non-Greedy Positive Closure: {@code (...)+?}
-///
-///
-///
-/// Non-Greedy Optional: {@code (...)??}
-///
-///
-
+/// _org.antlr.v4.runtime.atn.ATNState#transitions_ for various grammar constructs.
+///
+///
+/// * Solid edges marked with an ε indicate a required
+/// _org.antlr.v4.runtime.atn.EpsilonTransition_.
+///
+/// * Dashed edges indicate locations where any transition derived from
+/// _org.antlr.v4.runtime.atn.Transition_ might appear.
+///
+/// * Dashed nodes are place holders for either a sequence of linked
+/// _org.antlr.v4.runtime.atn.BasicState_ states or the inclusion of a block representing a nested
+/// construct in one of the forms below.
+///
+/// * Nodes showing multiple outgoing alternatives with a `...` support
+/// any number of alternatives (one or more). Nodes without the `...` only
+/// support the exact number of alternatives shown in the diagram.
+///
+///
+/// ## Basic Blocks
+///
+/// ### Rule
+///
+///
+///
+/// ## Block of 1 or more alternatives
+///
+///
+///
+/// ## Greedy Loops
+///
+/// ### Greedy Closure: `(...)*`
+///
+///
+///
+/// ### Greedy Positive Closure: `(...)+`
+///
+///
+///
+/// ### Greedy Optional: `(...)?`
+///
+///
+///
+/// ## Non-Greedy Loops
+///
+/// ### Non-Greedy Closure: `(...)*?`
+///
+///
+///
+/// ### Non-Greedy Positive Closure: `(...)+?`
+///
+///
+///
+/// ### Non-Greedy Optional: `(...)??`
+///
+///
+///
+///
public class ATNState: Hashable, CustomStringConvertible {
public static let INITIAL_NUM_TRANSITIONS: Int = 4
@@ -100,7 +102,9 @@ public class ATNState: Hashable, CustomStringConvertible {
public static let INVALID_STATE_NUMBER: Int = -1
+ ///
/// Which ATN are we in?
+ ///
public final var atn: ATN? = nil
public final var stateNumber: Int = INVALID_STATE_NUMBER
@@ -110,11 +114,15 @@ public class ATNState: Hashable, CustomStringConvertible {
public final var epsilonOnlyTransitions: Bool = false
+ ///
/// Track the transitions emanating from this ATN state.
+ ///
internal final var transitions: Array