Merge branch 'master_upstream'

This commit is contained in:
Mike Lischke 2016-11-25 08:58:15 +01:00
commit a6161326e1
304 changed files with 51435 additions and 1059 deletions

10
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,10 @@
Before submitting an issue to ANTLR, please check off these boxes:
- [ ] I am not submitting a question on how to use ANTLR; instead, go to [antlr4-discussion google group](https://groups.google.com/forum/#!forum/antlr-discussion) or ask at [stackoverflow](http://stackoverflow.com/questions/tagged/antlr4)
- [ ] I have done a search of the existing issues to make sure I'm not sending in a duplicate
### Expected behavior
### Actual behavior
### Steps to reproduce the behavior

3
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,3 @@
Thank you for proposing a contribution to the ANTLR project. In order to accept changes from the outside world, all contributors most "sign" the [contributors.txt](https://github.com/antlr/antlr4/blob/master/contributors.txt) contributors certificate of origin. It's an unfortunate reality of today's fuzzy and bizarre world of open-source ownership.
Make sure you are already in the contributors.txt file or add a commit to this pull request with the appropriate change. Thanks!

View File

@ -1,31 +1,24 @@
sudo: true
language: java
script:
- mvn -Dparallel=methods -DthreadCount=4 install
jdk:
- oraclejdk7
- oraclejdk8
matrix:
include:
- os: linux
env: CXX=g++-5
compiler: clang
language: java
jdk: oraclejdk7
- os: osx
compiler: clang
language: java
osx_image: xcode8.1
script:
- if [[ $TRAVIS_OS_NAME == osx ]]; then cd runtime-testsuite; ../.travis/run-tests-macos.sh; fi
- if [[ $TRAVIS_OS_NAME == linux ]]; then cd runtime-testsuite; ../.travis/run-tests-linux.sh; fi
before_install:
- sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
- sudo add-apt-repository ppa:fkrull/deadsnakes -y
- sudo add-apt-repository ppa:rwky/nodejs -y
- sudo apt-get update -qq
- sudo apt-get install -qq python3.5
- sudo apt-get install -qq nodejs
- echo "deb http://download.mono-project.com/repo/debian wheezy/snapshots/3.12.1 main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
- sudo apt-get install -qq mono-complete
- eval "$(sudo gimme 1.7.3)"
- go version ; go env
- python --version
- python3 --version
env:
- CXX=g++-5
compiler:
- clang
- if [[ $TRAVIS_OS_NAME == osx ]]; then ./.travis/before-install-macos.sh; fi
- if [[ $TRAVIS_OS_NAME == linux ]]; then ./.travis/before-install-linux.sh; fi
addons:
apt:

17
.travis/before-install-linux.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
set -euo pipefail
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
sudo add-apt-repository ppa:fkrull/deadsnakes -y
sudo add-apt-repository ppa:rwky/nodejs -y
sudo apt-get update -qq
sudo apt-get install -qq python3.5
sudo apt-get install -qq nodejs
echo "deb http://download.mono-project.com/repo/debian wheezy/snapshots/3.12.1 main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
sudo apt-get install -qq mono-complete
eval "$(sudo gimme 1.7.3)"
( go version ; go env ) || true
python --version
python3 --version

17
.travis/before-install-macos.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
set -euo pipefail
thisdir=$(dirname "$0")
brew update
brew install mono python3 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() { :; }
( go version ; go env ) || true
python --version
python3 --version

10
.travis/run-tests-linux.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/bash
mvn -Dparallel=methods -DthreadCount=4 -Dtest=java.* test
mvn -Dparallel=methods -DthreadCount=4 -Dtest=csharp.* test
mvn -Dparallel=methods -DthreadCount=4 -Dtest=python2.* test
mvn -Dparallel=methods -DthreadCount=4 -Dtest=python3.* test
mvn -Dparallel=methods -DthreadCount=4 -Dtest=node.* test
mvn -Dparallel=methods -DthreadCount=4 -Dtest=go.* test
mvn -Dtest=cpp.* test # timeout due to no output for 10 min on travis if in parallel
#mvn -Dparallel=methods -DthreadCount=4 -Dtest=swift.* test

4
.travis/run-tests-macos.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
# only test swift as we develop on os x so likely well tested and its dog slow on travis
mvn -Dtest=swift.* test

View File

@ -17,6 +17,8 @@ ANTLR project lead and supreme dictator for life
* [Mike Lischke](http://www.soft-gems.net/) (C++ completed target)
* Dan McLaughlin (C++ initial target)
* David Sisson (C++ initial target and test)
* [Janyou](https://github.com/janyou) (Swift target)
* [Ewan Mellor](https://github.com/ewanmellor), [Hanzhou Shi](https://github.com/hanjoes) (Swift target merging)
## Useful information
@ -25,7 +27,7 @@ ANTLR project lead and supreme dictator for life
* [Official site](http://www.antlr.org/)
* [Documentation](https://github.com/antlr/antlr4/blob/master/doc/index.md)
* [FAQ](https://github.com/antlr/antlr4/blob/master/doc/faq/index.md)
* [ANTLR code generation targets](https://github.com/antlr/antlr4/blob/master/doc/targets.md)<br>(Currently: Java, C#, Python2|3, JavaScript, Go, C++)
* [ANTLR code generation targets](https://github.com/antlr/antlr4/blob/master/doc/targets.md)<br>(Currently: Java, C#, Python2|3, JavaScript, Go, C++, Swift)
* [Java API](http://www.antlr.org/api/Java/index.html)
* [ANTLR v3](http://www.antlr3.org/)
* [v3 to v4 Migration, differences](https://github.com/antlr/antlr4/blob/master/doc/faq/general.md)

View File

@ -48,6 +48,11 @@
<!-- Ancilliary information for completeness -->
<inceptionYear>2009</inceptionYear>
<properties>
<mavenVersion>3.3.9</mavenVersion>
<takariLifecycleVersion>1.11.12</takariLifecycleVersion>
</properties>
<!-- ============================================================================= -->
<!-- What are we depedent on for the Mojos to execute? We need the plugin
@ -63,11 +68,6 @@
<version>3.0.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-api</artifactId>
@ -93,21 +93,50 @@
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-plugin-testing-harness</artifactId>
<version>1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.takari.maven.plugins</groupId>
<artifactId>takari-plugin-testing</artifactId>
<version>2.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>${mavenVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>${mavenVersion}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>3.0.15</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
<build>
<testSourceDirectory>src/test</testSourceDirectory>
<testResources>
<testResource>
<directory>src/test/resources</directory>
</testResource>
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@ -132,6 +161,21 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>io.takari.maven.plugins</groupId>
<artifactId>takari-lifecycle-plugin</artifactId>
<version>${takariLifecycleVersion}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>testProperties</id>
<phase>process-test-resources</phase>
<goals>
<goal>testProperties</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

View File

@ -59,6 +59,7 @@ import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -190,6 +191,12 @@ public class Antlr4Mojo extends AbstractMojo {
@Parameter(defaultValue = "${basedir}/src/main/antlr4/imports")
private File libDirectory;
/**
* The directory where build status information is located.
*/
@Parameter(defaultValue = "${project.build.directory}/maven-status/antlr4", readonly=true)
private File statusDirectory;
@Component
private BuildContext buildContext;
@ -228,6 +235,8 @@ public class Antlr4Mojo extends AbstractMojo {
Log log = getLog();
outputEncoding = validateEncoding(outputEncoding);
if (log.isDebugEnabled()) {
for (String e : excludes) {
log.debug("ANTLR: Exclude: " + e);
@ -255,16 +264,22 @@ public class Antlr4Mojo extends AbstractMojo {
outputDir.mkdirs();
}
GrammarDependencies dependencies = new GrammarDependencies(sourceDirectory, libDirectory, arguments, getDependenciesStatusFile(), getLog());
// Now pick up all the files and process them with the Tool
//
List<List<String>> argumentSets;
Set<File> grammarFiles;
Set<File> importGrammarFiles;
try {
List<String> args = getCommandArguments();
argumentSets = processGrammarFiles(args, sourceDirectory);
} catch (InclusionScanException ie) {
log.error(ie);
throw new MojoExecutionException("Fatal error occured while evaluating the names of the grammar files to analyze", ie);
grammarFiles = getGrammarFiles(sourceDirectory);
importGrammarFiles = getImportFiles(sourceDirectory);
argumentSets = processGrammarFiles(args, grammarFiles, dependencies, sourceDirectory);
} catch (Exception e) {
log.error(e);
throw new MojoExecutionException("Fatal error occured while evaluating the names of the grammar files to analyze", e);
}
log.debug("Output directory base will be " + outputDirectory.getAbsolutePath());
@ -278,6 +293,14 @@ public class Antlr4Mojo extends AbstractMojo {
throw new MojoFailureException("Error creating an instanceof the ANTLR tool.", e);
}
try {
dependencies.analyze(grammarFiles, importGrammarFiles, tool);
} catch (Exception e) {
log.error("Dependency analysis failed, see exception report for details",
e);
throw new MojoFailureException("Dependency analysis failed.", e);
}
// Set working directory for ANTLR to be the base source directory
tool.inputDirectory = sourceDirectory;
@ -294,6 +317,12 @@ public class Antlr4Mojo extends AbstractMojo {
// Tell Maven that there are some new source files underneath the output directory.
addSourceRoot(this.getOutputDirectory());
}
try {
dependencies.save();
} catch (IOException ex) {
log.warn("Could not save grammar dependency status", ex);
}
}
private List<String> getCommandArguments() {
@ -316,8 +345,9 @@ public class Antlr4Mojo extends AbstractMojo {
args.add("-atn");
}
if ( inputEncoding!= null && !inputEncoding.isEmpty()) {
if ( inputEncoding!=null && !inputEncoding.isEmpty()) {
args.add("-encoding");
outputEncoding = inputEncoding;
args.add(inputEncoding);
}
@ -361,22 +391,11 @@ public class Antlr4Mojo extends AbstractMojo {
* @param sourceDirectory
* @exception InclusionScanException
*/
private List<List<String>> processGrammarFiles(List<String> args, File sourceDirectory) throws InclusionScanException {
// Which files under the source set should we be looking for as grammar files
SourceMapping mapping = new SuffixMapping("g4", Collections.<String>emptySet());
// What are the sets of includes (defaulted or otherwise).
Set<String> includes = getIncludesPatterns();
// Now, to the excludes, we need to add the imports directory
// as this is autoscanned for imported grammars and so is auto-excluded from the
// set of grammar fields we should be analyzing.
excludes.add("imports/**");
SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes, excludes);
scan.addSourceMapping(mapping);
Set<File> grammarFiles = scan.getIncludedSources(sourceDirectory, null);
private List<List<String>> processGrammarFiles(
List<String> args,
Set<File> grammarFiles,
GrammarDependencies dependencies,
File sourceDirectory) throws InclusionScanException, IOException {
// We don't want the plugin to run for every grammar, regardless of whether
// it's changed since the last compilation. Check the mtime of the tokens vs
@ -387,7 +406,8 @@ 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);
}
}
@ -411,7 +431,7 @@ public class Antlr4Mojo extends AbstractMojo {
getLog().debug("Grammar file '" + grammarFile.getPath() + "' detected.");
String relPathBase = findSourceSubdir(sourceDirectory, grammarFile.getPath());
String relPathBase = MojoUtils.findSourceSubdir(sourceDirectory, grammarFile);
String relPath = relPathBase + grammarFile.getName();
getLog().debug(" ... relative path is: " + relPath);
@ -436,6 +456,39 @@ public class Antlr4Mojo extends AbstractMojo {
return result;
}
private Set<File> getImportFiles(File sourceDirectory) throws InclusionScanException {
if (!libDirectory.exists()) return Collections.emptySet();
Set<String> includes = new HashSet<String>();
includes.add("*.g4");
includes.add("*.tokens");
SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes,
Collections.<String>emptySet());
scan.addSourceMapping(new SuffixMapping("G4", "g4"));
return scan.getIncludedSources(libDirectory, null);
}
private Set<File> getGrammarFiles(File sourceDirectory) throws InclusionScanException
{
// Which files under the source set should we be looking for as grammar files
SourceMapping mapping = new SuffixMapping("g4", Collections.<String>emptySet());
// What are the sets of includes (defaulted or otherwise).
Set<String> includes = getIncludesPatterns();
// Now, to the excludes, we need to add the imports directory
// as this is autoscanned for imported grammars and so is auto-excluded from the
// set of grammar fields we should be analyzing.
excludes.add("imports/**");
SourceInclusionScanner scan = new SimpleSourceInclusionScanner(includes, excludes);
scan.addSourceMapping(mapping);
return scan.getIncludedSources(sourceDirectory, null);
}
private static String getPackageName(String relativeFolderPath) {
if (relativeFolderPath.contains("..")) {
throw new UnsupportedOperationException("Cannot handle relative paths containing '..'");
@ -456,30 +509,14 @@ public class Antlr4Mojo extends AbstractMojo {
return includes;
}
/**
* Given the source directory File object and the full PATH to a grammar,
* produce the path to the named grammar file in relative terms to the
* {@code sourceDirectory}. This will then allow ANTLR to produce output
* relative to the base of the output directory and reflect the input
* organization of the grammar files.
*
* @param sourceDirectory The source directory {@link File} object
* @param grammarFileName The full path to the input grammar file
* @return The path to the grammar file relative to the source directory
*/
private String findSourceSubdir(File sourceDirectory, String grammarFileName) {
String srcPath = sourceDirectory.getPath() + File.separator;
private File getDependenciesStatusFile() {
File statusFile = new File(statusDirectory, "dependencies.ser");
if (!grammarFileName.startsWith(srcPath)) {
throw new IllegalArgumentException("expected " + grammarFileName + " to be prefixed with " + sourceDirectory);
if (!statusFile.getParentFile().exists()) {
statusFile.getParentFile().mkdirs();
}
File unprefixedGrammarFileName = new File(grammarFileName.substring(srcPath.length()));
if (unprefixedGrammarFileName.getParent() == null) {
return "";
}
return unprefixedGrammarFileName.getParent() + File.separator;
return statusFile;
}
private final class CustomTool extends Tool {
@ -521,7 +558,21 @@ public class Antlr4Mojo extends AbstractMojo {
URI relativePath = project.getBasedir().toURI().relativize(outputFile.toURI());
getLog().debug(" Writing file: " + relativePath);
OutputStream outputStream = buildContext.newFileOutputStream(outputFile);
return new BufferedWriter(new OutputStreamWriter(outputStream, outputEncoding));
if ( outputEncoding!=null && !outputEncoding.isEmpty()) {
return new BufferedWriter(new OutputStreamWriter(outputStream, outputEncoding));
}
else {
return new BufferedWriter(new OutputStreamWriter(outputStream));
}
}
}
/**
* Validates the given encoding.
*
* @return the validated encoding. If {@code null} was provided, returns the platform default encoding.
*/
private String validateEncoding(String encoding) {
return (encoding == null) ? Charset.defaultCharset().name() : Charset.forName(encoding.trim()).name();
}
}

View File

@ -0,0 +1,311 @@
package org.antlr.mojo.antlr4;
import org.antlr.runtime.tree.Tree;
import org.antlr.v4.Tool;
import org.antlr.v4.misc.Graph;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.tool.ast.GrammarAST;
import org.antlr.v4.tool.ast.GrammarRootAST;
import org.apache.maven.plugin.logging.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
class GrammarDependencies {
private final Graph<String> graph = new Graph<String>();
private final File sourceDirectory;
private final File libDirectory;
private final File statusFile;
private final String packageName;
/** Map grammars to their checksum and references. */
private final Map<File, Map.Entry<byte[], Collection<String>>> grammars;
private final Log log;
public GrammarDependencies(File sourceDirectory, File libDirectory,
List<String> arguments, File status, Log log) {
this.log = log;
this.sourceDirectory = sourceDirectory;
this.libDirectory = libDirectory;
this.statusFile = status;
this.grammars = loadStatus(status);
this.packageName = getPackage(arguments);
}
/**
* Determines the package to use.
*
* @param arguments the tool arguments.
*
* @return the package. Returns {@code null} to indicate that no package should be
* used.
*/
private String getPackage(List<String> arguments) {
int index = (arguments != null) ? arguments.indexOf("-package") : -1;
return (index > -1)
? (arguments.get(index + 1).replace('.', File.separatorChar) +
File.separatorChar)
: null;
}
public void save() throws IOException {
if (!grammars.isEmpty()) {
log.debug("Persisting grammars dependency status: " + statusFile);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(
statusFile));
try {
out.writeObject(grammars);
} finally {
out.close();
}
}
}
/**
* Performs dependency analysis for the given grammar files.
*
* @param grammarFiles the grammar files.
* @param importGrammarFiles the import grammar files.
* @param tool the tool to use.
*
* @return self-reference.
*/
public GrammarDependencies analyze(Set<File> grammarFiles,
Set<File> importGrammarFiles, Tool tool) throws IOException {
log.debug("Analysing grammar dependencies " + sourceDirectory);
// for dependency analysis we require all grammars
Collection<File> grammarsAndTokens = new HashSet<File>();
grammarsAndTokens.addAll(importGrammarFiles);
grammarsAndTokens.addAll(grammarFiles);
for (File grammarFile : grammarsAndTokens) {
// .tokens files must not be parsed, they can just be referenced
if (!grammarFile.getName().endsWith(".tokens"))
analyse(grammarFile, grammarsAndTokens, tool);
}
for (File grammarFile : grammarFiles) {
Collection<String> usages = findUsages(getRelativePath(grammarFile));
if (!usages.isEmpty()) {
grammars.put(grammarFile,
new AbstractMap.SimpleImmutableEntry<byte[], Collection<String>>(
MojoUtils.checksum(grammarFile), usages));
log.debug(" " + getRelativePath(grammarFile) + " used by " + usages);
}
}
for (File grammarFile : importGrammarFiles) {
// imported files are not allowed to be qualified
Collection<String> usages = findUsages(grammarFile.getName());
if (!usages.isEmpty()) {
grammars.put(grammarFile,
new AbstractMap.SimpleImmutableEntry<byte[], Collection<String>>(
MojoUtils.checksum(grammarFile), usages));
log.debug(" " + grammarFile.getName() + " imported by " + usages);
}
}
return this;
}
/**
* Determines whether a grammar used by the given grammar was modified since the last
* build.
*
* @param grammarFile the grammar.
*
* @return {@code true} if a grammar used by the given grammar has been modified.
*/
public boolean isDependencyChanged(File grammarFile) throws IOException {
String grammarPath = getRelativePath(grammarFile);
for (Map.Entry<File, Map.Entry<byte[], Collection<String>>> e : grammars.entrySet()) {
File depGrammarFile = e.getKey();
byte[] checksum = e.getValue().getKey();
Collection<String> usages = e.getValue().getValue();
if (usages.contains(grammarPath)) {
if (!depGrammarFile.exists() || !Arrays.equals(MojoUtils.checksum(depGrammarFile), checksum)) {
log.debug(" " + grammarPath + ": dependency " +
depGrammarFile.getName() + " changed");
return true;
}
}
}
return false;
}
/**
* Determines the relative target path of the given grammar file.
*
* @param grammarFile the grammar file.
*
* @return the relative path.
*/
private String getRelativePath(File grammarFile) {
// the library directory does not allow sub-directories
if (grammarFile.getPath().startsWith(libDirectory.getPath()))
return grammarFile.getName();
// if a package is given, we have to use it
if (packageName != null)
return packageName + grammarFile.getName();
// otherwise resolve the path relative to the source directory
String path = MojoUtils.findSourceSubdir(sourceDirectory, grammarFile);
return path + grammarFile.getName();
}
/**
* Returns the grammar file names that directly or indirectly use the given grammar.
*
* @param grammarFileName the grammar file name.
*
* @return the grammar file names that use the given grammar file.
*/
private Collection<String> findUsages(String grammarFileName) {
Collection<String> result = new ArrayList<String>();
explore(grammarFileName, result);
return result;
}
private void explore(String grammarName, Collection<String> result) {
for (Graph.Node<String> node : graph.getNode(grammarName).edges) {
result.add(node.payload);
explore(node.payload, result);
}
}
private void analyse(File grammarFile, Collection<File> grammarFiles, Tool tool) {
GrammarRootAST grammar = tool.parseGrammar(grammarFile.getAbsolutePath());
if (grammar == null)
return;
for (GrammarAST importDecl : grammar.getAllChildrenWithType(ANTLRParser.IMPORT)) {
Tree id = importDecl.getFirstChildWithType(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);
graph.addEdge(id.getText() + ".g4", grammarPath);
}
}
for (GrammarAST options : grammar.getAllChildrenWithType(ANTLRParser.OPTIONS)) {
for (int i = 0, count = options.getChildCount(); i < count; i++) {
Tree option = options.getChild(i);
if (option.getType() == ANTLRParser.ASSIGN) {
String key = option.getChild(0).getText();
String value = option.getChild(1).getText();
if ("tokenVocab".equals(key)) {
String name = stripQuotes(value);
// the grammar name may be qualified, but we resolve the path anyway
String grammarName = stripPath(name);
String grammarPath = MojoUtils.findSourceSubdir(sourceDirectory,
grammarFile);
File depGrammarFile = resolve(grammarName, grammarPath);
// if a package has been given, we use it instead of the file directory path
// (files probably reside in the root directory anyway with such a configuration )
if (packageName != null)
grammarPath = packageName;
graph.addEdge(getRelativePath(depGrammarFile),
grammarPath + grammarFile.getName());
}
}
}
}
}
/**
* Resolves the given grammar name.
*
* @param name the name.
* @param path the relative path.
*
* @return the grammar file.
*/
private File resolve(String name, String path) {
File file = new File(sourceDirectory, path + name + ".g4");
if (file.exists())
return file;
file = new File(libDirectory, name + ".g4");
if (file.exists())
return file;
return new File(libDirectory, name + ".tokens");
}
private Map<File, Map.Entry<byte[], Collection<String>>> loadStatus(File statusFile) {
if (statusFile.exists()) {
log.debug("Load grammars dependency status: " + statusFile);
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(
statusFile));
try {
@SuppressWarnings("unchecked")
Map<File, Map.Entry<byte[], Collection<String>>> data =
(Map<File, Map.Entry<byte[], Collection<String>>>)
in.readObject();
return data;
} finally {
in.close();
}
} catch (Exception ex) {
log.warn("Could not load grammar dependency status information", ex);
}
}
return new HashMap<File, Map.Entry<byte[], Collection<String>>>();
}
private String stripPath(String str) {
return str.replaceAll("^.*[/\\\\]", "");
}
private String stripQuotes(String str) {
return str.replaceAll("\\A'|'\\Z", "");
}
}

View File

@ -0,0 +1,74 @@
package org.antlr.mojo.antlr4;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
class MojoUtils {
/**
* Creates the MD5 checksum for the given file.
*
* @param file the file.
*
* @return the checksum.
*/
public static byte[] checksum(File file) throws IOException {
try {
InputStream in = new FileInputStream(file);
byte[] buffer = new byte[2048];
MessageDigest complete = MessageDigest.getInstance("MD5");
try {
int n;
do {
n = in.read(buffer);
if (n > 0) {
complete.update(buffer, 0, n);
}
} while (n != -1);
} finally {
in.close();
}
return complete.digest();
} catch (NoSuchAlgorithmException ex) {
throw new IOException("Could not create checksum " + file, ex);
}
}
/**
* Given the source directory File object and the full PATH to a grammar, produce the
* path to the named grammar file in relative terms to the {@code sourceDirectory}.
* This will then allow ANTLR to produce output relative to the base of the output
* directory and reflect the input organization of the grammar files.
*
* @param sourceDirectory The source directory {@link File} object
* @param grammarFileName The full path to the input grammar file
*
* @return The path to the grammar file relative to the source directory
*/
public static String findSourceSubdir(File sourceDirectory, File grammarFile) {
String srcPath = sourceDirectory.getPath() + File.separator;
String path = grammarFile.getPath();
if (!path.startsWith(srcPath)) {
throw new IllegalArgumentException("expected " + path +
" to be prefixed with " + sourceDirectory);
}
File unprefixedGrammarFileName = new File(path.substring(srcPath.length()));
if (unprefixedGrammarFileName.getParent() == null) {
return "";
}
return unprefixedGrammarFileName.getParent() + File.separator;
}
}

View File

@ -0,0 +1,356 @@
package org.antlr.mojo.antlr4;
import io.takari.maven.testing.TestMavenRuntime;
import io.takari.maven.testing.TestResources;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import static org.junit.Assert.*;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
public class Antlr4MojoTest {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Rule
public final TestResources resources = new TestResources();
@Rule
public final TestMavenRuntime maven = new TestMavenRuntime();
@Test
public void importTokens() throws Exception {
Path baseDir = resources.getBasedir("importTokens").toPath();
Path antlrDir = baseDir.resolve("src/main/antlr4");
Path generatedSources = baseDir.resolve("target/generated-sources/antlr4");
Path genParser = generatedSources.resolve("test/SimpleParser.java");
Path tokens = antlrDir.resolve("imports/SimpleLexer.tokens");
MavenProject project = maven.readMavenProject(baseDir.toFile());
MavenSession session = maven.newMavenSession(project);
MojoExecution exec = maven.newMojoExecution("antlr4");
////////////////////////////////////////////////////////////////////////
// 1st - all grammars have to be processed
////////////////////////////////////////////////////////////////////////
assertFalse(Files.exists(genParser));
maven.executeMojo(session, project, exec);
assertTrue(Files.exists(genParser));
////////////////////////////////////////////////////////////////////////
// 2nd - nothing has been modified, no grammars have to be processed
////////////////////////////////////////////////////////////////////////
{
byte[] sum = checksum(genParser);
maven.executeMojo(session, project, exec);
assertTrue(Arrays.equals(sum, checksum(genParser)));
}
////////////////////////////////////////////////////////////////////////
// 3rd - the imported grammar changed, every dependency has to be processed
////////////////////////////////////////////////////////////////////////
try(Change change = Change.of(tokens, "DOT=4")) {
byte[] sum = checksum(genParser);
maven.executeMojo(session, project, exec);
assertFalse(Arrays.equals(sum, checksum(genParser)));
}
}
@Test
public void importsCustomLayout() throws Exception {
Path baseDir = resources.getBasedir("importsCustom").toPath();
Path antlrDir = baseDir.resolve("src/main/antlr4");
Path generatedSources = baseDir.resolve("src/main/java");
Path genTestLexer = generatedSources.resolve("foo/TestLexer.java");
Path genTestParser = generatedSources.resolve("foo/TestParser.java");
Path genHello = generatedSources.resolve("foo/HelloParser.java");
Path baseGrammar = antlrDir.resolve("imports/TestBaseLexer.g4");
Path lexerGrammar = antlrDir.resolve("TestLexer.g4");
Path parserGrammar = antlrDir.resolve("TestParser.g4");
Xpp3Dom outputDirectory = TestMavenRuntime.newParameter("outputDirectory",
"src/main/java/foo");
Xpp3Dom arguments = new Xpp3Dom("arguments");
arguments.addChild(TestMavenRuntime.newParameter("argument", "-package"));
arguments.addChild(TestMavenRuntime.newParameter("argument", "foo"));
MavenProject project = maven.readMavenProject(baseDir.toFile());
MavenSession session = maven.newMavenSession(project);
MojoExecution exec = maven.newMojoExecution("antlr4", outputDirectory, arguments);
////////////////////////////////////////////////////////////////////////
// 1st - all grammars have to be processed
////////////////////////////////////////////////////////////////////////
assertFalse(Files.exists(genHello));
assertFalse(Files.exists(genTestParser));
assertFalse(Files.exists(genTestLexer));
maven.executeMojo(session, project, exec);
assertTrue(Files.exists(genHello));
assertTrue(Files.exists(genTestParser));
assertTrue(Files.exists(genTestLexer));
////////////////////////////////////////////////////////////////////////
// 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)));
}
////////////////////////////////////////////////////////////////////////
// 3rd - the imported grammar changed, every dependency has to be processed
////////////////////////////////////////////////////////////////////////
// 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)));
}
////////////////////////////////////////////////////////////////////////
// 4th - 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, "fragment 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)));
}
////////////////////////////////////////////////////////////////////////
// 5th - 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)));
}
}
@Test
public void importsStandardLayout() throws Exception {
Path baseDir = resources.getBasedir("importsStandard").toPath();
Path antlrDir = baseDir.resolve("src/main/antlr4");
Path generatedSources = baseDir.resolve("target/generated-sources/antlr4");
Path genTestLexer = generatedSources.resolve("test/TestLexer.java");
Path genTestParser = generatedSources.resolve("test/TestParser.java");
Path genHello = generatedSources.resolve("test/HelloParser.java");
Path baseGrammar = antlrDir.resolve("imports/TestBaseLexer.g4");
Path lexerGrammar = antlrDir.resolve("test/TestLexer.g4");
Path parserGrammar = antlrDir.resolve("test/TestParser.g4");
MavenProject project = maven.readMavenProject(baseDir.toFile());
MavenSession session = maven.newMavenSession(project);
MojoExecution exec = maven.newMojoExecution("antlr4");
////////////////////////////////////////////////////////////////////////
// 1st - all grammars have to be processed
////////////////////////////////////////////////////////////////////////
assertFalse(Files.exists(genHello));
assertFalse(Files.exists(genTestParser));
assertFalse(Files.exists(genTestLexer));
maven.executeMojo(session, project, exec);
assertTrue(Files.exists(genHello));
assertTrue(Files.exists(genTestParser));
assertTrue(Files.exists(genTestLexer));
////////////////////////////////////////////////////////////////////////
// 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)));
}
////////////////////////////////////////////////////////////////////////
// 3rd - the imported grammar changed, every dependency has to be processed
////////////////////////////////////////////////////////////////////////
// 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)));
}
////////////////////////////////////////////////////////////////////////
// 4th - 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)) {
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)));
}
////////////////////////////////////////////////////////////////////////
// 5th - 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)));
}
}
@Test
public void processWhenDependencyRemoved() throws Exception {
Path baseDir = resources.getBasedir("dependencyRemoved").toPath();
Path antlrDir = baseDir.resolve("src/main/antlr4");
Path baseGrammar = antlrDir.resolve("imports/HelloBase.g4");
MavenProject project = maven.readMavenProject(baseDir.toFile());
MavenSession session = maven.newMavenSession(project);
MojoExecution exec = maven.newMojoExecution("antlr4");
maven.executeMojo(session, project, exec);
try(Change temp = Change.of(baseGrammar)) {
// if the base grammar no longer exists, processing must be performed
Files.delete(baseGrammar);
thrown.expect(MojoExecutionException.class);
thrown.expectMessage("ANTLR 4 caught 1 build errors.");
maven.executeMojo(session, project, exec);
}
}
private byte[] checksum(Path path) throws IOException {
return MojoUtils.checksum(path.toFile());
}
private static class Change implements AutoCloseable {
final Path file;
final byte[] original;
public Change(Path file, String change) {
this.file = file;
try {
original = Files.readAllBytes(file);
} catch (IOException ex) {
throw new RuntimeException("Could not read file " + file);
}
String text = new String(original, StandardCharsets.UTF_8) + change;
write(file, text.getBytes(StandardCharsets.UTF_8));
}
private void write(Path file, byte[] data) {
try {
Files.write(file, data);
} catch (IOException ex) {
throw new RuntimeException("Could not write file " + file);
}
}
public static Change of(Path file, String change) {
return new Change(file, change);
}
public static Change of(Path file) {
return new Change(file, "\n");
}
@Override
public void close() {
write(file, original);
}
}
}

View File

@ -0,0 +1,27 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>deps.removed</groupId>
<artifactId>depRemoved</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test processing after dependency removed</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>antlr4-maven-plugin</artifactId>
<configuration>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,16 @@
lexer grammar TestBaseLexer;
tokens { Name }
// Default "mode": Everything OUTSIDE of a tag
Comment : '<!--' .*? '-->' ;
CDSect : '<![CDATA[' .*? ']]>' ;
fragment
Whitespace : ' ' | '\n' | '\t' | '\r' ;
fragment
Hexdigit : [a-fA-F0-9] ;
fragment
Digit : [0-9] ;

View File

@ -0,0 +1,7 @@
grammar Hello;
import HelloBase;
r : 'hello' ID ;
ID : [a-z]+ ;
WS : [ \r\t\n]+ -> skip ;

View File

@ -0,0 +1,27 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>import.tokens</groupId>
<artifactId>importTokens</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test importing tokens file</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>antlr4-maven-plugin</artifactId>
<configuration>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,8 @@
parser grammar SimpleParser;
options {
// get token types from SimpleLexer.tokens; don't name it
// SimpleParser.tokens as ANTLR will overwrite!
tokenVocab=SimpleLexer;
}
s : ( ID | INT )* SEMI ;

View File

@ -0,0 +1,42 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>imports.custom</groupId>
<artifactId>importsCustom</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test importing, custom layout</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>antlr4-maven-plugin</artifactId>
<configuration>
<outputDirectory>${basedir}/src/main/java/com/foo</outputDirectory>
<arguments>
<argument>-visitor</argument>
<argument>-no-listener</argument>
<argument>-Xlog</argument>
<argument>-package</argument>
<argument>com.foo</argument>
</arguments>
</configuration>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,4 @@
grammar Hello;
r : 'hello' ID ;
ID : [a-z]+ ;
WS : [ \r\t\n]+ -> skip ;

View File

@ -0,0 +1,6 @@
lexer grammar TestLexer;
import TestBaseLexer;
WS : Whitespace+ -> skip;
TEXT : ~[<&]+ ; // match any 16 bit char other than < and &

View File

@ -0,0 +1,5 @@
parser grammar TestParser;
options { tokenVocab=TestLexer; }
document : (Comment | Name) EOF ;

View File

@ -0,0 +1,16 @@
lexer grammar TestBaseLexer;
tokens { Name }
// Default "mode": Everything OUTSIDE of a tag
Comment : '<!--' .*? '-->' ;
CDSect : '<![CDATA[' .*? ']]>' ;
fragment
Whitespace : ' ' | '\n' | '\t' | '\r' ;
fragment
Hexdigit : [a-fA-F0-9] ;
fragment
Digit : [0-9] ;

View File

@ -0,0 +1,27 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>imports.standard</groupId>
<artifactId>importsStandard</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Test importing, standard layout</name>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>antlr4-maven-plugin</artifactId>
<configuration>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,16 @@
lexer grammar TestBaseLexer;
tokens { Name }
// Default "mode": Everything OUTSIDE of a tag
Comment : '<!--' .*? '-->' ;
CDSect : '<![CDATA[' .*? ']]>' ;
fragment
Whitespace : ' ' | '\n' | '\t' | '\r' ;
fragment
Hexdigit : [a-fA-F0-9] ;
fragment
Digit : [0-9] ;

View File

@ -0,0 +1,4 @@
grammar Hello;
r : 'hello' ID ;
ID : [a-z]+ ;
WS : [ \r\t\n]+ -> skip ;

View File

@ -0,0 +1,6 @@
lexer grammar TestLexer;
import TestBaseLexer;
WS : Whitespace+ -> skip;
TEXT : ~[<&]+ ; // match any 16 bit char other than < and &

View File

@ -0,0 +1,5 @@
parser grammar TestParser;
options { tokenVocab=TestLexer; }
document : (Comment | Name) EOF ;

8
appveyor.yml Normal file
View File

@ -0,0 +1,8 @@
version: '4.6-SNAPSHOT+AppVeyor.{build}'
os: Windows Server 2012
build_script:
- mvn -DskipTests install -q --batch-mode
test_script:
- mvn install -q -Dantlr-python2-python="C:\Python27\python.exe" -Dantlr-python3-python="C:\Python35\python.exe" -Dantlr-javascript-nodejs="C:\Program Files (x86)\nodejs\node.exe" --batch-mode
build:
verbosity: minimal

View File

@ -1,4 +1,4 @@
ANTLR Project Contributors Certification of Origin and Rights
ANTLR Project Contributors Certification of Origin and Rights
All contributors to ANTLR v4 must formally agree to abide by this
certificate of origin by signing on the bottom with their github
@ -114,3 +114,7 @@ YYYY/MM/DD, github id, Full name, email
2016/11/06, NoodleOfDeath, Thom Morgan, github@bytemeapp.com
2016/11/01, sebkur, Sebastian Kürten, sebastian@topobyte.de
2016/04/13, renatahodovan, Renata Hodovan, reni@inf.u-szeged.hu
2016/11/05, ewanmellor, Ewan Mellor, github@ewanmellor.org
2016/11/06, janyou, Janyou, janyou.antlr@outlook.com
2016/11/20, marcohu, Marco Hunsicker, antlr@hunsicker.de
2016/09/02, lygav, Vladimir (Vladi) Lyga, lyvladi@gmail.com

View File

@ -7,6 +7,8 @@ Most programmers do not need the information on this page because they will simp
I will assume that the root directory is `/tmp` for the purposes of explaining how to build ANTLR in this document.
*As of 4.6, ANTLR tool and Java-target runtime requires Java 7.*
# Get the source
The first step is to get the Java source code from the ANTLR 4 repository at github. You can download the repository from github, but the easiest thing to do is simply clone the repository on your local disk:
@ -36,36 +38,49 @@ Receiving objects: 100% (59858/59858), 31.10 MiB | 819.00 KiB/s, done.
Resolving deltas: 100% (31898/31898), done.
Checking connectivity... done.
$ cd antlr4
$ mvn compile
..
$ mvn -DskipTests install
...
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] ANTLR 4 ............................................ SUCCESS [ 0.432 s]
[INFO] ANTLR 4 Runtime .................................... SUCCESS [ 4.334 s]
[INFO] ANTLR 4 Tool ....................................... SUCCESS [ 1.686 s]
[INFO] ANTLR 4 Maven plugin ............................... SUCCESS [ 1.654 s]
[INFO] ANTLR 4 Runtime Test Annotations ................... SUCCESS [ 0.096 s]
[INFO] ANTLR 4 Runtime Test Processors .................... SUCCESS [ 0.025 s]
[INFO] ANTLR 4 Runtime Tests (2nd generation) ............. SUCCESS [ 1.932 s]
[INFO] ANTLR 4 Tool Tests ................................. SUCCESS [ 0.018 s]
[INFO] ANTLR 4 ............................................ SUCCESS [ 0.287 s]
[INFO] ANTLR 4 Runtime .................................... SUCCESS [ 4.915 s]
[INFO] ANTLR 4 Tool ....................................... SUCCESS [ 1.315 s]
[INFO] ANTLR 4 Maven plugin ............................... SUCCESS [ 2.393 s]
[INFO] ANTLR 4 Runtime Test Annotations ................... SUCCESS [ 0.078 s]
[INFO] ANTLR 4 Runtime Test Processors .................... SUCCESS [ 0.019 s]
[INFO] ANTLR 4 Runtime Tests (2nd generation) ............. SUCCESS [ 1.986 s]
[INFO] ANTLR 4 Tool Tests ................................. SUCCESS [ 0.513 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.324 s
[INFO] Finished at: 2016-11-16T13:49:38-08:00
[INFO] Final Memory: 42M/488M
[INFO] Total time: 12.005 s
[INFO] Finished at: 2016-11-21T11:42:42-08:00
[INFO] Final Memory: 52M/434M
[INFO] ------------------------------------------------------------------------
```
We do `install` not `compile` as tool tests and such refer to modules that must be pulled from the maven install local cache.
# Installing libs to mvn cache locally
To skip the tests (which require all the target languages be installed) and **install into local repository** `~/.m2/repository/org/antlr`, do this:
```bash
$ mvn install -DskipTests=true # make sure all artifacts are visible on this machine
```
# Testing tool and targets
In order to perform the tests on all target languages, make sure that you have `mono` and `nodejs` installed. For example, on OS X:
In order to perform the tests on all target languages, you need to have the following languages installed:
```bash
$ brew install mono
$ brew install node
```
* `mono` (e.g., `brew install mono`)
* `nodejs`
* Python 2.7
* Python 3.5
* Go
* Swift 3 (via XCode 8.x) tested currently only osx
* clang (for C++ target)
To run the tests and **install into local repository** `~/.m2/repository/org/antlr`, do this:

113
doc/swift-target.md Normal file
View File

@ -0,0 +1,113 @@
# ANTLR4 Language Target, Runtime for Swift
### Usage
#### 1. Install ANTLR4
[The getting started guide](getting-started.md) should get you started.
#### 2. create a Swift lexer or parser
This is pretty much the same as creating a Java lexer or parser, except you need to specify the language target, for example:
```
$ antlr4 -Dlanguage=Swift MyGrammar.g4
```
For a full list of antlr4 tool options, please visit the [tool documentation page](tool-options.md).
#### 3. Get the Swift ANTLR runtime
You will find Swift runtime (framework project) in
```
antlr4/runtime/Swift
```
#### 4. Example
The example from [here](https://github.com/janyou/Antlr-Swift-Runtime/tree/master/Test)
(1). Hello.g4
```
grammar Hello;
r : 'hello' ID ;
ID : [a-z]+ ;
WS : [ \t\r\n]+ -> skip ;
```
(2). generate lexer/parser/visitor from Hello.g4 file
```
$ antlr4 -Dlanguage=Swift -visitor -o gen Hello.g4
```
in gen folder
```
Hello.tokens
HelloBaseListener.swift
HelloBaseVisitor.swift
HelloLexer.swift
HelloLexer.tokens
HelloLexerATN.swift
HelloListener.swift
HelloParser.swift
HelloParserATN.swift
HelloVisitor.swift
```
(3). make a custom listener
```
public class HelloWalker: HelloBaseListener{
public override func enterR(_ ctx: HelloParser.RContext) {
print( "enterR: " + ((ctx.ID()?.getText()) ?? ""))
}
public override func exitR(_ ctx: HelloParser.RContext) {
print( "exitR ")
}
}
```
(4). call and run
add TestHello.txt
```
hello world
```
run:
```
import Antlr4
....
do {
let textFileName = "TestHello.txt"
if let textFilePath = Bundle.main.path(forResource: textFileName, ofType: nil) {
let lexer = HelloLexer(ANTLRFileStream(textFilePath))
let tokens = CommonTokenStream(lexer)
let parser = try HelloParser(tokens)
let tree = try parser.r()
let walker = ParseTreeWalker()
try walker.walk(HelloWalker(),tree)
} else {
print("error occur: can not open \(textFileName)")
}
}catch ANTLRException.cannotInvokeStartRule {
print("error occur: CannotInvokeStartRule")
}catch ANTLRException.recognition(let e ) {
print("error occur\(e)")
}catch {
print("error occur")
}
```

View File

@ -8,7 +8,7 @@ This page lists the available and upcoming ANTLR runtimes. Please note that you
* [JavaScript](javascript-target.md)
* [Go](go-target.md)
* [C++](cpp-target.md)
* Swift (not yet available)
* [Swift](swift-target.md)
## Target feature parity

View File

@ -33,6 +33,6 @@ slaveGrammar(grammarName) ::= <<
parser grammar S;
type_ : 'int' ;
decl : type_ ID ';'
| type_ ID init ';' {<write("\"JavaDecl: \" + $text")>};
init : '=' INT;
| type_ ID init_ ';' {<write("\"JavaDecl: \" + $text")>};
init_ : '=' INT;
>>

View File

@ -498,39 +498,6 @@ public abstract class BaseBrowserTest {
return file.getAbsolutePath();
}
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i+=2) {
String input = pairs[i];
String expect = pairs[i+1];
String[] lines = input.split("\n");
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
ErrorQueue equeue = antlr(fileName, fileName, input, false);
String actual = equeue.toString(true);
actual = actual.replace(tmpdir + File.separator, "");
System.err.println(actual);
String msg = input;
msg = msg.replace("\n","\\n");
msg = msg.replace("\r","\\r");
msg = msg.replace("\t","\\t");
assertEquals("error in: "+msg,expect,actual);
}
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
int grIndex = line.lastIndexOf("grammar");
int semi = line.lastIndexOf(';');
if ( grIndex>=0 && semi>=0 ) {
int space = line.indexOf(' ', grIndex);
fileName = line.substring(space+1, semi)+Tool.GRAMMAR_EXTENSION;
}
if ( fileName.length()==Tool.GRAMMAR_EXTENSION.length() ) fileName = "A" + Tool.GRAMMAR_EXTENSION;
return fileName;
}
List<ANTLRMessage> getMessagesOfType(List<ANTLRMessage> msgs, Class<? extends ANTLRMessage> c) {
List<ANTLRMessage> filtered = new ArrayList<ANTLRMessage>();
for (ANTLRMessage m : msgs) {

View File

@ -0,0 +1,902 @@
/*
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 Sam Harwell
* Copyright (c) 2016 Janyou
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.test.runtime.legacy.swift;
import org.antlr.v4.Tool;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenSource;
import org.antlr.v4.runtime.WritableToken;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.test.runtime.legacy.java.ErrorQueue;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.DefaultToolListener;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.junit.Before;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.stringtemplate.v4.ST;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public abstract class BaseTest {
public static final String newline = System.getProperty("line.separator");
public static final String pathSep = System.getProperty("path.separator");
/**
* When the {@code antlr.preserve-test-dir} runtime property is set to
* {@code true}, the temporary directories created by the test run will not
* be removed at the end of the test run, even for tests that completed
* successfully.
*
* <p>
* The default behavior (used in all other cases) is removing the temporary
* directories for all tests which completed successfully, and preserving
* the directories for tests which failed.</p>
*/
public static final boolean PRESERVE_TEST_DIR = Boolean.parseBoolean(System.getProperty("antlr-preserve-swift-test-dir"));
/**
* The base test directory is the directory where generated files get placed
* during unit test execution.
*
* <p>
* The default value for this property is the {@code java.io.tmpdir} system
* property, and can be overridden by setting the
* {@code antlr.java-test-dir} property to a custom location. Note that the
* {@code antlr.java-test-dir} property directly affects the
* {@link #CREATE_PER_TEST_DIRECTORIES} value as well.</p>
*/
public static final String BASE_TEST_DIR;
/**
* When {@code true}, a temporary directory will be created for each test
* executed during the test run.
*
* <p>
* This value is {@code true} when the {@code antlr.java-test-dir} system
* property is set, and otherwise {@code false}.</p>
*/
public static final boolean CREATE_PER_TEST_DIRECTORIES;
public static final String EXEC_NAME = "Test";
public static String ANTLR_FRAMEWORK_DIR;
static {
String baseTestDir = System.getProperty("antlr-swift-test-dir");
boolean perTestDirectories = false;
if (baseTestDir == null || baseTestDir.isEmpty()) {
baseTestDir = System.getProperty("java.io.tmpdir");
perTestDirectories = true;
}
if (!new File(baseTestDir).isDirectory()) {
throw new UnsupportedOperationException("The specified base test directory does not exist: " + baseTestDir);
}
BASE_TEST_DIR = baseTestDir;
CREATE_PER_TEST_DIRECTORIES = perTestDirectories;
//add antlr.swift
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
//TODO
final URL swiftRuntime = loader.getResource("Swift/Antlr4");
if ( swiftRuntime==null ) {
throw new RuntimeException("Swift runtime file not found at:" + swiftRuntime.getPath());
}
String swiftRuntimePath = swiftRuntime.getPath();
//get Antlr4 framework
try {
String commandLine = "find " + swiftRuntimePath + "/ -iname *.swift -not -name merge.swift -exec cat {} ;" ;
ProcessBuilder builder = new ProcessBuilder(commandLine.split(" "));
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
Process p = builder.start();
StreamVacuum stdoutVacuum = new StreamVacuum(p.getInputStream());
stdoutVacuum.start();
p.waitFor();
stdoutVacuum.join();
String antlrSwift = stdoutVacuum.toString();
//write to Antlr4
ANTLR_FRAMEWORK_DIR = new File(BASE_TEST_DIR, "Antlr4").getAbsolutePath();
mkdir(ANTLR_FRAMEWORK_DIR);
writeFile(ANTLR_FRAMEWORK_DIR,"Antlr4.swift",antlrSwift);
//compile Antlr4 module
buildAntlr4Framework();
String argsString;
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
// shutdown logic
eraseAntlrFrameWorkDir();
}
});
}
private static boolean buildAntlr4Framework() throws Exception {
String argsString = "xcrun -sdk macosx swiftc -emit-library -emit-module Antlr4.swift -module-name Antlr4 -module-link-name Antlr4 -Xlinker -install_name -Xlinker " + ANTLR_FRAMEWORK_DIR + "/libAntlr4.dylib ";
return runProcess(argsString,ANTLR_FRAMEWORK_DIR);
}
public String tmpdir = null;
/** If error during parser execution, store stderr here; can't return
* stdout and stderr. This doesn't trap errors from running antlr.
*/
protected String stderrDuringParse;
@org.junit.Rule
public final TestRule testWatcher = new TestWatcher() {
@Override
protected void succeeded(Description description) {
// remove tmpdir if no error.
if (!PRESERVE_TEST_DIR) {
eraseTempDir();
}
}
};
@Before
public void setUp() throws Exception {
if (CREATE_PER_TEST_DIRECTORIES) {
// new output dir for each test
String testDirectory = getClass().getSimpleName() + "-" + System.currentTimeMillis();
tmpdir = new File(BASE_TEST_DIR, testDirectory).getAbsolutePath();
}
else {
tmpdir = new File(BASE_TEST_DIR).getAbsolutePath();
if (!PRESERVE_TEST_DIR && new File(tmpdir).exists()) {
eraseFiles(tmpdir);
}
}
}
// private void copyAntlrFramework(){
// writeFile(tmpdir,"Antlr4.swift",ANTLR_FRAMEWORK);
// }
protected Tool newTool(String[] args) {
Tool tool = new Tool(args);
return tool;
}
protected Tool newTool() {
Tool tool = new Tool(new String[] {"-o", tmpdir});
return tool;
}
protected String load(String fileName, String encoding)
throws IOException
{
if ( fileName==null ) {
return null;
}
String fullFileName = getClass().getPackage().getName().replace('.', '/') + '/' + fileName;
int size = 65000;
InputStreamReader isr;
InputStream fis = getClass().getClassLoader().getResourceAsStream(fullFileName);
if ( encoding!=null ) {
isr = new InputStreamReader(fis, encoding);
}
else {
isr = new InputStreamReader(fis);
}
try {
char[] data = new char[size];
int n = isr.read(data);
return new String(data, 0, n);
}
finally {
isr.close();
}
}
protected ErrorQueue antlr(String grammarFileName, boolean defaultListener, String... extraOptions) {
final List<String> options = new ArrayList<String>();
Collections.addAll(options, extraOptions);
options.add("-Dlanguage=Swift");
if ( !options.contains("-o") ) {
options.add("-o");
options.add(tmpdir);
}
if ( !options.contains("-lib") ) {
options.add("-lib");
options.add(tmpdir);
}
if ( !options.contains("-encoding") ) {
options.add("-encoding");
options.add("UTF-8");
}
options.add(new File(tmpdir,grammarFileName).toString());
final String[] optionsA = new String[options.size()];
options.toArray(optionsA);
Tool antlr = newTool(optionsA);
ErrorQueue equeue = new ErrorQueue(antlr);
antlr.addListener(equeue);
if (defaultListener) {
antlr.addListener(new DefaultToolListener(antlr));
}
antlr.processGrammarsOnCommandLine();
if ( !defaultListener && !equeue.errors.isEmpty() ) {
System.err.println("antlr reports errors from "+options);
for (int i = 0; i < equeue.errors.size(); i++) {
ANTLRMessage msg = equeue.errors.get(i);
System.err.println(msg);
}
System.out.println("!!!\ngrammar:");
try {
System.out.println(new String(Utils.readFile(tmpdir+"/"+grammarFileName)));
}
catch (IOException ioe) {
System.err.println(ioe.toString());
}
System.out.println("###");
}
if ( !defaultListener && !equeue.warnings.isEmpty() ) {
System.err.println("antlr reports warnings from "+options);
for (int i = 0; i < equeue.warnings.size(); i++) {
ANTLRMessage msg = equeue.warnings.get(i);
System.err.println(msg);
}
}
return equeue;
}
protected ErrorQueue antlr(String grammarFileName, String grammarStr, boolean defaultListener, String... extraOptions) {
System.out.println("dir "+tmpdir);
mkdir(tmpdir);
writeFile(tmpdir, grammarFileName, grammarStr);
return antlr(grammarFileName, defaultListener, extraOptions);
}
protected String execLexer(String grammarFileName,
String grammarStr,
String lexerName,
String input)
{
return execLexer(grammarFileName, grammarStr, lexerName, input, false);
}
protected String execLexer(String grammarFileName,
String grammarStr,
String lexerName,
String input,
boolean showDFA)
{
boolean success = rawGenerateRecognizer(grammarFileName,
grammarStr,
null,
lexerName);
assertTrue(success);
writeFile(tmpdir, "input", input);
writeLexerTestFile(lexerName, showDFA);
addSourceFiles("main.swift");
// addSourceFiles("Antlr4.swift");
compile();
String output = execTest();
if ( stderrDuringParse!=null && stderrDuringParse.length()>0 ) {
System.err.println(stderrDuringParse);
}
return output;
}
Set<String> sourceFiles = new HashSet<String>();
private void addSourceFiles(String ... files) {
for(String file : files)
this.sourceFiles.add(file);
}
protected String execParser(String grammarFileName,
String grammarStr,
String parserName,
String lexerName,
String startRuleName,
String input, boolean debug)
{
return execParser(grammarFileName, grammarStr, parserName,
lexerName, startRuleName, input, debug, false);
}
protected String execParser(String grammarFileName,
String grammarStr,
String parserName,
String lexerName,
String startRuleName,
String input, boolean debug,boolean profile)
{
boolean success = rawGenerateRecognizer(grammarFileName,
grammarStr,
parserName,
lexerName,
"-visitor");
assertTrue(success);
writeFile(tmpdir, "input", input);
return rawExecRecognizer(parserName,
lexerName,
startRuleName,
debug,profile);
}
/** Return true if all is well */
protected boolean rawGenerateRecognizer(String grammarFileName,
String grammarStr,
String parserName,
String lexerName,
String... extraOptions)
{
return rawGenerateRecognizer(grammarFileName, grammarStr, parserName, lexerName, false, extraOptions);
}
/** Return true if all is well */
protected boolean rawGenerateRecognizer(String grammarFileName,
String grammarStr,
String parserName,
String lexerName,
boolean defaultListener,
String... extraOptions)
{
ErrorQueue equeue = antlr(grammarFileName, grammarStr, defaultListener, extraOptions);
if (!equeue.errors.isEmpty()) {
return false;
}
List<String> files = new ArrayList<String>();
if ( lexerName!=null ) {
files.add(lexerName+".swift");
files.add(lexerName+"ATN.swift");
}
if ( parserName!=null ) {
files.add(parserName+".swift");
files.add(parserName+"ATN.swift");
Set<String> optionsSet = new HashSet<String>(Arrays.asList(extraOptions));
String grammarName = grammarFileName.substring(0, grammarFileName.lastIndexOf('.'));
if (!optionsSet.contains("-no-listener")) {
files.add(grammarName+"Listener.swift");
files.add(grammarName+"BaseListener.swift");
}
if (optionsSet.contains("-visitor")) {
files.add(grammarName+"Visitor.swift");
files.add(grammarName+"BaseVisitor.swift");
}
}
addSourceFiles(files.toArray(new String[files.size()]));
return true;
}
protected String rawExecRecognizer(String parserName,
String lexerName,
String parserStartRuleName,
boolean debug,
boolean profile)
{
this.stderrDuringParse = null;
if ( parserName==null ) {
writeLexerTestFile(lexerName, false);
}
else {
writeParserTestFile(parserName,
lexerName,
parserStartRuleName,
debug,
profile);
}
addSourceFiles("main.swift");
// addSourceFiles("Antlr4.swift");
return execRecognizer();
}
public String execRecognizer() {
compile();
return execTest();
}
public boolean compile() {
try {
if(!buildProject())
return false;
return true;
} catch(Exception e) {
return false;
}
}
private boolean buildProject() throws Exception {
String fileList = sourceFiles.toString().replace("[", "").replace("]", "")
.replace(", ", " ");
String argsString = "xcrun -sdk macosx swiftc " + fileList + " -o " + EXEC_NAME + " -I "+ ANTLR_FRAMEWORK_DIR + " -L "+ ANTLR_FRAMEWORK_DIR + " -module-link-name Antlr4" ;
return runProcess(argsString,tmpdir);
}
private static boolean runProcess(String argsString, String execPath) throws IOException, InterruptedException {
String[] args = argsString.split(" ");
System.err.println("Starting build "+ argsString);//Utils.join(args, " "))
Process process = Runtime.getRuntime().exec(args, null, new File(execPath));
StreamVacuum stdoutVacuum = new StreamVacuum(process.getInputStream());
StreamVacuum stderrVacuum = new StreamVacuum(process.getErrorStream());
stdoutVacuum.start();
stderrVacuum.start();
process.waitFor();
stdoutVacuum.join();
stderrVacuum.join();
if ( stderrVacuum.toString().length()>0 ) {
//this.stderrDuringParse = stderrVacuum.toString();
System.err.println("buildProject stderrVacuum: "+ stderrVacuum);
}
return process.exitValue()==0;
}
public String execTest() {
try {
String exec = tmpdir + "/" + EXEC_NAME ;
String[] args =
new String[] { exec,"input"};//new File(tmpdir, "input").getAbsolutePath()
ProcessBuilder pb = new ProcessBuilder(args);
pb.directory(new File(tmpdir));
Process p = pb.start();
StreamVacuum stdoutVacuum = new StreamVacuum(p.getInputStream());
StreamVacuum stderrVacuum = new StreamVacuum(p.getErrorStream());
stdoutVacuum.start();
stderrVacuum.start();
p.waitFor();
stdoutVacuum.join();
stderrVacuum.join();
String output = stdoutVacuum.toString();
if ( stderrVacuum.toString().length()>0 ) {
this.stderrDuringParse = stderrVacuum.toString();
System.err.println("execTest stderrVacuum: "+ stderrVacuum);
}
return output;
}
catch (Exception e) {
System.err.println("can't exec recognizer");
e.printStackTrace(System.err);
}
return null;
}
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i+=2) {
String input = pairs[i];
String expect = pairs[i+1];
String[] lines = input.split("\n");
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
ErrorQueue equeue = antlr(fileName, input, false);
String actual = equeue.toString(true);
actual = actual.replace(tmpdir + File.separator, "");
System.err.println(actual);
String msg = input;
msg = msg.replace("\n","\\n");
msg = msg.replace("\r","\\r");
msg = msg.replace("\t","\\t");
org.junit.Assert.assertEquals("error in: "+msg,expect,actual);
}
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
int grIndex = line.lastIndexOf("grammar");
int semi = line.lastIndexOf(';');
if ( grIndex>=0 && semi>=0 ) {
int space = line.indexOf(' ', grIndex);
fileName = line.substring(space+1, semi)+Tool.GRAMMAR_EXTENSION;
}
if ( fileName.length()==Tool.GRAMMAR_EXTENSION.length() ) fileName = "A" + Tool.GRAMMAR_EXTENSION;
return fileName;
}
List<ANTLRMessage> getMessagesOfType(List<ANTLRMessage> msgs, Class<? extends ANTLRMessage> c) {
List<ANTLRMessage> filtered = new ArrayList<ANTLRMessage>();
for (ANTLRMessage m : msgs) {
if ( m.getClass() == c ) filtered.add(m);
}
return filtered;
}
public static class StreamVacuum implements Runnable {
StringBuilder buf = new StringBuilder();
BufferedReader in;
Thread sucker;
public StreamVacuum(InputStream in) {
this.in = new BufferedReader( new InputStreamReader(in) );
}
public void start() {
sucker = new Thread(this);
sucker.start();
}
@Override
public void run() {
try {
String line = in.readLine();
while (line!=null) {
buf.append(line);
buf.append('\n');
line = in.readLine();
}
}
catch (IOException ioe) {
System.err.println("can't read output from process");
}
}
/** wait for the thread to finish */
public void join() throws InterruptedException {
sucker.join();
}
@Override
public String toString() {
return buf.toString();
}
}
protected void checkGrammarSemanticsError(ErrorQueue equeue,
GrammarSemanticsMessage expectedMessage)
throws Exception
{
ANTLRMessage foundMsg = null;
for (int i = 0; i < equeue.errors.size(); i++) {
ANTLRMessage m = equeue.errors.get(i);
if (m.getErrorType()==expectedMessage.getErrorType() ) {
foundMsg = m;
}
}
assertNotNull("no error; "+expectedMessage.getErrorType()+" expected", foundMsg);
assertTrue("error is not a GrammarSemanticsMessage",
foundMsg instanceof GrammarSemanticsMessage);
assertEquals(Arrays.toString(expectedMessage.getArgs()), Arrays.toString(foundMsg.getArgs()));
if ( equeue.size()!=1 ) {
System.err.println(equeue);
}
}
public static class FilteringTokenStream extends CommonTokenStream {
public FilteringTokenStream(TokenSource src) { super(src); }
Set<Integer> hide = new HashSet<Integer>();
@Override
protected boolean sync(int i) {
if (!super.sync(i)) {
return false;
}
Token t = get(i);
if ( hide.contains(t.getType()) ) {
((WritableToken)t).setChannel(Token.HIDDEN_CHANNEL);
}
return true;
}
public void setTokenTypeChannel(int ttype, int channel) {
hide.add(ttype);
}
}
public static void writeFile(String dir, String fileName, String content) {
try {
Utils.writeFile(dir+"/"+fileName, content, "UTF-8");
}
catch (IOException ioe) {
System.err.println("can't write file");
ioe.printStackTrace(System.err);
}
}
protected static void mkdir(String dir) {
File f = new File(dir);
f.mkdirs();
}
protected void writeParserTestFile(String parserName,
String lexerName,
String parserStartRuleName,
boolean debug,
boolean profile)
{
ST outputFileST = new ST(
"import Antlr4\n" +
"import Foundation\n" +
"setbuf(__stdoutp, nil)\n" +
"class TreeShapeListener: ParseTreeListener{\n" +
" func visitTerminal(_ node: TerminalNode){ }\n" +
" func visitErrorNode(_ node: ErrorNode){ }\n" +
" func enterEveryRule(_ ctx: ParserRuleContext) throws { }\n" +
" func exitEveryRule(_ ctx: ParserRuleContext) throws {\n" +
" for i in 0..\\<ctx.getChildCount() {\n" +
" let parent = ctx.getChild(i)?.getParent()\n" +
" if (!(parent is RuleNode) || (parent as! RuleNode ).getRuleContext() !== ctx) {\n" +
" throw ANTLRError.illegalState(msg: \"Invalid parse tree shape detected.\")\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n" +
"\n" +
"do {\n" +
"let args = CommandLine.arguments\n" +
"let input = ANTLRFileStream(args[1])\n" +
"let lex = <lexerName>(input)\n" +
"let tokens = CommonTokenStream(lex)\n" +
"<createParser>\n" +
"parser.setBuildParseTree(true)\n" +
"<profile>\n" +
"let tree = try parser.<parserStartRuleName>()\n" +
"<if(profile)>print(profiler.getDecisionInfo().description)<endif>\n" +
"try ParseTreeWalker.DEFAULT.walk(TreeShapeListener(), tree)\n" +
"}catch ANTLRException.cannotInvokeStartRule {\n" +
" print(\"error occur: cannotInvokeStartRule\")\n" +
"}catch ANTLRException.recognition(let e ) {\n" +
" print(\"error occur\\(e)\")\n" +
"}catch {\n" +
" print(\"error occur\")\n" +
"}\n"
);
ST createParserST = new ST(" let parser = try <parserName>(tokens)\n");
if ( debug ) {
createParserST =
new ST(
" let parser = try <parserName>(tokens)\n" +
" parser.addErrorListener(DiagnosticErrorListener())\n");
}
if ( profile ) {
outputFileST.add("profile",
"let profiler = ProfilingATNSimulator(parser)\n" +
"parser.setInterpreter(profiler)");
}
else {
outputFileST.add("profile", new ArrayList<Object>());
}
outputFileST.add("createParser", createParserST);
outputFileST.add("parserName", parserName);
outputFileST.add("lexerName", lexerName);
outputFileST.add("parserStartRuleName", parserStartRuleName);
writeFile(tmpdir, "main.swift", outputFileST.render());
}
protected void writeLexerTestFile(String lexerName, boolean showDFA) {
ST outputFileST = new ST(
"import Antlr4\n" +
"import Foundation\n" +
"setbuf(__stdoutp, nil)\n" +
"let args = CommandLine.arguments\n" +
"let input = ANTLRFileStream(args[1])\n" +
"let lex = <lexerName>(input)\n" +
"let tokens = CommonTokenStream(lex)\n" +
"do {\n" +
" try tokens.fill()\n" +
"}catch ANTLRException.cannotInvokeStartRule {\n" +
" print(\"error occur: cannotInvokeStartRule\")\n" +
"}catch ANTLRException.recognition(let e ) {\n" +
" print(\"error occur\\(e)\")\n" +
"}catch {\n" +
" print(\"error occur\")\n" +
"}\n" +
"for t in tokens.getTokens() {\n" +
" print(t)\n" +
"}\n" +
(showDFA?"print(lex.getInterpreter().getDFA(Lexer.DEFAULT_MODE).toLexerString(), terminator: \"\" )\n":"") );
outputFileST.add("lexerName", lexerName);
writeFile(tmpdir, "main.swift", outputFileST.render());
}
public void writeRecognizerAndCompile(String parserName, String lexerName,
String parserStartRuleName,
boolean debug,
boolean profile) {
if ( parserName==null ) {
writeLexerTestFile(lexerName, debug);
}
else {
writeParserTestFile(parserName,
lexerName,
parserStartRuleName,
debug,
profile);
}
addSourceFiles("main.swift");
// addSourceFiles("Antlr4.swift");
}
protected void eraseFiles(final String filesEndingWith) {
File tmpdirF = new File(tmpdir);
String[] files = tmpdirF.list();
for(int i = 0; files!=null && i < files.length; i++) {
if ( files[i].endsWith(filesEndingWith) ) {
new File(tmpdir+"/"+files[i]).delete();
}
}
}
protected void eraseTempDir() {
File tmpdirF = new File(tmpdir);
if ( tmpdirF.exists() ) {
eraseFilesIn(tmpdir);
tmpdirF.delete();
}
}
protected static void eraseFilesIn(String dirName) {
if (dirName == null) {
return;
}
File dir = new File(dirName);
String[] files = dir.list();
if(files!=null) for(String file : files) {
new File(dirName+"/"+file).delete();
}
}
protected static void eraseAntlrFrameWorkDir() {
File frameworkdir = new File(ANTLR_FRAMEWORK_DIR);
if ( frameworkdir.exists() ) {
eraseFilesIn(ANTLR_FRAMEWORK_DIR);
frameworkdir.delete();
}
}
public String getFirstLineOfException() {
if ( this.stderrDuringParse ==null ) {
return null;
}
String[] lines = this.stderrDuringParse.split("\n");
String prefix="Exception in thread \"main\" ";
return lines[0].substring(prefix.length(),lines[0].length());
}
public List<String> realElements(List<String> elements) {
return elements.subList(Token.MIN_USER_TOKEN_TYPE, elements.size());
}
public void assertNotNullOrEmpty(String message, String text) {
assertNotNull(message, text);
assertFalse(message, text.isEmpty());
}
public void assertNotNullOrEmpty(String text) {
assertNotNull(text);
assertFalse(text.isEmpty());
}
/** Return map sorted by key */
public <K extends Comparable<? super K>,V> LinkedHashMap<K,V> sort(Map<K,V> data) {
LinkedHashMap<K,V> dup = new LinkedHashMap<K, V>();
List<K> keys = new ArrayList<K>();
keys.addAll(data.keySet());
Collections.sort(keys);
for (K k : keys) {
dup.put(k, data.get(k));
}
return dup;
}
protected static void assertEquals(String msg, int a, int b) {
org.junit.Assert.assertEquals(msg, a, b);
}
protected static void assertEquals(String a, String b) {
a = absorbExpectedDifferences(a);
b = absorbActualDifferences(b);
org.junit.Assert.assertEquals(a, b);
}
protected static void assertNull(String a) {
a = absorbActualDifferences(a);
org.junit.Assert.assertNull(a);
}
private static String absorbExpectedDifferences(String a) {
if(a==null)
return a;
// work around the lack of requiresFullContext field in DFAState
//if(a.startsWith("Decision"))
//a = a.replaceAll("\\^", "");
// work around the algo difference for full context
//a = stripOutUnwantedLinesWith(a, "reportAttemptingFullContext","reportContextSensitivity", "reportAmbiguity");
if(a.isEmpty())
a = null;
return a;
}
private static String absorbActualDifferences(String a) {
if(a==null)
return a;
// work around the algo difference for full context
// work around the algo difference for semantic predicates
//a = stripOutUnwantedLinesWith(a, "reportContextSensitivity","eval=false");
if(a.isEmpty())
a = null;
return a;
}
private static String stripOutUnwantedLinesWith(String a, String ... unwanteds) {
String[] lines = a.split("\n");
StringBuilder sb = new StringBuilder();
for(String line : lines) {
boolean wanted = true;
for(String unwanted : unwanteds) {
if(line.contains(unwanted) ) {
wanted = false;
break;
}
}
if(!wanted)
continue;
sb.append(line);
sb.append("\n");
}
return sb.toString();
}
}

View File

@ -0,0 +1,68 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestCompositeLexers extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLexerDelegatorInvokesDelegateRule() throws Exception {
mkdir(tmpdir);
String slave_S =
"lexer grammar S;\n" +
"A : 'a' {print(\"S.A\")};\n" +
"C : 'c' ;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(61);
grammarBuilder.append("lexer grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("B : 'b';\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc";
String found = execLexer("M.g4", grammar, "M", input, false);
assertEquals(
"S.A\n" +
"[@0,0:0='a',<3>,1:0]\n" +
"[@1,1:1='b',<1>,1:1]\n" +
"[@2,2:2='c',<4>,1:2]\n" +
"[@3,3:2='<EOF>',<-1>,1:3]\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLexerDelegatorRuleOverridesDelegate() throws Exception {
mkdir(tmpdir);
String slave_S =
"lexer grammar S;\n" +
"A : 'a' {print(\"S.A\")} ;\n" +
"B : 'b' {print(\"S.B\")} ;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(79);
grammarBuilder.append("lexer grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("A : 'a' B {print(\"M.A\")} ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="ab";
String found = execLexer("M.g4", grammar, "M", input, false);
assertEquals(
"M.A\n" +
"[@0,0:1='ab',<1>,1:0]\n" +
"[@1,2:1='<EOF>',<-1>,1:2]\n", found);
assertNull(this.stderrDuringParse);
}
}

View File

@ -0,0 +1,469 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.antlr.v4.test.runtime.legacy.java.ErrorQueue;
import org.antlr.v4.tool.Grammar;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestCompositeParsers extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testBringInLiteralsFromDelegate() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"a : '=' 'a' {print(\"S.a\", terminator: \"\")};";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(54);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("s : a ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="=a";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals("S.a\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testCombinedImportsCombined() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"tokens { A, B, C }\n" +
"x : 'x' INT {print(\"S.x\")};\n" +
"INT : '0'..'9'+ ;\n" +
"WS : (' '|'\\n') -> skip ;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(31);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("s : x INT;");
String grammar = grammarBuilder.toString();
writeFile(tmpdir, "M.g4", grammar);
ErrorQueue equeue = new ErrorQueue();
new Grammar(tmpdir+"/M.g4", grammar, equeue);
assertEquals("unexpected errors: " + equeue, 0, equeue.errors.size());
String input ="x 34 9";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals("S.x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDelegatesSeeSameTokenType() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"tokens { A, B, C }\n" +
"x : A {print(\"S.x\")};";
writeFile(tmpdir, "S.g4", slave_S);
String slave_T =
"parser grammar T;\n" +
"tokens { C, B, A } // reverse order\n" +
"y : A {print(\"T.y\")};";
writeFile(tmpdir, "T.g4", slave_T);
StringBuilder grammarBuilder = new StringBuilder(598);
grammarBuilder.append("// The lexer will create rules to match letters a, b, c.\n");
grammarBuilder.append("// The associated token types A, B, C must have the same value\n");
grammarBuilder.append("// and all import'd parsers. Since ANTLR regenerates all imports\n");
grammarBuilder.append("// for use with the delegator M, it can generate the same token type\n");
grammarBuilder.append("// mapping in each parser:\n");
grammarBuilder.append("// public static final int C=6;\n");
grammarBuilder.append("// public static final int EOF=-1;\n");
grammarBuilder.append("// public static final int B=5;\n");
grammarBuilder.append("// public static final int WS=7;\n");
grammarBuilder.append("// public static final int A=4;\n");
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S,T;\n");
grammarBuilder.append("s : x y ; // matches AA, which should be 'aa'\n");
grammarBuilder.append("B : 'b' ; // another order: B, A, C\n");
grammarBuilder.append("A : 'a' ; \n");
grammarBuilder.append("C : 'c' ; \n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
writeFile(tmpdir, "M.g4", grammar);
ErrorQueue equeue = new ErrorQueue();
Grammar g = new Grammar(tmpdir+"/M.g4", grammar, equeue);
String expectedTokenIDToTypeMap = "{EOF=-1, B=1, A=2, C=3, WS=4}";
String expectedStringLiteralToTypeMap = "{'a'=2, 'b'=1, 'c'=3}";
String expectedTypeToTokenList = "[B, A, C, WS]";
assertEquals(expectedTokenIDToTypeMap, g.tokenNameToTypeMap.toString());
assertEquals(expectedStringLiteralToTypeMap, sort(g.stringLiteralToTypeMap).toString());
assertEquals(expectedTypeToTokenList, realElements(g.typeToTokenList).toString());
assertEquals("unexpected errors: "+equeue, 0, equeue.errors.size());
String input ="aa";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals(
"S.x\n" +
"T.y\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDelegatorAccessesDelegateMembers() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"@parser::members {\n" +
" public func foo() {print(\"foo\")}\n" +
"}\n" +
"a : B;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(121);
grammarBuilder.append("grammar M; // uses no rules from the import\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("s : 'b' {foo()} ; // gS is import pointer\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="b";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals("foo\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDelegatorInvokesDelegateRule() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"a : B {print(\"S.a\")};";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(104);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("s : a ;\n");
grammarBuilder.append("B : 'b' ; // defines B from inherited token space\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="b";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals("S.a\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDelegatorInvokesDelegateRuleWithArgs() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"a[int x] returns [int y] : B {print(\"S.a\", terminator: \"\")} {$y=1000;} ;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(131);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("s : label=a[3] {print($label.y)} ;\n");
grammarBuilder.append("B : 'b' ; // defines B from inherited token space\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="b";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals("S.a1000\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDelegatorInvokesDelegateRuleWithReturnStruct() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"a : B {print(\"S.a\", terminator: \"\")} ;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(137);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("s : a {print($a.text, terminator: \"\")} ;\n");
grammarBuilder.append("B : 'b' ; // defines B from inherited token space\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="b";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals("S.ab\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDelegatorInvokesFirstVersionOfDelegateRule() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"a : b {print(\"S.a\")};\n" +
"b : B;";
writeFile(tmpdir, "S.g4", slave_S);
String slave_T =
"parser grammar T;\n" +
"a : B {print(\"T.a\")};";
writeFile(tmpdir, "T.g4", slave_T);
StringBuilder grammarBuilder = new StringBuilder(106);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S,T;\n");
grammarBuilder.append("s : a ;\n");
grammarBuilder.append("B : 'b' ; // defines B from inherited token space\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="b";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals("S.a\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDelegatorRuleOverridesDelegate() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"a : b {print(\"S.a\", terminator: \"\")};\n" +
"b : B ;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(59);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("b : 'b'|'c';\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="c";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "a", input, false);
assertEquals("S.a\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDelegatorRuleOverridesDelegates() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"a : b {print(\"S.a\")};\n" +
"b : 'b' ;";
writeFile(tmpdir, "S.g4", slave_S);
String slave_T =
"parser grammar T;\n" +
"tokens { A }\n" +
"b : 'b' {print(\"T.b\")};";
writeFile(tmpdir, "T.g4", slave_T);
StringBuilder grammarBuilder = new StringBuilder(81);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S, T;\n");
grammarBuilder.append("b : 'b'|'c' {print(\"M.b\")}|B|A;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="c";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "a", input, false);
assertEquals(
"M.b\n" +
"S.a\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDelegatorRuleOverridesLookaheadInDelegate() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"type_ : 'int' ;\n" +
"decl : type_ ID ';'\n" +
" | type_ ID init_ ';' {print(\"JavaDecl: \" + $text, terminator: \"\")};\n" +
"init_ : '=' INT;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(121);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("prog : decl ;\n");
grammarBuilder.append("type_ : 'int' | 'float' ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="float x = 3;";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "prog", input, false);
assertEquals("JavaDecl: floatx=3;\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testImportLexerWithOnlyFragmentRules() throws Exception {
mkdir(tmpdir);
String slave_Unicode =
"lexer grammar Unicode;\n" +
"\n" +
"fragment\n" +
"UNICODE_CLASS_Zs : '\\u0020' | '\\u00A0' | '\\u1680' | '\\u180E'\n" +
" | '\\u2000'..'\\u200A'\n" +
" | '\\u202F' | '\\u205F' | '\\u3000'\n" +
" ;\n";
writeFile(tmpdir, "Unicode.g4", slave_Unicode);
StringBuilder grammarBuilder = new StringBuilder(91);
grammarBuilder.append("grammar Test;\n");
grammarBuilder.append("import Unicode;\n");
grammarBuilder.append("\n");
grammarBuilder.append("program : 'test' 'test';\n");
grammarBuilder.append("\n");
grammarBuilder.append("WS : (UNICODE_CLASS_Zs)+ -> skip;\n");
String grammar = grammarBuilder.toString();
String input ="test test";
String found = execParser("Test.g4", grammar, "TestParser", "TestLexer", "program", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testImportedGrammarWithEmptyOptions() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"options {}\n" +
"a : B ;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(64);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("s : a ;\n");
grammarBuilder.append("B : 'b' ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="b";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testImportedRuleWithAction() throws Exception {
mkdir(tmpdir);
String slave_S =
"parser grammar S;\n" +
"a @after {var x = 0} : B;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(62);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("s : a;\n");
grammarBuilder.append("B : 'b';\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="b";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "s", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testKeywordVSIDOrder() throws Exception {
mkdir(tmpdir);
String slave_S =
"lexer grammar S;\n" +
"ID : 'a'..'z'+;";
writeFile(tmpdir, "S.g4", slave_S);
StringBuilder grammarBuilder = new StringBuilder(101);
grammarBuilder.append("grammar M;\n");
grammarBuilder.append("import S;\n");
grammarBuilder.append("a : A {print(\"M.a: \" + $A)};\n");
grammarBuilder.append("A : 'abc' {print(\"M.A\")};\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc";
String found = execParser("M.g4", grammar, "MParser", "MLexer", "a", input, false);
assertEquals(
"M.A\n" +
"M.a: [@0,0:2='abc',<1>,1:0]\n", found);
assertNull(this.stderrDuringParse);
}
}

View File

@ -0,0 +1,489 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestFullContextParsing extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAmbigYieldsCtxSensitiveDFA() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(100);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s @after {self.dumpDFA()}\n");
grammarBuilder.append(" : ID | ID {} ;\n");
grammarBuilder.append("ID : 'a'..'z'+;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 0:\n" +
"s0-ID->:s1^=>1\n", found);
assertEquals("line 1:0 reportAttemptingFullContext d=0 (s), input='abc'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAmbiguityNoLoop() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(203);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("prog\n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append(" : expr expr {print(\"alt 1\")}\n");
grammarBuilder.append(" | expr\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("expr: '@'\n");
grammarBuilder.append(" | ID '@'\n");
grammarBuilder.append(" | ID\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\r\\n\\t]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a@";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "prog", input, true);
assertEquals("alt 1\n", found);
assertEquals(
"line 1:2 reportAttemptingFullContext d=0 (prog), input='a@'\n" +
"line 1:2 reportAmbiguity d=0 (prog): ambigAlts={1, 2}, input='a@'\n" +
"line 1:2 reportAttemptingFullContext d=1 (expr), input='a@'\n" +
"line 1:2 reportContextSensitivity d=1 (expr), input='a@'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testCtxSensitiveDFATwoDiffInput() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(164);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s @after {self.dumpDFA()}\n");
grammarBuilder.append(" : ('$' a | '@' b)+ ;\n");
grammarBuilder.append("a : e ID ;\n");
grammarBuilder.append("b : e INT ID ;\n");
grammarBuilder.append("e : INT | ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="$ 34 abc @ 34 abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 2:\n" +
"s0-INT->s1\n" +
"s1-ID->:s2^=>1\n", found);
assertEquals(
"line 1:5 reportAttemptingFullContext d=2 (e), input='34abc'\n" +
"line 1:2 reportContextSensitivity d=2 (e), input='34'\n" +
"line 1:14 reportAttemptingFullContext d=2 (e), input='34abc'\n" +
"line 1:14 reportContextSensitivity d=2 (e), input='34abc'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testCtxSensitiveDFA_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(161);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s @after {self.dumpDFA()}\n");
grammarBuilder.append(" : '$' a | '@' b ;\n");
grammarBuilder.append("a : e ID ;\n");
grammarBuilder.append("b : e INT ID ;\n");
grammarBuilder.append("e : INT | ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="$ 34 abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 1:\n" +
"s0-INT->s1\n" +
"s1-ID->:s2^=>1\n", found);
assertEquals(
"line 1:5 reportAttemptingFullContext d=1 (e), input='34abc'\n" +
"line 1:2 reportContextSensitivity d=1 (e), input='34'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testCtxSensitiveDFA_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(161);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s @after {self.dumpDFA()}\n");
grammarBuilder.append(" : '$' a | '@' b ;\n");
grammarBuilder.append("a : e ID ;\n");
grammarBuilder.append("b : e INT ID ;\n");
grammarBuilder.append("e : INT | ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="@ 34 abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 1:\n" +
"s0-INT->s1\n" +
"s1-ID->:s2^=>1\n", found);
assertEquals(
"line 1:5 reportAttemptingFullContext d=1 (e), input='34abc'\n" +
"line 1:5 reportContextSensitivity d=1 (e), input='34abc'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testExprAmbiguity_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(277);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append(": expr[0] {print($expr.ctx.toStringTree(self))};\n");
grammarBuilder.append(" expr[int _p]\n");
grammarBuilder.append(" : ID \n");
grammarBuilder.append(" ( \n");
grammarBuilder.append(" {5 >= $_p}? '*' expr[6]\n");
grammarBuilder.append(" | {4 >= $_p}? '+' expr[5]\n");
grammarBuilder.append(" )*\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : [a-zA-Z]+ ;\n");
grammarBuilder.append("WS : [ \\r\\n\\t]+ -> skip ;\n");
String grammar = grammarBuilder.toString();
String input ="a+b";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals("(expr a + (expr b))\n", found);
assertEquals(
"line 1:1 reportAttemptingFullContext d=1 (expr), input='+'\n" +
"line 1:2 reportContextSensitivity d=1 (expr), input='+b'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testExprAmbiguity_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(277);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append(": expr[0] {print($expr.ctx.toStringTree(self))};\n");
grammarBuilder.append(" expr[int _p]\n");
grammarBuilder.append(" : ID \n");
grammarBuilder.append(" ( \n");
grammarBuilder.append(" {5 >= $_p}? '*' expr[6]\n");
grammarBuilder.append(" | {4 >= $_p}? '+' expr[5]\n");
grammarBuilder.append(" )*\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : [a-zA-Z]+ ;\n");
grammarBuilder.append("WS : [ \\r\\n\\t]+ -> skip ;\n");
String grammar = grammarBuilder.toString();
String input ="a+b*c";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals("(expr a + (expr b * (expr c)))\n", found);
assertEquals(
"line 1:1 reportAttemptingFullContext d=1 (expr), input='+'\n" +
"line 1:2 reportContextSensitivity d=1 (expr), input='+b'\n" +
"line 1:3 reportAttemptingFullContext d=1 (expr), input='*'\n" +
"line 1:5 reportAmbiguity d=1 (expr): ambigAlts={1, 2}, input='*c'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testFullContextIF_THEN_ELSEParse_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(237);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s \n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append("@after {self.dumpDFA()}\n");
grammarBuilder.append(" : '{' stat* '}' ;\n");
grammarBuilder.append("stat: 'if' ID 'then' stat ('else' ID)?\n");
grammarBuilder.append(" | 'return'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="{ if x then return }";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 1:\n" +
"s0-'}'->:s1=>2\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testFullContextIF_THEN_ELSEParse_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(237);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s \n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append("@after {self.dumpDFA()}\n");
grammarBuilder.append(" : '{' stat* '}' ;\n");
grammarBuilder.append("stat: 'if' ID 'then' stat ('else' ID)?\n");
grammarBuilder.append(" | 'return'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="{ if x then return else foo }";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 1:\n" +
"s0-'else'->:s1^=>1\n", found);
assertEquals(
"line 1:19 reportAttemptingFullContext d=1 (stat), input='else'\n" +
"line 1:19 reportContextSensitivity d=1 (stat), input='else'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testFullContextIF_THEN_ELSEParse_3() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(237);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s \n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append("@after {self.dumpDFA()}\n");
grammarBuilder.append(" : '{' stat* '}' ;\n");
grammarBuilder.append("stat: 'if' ID 'then' stat ('else' ID)?\n");
grammarBuilder.append(" | 'return'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="{ if x then if y then return else foo }";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 1:\n" +
"s0-'}'->:s2=>2\n" +
"s0-'else'->:s1^=>1\n", found);
assertEquals(
"line 1:29 reportAttemptingFullContext d=1 (stat), input='else'\n" +
"line 1:38 reportAmbiguity d=1 (stat): ambigAlts={1, 2}, input='elsefoo}'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testFullContextIF_THEN_ELSEParse_4() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(237);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s \n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append("@after {self.dumpDFA()}\n");
grammarBuilder.append(" : '{' stat* '}' ;\n");
grammarBuilder.append("stat: 'if' ID 'then' stat ('else' ID)?\n");
grammarBuilder.append(" | 'return'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="{ if x then if y then return else foo else bar }";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 1:\n" +
"s0-'else'->:s1^=>1\n", found);
assertEquals(
"line 1:29 reportAttemptingFullContext d=1 (stat), input='else'\n" +
"line 1:38 reportContextSensitivity d=1 (stat), input='elsefooelse'\n" +
"line 1:38 reportAttemptingFullContext d=1 (stat), input='else'\n" +
"line 1:38 reportContextSensitivity d=1 (stat), input='else'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testFullContextIF_THEN_ELSEParse_5() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(237);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s \n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append("@after {self.dumpDFA()}\n");
grammarBuilder.append(" : '{' stat* '}' ;\n");
grammarBuilder.append("stat: 'if' ID 'then' stat ('else' ID)?\n");
grammarBuilder.append(" | 'return'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input =
"{ if x then return else foo\n" +
"if x then if y then return else foo }";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 1:\n" +
"s0-'}'->:s2=>2\n" +
"s0-'else'->:s1^=>1\n", found);
assertEquals(
"line 1:19 reportAttemptingFullContext d=1 (stat), input='else'\n" +
"line 1:19 reportContextSensitivity d=1 (stat), input='else'\n" +
"line 2:27 reportAttemptingFullContext d=1 (stat), input='else'\n" +
"line 2:36 reportAmbiguity d=1 (stat): ambigAlts={1, 2}, input='elsefoo}'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testFullContextIF_THEN_ELSEParse_6() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(237);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s \n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append("@after {self.dumpDFA()}\n");
grammarBuilder.append(" : '{' stat* '}' ;\n");
grammarBuilder.append("stat: 'if' ID 'then' stat ('else' ID)?\n");
grammarBuilder.append(" | 'return'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input =
"{ if x then return else foo\n" +
"if x then if y then return else foo }";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 1:\n" +
"s0-'}'->:s2=>2\n" +
"s0-'else'->:s1^=>1\n", found);
assertEquals(
"line 1:19 reportAttemptingFullContext d=1 (stat), input='else'\n" +
"line 1:19 reportContextSensitivity d=1 (stat), input='else'\n" +
"line 2:27 reportAttemptingFullContext d=1 (stat), input='else'\n" +
"line 2:36 reportAmbiguity d=1 (stat): ambigAlts={1, 2}, input='elsefoo}'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLoopsSimulateTailRecursion() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(296);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("prog\n");
grammarBuilder.append("@init {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);}\n");
grammarBuilder.append(" : expr_or_assign*;\n");
grammarBuilder.append("expr_or_assign\n");
grammarBuilder.append(" : expr '++' {print(\"fail.\")}\n");
grammarBuilder.append(" | expr {print(\"pass: \"+$expr.text)}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("expr: expr_primary ('<-' ID)?;\n");
grammarBuilder.append("expr_primary\n");
grammarBuilder.append(" : '(' ID ')'\n");
grammarBuilder.append(" | ID '(' ID ')'\n");
grammarBuilder.append(" | ID\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : [a-z]+ ;");
String grammar = grammarBuilder.toString();
String input ="a(i)<-x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "prog", input, true);
assertEquals("pass: a(i)<-x\n", found);
assertEquals(
"line 1:3 reportAttemptingFullContext d=3 (expr_primary), input='a(i)'\n" +
"line 1:7 reportAmbiguity d=3 (expr_primary): ambigAlts={2, 3}, input='a(i)<-x'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSLLSeesEOFInLLGrammar() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(148);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s @after {self.dumpDFA()}\n");
grammarBuilder.append(" : a;\n");
grammarBuilder.append("a : e ID ;\n");
grammarBuilder.append("b : e INT ID ;\n");
grammarBuilder.append("e : INT | ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+ ;\n");
grammarBuilder.append("WS : (' '|'\\t'|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="34 abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"Decision 0:\n" +
"s0-INT->s1\n" +
"s1-ID->:s2^=>1\n", found);
assertEquals(
"line 1:3 reportAttemptingFullContext d=0 (e), input='34abc'\n" +
"line 1:0 reportContextSensitivity d=0 (e), input='34'\n", this.stderrDuringParse);
}
}

View File

@ -0,0 +1,256 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestLexerErrors extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDFAToATNThatFailsBackToDFA() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(39);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("A : 'ab' ;\n");
grammarBuilder.append("B : 'abc' ;");
String grammar = grammarBuilder.toString();
String input ="ababx";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals(
"[@0,0:1='ab',<1>,1:0]\n" +
"[@1,2:3='ab',<1>,1:2]\n" +
"[@2,5:4='<EOF>',<-1>,1:5]\n", found);
assertEquals("line 1:4 token recognition error at: 'x'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDFAToATNThatMatchesThenFailsInATN() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(52);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("A : 'ab' ;\n");
grammarBuilder.append("B : 'abc' ;\n");
grammarBuilder.append("C : 'abcd' ;");
String grammar = grammarBuilder.toString();
String input ="ababcx";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals(
"[@0,0:1='ab',<1>,1:0]\n" +
"[@1,2:4='abc',<2>,1:2]\n" +
"[@2,6:5='<EOF>',<-1>,1:6]\n", found);
assertEquals("line 1:5 token recognition error at: 'x'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testEnforcedGreedyNestedBrances_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(77);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("ACTION : '{' (ACTION | ~[{}])* '}';\n");
grammarBuilder.append("WS : [ \\r\\n\\t]+ -> skip;");
String grammar = grammarBuilder.toString();
String input ="{ { } }";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals(
"[@0,0:6='{ { } }',<1>,1:0]\n" +
"[@1,7:6='<EOF>',<-1>,1:7]\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testEnforcedGreedyNestedBrances_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(77);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("ACTION : '{' (ACTION | ~[{}])* '}';\n");
grammarBuilder.append("WS : [ \\r\\n\\t]+ -> skip;");
String grammar = grammarBuilder.toString();
String input ="{ { }";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals("[@0,5:4='<EOF>',<-1>,1:5]\n", found);
assertEquals("line 1:0 token recognition error at: '{ { }'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testErrorInMiddle() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(28);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("A : 'abc' ;");
String grammar = grammarBuilder.toString();
String input ="abx";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals("[@0,3:2='<EOF>',<-1>,1:3]\n", found);
assertEquals("line 1:0 token recognition error at: 'abx'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testInvalidCharAtStart() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(30);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("A : 'a' 'b' ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals("[@0,1:0='<EOF>',<-1>,1:1]\n", found);
assertEquals("line 1:0 token recognition error at: 'x'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testInvalidCharAtStartAfterDFACache() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(30);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("A : 'a' 'b' ;");
String grammar = grammarBuilder.toString();
String input ="abx";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals(
"[@0,0:1='ab',<1>,1:0]\n" +
"[@1,3:2='<EOF>',<-1>,1:3]\n", found);
assertEquals("line 1:2 token recognition error at: 'x'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testInvalidCharInToken() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(30);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("A : 'a' 'b' ;");
String grammar = grammarBuilder.toString();
String input ="ax";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals("[@0,2:1='<EOF>',<-1>,1:2]\n", found);
assertEquals("line 1:0 token recognition error at: 'ax'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testInvalidCharInTokenAfterDFACache() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(30);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("A : 'a' 'b' ;");
String grammar = grammarBuilder.toString();
String input ="abax";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals(
"[@0,0:1='ab',<1>,1:0]\n" +
"[@1,4:3='<EOF>',<-1>,1:4]\n", found);
assertEquals("line 1:2 token recognition error at: 'ax'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLexerExecDFA() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(98);
grammarBuilder.append("grammar L;\n");
grammarBuilder.append("start : ID ':' expr;\n");
grammarBuilder.append("expr : primary expr? {} | expr '->' ID;\n");
grammarBuilder.append("primary : ID;\n");
grammarBuilder.append("ID : [a-z]+;");
String grammar = grammarBuilder.toString();
String input ="x : x";
String found = execLexer("L.g4", grammar, "LLexer", input, false);
assertEquals(
"[@0,0:0='x',<3>,1:0]\n" +
"[@1,2:2=':',<1>,1:2]\n" +
"[@2,4:4='x',<3>,1:4]\n" +
"[@3,5:4='<EOF>',<-1>,1:5]\n", found);
assertEquals(
"line 1:1 token recognition error at: ' '\n" +
"line 1:3 token recognition error at: ' '\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testStringsEmbeddedInActions_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(109);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("ACTION2 : '[' (STRING | ~'\"')*? ']';\n");
grammarBuilder.append("STRING : '\"' ('\\\"' | .)*? '\"';\n");
grammarBuilder.append("WS : [ \\t\\r\\n]+ -> skip;");
String grammar = grammarBuilder.toString();
String input ="[\"foo\"]";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals(
"[@0,0:6='[\"foo\"]',<1>,1:0]\n" +
"[@1,7:6='<EOF>',<-1>,1:7]\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testStringsEmbeddedInActions_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(109);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("ACTION2 : '[' (STRING | ~'\"')*? ']';\n");
grammarBuilder.append("STRING : '\"' ('\\\"' | .)*? '\"';\n");
grammarBuilder.append("WS : [ \\t\\r\\n]+ -> skip;");
String grammar = grammarBuilder.toString();
String input ="[\"foo]";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals("[@0,6:5='<EOF>',<-1>,1:6]\n", found);
assertEquals("line 1:0 token recognition error at: '[\"foo]'\n", this.stderrDuringParse);
}
}

View File

@ -0,0 +1,374 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestListeners extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testBasic() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(434);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("open class LeafListener: TBaseListener {\n");
grammarBuilder.append(" override\n");
grammarBuilder.append(" open func visitTerminal(_ node: TerminalNode) {\n");
grammarBuilder.append(" print(node.getSymbol()?.getText() ?? \"\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("let walker = ParseTreeWalker()\n");
grammarBuilder.append("try! walker.walk(LeafListener(), $ctx.r)\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : INT INT\n");
grammarBuilder.append(" | ID\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1 2";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a 1 2)\n" +
"1\n" +
"2\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLR() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(628);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("open class LeafListener: TBaseListener {\n");
grammarBuilder.append(" override\n");
grammarBuilder.append(" open func exitE(_ ctx: TParser.EContext) {\n");
grammarBuilder.append(" if (ctx.getChildCount() == 3) {\n");
grammarBuilder.append(" print(\"\\(ctx.e(0)?.start?.getText() ?? \"\") \\(ctx.e(1)?.start?.getText() ?? \"\") \\(ctx.e()[0].start?.getText() ?? \"\")\")\n");
grammarBuilder.append(" } else {\n");
grammarBuilder.append(" print(ctx.INT()?.getSymbol()?.getText() ?? \"\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" }\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("let walker = ParseTreeWalker()\n");
grammarBuilder.append("try! walker.walk(LeafListener(), $ctx.r)\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=e ;\n");
grammarBuilder.append("e : e op='*' e\n");
grammarBuilder.append(" | e op='+' e\n");
grammarBuilder.append(" | INT\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1+2*3";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(e (e 1) + (e (e 2) * (e 3)))\n" +
"1\n" +
"2\n" +
"3\n" +
"2 3 2\n" +
"1 2 1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLRWithLabels() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(619);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("open class LeafListener: TBaseListener {\n");
grammarBuilder.append(" override\n");
grammarBuilder.append(" open func exitCall(_ ctx: TParser.CallContext) {\n");
grammarBuilder.append(" print(\"\\(ctx.e()?.start?.getText() ?? \"\") \\(ctx.eList()!)\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" override\n");
grammarBuilder.append(" open func exitInt(_ ctx: TParser.IntContext) {\n");
grammarBuilder.append(" print(ctx.INT()?.getSymbol()?.getText() ?? \"\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("let walker = ParseTreeWalker()\n");
grammarBuilder.append("try! walker.walk(LeafListener(), $ctx.r)\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=e ;\n");
grammarBuilder.append("e : e '(' eList ')' # Call\n");
grammarBuilder.append(" | INT # Int\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("eList : e (',' e)* ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1(2,3)";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(e (e 1) ( (eList (e 2) , (e 3)) ))\n" +
"1\n" +
"2\n" +
"3\n" +
"1 [13 6]\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testRuleGetters_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(641);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("open class LeafListener: TBaseListener {\n");
grammarBuilder.append(" override\n");
grammarBuilder.append(" open func exitA(_ ctx: TParser.AContext) {\n");
grammarBuilder.append(" if (ctx.getChildCount() == 2) {\n");
grammarBuilder.append(" print(\"\\(ctx.b(0)?.start?.getText() ?? \"\") \\(ctx.b(1)?.start?.getText() ?? \"\") \\(ctx.b()[0].start?.getText() ?? \"\")\")\n");
grammarBuilder.append(" } else {\n");
grammarBuilder.append(" print(ctx.b(0)?.start?.getText() ?? \"\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" }\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("let walker = ParseTreeWalker()\n");
grammarBuilder.append("try! walker.walk(LeafListener(), $ctx.r)\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : b b // forces list\n");
grammarBuilder.append(" | b // a list still\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : ID | INT;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1 2";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a (b 1) (b 2))\n" +
"1 2 1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testRuleGetters_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(641);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("open class LeafListener: TBaseListener {\n");
grammarBuilder.append(" override\n");
grammarBuilder.append(" open func exitA(_ ctx: TParser.AContext) {\n");
grammarBuilder.append(" if (ctx.getChildCount() == 2) {\n");
grammarBuilder.append(" print(\"\\(ctx.b(0)?.start?.getText() ?? \"\") \\(ctx.b(1)?.start?.getText() ?? \"\") \\(ctx.b()[0].start?.getText() ?? \"\")\")\n");
grammarBuilder.append(" } else {\n");
grammarBuilder.append(" print(ctx.b(0)?.start?.getText() ?? \"\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" }\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("let walker = ParseTreeWalker()\n");
grammarBuilder.append("try! walker.walk(LeafListener(), $ctx.r)\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : b b // forces list\n");
grammarBuilder.append(" | b // a list still\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : ID | INT;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a (b abc))\n" +
"abc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testTokenGetters_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(589);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("open class LeafListener: TBaseListener {\n");
grammarBuilder.append(" override\n");
grammarBuilder.append(" open func exitA(_ ctx: TParser.AContext) {\n");
grammarBuilder.append(" if (ctx.getChildCount() == 2) {\n");
grammarBuilder.append(" print(\"\\(ctx.INT(0)?.getSymbol()?.getText() ?? \"\") \\(ctx.INT(1)?.getSymbol()?.getText() ?? \"\") \\(ctx.INT())\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" else {\n");
grammarBuilder.append(" print(ctx.ID()?.getSymbol() ?? \"\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" }\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("let walker = ParseTreeWalker()\n");
grammarBuilder.append("try! walker.walk(LeafListener(), $ctx.r)\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : INT INT\n");
grammarBuilder.append(" | ID\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1 2";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a 1 2)\n" +
"1 2 [1, 2]\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testTokenGetters_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(589);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("open class LeafListener: TBaseListener {\n");
grammarBuilder.append(" override\n");
grammarBuilder.append(" open func exitA(_ ctx: TParser.AContext) {\n");
grammarBuilder.append(" if (ctx.getChildCount() == 2) {\n");
grammarBuilder.append(" print(\"\\(ctx.INT(0)?.getSymbol()?.getText() ?? \"\") \\(ctx.INT(1)?.getSymbol()?.getText() ?? \"\") \\(ctx.INT())\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" else {\n");
grammarBuilder.append(" print(ctx.ID()?.getSymbol() ?? \"\")\n");
grammarBuilder.append(" }\n");
grammarBuilder.append(" }\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("let walker = ParseTreeWalker()\n");
grammarBuilder.append("try! walker.walk(LeafListener(), $ctx.r)\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : INT INT\n");
grammarBuilder.append(" | ID\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a abc)\n" +
"[@0,0:2='abc',<4>,1:0]\n", found);
assertNull(this.stderrDuringParse);
}
}

View File

@ -0,0 +1,280 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestParseTrees extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void test2AltLoop() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(125);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true)\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : ('x' | 'y')* 'z'\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xyyxyxz";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a x y y x y x z)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void test2Alts() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(118);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true)\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : 'x' | 'y'\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="y";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a y)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAltNum() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(210);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("\n");
grammarBuilder.append("options { contextSuperClass=MyRuleNode; }\n");
grammarBuilder.append("\n");
grammarBuilder.append("// TODO\n");
grammarBuilder.append("\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true)\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("a : 'f'\n");
grammarBuilder.append(" | 'g'\n");
grammarBuilder.append(" | 'x' b 'z'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : 'e' {} | 'y'\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xyz";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a:3 x (b:2 y) z)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testExtraToken() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(131);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true)\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : 'x' 'y'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("Z : 'z' \n");
grammarBuilder.append(" ;\n");
grammarBuilder.append(" ");
String grammar = grammarBuilder.toString();
String input ="xzy";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a x z y)\n", found);
assertEquals("line 1:1 extraneous input 'z' expecting 'y'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testNoViableAlt() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(133);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true)\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : 'x' | 'y'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("Z : 'z' \n");
grammarBuilder.append(" ;\n");
grammarBuilder.append(" ");
String grammar = grammarBuilder.toString();
String input ="z";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a z)\n", found);
assertEquals("line 1:0 mismatched input 'z' expecting {'x', 'y'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testRuleRef() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(127);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true)\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : b 'x'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : 'y' \n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="yx";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a (b y) x)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSync() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(134);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true)\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : 'x' 'y'* '!'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("Z : 'z' \n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xzyy!";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a x z y y !)\n", found);
assertEquals("line 1:1 extraneous input 'z' expecting {'y', '!'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testToken2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(116);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true)\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : 'x' 'y'\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xy";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("(a x y)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testTokenAndRuleContextString() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(200);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@init {\n");
grammarBuilder.append("setBuildParseTree(true)\n");
grammarBuilder.append("}\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($r.ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : 'x' { \n");
grammarBuilder.append("print(getRuleInvocationStack().description.replacingOccurrences(of: \"\\\"\", with: \"\"))\n");
grammarBuilder.append("} ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"[a, s]\n" +
"(a x)\n", found);
assertNull(this.stderrDuringParse);
}
}

View File

@ -0,0 +1,685 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestParserErrors extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testConjuringUpToken() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(56);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' x='b' {print(\"conjured=\" + $x)} 'c' ;");
String grammar = grammarBuilder.toString();
String input ="ac";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("conjured=[@-1,-1:-1='<missing 'b'>',<2>,1:1]\n", found);
assertEquals("line 1:1 missing 'b' at 'c'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testConjuringUpTokenFromSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(62);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' x=('b'|'c') {print(\"conjured=\" + $x)} 'd' ;");
String grammar = grammarBuilder.toString();
String input ="ad";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("conjured=[@-1,-1:-1='<missing 'b'>',<2>,1:1]\n", found);
assertEquals("line 1:1 missing {'b', 'c'} at 'd'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testContextListGetters() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(223);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members{\n");
grammarBuilder.append("func foo() {\n");
grammarBuilder.append(" //let s: SContext? = nil\n");
grammarBuilder.append(" //let a: [AContext]? = s?.a()\n");
grammarBuilder.append(" //let b: [BContext]? = s?.b()\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("s : (a | b)+;\n");
grammarBuilder.append("a : 'a' {print(\"a\", terminator: \"\")};\n");
grammarBuilder.append("b : 'b' {print(\"b\", terminator: \"\")};");
String grammar = grammarBuilder.toString();
String input ="abab";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals("abab\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDuplicatedLeftRecursiveCall_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(63);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : expr EOF;\n");
grammarBuilder.append("expr : 'x'\n");
grammarBuilder.append(" | expr expr\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, true);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDuplicatedLeftRecursiveCall_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(63);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : expr EOF;\n");
grammarBuilder.append("expr : 'x'\n");
grammarBuilder.append(" | expr expr\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xx";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, true);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDuplicatedLeftRecursiveCall_3() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(63);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : expr EOF;\n");
grammarBuilder.append("expr : 'x'\n");
grammarBuilder.append(" | expr expr\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xxx";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, true);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDuplicatedLeftRecursiveCall_4() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(63);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : expr EOF;\n");
grammarBuilder.append("expr : 'x'\n");
grammarBuilder.append(" | expr expr\n");
grammarBuilder.append(" ;");
String grammar = grammarBuilder.toString();
String input ="xxxx";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, true);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testInvalidATNStateRemoval() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(98);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : ID ':' expr;\n");
grammarBuilder.append("expr : primary expr? {} | expr '->' ID;\n");
grammarBuilder.append("primary : ID;\n");
grammarBuilder.append("ID : [a-z]+;");
String grammar = grammarBuilder.toString();
String input ="x:x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testInvalidEmptyInput() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(36);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : ID+;\n");
grammarBuilder.append("ID : [a-z]+;");
String grammar = grammarBuilder.toString();
String input ="";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, true);
assertEquals("", found);
assertEquals("line 1:0 missing ID at '<EOF>'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLL1ErrorInfo() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(296);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : animal (AND acClass)? service EOF;\n");
grammarBuilder.append("animal : (DOG | CAT );\n");
grammarBuilder.append("service : (HARDWARE | SOFTWARE) ;\n");
grammarBuilder.append("AND : 'and';\n");
grammarBuilder.append("DOG : 'dog';\n");
grammarBuilder.append("CAT : 'cat';\n");
grammarBuilder.append("HARDWARE: 'hardware';\n");
grammarBuilder.append("SOFTWARE: 'software';\n");
grammarBuilder.append("WS : ' ' -> skip ;\n");
grammarBuilder.append("acClass\n");
grammarBuilder.append("@init\n");
grammarBuilder.append("{print(try self.getExpectedTokens().toString(self.tokenNames))}\n");
grammarBuilder.append(" : ;");
String grammar = grammarBuilder.toString();
String input ="dog and software";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, false);
assertEquals("{'hardware', 'software'}\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLL2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(46);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' 'b'\n");
grammarBuilder.append(" | 'a' 'c'\n");
grammarBuilder.append(";\n");
grammarBuilder.append("q : 'e' ;");
String grammar = grammarBuilder.toString();
String input ="ae";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:1 no viable alternative at input 'ae'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLL3() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(55);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' 'b'* 'c'\n");
grammarBuilder.append(" | 'a' 'b' 'd'\n");
grammarBuilder.append(";\n");
grammarBuilder.append("q : 'e' ;");
String grammar = grammarBuilder.toString();
String input ="abe";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:2 no viable alternative at input 'abe'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLLStar() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(48);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a'+ 'b'\n");
grammarBuilder.append(" | 'a'+ 'c'\n");
grammarBuilder.append(";\n");
grammarBuilder.append("q : 'e' ;");
String grammar = grammarBuilder.toString();
String input ="aaae";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:3 no viable alternative at input 'aaae'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testMultiTokenDeletionBeforeLoop() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(28);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' 'b'* 'c';");
String grammar = grammarBuilder.toString();
String input ="aacabc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:1 extraneous input 'a' expecting {'b', 'c'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testMultiTokenDeletionBeforeLoop2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(36);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' ('b'|'z'{})* 'c';");
String grammar = grammarBuilder.toString();
String input ="aacabc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:1 extraneous input 'a' expecting {'b', 'z', 'c'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testMultiTokenDeletionDuringLoop() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(29);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' 'b'* 'c' ;");
String grammar = grammarBuilder.toString();
String input ="abaaababc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals(
"line 1:2 extraneous input 'a' expecting {'b', 'c'}\n" +
"line 1:6 extraneous input 'a' expecting {'b', 'c'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testMultiTokenDeletionDuringLoop2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(37);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' ('b'|'z'{})* 'c' ;");
String grammar = grammarBuilder.toString();
String input ="abaaababc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals(
"line 1:2 extraneous input 'a' expecting {'b', 'z', 'c'}\n" +
"line 1:6 extraneous input 'a' expecting {'b', 'z', 'c'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testNoViableAltAvoidance() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(83);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : e '!' ;\n");
grammarBuilder.append("e : 'a' 'b'\n");
grammarBuilder.append(" | 'a'\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("DOT : '.' ;\n");
grammarBuilder.append("WS : [ \\t\\r\\n]+ -> skip;");
String grammar = grammarBuilder.toString();
String input ="a.";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("", found);
assertEquals("line 1:1 mismatched input '.' expecting '!'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleSetInsertion() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(34);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' ('b'|'c') 'd' ;");
String grammar = grammarBuilder.toString();
String input ="ad";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:1 missing {'b', 'c'} at 'd'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleSetInsertionConsumption() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(75);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("myset: ('b'|'c') ;\n");
grammarBuilder.append("a: 'a' myset 'd' {print(\"\" + $myset.stop)} ; ");
String grammar = grammarBuilder.toString();
String input ="ad";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("[@0,0:0='a',<3>,1:0]\n", found);
assertEquals("line 1:1 missing {'b', 'c'} at 'd'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenDeletion() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(24);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' 'b' ;");
String grammar = grammarBuilder.toString();
String input ="aab";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:1 extraneous input 'a' expecting 'b'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenDeletionBeforeAlt() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(38);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ('b' | 'c')\n");
grammarBuilder.append(";\n");
grammarBuilder.append("q : 'a'\n");
grammarBuilder.append(";");
String grammar = grammarBuilder.toString();
String input ="ac";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:0 extraneous input 'a' expecting {'b', 'c'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenDeletionBeforeLoop() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(25);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' 'b'* ;");
String grammar = grammarBuilder.toString();
String input ="aabc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals(
"line 1:1 extraneous input 'a' expecting {<EOF>, 'b'}\n" +
"line 1:3 token recognition error at: 'c'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenDeletionBeforeLoop2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(32);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' ('b'|'z'{})*;");
String grammar = grammarBuilder.toString();
String input ="aabc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals(
"line 1:1 extraneous input 'a' expecting {<EOF>, 'b', 'z'}\n" +
"line 1:3 token recognition error at: 'c'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenDeletionBeforePredict() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(48);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a'+ 'b'\n");
grammarBuilder.append(" | 'a'+ 'c'\n");
grammarBuilder.append(";\n");
grammarBuilder.append("q : 'e' ;");
String grammar = grammarBuilder.toString();
String input ="caaab";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:0 extraneous input 'c' expecting 'a'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenDeletionConsumption() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(75);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("myset: ('b'|'c') ;\n");
grammarBuilder.append("a: 'a' myset 'd' {print(\"\" + $myset.stop)} ; ");
String grammar = grammarBuilder.toString();
String input ="aabd";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("[@2,2:2='b',<1>,1:2]\n", found);
assertEquals("line 1:1 extraneous input 'a' expecting {'b', 'c'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenDeletionDuringLoop() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(29);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' 'b'* 'c' ;");
String grammar = grammarBuilder.toString();
String input ="ababbc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:2 extraneous input 'a' expecting {'b', 'c'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenDeletionDuringLoop2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(37);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' ('b'|'z'{})* 'c' ;");
String grammar = grammarBuilder.toString();
String input ="ababbc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:2 extraneous input 'a' expecting {'b', 'z', 'c'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenDeletionExpectingSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(30);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' ('b'|'c') ;");
String grammar = grammarBuilder.toString();
String input ="aab";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:1 extraneous input 'a' expecting {'b', 'c'}\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSingleTokenInsertion() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(28);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' 'b' 'c' ;");
String grammar = grammarBuilder.toString();
String input ="ac";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:1 missing 'b' at 'c'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testTokenMismatch() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(24);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : 'a' 'b' ;");
String grammar = grammarBuilder.toString();
String input ="aa";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertEquals("line 1:1 mismatched input 'a' expecting 'b'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testTokenMismatch2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(165);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("\n");
grammarBuilder.append("stat: ( '(' expr? ')' )? EOF ;\n");
grammarBuilder.append("expr: ID '=' STR ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("ERR : '~FORCE_ERROR~' ;\n");
grammarBuilder.append("ID : [a-zA-Z]+ ;\n");
grammarBuilder.append("STR : '\"' ~[\"]* '\"' ;\n");
grammarBuilder.append("WS : [ \\t\\r\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="( ~FORCE_ERROR~ ";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "stat", input, false);
assertEquals("", found);
assertEquals("line 1:2 mismatched input '~FORCE_ERROR~' expecting ')'\n", this.stderrDuringParse);
}
}

View File

@ -0,0 +1,756 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestParserExec extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAPlus() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(77);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ID+ {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="a b c";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("abc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAStar_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(77);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ID* {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAStar_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(77);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ID* {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="a b c";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("abc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAorAPlus() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(82);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|ID)+ {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="a b c";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("abc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAorAStar_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(82);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|ID)* {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAorAStar_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(82);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|ID)* {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="a b c";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("abc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAorB() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(122);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ID {\n");
grammarBuilder.append("print(\"alt 1\")\n");
grammarBuilder.append("} | INT {\n");
grammarBuilder.append("print(\"alt 2\")\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="34";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("alt 2\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAorBPlus() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(105);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|INT{\n");
grammarBuilder.append("})+ {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a 34 c";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("a34c\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAorBStar_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(105);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|INT{\n");
grammarBuilder.append("})* {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAorBStar_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(105);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|INT{\n");
grammarBuilder.append("})* {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a 34 c";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("a34c\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testBasic() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(98);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ID INT {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="abc 34";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("abc34\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testEOFInClosure() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(53);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("prog : stat EOF;\n");
grammarBuilder.append("stat : 'x' ('y' | EOF)*?;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "prog", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testIfIfElseGreedyBinding1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(186);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : statement+ ;\n");
grammarBuilder.append("statement : 'x' | ifStatement;\n");
grammarBuilder.append("ifStatement : 'if' 'y' statement ('else' statement)? {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> channel(HIDDEN);");
String grammar = grammarBuilder.toString();
String input ="if y if y x else x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, false);
assertEquals(
"if y x else x\n" +
"if y if y x else x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testIfIfElseGreedyBinding2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(186);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : statement+ ;\n");
grammarBuilder.append("statement : 'x' | ifStatement;\n");
grammarBuilder.append("ifStatement : 'if' 'y' statement ('else' statement|) {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> channel(HIDDEN);");
String grammar = grammarBuilder.toString();
String input ="if y if y x else x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, false);
assertEquals(
"if y x else x\n" +
"if y if y x else x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testIfIfElseNonGreedyBinding1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(187);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : statement+ ;\n");
grammarBuilder.append("statement : 'x' | ifStatement;\n");
grammarBuilder.append("ifStatement : 'if' 'y' statement ('else' statement)?? {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> channel(HIDDEN);");
String grammar = grammarBuilder.toString();
String input ="if y if y x else x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, false);
assertEquals(
"if y x\n" +
"if y if y x else x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testIfIfElseNonGreedyBinding2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(186);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : statement+ ;\n");
grammarBuilder.append("statement : 'x' | ifStatement;\n");
grammarBuilder.append("ifStatement : 'if' 'y' statement (|'else' statement) {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> channel(HIDDEN);");
String grammar = grammarBuilder.toString();
String input ="if y if y x else x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, false);
assertEquals(
"if y x\n" +
"if y if y x else x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLL1OptionalBlock_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(103);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|{}INT)? {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+;\n");
grammarBuilder.append("INT : '0'..'9'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLL1OptionalBlock_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(103);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|{}INT)? {\n");
grammarBuilder.append("print($text)\n");
grammarBuilder.append("};\n");
grammarBuilder.append("ID : 'a'..'z'+;\n");
grammarBuilder.append("INT : '0'..'9'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="a";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("a\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLabelAliasingAcrossLabeledAlternatives() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(157);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : a* EOF;\n");
grammarBuilder.append("a\n");
grammarBuilder.append(" : label=subrule {print($label.text)} #One\n");
grammarBuilder.append(" | label='y' {print($label.text)} #Two\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("subrule : 'x';\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="xy";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, false);
assertEquals(
"x\n" +
"y\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLabels() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(118);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : b1=b b2+=b* b3+=';' ;\n");
grammarBuilder.append("b : id_=ID val+=INT*;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc 34;";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testListLabelForClosureContext() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(458);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("ifStatement\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("var __ttt__ = $ctx.elseIfStatement();\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : 'if' expression\n");
grammarBuilder.append(" ( ( 'then'\n");
grammarBuilder.append(" executableStatement*\n");
grammarBuilder.append(" elseIfStatement* // <--- problem is here; should yield a list not node\n");
grammarBuilder.append(" elseStatement?\n");
grammarBuilder.append(" 'end' 'if'\n");
grammarBuilder.append(" ) | executableStatement )\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("elseIfStatement\n");
grammarBuilder.append(" : 'else' 'if' expression 'then' executableStatement*\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("expression : 'a' ;\n");
grammarBuilder.append("executableStatement : 'a' ;\n");
grammarBuilder.append("elseStatement : 'a' ;");
String grammar = grammarBuilder.toString();
String input ="a";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "expression", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testListLabelsOnSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(140);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : b b* ';' ;\n");
grammarBuilder.append("b : ID val+=(INT | FLOAT)*;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("FLOAT : [0-9]+ '.' [0-9]+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc 34;";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testMultipleEOFHandling() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(42);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("prog : ('x' | 'x' 'y') EOF EOF;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "prog", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testOptional_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(90);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("stat : ifstat | 'x';\n");
grammarBuilder.append("ifstat : 'if' stat ('else' stat)?;\n");
grammarBuilder.append("WS : [ \\n\\t]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "stat", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testOptional_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(90);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("stat : ifstat | 'x';\n");
grammarBuilder.append("ifstat : 'if' stat ('else' stat)?;\n");
grammarBuilder.append("WS : [ \\n\\t]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="if x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "stat", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testOptional_3() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(90);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("stat : ifstat | 'x';\n");
grammarBuilder.append("ifstat : 'if' stat ('else' stat)?;\n");
grammarBuilder.append("WS : [ \\n\\t]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="if x else x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "stat", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testOptional_4() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(90);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("stat : ifstat | 'x';\n");
grammarBuilder.append("ifstat : 'if' stat ('else' stat)?;\n");
grammarBuilder.append("WS : [ \\n\\t]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="if if x else x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "stat", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testParserProperty() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(158);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@members {\n");
grammarBuilder.append("func Property() -> Bool {\n");
grammarBuilder.append(" return true\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("a : {$parser.Property()}? ID {print(\"valid\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("valid\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredicatedIfIfElse() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(197);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : stmt EOF ;\n");
grammarBuilder.append("stmt : ifStmt | ID;\n");
grammarBuilder.append("ifStmt : 'if' ID stmt ('else' stmt | { try self._input.LA(1) != TParser.Tokens.ELSE.rawValue }?);\n");
grammarBuilder.append("ELSE : 'else';\n");
grammarBuilder.append("ID : [a-zA-Z]+;\n");
grammarBuilder.append("WS : [ \\n\\t]+ -> skip;");
String grammar = grammarBuilder.toString();
String input ="if x if x a else b";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredictionIssue334() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(236);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("file_ @init{\n");
grammarBuilder.append("setErrorHandler(BailErrorStrategy())\n");
grammarBuilder.append("} \n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : item (SEMICOLON item)* SEMICOLON? EOF ;\n");
grammarBuilder.append("item : A B?;\n");
grammarBuilder.append("SEMICOLON: ';';\n");
grammarBuilder.append("A : 'a'|'A';\n");
grammarBuilder.append("B : 'b'|'B';\n");
grammarBuilder.append("WS : [ \\r\\t\\n]+ -> skip;");
String grammar = grammarBuilder.toString();
String input ="a";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "file_", input, false);
assertEquals("(file_ (item a) <EOF>)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testReferenceToATN_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(106);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|ATN)* ATN? {print($text)} ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("ATN : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testReferenceToATN_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(106);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (ID|ATN)* ATN? {print($text)} ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("ATN : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a 34 c";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("a34c\n", found);
assertNull(this.stderrDuringParse);
}
}

View File

@ -0,0 +1,213 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestPerformance extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test(timeout = 60000)
public void testExpressionGrammar_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(164);
grammarBuilder.append("grammar Expr;\n");
grammarBuilder.append("\n");
grammarBuilder.append("program: expr EOF;\n");
grammarBuilder.append("\n");
grammarBuilder.append("expr\n");
grammarBuilder.append(" : ID\n");
grammarBuilder.append(" | 'not' expr\n");
grammarBuilder.append(" | expr 'and' expr\n");
grammarBuilder.append(" | expr 'or' expr\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("ID: [a-zA-Z_][a-zA-Z_0-9]*;\n");
grammarBuilder.append("WS: [ \\t\\n\\r\\f]+ -> skip;\n");
grammarBuilder.append("ERROR: .;");
String grammar = grammarBuilder.toString();
String input =
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12";
String found = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "program", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test(timeout = 60000)
public void testExpressionGrammar_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(164);
grammarBuilder.append("grammar Expr;\n");
grammarBuilder.append("\n");
grammarBuilder.append("program: expr EOF;\n");
grammarBuilder.append("\n");
grammarBuilder.append("expr\n");
grammarBuilder.append(" : ID\n");
grammarBuilder.append(" | 'not' expr\n");
grammarBuilder.append(" | expr 'and' expr\n");
grammarBuilder.append(" | expr 'or' expr\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("\n");
grammarBuilder.append("ID: [a-zA-Z_][a-zA-Z_0-9]*;\n");
grammarBuilder.append("WS: [ \\t\\n\\r\\f]+ -> skip;\n");
grammarBuilder.append("ERROR: .;");
String grammar = grammarBuilder.toString();
String input =
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
" X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and X6 and not X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and X7 and not X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and X8 and not X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and X9 and not X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and X10 and not X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and X11 and not X12 or\n" +
"not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 and not X8 and not X9 and not X10 and not X11 and X12";
String found = execParser("Expr.g4", grammar, "ExprParser", "ExprLexer", "program", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
}

View File

@ -0,0 +1,215 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestSemPredEvalLexer extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDisableRule() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(131);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("E1 : 'enum' { false }? ;\n");
grammarBuilder.append("E2 : 'enum' { true }? ; // winner not E1 or ID\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="enum abc";
String found = execLexer("L.g4", grammar, "L", input, true);
assertEquals(
"[@0,0:3='enum',<2>,1:0]\n" +
"[@1,5:7='abc',<3>,1:5]\n" +
"[@2,8:7='<EOF>',<-1>,1:8]\n" +
"s0-' '->:s5=>4\n" +
"s0-'a'->:s6=>3\n" +
"s0-'e'->:s1=>3\n" +
":s1=>3-'n'->:s2=>3\n" +
":s2=>3-'u'->:s3=>3\n" +
":s6=>3-'b'->:s6=>3\n" +
":s6=>3-'c'->:s6=>3\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testEnumNotID() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(103);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("ENUM : [a-z]+ { self.getText() == \"enum\" }? ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="enum abc enum";
String found = execLexer("L.g4", grammar, "L", input, true);
assertEquals(
"[@0,0:3='enum',<1>,1:0]\n" +
"[@1,5:7='abc',<2>,1:5]\n" +
"[@2,9:12='enum',<1>,1:9]\n" +
"[@3,13:12='<EOF>',<-1>,1:13]\n" +
"s0-' '->:s3=>3\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testIDnotEnum() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(84);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("ENUM : [a-z]+ { false }? ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="enum abc enum";
String found = execLexer("L.g4", grammar, "L", input, true);
assertEquals(
"[@0,0:3='enum',<2>,1:0]\n" +
"[@1,5:7='abc',<2>,1:5]\n" +
"[@2,9:12='enum',<2>,1:9]\n" +
"[@3,13:12='<EOF>',<-1>,1:13]\n" +
"s0-' '->:s2=>3\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testIDvsEnum() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(85);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("ENUM : 'enum' { false }? ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input ="enum abc enum";
String found = execLexer("L.g4", grammar, "L", input, true);
assertEquals(
"[@0,0:3='enum',<2>,1:0]\n" +
"[@1,5:7='abc',<2>,1:5]\n" +
"[@2,9:12='enum',<2>,1:9]\n" +
"[@3,13:12='<EOF>',<-1>,1:13]\n" +
"s0-' '->:s5=>3\n" +
"s0-'a'->:s4=>2\n" +
"s0-'e'->:s1=>2\n" +
":s1=>2-'n'->:s2=>2\n" +
":s2=>2-'u'->:s3=>2\n" +
":s4=>2-'b'->:s4=>2\n" +
":s4=>2-'c'->:s4=>2\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testIndent() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(149);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("INDENT : [ \\t]+ { self._tokenStartCharPositionInLine == 0 }?\n");
grammarBuilder.append(" { print(\"INDENT\") } ;\n");
grammarBuilder.append("NL : '\\n';\n");
grammarBuilder.append("WS : [ \\t]+ ;");
String grammar = grammarBuilder.toString();
String input =
"abc\n" +
" def \n";
String found = execLexer("L.g4", grammar, "L", input, true);
assertEquals(
"INDENT\n" +
"[@0,0:2='abc',<1>,1:0]\n" +
"[@1,3:3='\\n',<3>,1:3]\n" +
"[@2,4:5=' ',<2>,2:0]\n" +
"[@3,6:8='def',<1>,2:2]\n" +
"[@4,9:10=' ',<4>,2:5]\n" +
"[@5,11:11='\\n',<3>,2:7]\n" +
"[@6,12:11='<EOF>',<-1>,3:0]\n" +
"s0-'\n" +
"'->:s2=>3\n" +
"s0-'a'->:s1=>1\n" +
"s0-'d'->:s1=>1\n" +
":s1=>1-'b'->:s1=>1\n" +
":s1=>1-'c'->:s1=>1\n" +
":s1=>1-'e'->:s1=>1\n" +
":s1=>1-'f'->:s1=>1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLexerInputPositionSensitivePredicates() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(250);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("WORD1 : ID1+ { print(self.getText()) } ;\n");
grammarBuilder.append("WORD2 : ID2+ { print(self.getText()) } ;\n");
grammarBuilder.append("fragment ID1 : { self.getCharPositionInLine() < 2 }? [a-zA-Z];\n");
grammarBuilder.append("fragment ID2 : { self.getCharPositionInLine() >= 2 }? [a-zA-Z];\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip;");
String grammar = grammarBuilder.toString();
String input =
"a cde\n" +
"abcde\n";
String found = execLexer("L.g4", grammar, "L", input, true);
assertEquals(
"a\n" +
"cde\n" +
"ab\n" +
"cde\n" +
"[@0,0:0='a',<1>,1:0]\n" +
"[@1,2:4='cde',<2>,1:2]\n" +
"[@2,6:7='ab',<1>,2:0]\n" +
"[@3,8:10='cde',<2>,2:2]\n" +
"[@4,12:11='<EOF>',<-1>,3:0]\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredicatedKeywords() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(154);
grammarBuilder.append("lexer grammar L;\n");
grammarBuilder.append("ENUM : [a-z]+ { self.getText() == \"enum\" }? { print(\"enum!\") } ;\n");
grammarBuilder.append("ID : [a-z]+ { print(\"ID \" + self.getText()) } ;\n");
grammarBuilder.append("WS : [ \\n] -> skip ;");
String grammar = grammarBuilder.toString();
String input ="enum enu a";
String found = execLexer("L.g4", grammar, "L", input, false);
assertEquals(
"enum!\n" +
"ID enu\n" +
"ID a\n" +
"[@0,0:3='enum',<1>,1:0]\n" +
"[@1,5:7='enu',<2>,1:5]\n" +
"[@2,9:9='a',<2>,1:9]\n" +
"[@3,10:9='<EOF>',<-1>,1:10]\n", found);
assertNull(this.stderrDuringParse);
}
}

View File

@ -0,0 +1,733 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestSemPredEvalParser extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void test2UnpredicatedAlts() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(273);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);} a ';' a; // do 2x: once in ATN, next in DFA\n");
grammarBuilder.append("a : ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | ID {print(\"alt 2\")}\n");
grammarBuilder.append(" | {false}? ID {print(\"alt 3\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x; y";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"alt 1\n" +
"alt 1\n", found);
assertEquals(
"line 1:0 reportAttemptingFullContext d=0 (a), input='x'\n" +
"line 1:0 reportAmbiguity d=0 (a): ambigAlts={1, 2}, input='x'\n" +
"line 1:3 reportAttemptingFullContext d=0 (a), input='y'\n" +
"line 1:3 reportAmbiguity d=0 (a): ambigAlts={1, 2}, input='y'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void test2UnpredicatedAltsAndOneOrthogonalAlt() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(318);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : {_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);} a ';' a ';' a;\n");
grammarBuilder.append("a : INT {print(\"alt 1\")}\n");
grammarBuilder.append(" | ID {print(\"alt 2\")} // must pick this one for ID since pred is false\n");
grammarBuilder.append(" | ID {print(\"alt 3\")}\n");
grammarBuilder.append(" | {false}? ID {print(\"alt 4\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="34; x; y";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, true);
assertEquals(
"alt 1\n" +
"alt 2\n" +
"alt 2\n", found);
assertEquals(
"line 1:4 reportAttemptingFullContext d=0 (a), input='x'\n" +
"line 1:4 reportAmbiguity d=0 (a): ambigAlts={2, 3}, input='x'\n" +
"line 1:7 reportAttemptingFullContext d=0 (a), input='y'\n" +
"line 1:7 reportAmbiguity d=0 (a): ambigAlts={2, 3}, input='y'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testActionHidesPreds() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(216);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members {var i = 0}\n");
grammarBuilder.append("s : a+ ;\n");
grammarBuilder.append("a : {self.i = 1} ID {self.i == 1}? {print(\"alt 1\")}\n");
grammarBuilder.append(" | {self.i = 2} ID {self.i == 2}? {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x x y";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"alt 1\n" +
"alt 1\n" +
"alt 1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testActionsHidePredsInGlobalFOLLOW() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(277);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("func pred(_ v: Bool) -> Bool {\n");
grammarBuilder.append(" print(\"eval=\\(v)\")\n");
grammarBuilder.append(" return v\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("s : e {} {self.pred(true)}? {print(\"parse\")} '!' ;\n");
grammarBuilder.append("t : e {} {self.pred(false)}? ID ;\n");
grammarBuilder.append("e : ID | ; // non-LL(1) so we use ATN\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a!";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"eval=true\n" +
"parse\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testAtomWithClosureInTranslatedLRRule() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(94);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("start : e[0] EOF;\n");
grammarBuilder.append("e[int _p]\n");
grammarBuilder.append(" : ( 'a' | 'b'+ ) ( {3 >= $_p}? '+' e[4] )*\n");
grammarBuilder.append(" ;\n");
String grammar = grammarBuilder.toString();
String input ="a+b+a";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "start", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDepedentPredsInGlobalFOLLOW() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(300);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("func pred(_ v: Bool) -> Bool {\n");
grammarBuilder.append(" print(\"eval=\\(v)\")\n");
grammarBuilder.append(" return v\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("s : a[99] ;\n");
grammarBuilder.append("a[int i] : e {self.pred($i==99)}? {print(\"parse\")} '!' ;\n");
grammarBuilder.append("b[int i] : e {self.pred($i==99)}? ID ;\n");
grammarBuilder.append("e : ID | ; // non-LL(1) so we use ATN\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a!";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"eval=true\n" +
"parse\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDependentPredNotInOuterCtxShouldBeIgnored() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(256);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : b[2] ';' | b[2] '.' ; // decision in s drills down to ctx-dependent pred in a;\n");
grammarBuilder.append("b[int i] : a[i] ;\n");
grammarBuilder.append("a[int i]\n");
grammarBuilder.append(" : {$i==1}? ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {$i==2}? ID {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;\n");
String grammar = grammarBuilder.toString();
String input ="a;";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("alt 2\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testDisabledAlternative() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(121);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("cppCompilationUnit : content+ EOF;\n");
grammarBuilder.append("content: anything | {false}? .;\n");
grammarBuilder.append("anything: ANY_CHAR;\n");
grammarBuilder.append("ANY_CHAR: [_a-zA-Z0-9];");
String grammar = grammarBuilder.toString();
String input ="hello";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "cppCompilationUnit", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testIndependentPredNotPassedOuterCtxToAvoidCastException() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(169);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : b ';' | b '.' ;\n");
grammarBuilder.append("b : a ;\n");
grammarBuilder.append("a\n");
grammarBuilder.append(" : {false}? ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {true}? ID {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a;";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("alt 2\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testNoTruePredsThrowsNoViableAlt() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(157);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : a a;\n");
grammarBuilder.append("a : {false}? ID INT {print(\"alt 1\")}\n");
grammarBuilder.append(" | {false}? ID INT {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="y 3 x 4";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("", found);
assertEquals("line 1:0 no viable alternative at input 'y'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testOrder() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(283);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : a {} a; // do 2x: once in ATN, next in DFA;\n");
grammarBuilder.append("// action blocks lookahead from falling off of 'a'\n");
grammarBuilder.append("// and looking into 2nd 'a' ref. !ctx dependent pred\n");
grammarBuilder.append("a : ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {true}? ID {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x y";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"alt 1\n" +
"alt 1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredFromAltTestedInLoopBack_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(219);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("file_\n");
grammarBuilder.append("@after {print($ctx.toStringTree(self))}\n");
grammarBuilder.append(" : para para EOF ;\n");
grammarBuilder.append("para: paraContent NL NL ;\n");
grammarBuilder.append("paraContent : ('s'|'x'|{try self._input.LA(2) != TParser.Tokens.NL.rawValue}? NL)+ ;\n");
grammarBuilder.append("NL : '\\n' ;\n");
grammarBuilder.append("s : 's' ;\n");
grammarBuilder.append("X : 'x' ;");
String grammar = grammarBuilder.toString();
String input =
"s\n" +
"\n" +
"\n" +
"x\n";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "file_", input, true);
assertEquals("(file_ (para (paraContent s) \\n \\n) (para (paraContent \\n x \\n)) <EOF>)\n", found);
assertEquals(
"line 5:0 mismatched input '<EOF>' expecting '\n" +
"'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredFromAltTestedInLoopBack_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(219);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("file_\n");
grammarBuilder.append("@after {print($ctx.toStringTree(self))}\n");
grammarBuilder.append(" : para para EOF ;\n");
grammarBuilder.append("para: paraContent NL NL ;\n");
grammarBuilder.append("paraContent : ('s'|'x'|{try self._input.LA(2) != TParser.Tokens.NL.rawValue}? NL)+ ;\n");
grammarBuilder.append("NL : '\\n' ;\n");
grammarBuilder.append("s : 's' ;\n");
grammarBuilder.append("X : 'x' ;");
String grammar = grammarBuilder.toString();
String input =
"s\n" +
"\n" +
"\n" +
"x\n" +
"\n";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "file_", input, true);
assertEquals("(file_ (para (paraContent s) \\n \\n) (para (paraContent \\n x) \\n \\n) <EOF>)\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredTestedEvenWhenUnAmbig_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(193);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members {var enumKeyword = true}\n");
grammarBuilder.append("primary\n");
grammarBuilder.append(" : ID {print(\"ID \"+$ID.text)}\n");
grammarBuilder.append(" | {!self.enumKeyword}? 'enum' {print(\"enum\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n\\r]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "primary", input, false);
assertEquals("ID abc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredTestedEvenWhenUnAmbig_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(193);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members {var enumKeyword = true}\n");
grammarBuilder.append("primary\n");
grammarBuilder.append(" : ID {print(\"ID \"+$ID.text)}\n");
grammarBuilder.append(" | {!self.enumKeyword}? 'enum' {print(\"enum\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n\\r]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="enum";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "primary", input, false);
assertEquals("", found);
assertEquals("line 1:0 no viable alternative at input 'enum'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredicateDependentOnArg() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(193);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members {var i = 0}\n");
grammarBuilder.append("s : a[2] a[1];\n");
grammarBuilder.append("a[int i]\n");
grammarBuilder.append(" : {$i==1}? ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {$i==2}? ID {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a b";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"alt 2\n" +
"alt 1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredicateDependentOnArg2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(161);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members {var i = 0}\n");
grammarBuilder.append("s : a[2] a[1];\n");
grammarBuilder.append("a[int i]\n");
grammarBuilder.append(" : {$i==1}? ID \n");
grammarBuilder.append(" | {$i==2}? ID \n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a b";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPredsInGlobalFOLLOW() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(271);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("func pred(_ v: Bool) -> Bool {\n");
grammarBuilder.append(" print(\"eval=\\(v)\")\n");
grammarBuilder.append(" return v\n");
grammarBuilder.append("}\n");
grammarBuilder.append("}\n");
grammarBuilder.append("s : e {self.pred(true)}? {print(\"parse\")} '!' ;\n");
grammarBuilder.append("t : e {self.pred(false)}? ID ;\n");
grammarBuilder.append("e : ID | ; // non-LL(1) so we use ATN\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="a!";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"eval=true\n" +
"parse\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testRewindBeforePredEval() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(225);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : a a;\n");
grammarBuilder.append("a : {try self._input.LT(1)?.getText() == \"x\"}? ID INT {print(\"alt 1\")}\n");
grammarBuilder.append(" | {try self._input.LT(1)?.getText() == \"y\"}? ID INT {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="y 3 x 4";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"alt 2\n" +
"alt 1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSimple() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(235);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : a a a; // do 3x: once in ATN, next in DFA then INT in ATN\n");
grammarBuilder.append("a : {false}? ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {true}? ID {print(\"alt 2\")}\n");
grammarBuilder.append(" | INT {print(\"alt 3\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x y 3";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"alt 2\n" +
"alt 2\n" +
"alt 3\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSimpleValidate() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(150);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : a ;\n");
grammarBuilder.append("a : {false}? ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {true}? INT {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("", found);
assertEquals("line 1:0 no viable alternative at input 'x'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSimpleValidate2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(153);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : a a a;\n");
grammarBuilder.append("a : {false}? ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {true}? INT {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="3 4 x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"alt 2\n" +
"alt 2\n", found);
assertEquals("line 1:4 no viable alternative at input 'x'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testToLeft() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(150);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append(" s : a+ ;\n");
grammarBuilder.append("a : {false}? ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {true}? ID {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x x y";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"alt 2\n" +
"alt 2\n" +
"alt 2\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testToLeftWithVaryingPredicate() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(235);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::members {var i = 0}\n");
grammarBuilder.append("s : ({self.i += 1\n");
grammarBuilder.append("print(\"i=\" + self.i)} a)+ ;\n");
grammarBuilder.append("a : {self.i % 2 == 0}? ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {self.i % 2 != 0}? ID {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x x y";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"i=1\n" +
"alt 2\n" +
"i=2\n" +
"alt 1\n" +
"i=3\n" +
"alt 2\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testUnpredicatedPathsInAlt() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(169);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : a {print(\"alt 1\")}\n");
grammarBuilder.append(" | b {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("a : {false}? ID INT\n");
grammarBuilder.append(" | ID INT\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : ID ID\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x 4";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("alt 1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testValidateInDFA() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(318);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("s : a ';' a;\n");
grammarBuilder.append("// ';' helps us to resynchronize without consuming\n");
grammarBuilder.append("// 2nd 'a' reference. We our testing that the DFA also\n");
grammarBuilder.append("// throws an exception if the validating predicate fails\n");
grammarBuilder.append("a : {false}? ID {print(\"alt 1\")}\n");
grammarBuilder.append(" | {true}? INT {print(\"alt 2\")}\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("ID : 'a'..'z'+ ;\n");
grammarBuilder.append("INT : '0'..'9'+;\n");
grammarBuilder.append("WS : (' '|'\\n') -> skip ;");
String grammar = grammarBuilder.toString();
String input ="x ; y";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals("", found);
assertEquals(
"line 1:0 no viable alternative at input 'x'\n" +
"line 1:4 no viable alternative at input 'y'\n", this.stderrDuringParse);
}
}

View File

@ -0,0 +1,451 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestSets extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testCharSetLiteral() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(78);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : (A {print($A.text)})+ ;\n");
grammarBuilder.append("A : [AaBb] ;\n");
grammarBuilder.append("WS : (' '|'\\n')+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="A a B b";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals(
"A\n" +
"a\n" +
"B\n" +
"b\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testComplementSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(51);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("parse : ~NEW_LINE;\n");
grammarBuilder.append("NEW_LINE: '\\r'? '\\n';");
String grammar = grammarBuilder.toString();
String input ="a";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "parse", input, false);
assertEquals("", found);
assertEquals(
"line 1:0 token recognition error at: 'a'\n" +
"line 1:1 missing {} at '<EOF>'\n", this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLexerOptionalSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(74);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print(try self._input.getText())} ;\n");
grammarBuilder.append("A : ('a'|'b')? 'c' ;");
String grammar = grammarBuilder.toString();
String input ="ac";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("ac\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLexerPlusSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(74);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print(try self._input.getText())} ;\n");
grammarBuilder.append("A : ('a'|'b')+ 'c' ;");
String grammar = grammarBuilder.toString();
String input ="abaac";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("abaac\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLexerStarSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(74);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print(try self._input.getText())} ;\n");
grammarBuilder.append("A : ('a'|'b')* 'c' ;");
String grammar = grammarBuilder.toString();
String input ="abaac";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("abaac\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testNotChar() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(46);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print($A.text)} ;\n");
grammarBuilder.append("A : ~'b' ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testNotCharSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(52);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print($A.text)} ;\n");
grammarBuilder.append("A : ~('b'|'c') ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testNotCharSetWithLabel() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(54);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print($A.text)} ;\n");
grammarBuilder.append("A : h=~('b'|'c') ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testNotCharSetWithRuleRef3() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(118);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print($A.text)} ;\n");
grammarBuilder.append("A : ('a'|B) ; // this doesn't collapse to set but works\n");
grammarBuilder.append("fragment\n");
grammarBuilder.append("B : ~('a'|'c') ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testOptionalLexerSingleElement() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(68);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print(try self._input.getText())} ;\n");
grammarBuilder.append("A : 'b'? 'c' ;");
String grammar = grammarBuilder.toString();
String input ="bc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("bc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testOptionalSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(66);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ('a'|'b')? 'c' {print(try self._input.getText())} ;");
String grammar = grammarBuilder.toString();
String input ="ac";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("ac\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testOptionalSingleElement() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(68);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A? 'c' {print(try self._input.getText())} ;\n");
grammarBuilder.append("A : 'b' ;");
String grammar = grammarBuilder.toString();
String input ="bc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("bc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testParserNotSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(50);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : t=~('x'|'y') 'z' {print($t.text)} ;");
String grammar = grammarBuilder.toString();
String input ="zz";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("z\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testParserNotToken() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(60);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ~'x' 'z' {print(try self._input.getText())} ;");
String grammar = grammarBuilder.toString();
String input ="zz";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("zz\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testParserNotTokenWithLabel() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(44);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : t=~'x' 'z' {print($t.text)} ;");
String grammar = grammarBuilder.toString();
String input ="zz";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("z\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testParserSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(45);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : t=('x'|'y') {print($t.text)} ;");
String grammar = grammarBuilder.toString();
String input ="x";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("x\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPlusLexerSingleElement() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(68);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print(try self._input.getText())} ;\n");
grammarBuilder.append("A : 'b'+ 'c' ;");
String grammar = grammarBuilder.toString();
String input ="bbbbc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("bbbbc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testPlusSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(66);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ('a'|'b')+ 'c' {print(try self._input.getText())} ;");
String grammar = grammarBuilder.toString();
String input ="abaac";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("abaac\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testRuleAsSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(73);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a @after {print(try self._input.getText())} : 'a' | 'b' |'c' ;");
String grammar = grammarBuilder.toString();
String input ="b";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("b\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testSeqDoesNotBecomeSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(110);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : C {print(try self._input.getText())} ;\n");
grammarBuilder.append("fragment A : '1' | '2';\n");
grammarBuilder.append("fragment B : '3' '4';\n");
grammarBuilder.append("C : A | B;");
String grammar = grammarBuilder.toString();
String input ="34";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("34\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testStarLexerSingleElement_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(68);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print(try self._input.getText())} ;\n");
grammarBuilder.append("A : 'b'* 'c' ;");
String grammar = grammarBuilder.toString();
String input ="bbbbc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("bbbbc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testStarLexerSingleElement_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(68);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : A {print(try self._input.getText())} ;\n");
grammarBuilder.append("A : 'b'* 'c' ;");
String grammar = grammarBuilder.toString();
String input ="c";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("c\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testStarSet() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(66);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("a : ('a'|'b')* 'c' {print(try self._input.getText())} ;");
String grammar = grammarBuilder.toString();
String input ="abaac";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
assertEquals("abaac\n", found);
assertNull(this.stderrDuringParse);
}
}

View File

@ -0,0 +1,280 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.legacy.swift;
import org.junit.Test;
@SuppressWarnings("unused")
public class TestVisitors extends BaseTest {
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testBasic() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(210);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : INT INT\n");
grammarBuilder.append(" | ID\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1 2";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a 1 2)\n" +
"[ '1', '2' ]\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLR() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(225);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=e ;\n");
grammarBuilder.append("e : e op='*' e\n");
grammarBuilder.append(" | e op='+' e\n");
grammarBuilder.append(" | INT\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1+2*3";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(e (e 1) + (e (e 2) * (e 3)))\n" +
"1,,2,,32 3 21 2 1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testLRWithLabels() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(265);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=e ;\n");
grammarBuilder.append("e : e '(' eList ')' # Call\n");
grammarBuilder.append(" | INT # Int\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("eList : e (',' e)* ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1(2,3)";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(e (e 1) ( (eList (e 2) , (e 3)) ))\n" +
"1,,2,,3,1 [13 6]\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testRuleGetters_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(252);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : b b // forces list\n");
grammarBuilder.append(" | b // a list still\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : ID | INT;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1 2";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a (b 1) (b 2))\n" +
",1 2 1\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testRuleGetters_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(252);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : b b // forces list\n");
grammarBuilder.append(" | b // a list still\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("b : ID | INT;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a (b abc))\n" +
"abc\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testTokenGetters_1() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(210);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : INT INT\n");
grammarBuilder.append(" | ID\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="1 2";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a 1 2)\n" +
",1 2 [1, 2]\n", found);
assertNull(this.stderrDuringParse);
}
/* This file and method are generated by TestGenerator, any edits will be overwritten by the next generation. */
@Test
public void testTokenGetters_2() throws Exception {
mkdir(tmpdir);
StringBuilder grammarBuilder = new StringBuilder(210);
grammarBuilder.append("grammar T;\n");
grammarBuilder.append("@parser::header {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("@parser::members {\n");
grammarBuilder.append("}\n");
grammarBuilder.append("\n");
grammarBuilder.append("s\n");
grammarBuilder.append("@after {\n");
grammarBuilder.append("print($ctx.r.toStringTree(self))\n");
grammarBuilder.append("}\n");
grammarBuilder.append(" : r=a ;\n");
grammarBuilder.append("a : INT INT\n");
grammarBuilder.append(" | ID\n");
grammarBuilder.append(" ;\n");
grammarBuilder.append("MULT: '*' ;\n");
grammarBuilder.append("ADD : '+' ;\n");
grammarBuilder.append("INT : [0-9]+ ;\n");
grammarBuilder.append("ID : [a-z]+ ;\n");
grammarBuilder.append("WS : [ \\t\\n]+ -> skip ;");
String grammar = grammarBuilder.toString();
String input ="abc";
String found = execParser("T.g4", grammar, "TParser", "TLexer", "s", input, false);
assertEquals(
"(a abc)\n" +
"[@0,0:2='abc',<4>,1:0]\n", found);
assertNull(this.stderrDuringParse);
}
}

View File

@ -32,16 +32,6 @@
<artifactId>antlr4-runtime</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime-test-annotations</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime-test-annotation-processors</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@ -60,47 +50,128 @@
<version>8.1.16.v20140903</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime-test-annotations</artifactId>
<version>4.6-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime-test-annotation-processors</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<testSourceDirectory>test</testSourceDirectory>
<resources>
<resource>
<directory>resources</directory>
</resource>
<resource>
<directory>../runtime</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<includes>
<include>**/csharp/Test*.java</include>
<include>**/java/Test*.java</include>
<include>**/go/Test*.java</include>
<include>**/javascript/node/Test*.java</include>
<include>**/python2/Test*.java</include>
<include>**/python3/Test*.java</include>
<include>**/cpp/Test*.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<build>
<sourceDirectory>src</sourceDirectory>
<testSourceDirectory>test</testSourceDirectory>
<resources>
<resource>
<directory>resources</directory>
</resource>
<resource>
<directory>../runtime</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<includes>
<include>**/csharp/Test*.java</include>
<include>**/java/Test*.java</include>
<include>**/go/Test*.java</include>
<include>**/javascript/node/Test*.java</include>
<include>**/python2/Test*.java</include>
<include>**/python3/Test*.java</include>
<include>${antlr.tests.swift}</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>includeSwiftTests</id>
<activation>
<os>
<family>mac</family>
</os>
</activation>
<properties>
<antlr.tests.swift>**/swift/Test*.java</antlr.tests.swift>
</properties>
</profile>
<profile>
<id>gen</id>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<phase>generate-test-sources</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>org.antlr.v4.testgen.TestGenerator</mainClass>
<arguments>
<argument>-root</argument>
<argument>${basedir}</argument>
<argument>-outdir</argument>
<argument>${basedir}/test</argument>
<argument>-templates</argument>
<argument>${basedir}/resources/org/antlr/v4/test/runtime/templates</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>tests</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<includes>
<include>**/Test*.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -278,7 +278,6 @@ Declare_pred() ::= <<this.pred = function(v) {
>>
Invoke_pred(v) ::= <<this.pred(<v>)>>
ContextRuleFunction(ctx, rule) ::= "<ctx>.<rule>"
StringType() ::= "String"
ContextMember(ctx, subctx, member) ::= "<ctx>.<subctx>.<member>"

View File

@ -332,7 +332,6 @@ func pred(v bool) bool {
>>
Invoke_pred(v) ::= <<pred(<v>)>>
ContextRuleFunction(ctx, rule) ::= "<ctx>.<rule>"
StringType() ::= "String"
ContextMember(ctx, subctx, member) ::= "<ctx>.<subctx>.<member; format={cap}>"

View File

@ -0,0 +1,309 @@
writeln(s) ::= <<print(<s>)>>
write(s) ::= <<print(<s>, terminator: "")>>
False() ::= "false"
True() ::= "true"
Not(v) ::= "!<v>"
Assert(s) ::= ""
Cast(t,v) ::= "((<v> as! <t>))"
Append(a,b) ::= "<a> + <b>"
Concat(a,b) ::= "<a><b>"
DeclareLocal(s,v) ::= "var <s> = <v>"
AssertIsList(v) ::= "var __ttt__ = <v>;" // just use static type system
AssignLocal(s,v) ::= "<s> = <v>"
InitIntMember(n,v) ::= <%var <n> = <v>%>
InitBooleanMember(n,v) ::= <%var <n> = <v>%>
GetMember(n) ::= <%self.<n>%>
SetMember(n,v) ::= <%self.<n> = <v>%>
AddMember(n,v) ::= <%self.<n> += <v>%>
PlusMember(v,n) ::= <%<v> + self.<n>%>
MemberEquals(n,v) ::= <%self.<n> == <v>%>
ModMemberEquals(n,m,v) ::= <%self.<n> % <m> == <v>%>
ModMemberNotEquals(n,m,v) ::= <%self.<n> % <m> != <v>%>
DumpDFA() ::= "self.dumpDFA()"
Pass() ::= ""
StringList() ::= "Array\<String>"
BuildParseTrees() ::= "setBuildParseTree(true)"
BailErrorStrategy() ::= <%setErrorHandler(BailErrorStrategy())%>
ToStringTree(s) ::= <%<s>.toStringTree(self)%>
Column() ::= "self.getCharPositionInLine()"
Text() ::= "self.getText()"
ValEquals(a,b) ::= <%<a>==<b>%>
TextEquals(a) ::= <%self.getText() == "<a>"%>
PlusText(a) ::= <%"<a>" + self.getText()%>
InputText() ::= "try self._input.getText()"
LTEquals(i, v) ::= <%try self._input.LT(<i>)?.getText() == <v>%>
LANotEquals(i, v) ::= <%try self._input.LA(<i>) != <v>%>
TokenStartColumnEquals(i) ::= <%self._tokenStartCharPositionInLine == <i>%>
ImportListener(X) ::= ""
GetExpectedTokenNames() ::= "try self.getExpectedTokens().toString(self.tokenNames)"
RuleInvocationStack() ::= "getRuleInvocationStack().description.replacingOccurrences(of: \"\\\"\", with: \"\")"
LL_EXACT_AMBIG_DETECTION() ::= <<_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);>>
ParserToken(parser, token) ::= <%<parser>.Tokens.<token>.rawValue%>
Production(p) ::= <%<p>%>
Result(r) ::= <%<r>%>
ParserPropertyMember() ::= <<
@members {
func Property() -> Bool {
return true
}
}
>>
ParserPropertyCall(parser, property) ::= <<
<parser>.<property>
>>
PositionAdjustingLexer() ::= <<
override
open func nextToken() throws -> Token {
if (!(_interp is PositionAdjustingLexerATNSimulator)) {
_interp = PositionAdjustingLexerATNSimulator(self, PositionAdjustingLexer._ATN, PositionAdjustingLexer._decisionToDFA, PositionAdjustingLexer._sharedContextCache)
}
return try super.nextToken()
}
override
open func emit() -> Token {
switch (_type) {
case PositionAdjustingLexer.TOKENS:
handleAcceptPositionForKeyword("tokens")
case PositionAdjustingLexer.LABEL:
handleAcceptPositionForIdentifier()
default:
break
}
return super.emit()
}
private func handleAcceptPositionForIdentifier() -> Bool {
let tokenText = getText()
var identifierLength = 0
while ((identifierLength \< tokenText.length) && isIdentifierChar(tokenText[tokenText.characters.index(tokenText.startIndex, offsetBy: identifierLength)])) {
identifierLength += 1
}
if (getInputStream()!.index() > _tokenStartCharIndex + identifierLength) {
let offset = identifierLength - 1
(getInterpreter() as! PositionAdjustingLexerATNSimulator).resetAcceptPosition(getInputStream()!, _tokenStartCharIndex + offset, _tokenStartLine, _tokenStartCharPositionInLine + offset)
return true
}
return false
}
private func handleAcceptPositionForKeyword(_ keyword:String) -> Bool {
if getInputStream()!.index() > _tokenStartCharIndex + keyword.length {
let offset = keyword.length - 1
(getInterpreter() as! PositionAdjustingLexerATNSimulator).resetAcceptPosition(getInputStream()!, _tokenStartCharIndex + offset, _tokenStartLine, _tokenStartCharPositionInLine + offset)
return true
}
return false
}
//public func getInterpreter() -> PositionAdjustingLexerATNSimulator {
// return super.getInterpreter() as! PositionAdjustingLexerATNSimulator
//}
private func isIdentifierChar(_ c: Character) -> Bool {
return (c >= "0" && c \<= "9") || (c >= "a" && c \<= "z") || c >= "A" && c \<= "Z" || c == "_"
}
class PositionAdjustingLexerATNSimulator: LexerATNSimulator {
init(_ recog: Lexer,_ atn: ATN,
_ decisionToDFA: [DFA],
_ sharedContextCache:PredictionContextCache)
{
super.init(recog, atn, decisionToDFA, sharedContextCache)
}
func resetAcceptPosition(_ input: CharStream,_ index: Int,_ line: Int,_ charPositionInLine: Int) {
try! input.seek(index)
self.line = line
self.charPositionInLine = charPositionInLine
try! consume(input)
}
}
>>
BasicListener(X) ::= <<
@parser::members {
open class LeafListener: TBaseListener {
override
open func visitTerminal(_ node: TerminalNode) {
print(node.getSymbol()?.getText() ?? "")
}
}
}
>>
WalkListener(s) ::= <<
let walker = ParseTreeWalker()
try! walker.walk(LeafListener(), <s>)
>>
TreeNodeWithAltNumField(X) ::= <<
@parser::members {
open class MyRuleNode: ParserRuleContext {
public var altNum: Int = 0
override
public init(_ parent: ParserRuleContext?, _ invokingStateNumber: Int) {
super.init(parent, invokingStateNumber)
}
override
open func getAltNumber() -> Int { return altNum }
override
open func setAltNumber(_ altNum: Int) { self.altNum = altNum }
}
}
>>
TokenGetterListener(X) ::= <<
@parser::members {
open class LeafListener: TBaseListener {
override
open func exitA(_ ctx: TParser.AContext) {
if (ctx.getChildCount() == 2) {
print("\(ctx.INT(0)?.getSymbol()?.getText() ?? "") \(ctx.INT(1)?.getSymbol()?.getText() ?? "") \(ctx.INT())")
}
else {
print(ctx.ID()?.getSymbol() ?? "")
}
}
}
}
>>
RuleGetterListener(X) ::= <<
@parser::members {
open class LeafListener: TBaseListener {
override
open func exitA(_ ctx: TParser.AContext) {
if (ctx.getChildCount() == 2) {
print("\(ctx.b(0)?.start?.getText() ?? "") \(ctx.b(1)?.start?.getText() ?? "") \(ctx.b()[0].start?.getText() ?? "")")
} else {
print(ctx.b(0)?.start?.getText() ?? "")
}
}
}
}
>>
LRListener(X) ::= <<
@parser::members {
open class LeafListener: TBaseListener {
override
open func exitE(_ ctx: TParser.EContext) {
if (ctx.getChildCount() == 3) {
print("\(ctx.e(0)?.start?.getText() ?? "") \(ctx.e(1)?.start?.getText() ?? "") \(ctx.e()[0].start?.getText() ?? "")")
} else {
print(ctx.INT()?.getSymbol()?.getText() ?? "")
}
}
}
}
>>
LRWithLabelsListener(X) ::= <<
@parser::members {
open class LeafListener: TBaseListener {
override
open func exitCall(_ ctx: TParser.CallContext) {
print("\(ctx.e()?.start?.getText() ?? "") \(ctx.eList()!)")
}
override
open func exitInt(_ ctx: TParser.IntContext) {
print(ctx.INT()?.getSymbol()?.getText() ?? "")
}
}
}
>>
ImportVisitor(X) ::= ""
BasicVisitor(X) ::= ""
WalkVisitor(s) ::= ""
LRWithLabelsVisitor(X) ::= ""
RuleGetterVisitor(X) ::= ""
LRVisitor(x) ::= ""
TokenGetterVisitor(x) ::= ""
DeclareContextListGettersFunction() ::= <<
func foo() {
//let s: SContext? = nil
//let a: [AContext]? = s?.a()
//let b: [BContext]? = s?.b()
}
>>
Declare_foo() ::= <<
public func foo() {print("foo")}
>>
Invoke_foo() ::= "foo()"
Declare_pred() ::= <<
func pred(_ v: Bool) -> Bool {
print("eval=\(v)")
return v
}
>>
StringType() ::= "String"
Invoke_pred(v) ::= <<self.pred(<v>)>>
ContextRuleFunction(ctx, rule) ::= "<ctx>.<rule>"
ContextMember(ctx, subctx, member) ::= "<ctx>.<subctx>!.<member>"

View File

@ -1,7 +1,11 @@
package org.antlr.v4.test.runtime;
import org.antlr.v4.Tool;
import org.antlr.v4.runtime.misc.Pair;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.test.runtime.java.BaseJavaTest;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.DefaultToolListener;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@ -18,6 +22,7 @@ import java.io.IOException;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import static junit.framework.TestCase.assertEquals;
@ -44,6 +49,9 @@ public abstract class BaseRuntimeTest {
"Node", "Safari", "Firefox", "Explorer", "Chrome"
};
/** ANTLR isn't thread-safe to process grammars so we use a global lock for testing */
public static final Object antlrLock = new Object();
protected RuntimeTestSupport delegate;
protected RuntimeTestDescriptor descriptor;
@ -52,8 +60,10 @@ public abstract class BaseRuntimeTest {
this.delegate = delegate;
}
// @org.junit.Rule
// public final Timeout eachTimeout = new Timeout(60000);
public static void mkdir(String dir) {
File f = new File(dir);
f.mkdirs();
}
@Before
public void setUp() throws Exception {
@ -178,6 +188,76 @@ public abstract class BaseRuntimeTest {
}
}
/** Write a grammar to tmpdir and run antlr */
public static ErrorQueue antlrOnString(String workdir,
String targetName,
String grammarFileName,
String grammarStr,
boolean defaultListener,
String... extraOptions)
{
mkdir(workdir);
BaseJavaTest.writeFile(workdir, grammarFileName, grammarStr);
return antlrOnString(workdir, targetName, grammarFileName, defaultListener, extraOptions);
}
/** Run ANTLR on stuff in workdir and error queue back */
public static ErrorQueue antlrOnString(String workdir,
String targetName,
String grammarFileName,
boolean defaultListener,
String... extraOptions)
{
final List<String> options = new ArrayList<>();
Collections.addAll(options, extraOptions);
if ( targetName!=null ) {
options.add("-Dlanguage="+targetName);
}
if ( !options.contains("-o") ) {
options.add("-o");
options.add(workdir);
}
if ( !options.contains("-lib") ) {
options.add("-lib");
options.add(workdir);
}
if ( !options.contains("-encoding") ) {
options.add("-encoding");
options.add("UTF-8");
}
options.add(new File(workdir,grammarFileName).toString());
final String[] optionsA = new String[options.size()];
options.toArray(optionsA);
Tool antlr = new Tool(optionsA);
ErrorQueue equeue = new ErrorQueue(antlr);
antlr.addListener(equeue);
if (defaultListener) {
antlr.addListener(new DefaultToolListener(antlr));
}
synchronized (antlrLock) {
antlr.processGrammarsOnCommandLine();
}
List<String> errors = new ArrayList<>();
if ( !defaultListener && !equeue.errors.isEmpty() ) {
for (int i = 0; i < equeue.errors.size(); i++) {
ANTLRMessage msg = equeue.errors.get(i);
ST msgST = antlr.errMgr.getMessageTemplate(msg);
errors.add(msgST.render());
}
}
if ( !defaultListener && !equeue.warnings.isEmpty() ) {
for (int i = 0; i < equeue.warnings.size(); i++) {
ANTLRMessage msg = equeue.warnings.get(i);
// antlrToolErrors.append(msg); warnings are hushed
}
}
return equeue;
}
// ---- support ----
public static RuntimeTestDescriptor[] getRuntimeTestDescriptors(Class<?> clazz, String targetName) {
@ -198,11 +278,6 @@ public abstract class BaseRuntimeTest {
return descriptors.toArray(new RuntimeTestDescriptor[0]);
}
protected void mkdir(String dir) {
File f = new File(dir);
f.mkdirs();
}
public static void writeFile(String dir, String fileName, String content) {
try {
Utils.writeFile(dir+"/"+fileName, content, "UTF-8");

View File

@ -56,14 +56,12 @@ import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.semantics.SemanticPipeline;
import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.DOTGenerator;
import org.antlr.v4.tool.DefaultToolListener;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.antlr.v4.tool.LexerGrammar;
@ -93,7 +91,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import static org.antlr.v4.test.runtime.java.BaseJavaTest.antlrLock;
import static org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -346,53 +344,6 @@ public class BaseCppTest implements RuntimeTestSupport {
return "Cpp";
}
/** Return true if all is ok, no errors */
protected ErrorQueue antlr(String fileName, String grammarFileName, String grammarStr, boolean defaultListener, String... extraOptions) {
mkdir(tmpdir);
writeFile(tmpdir, fileName, grammarStr);
final List<String> options = new ArrayList<String>();
Collections.addAll(options, extraOptions);
options.add("-Dlanguage=" + getLanguage());
options.add("-o");
options.add(tmpdir);
options.add("-lib");
options.add(tmpdir);
options.add(new File(tmpdir,grammarFileName).toString());
final String[] optionsA = new String[options.size()];
options.toArray(optionsA);
Tool antlr = newTool(optionsA);
ErrorQueue equeue = new ErrorQueue(antlr);
antlr.addListener(equeue);
if (defaultListener) {
antlr.addListener(new DefaultToolListener(antlr));
}
synchronized (antlrLock) {
antlr.processGrammarsOnCommandLine();
}
if ( !defaultListener && !equeue.errors.isEmpty() ) {
for (int i = 0; i < equeue.errors.size(); i++) {
ANTLRMessage msg = equeue.errors.get(i);
antlrToolErrors.append(msg.toString());
}
try {
antlrToolErrors.append(new String(Utils.readFile(tmpdir+"/"+grammarFileName)));
}
catch (IOException ioe) {
antlrToolErrors.append(ioe.toString());
}
}
if ( !defaultListener && !equeue.warnings.isEmpty() ) {
for (int i = 0; i < equeue.warnings.size(); i++) {
ANTLRMessage msg = equeue.warnings.get(i);
// antlrToolErrors.append(msg); warnings are hushed
}
}
return equeue;
}
protected String execLexer(String grammarFileName,
String grammarStr,
String lexerName,
@ -498,7 +449,7 @@ public class BaseCppTest implements RuntimeTestSupport {
String... extraOptions)
{
ErrorQueue equeue =
antlr(grammarFileName, grammarFileName, grammarStr, defaultListener, extraOptions);
antlrOnString(getTmpDir(), "Cpp", grammarFileName, grammarStr, defaultListener, extraOptions);
if (!equeue.errors.isEmpty()) {
return false;
}
@ -582,6 +533,7 @@ public class BaseCppTest implements RuntimeTestSupport {
}
private String runProcess(ProcessBuilder builder, String description) throws Exception {
// System.out.println("BUILDER: "+builder.command());
Process process = builder.start();
StreamVacuum stdoutVacuum = new StreamVacuum(process.getInputStream());
StreamVacuum stderrVacuum = new StreamVacuum(process.getErrorStream());
@ -593,6 +545,7 @@ public class BaseCppTest implements RuntimeTestSupport {
String output = stdoutVacuum.toString();
if ( stderrVacuum.toString().length()>0 ) {
this.stderrDuringParse = stderrVacuum.toString();
// System.err.println(this.stderrDuringParse);
}
if (errcode != 0) {
String err = "execution failed with error code: "+errcode;
@ -620,7 +573,7 @@ public class BaseCppTest implements RuntimeTestSupport {
System.out.println("Building ANTLR4 C++ runtime (if necessary) at "+ runtimePath);
try {
String command[] = { "cmake", ".", "-DCMAKE_BUILD_TYPE=release" };
String command[] = { "cmake", ".", /*"-DCMAKE_CXX_COMPILER=clang++",*/ "-DCMAKE_BUILD_TYPE=release" };
if (runCommand(command, runtimePath, "antlr runtime cmake") == null)
return false;
}
@ -688,11 +641,13 @@ public class BaseCppTest implements RuntimeTestSupport {
return null;
}
catch (Exception e) {
System.err.println("can't exec module: " + fileName);
System.err.println("can't create link to " + runtimePath + "/dist/libantlr4-runtime." + libExtension);
e.printStackTrace(System.err);
return null;
}
try {
List<String> command2 = new ArrayList<String>(Arrays.asList("clang++", "-std=c++11", "-I", includePath, "-L.", "-lantlr4-runtime"));
List<String> command2 = new ArrayList<String>(Arrays.asList("clang++", "-std=c++11", "-I", includePath, "-L.", "-lantlr4-runtime", "-o", "a.out"));
command2.addAll(allCppFiles(tmpdir));
if (runCommand(command2.toArray(new String[0]), tmpdir, "building test binary") == null) {
return null;
@ -700,6 +655,7 @@ public class BaseCppTest implements RuntimeTestSupport {
}
catch (Exception e) {
System.err.println("can't compile test module: " + e.getMessage());
e.printStackTrace(System.err);
return null;
}
@ -709,7 +665,7 @@ public class BaseCppTest implements RuntimeTestSupport {
ProcessBuilder builder = new ProcessBuilder(binPath, inputPath);
builder.directory(new File(tmpdir));
Map<String, String> env = builder.environment();
env.put("LD_PRELOAD", runtimePath + "/dist/libantlr4-runtime.so"); // For linux.
env.put("LD_PRELOAD", runtimePath + "/dist/libantlr4-runtime." + libExtension);
String output = runProcess(builder, "running test binary");
if ( output.length()==0 ) {
output = null;
@ -723,7 +679,8 @@ public class BaseCppTest implements RuntimeTestSupport {
return output;
}
catch (Exception e) {
System.err.println("can't exec module: " + fileName + "\nerror is: "+ e.getMessage());
System.err.println("can't exec module: " + fileName);
e.printStackTrace(System.err);
}
return null;
@ -738,39 +695,6 @@ public class BaseCppTest implements RuntimeTestSupport {
return runtimeSrc.getPath();
}
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i+=2) {
String input = pairs[i];
String expect = pairs[i+1];
String[] lines = input.split("\n");
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
ErrorQueue equeue = antlr(fileName, fileName, input, false);
String actual = equeue.toString(true);
actual = actual.replace(tmpdir + File.separator, "");
System.err.println(actual);
String msg = input;
msg = msg.replace("\n","\\n");
msg = msg.replace("\r","\\r");
msg = msg.replace("\t","\\t");
assertEquals("error in: "+msg,expect,actual);
}
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
int grIndex = line.lastIndexOf("grammar");
int semi = line.lastIndexOf(';');
if ( grIndex>=0 && semi>=0 ) {
int space = line.indexOf(' ', grIndex);
fileName = line.substring(space+1, semi)+Tool.GRAMMAR_EXTENSION;
}
if ( fileName.length()==Tool.GRAMMAR_EXTENSION.length() ) fileName = "A" + Tool.GRAMMAR_EXTENSION;
return fileName;
}
List<ANTLRMessage> getMessagesOfType(List<ANTLRMessage> msgs, Class<? extends ANTLRMessage> c) {
List<ANTLRMessage> filtered = new ArrayList<ANTLRMessage>();
for (ANTLRMessage m : msgs) {

View File

@ -39,7 +39,6 @@ import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.test.runtime.SpecialRuntimeTestAssert;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.DefaultToolListener;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
@ -74,7 +73,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.antlr.v4.test.runtime.java.BaseJavaTest.antlrLock;
import static org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@ -238,65 +237,6 @@ public class BaseCSharpTest implements RuntimeTestSupport, SpecialRuntimeTestAss
}
}
protected ErrorQueue antlr(String grammarFileName, boolean defaultListener, String... extraOptions) {
final List<String> options = new ArrayList<String>();
Collections.addAll(options, extraOptions);
options.add("-Dlanguage=CSharp");
if ( !options.contains("-o") ) {
options.add("-o");
options.add(tmpdir);
}
if ( !options.contains("-lib") ) {
options.add("-lib");
options.add(tmpdir);
}
if ( !options.contains("-encoding") ) {
options.add("-encoding");
options.add("UTF-8");
}
options.add(new File(tmpdir,grammarFileName).toString());
final String[] optionsA = new String[options.size()];
options.toArray(optionsA);
Tool antlr = newTool(optionsA);
ErrorQueue equeue = new ErrorQueue(antlr);
antlr.addListener(equeue);
if (defaultListener) {
antlr.addListener(new DefaultToolListener(antlr));
}
synchronized (antlrLock) {
antlr.processGrammarsOnCommandLine();
}
if ( !defaultListener && !equeue.errors.isEmpty() ) {
for (int i = 0; i < equeue.errors.size(); i++) {
ANTLRMessage msg = equeue.errors.get(i);
antlrToolErrors.append(msg.toString());
}
try {
antlrToolErrors.append(new String(Utils.readFile(tmpdir+"/"+grammarFileName)));
}
catch (IOException ioe) {
antlrToolErrors.append(ioe.toString());
}
}
if ( !defaultListener && !equeue.warnings.isEmpty() ) {
for (int i = 0; i < equeue.warnings.size(); i++) {
ANTLRMessage msg = equeue.warnings.get(i);
// antlrToolErrors.append(msg); warnings are hushed
}
}
return equeue;
}
protected ErrorQueue antlr(String grammarFileName, String grammarStr, boolean defaultListener, String... extraOptions) {
mkdir(tmpdir);
writeFile(tmpdir, grammarFileName, grammarStr);
return antlr(grammarFileName, defaultListener, extraOptions);
}
protected String execLexer(String grammarFileName,
String grammarStr,
String lexerName,
@ -380,7 +320,7 @@ public class BaseCSharpTest implements RuntimeTestSupport, SpecialRuntimeTestAss
boolean defaultListener,
String... extraOptions)
{
ErrorQueue equeue = antlr(grammarFileName, grammarStr, defaultListener, extraOptions);
ErrorQueue equeue = antlrOnString(getTmpDir(), "CSharp", grammarFileName, grammarStr, defaultListener, extraOptions);
if (!equeue.errors.isEmpty()) {
return false;
}
@ -610,40 +550,6 @@ public class BaseCSharpTest implements RuntimeTestSupport, SpecialRuntimeTestAss
}
}
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i+=2) {
String input = pairs[i];
String expect = pairs[i+1];
String[] lines = input.split("\n");
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
ErrorQueue equeue = antlr(fileName, input, false);
String actual = equeue.toString(true);
actual = actual.replace(tmpdir + File.separator, "");
System.err.println(actual);
String msg = input;
msg = msg.replace("\n","\\n");
msg = msg.replace("\r","\\r");
msg = msg.replace("\t","\\t");
org.junit.Assert.assertEquals("error in: "+msg,expect,actual);
}
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
int grIndex = line.lastIndexOf("grammar");
int semi = line.lastIndexOf(';');
if ( grIndex>=0 && semi>=0 ) {
int space = line.indexOf(' ', grIndex);
fileName = line.substring(space+1, semi)+Tool.GRAMMAR_EXTENSION;
}
if ( fileName.length()==Tool.GRAMMAR_EXTENSION.length() ) fileName = "A" + Tool.GRAMMAR_EXTENSION;
return fileName;
}
List<ANTLRMessage> getMessagesOfType(List<ANTLRMessage> msgs, Class<? extends ANTLRMessage> c) {
List<ANTLRMessage> filtered = new ArrayList<ANTLRMessage>();
for (ANTLRMessage m : msgs) {

View File

@ -412,8 +412,8 @@ public class CompositeParsersDescriptors {
parser grammar S;
type_ : 'int' ;
decl : type_ ID ';'
| type_ ID init ';' {<write("\"JavaDecl: \" + $text")>};
init : '=' INT;
| type_ ID init_ ';' {<write("\"JavaDecl: \" + $text")>};
init_ : '=' INT;
*/
@CommentHasStringValue
public String slaveGrammarS;

View File

@ -33,7 +33,6 @@ public class PerformanceDescriptors {
*/
@CommentHasStringValue
public String grammar;
}
public static class ExpressionGrammar_1 extends ExpressionGrammar {
@ -72,4 +71,158 @@ public class PerformanceDescriptors {
@CommentHasStringValue
public String input;
}
/** Test for https://github.com/antlr/antlr4/issues/1398.
* Seeing through a large expression takes 5 _minutes_ on
* my fast box to complete. After fix, it's instantaneous.
*/
public static abstract class DropLoopEntryBranchInLRRule extends BaseParserTestDescriptor {
public String grammarName = "Expr";
public String startRule = "stat";
/**
grammar Expr;
stat : expr ';'
| expr '.'
;
expr
: ID
| 'not' expr
| expr 'and' expr
| expr 'or' expr
| '(' ID ')' expr
| expr '?' expr ':' expr
| 'between' expr 'and' expr
;
ID: [a-zA-Z_][a-zA-Z_0-9]*;
WS: [ \t\n\r\f]+ -> skip;
*/
@CommentHasStringValue
public String grammar;
@Override
public boolean ignore(String targetName) {
return !targetName.equals("Java");
}
}
public static class DropLoopEntryBranchInLRRule_1 extends DropLoopEntryBranchInLRRule {
/**
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7
;
*/
@CommentHasStringValue
public String input;
}
public static class DropLoopEntryBranchInLRRule_2 extends DropLoopEntryBranchInLRRule {
/**
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7 or
X1 and X2 and X3 and X4 and X5 and X6 and X7
.
*/ // Different in final token
@CommentHasStringValue
public String input;
}
public static class DropLoopEntryBranchInLRRule_3 extends DropLoopEntryBranchInLRRule {
/**
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7 or
not X1 and not X2 and not X3 and not X4 and not X5 and not X6 and not X7
;
*/
@CommentHasStringValue
public String input;
}
public static class DropLoopEntryBranchInLRRule_4 extends DropLoopEntryBranchInLRRule {
/**
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4 and
between X1 and X2 or between X3 and X4
;
*/
@CommentHasStringValue
public String input;
}
public static class DropLoopEntryBranchInLRRule_5 extends DropLoopEntryBranchInLRRule {
/**
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z or
X ? Y : Z
;
*/
@CommentHasStringValue
public String input;
}
}

View File

@ -54,13 +54,11 @@ import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.semantics.SemanticPipeline;
import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.DOTGenerator;
import org.antlr.v4.tool.DefaultToolListener;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.antlr.v4.tool.LexerGrammar;
@ -95,7 +93,7 @@ import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertFalse;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertTrue;
import static org.antlr.v4.test.runtime.java.BaseJavaTest.antlrLock;
import static org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString;
import static org.junit.Assert.assertArrayEquals;
public class BaseGoTest implements RuntimeTestSupport {
@ -324,56 +322,6 @@ public class BaseGoTest implements RuntimeTestSupport {
return tokenTypes;
}
/** Return true if all is ok, no errors */
protected ErrorQueue antlr(String fileName, String grammarFileName,
String grammarStr, boolean defaultListener, String... extraOptions) {
if(grammarStr!=null) {
mkdir(tmpdir);
writeFile(tmpdir, fileName, grammarStr);
}
final List<String> options = new ArrayList<String>();
Collections.addAll(options, extraOptions);
options.add("-Dlanguage=Go");
options.add("-o");
options.add(tmpdir.getPath());
options.add("-lib");
options.add(tmpdir.getPath());
options.add(new File(tmpdir, grammarFileName).getPath());
final String[] optionsA = new String[options.size()];
options.toArray(optionsA);
Tool antlr = newTool(optionsA);
ErrorQueue equeue = new ErrorQueue(antlr);
antlr.addListener(equeue);
if (defaultListener) {
antlr.addListener(new DefaultToolListener(antlr));
}
synchronized (antlrLock) {
antlr.processGrammarsOnCommandLine();
}
if ( !defaultListener && !equeue.errors.isEmpty() ) {
for (int i = 0; i < equeue.errors.size(); i++) {
ANTLRMessage msg = equeue.errors.get(i);
antlrToolErrors.append(msg.toString());
}
try {
antlrToolErrors.append(new String(Utils.readFile(tmpdir+"/"+grammarFileName)));
}
catch (IOException ioe) {
antlrToolErrors.append(ioe.toString());
}
}
if ( !defaultListener && !equeue.warnings.isEmpty() ) {
for (int i = 0; i < equeue.warnings.size(); i++) {
ANTLRMessage msg = equeue.warnings.get(i);
// antlrToolErrors.append(msg); warnings are hushed
}
}
return equeue;
}
protected String execLexer(String grammarFileName, String grammarStr,
String lexerName, String input) {
return execLexer(grammarFileName, grammarStr, lexerName, input, false);
@ -432,29 +380,12 @@ public class BaseGoTest implements RuntimeTestSupport {
protected boolean rawGenerateAndBuildRecognizer(String grammarFileName,
String grammarStr, String parserName, String lexerName,
boolean defaultListener, String... extraOptions) {
ErrorQueue equeue = antlr(grammarFileName, grammarFileName, grammarStr,
defaultListener, extraOptions);
// List<String> files = new ArrayList<String>();
// if (lexerName != null) {
// files.add(lexerName + ".go");
// }
// if (parserName != null) {
// files.add(parserName + ".go");
// Set<String> optionsSet = new HashSet<String>(
// Arrays.asList(extraOptions));
// if (!optionsSet.contains("-no-listener")) {
// files.add(grammarFileName.substring(0,
// grammarFileName.lastIndexOf('.'))
// + "Listener.go");
// }
// if (optionsSet.contains("-visitor")) {
// files.add(grammarFileName.substring(0,
// grammarFileName.lastIndexOf('.'))
// + "Visitor.go");
// }
// }
return true; // allIsWell: no compile
ErrorQueue equeue = antlrOnString(getTmpDir(), "Go", grammarFileName, grammarStr,
defaultListener, extraOptions);
if (!equeue.errors.isEmpty()) {
return false;
}
return true;
}
protected void rawBuildRecognizerTestFile(String parserName,
@ -561,40 +492,6 @@ public class BaseGoTest implements RuntimeTestSupport {
return runtimeDir;
}
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i += 2) {
String input = pairs[i];
String expect = pairs[i + 1];
String[] lines = input.split("\n");
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
ErrorQueue equeue = antlr(fileName, fileName, input, false);
String actual = equeue.toString(true);
actual = actual.replace(overall_tmpdir+ File.separator, "");
System.err.println(actual);
String msg = input;
msg = msg.replace("\n", "\\n");
msg = msg.replace("\r", "\\r");
msg = msg.replace("\t", "\\t");
assertEquals("error in: " + msg, expect, actual);
}
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
int grIndex = line.lastIndexOf("grammar");
int semi = line.lastIndexOf(';');
if (grIndex >= 0 && semi >= 0) {
int space = line.indexOf(' ', grIndex);
fileName = line.substring(space + 1, semi) + Tool.GRAMMAR_EXTENSION;
}
if (fileName.length() == Tool.GRAMMAR_EXTENSION.length())
fileName = "A" + Tool.GRAMMAR_EXTENSION;
return fileName;
}
// void ambig(List<Message> msgs, int[] expectedAmbigAlts, String
// expectedAmbigInput)
// throws Exception

View File

@ -61,10 +61,10 @@ import org.antlr.v4.runtime.misc.Pair;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.semantics.SemanticPipeline;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.DefaultToolListener;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.antlr.v4.tool.LexerGrammar;
@ -475,62 +475,6 @@ public class BaseJavaTest implements RuntimeTestSupport {
return ok;
}
protected ErrorQueue antlr(String grammarFileName, boolean defaultListener, String... extraOptions) {
final List<String> options = new ArrayList<String>();
Collections.addAll(options, extraOptions);
if ( !options.contains("-o") ) {
options.add("-o");
options.add(tmpdir);
}
if ( !options.contains("-lib") ) {
options.add("-lib");
options.add(tmpdir);
}
if ( !options.contains("-encoding") ) {
options.add("-encoding");
options.add("UTF-8");
}
options.add(new File(tmpdir, grammarFileName).toString());
final String[] optionsA = new String[options.size()];
options.toArray(optionsA);
Tool antlr = newTool(optionsA);
ErrorQueue equeue = new ErrorQueue(antlr);
antlr.addListener(equeue);
if ( defaultListener ) {
antlr.addListener(new DefaultToolListener(antlr));
}
synchronized (antlrLock) {
antlr.processGrammarsOnCommandLine();
}
if ( !defaultListener && !equeue.errors.isEmpty() ) {
for (int i = 0; i<equeue.errors.size(); i++) {
ANTLRMessage msg = equeue.errors.get(i);
antlrToolErrors.append(msg.toString());
}
try {
antlrToolErrors.append(new String(Utils.readFile(tmpdir+"/"+grammarFileName)));
} catch (IOException ioe) {
antlrToolErrors.append(ioe.toString());
}
}
if ( !defaultListener && !equeue.warnings.isEmpty() ) {
for (int i = 0; i<equeue.warnings.size(); i++) {
ANTLRMessage msg = equeue.warnings.get(i);
// antlrToolErrors.append(msg); warnings are hushed
}
}
return equeue;
}
protected ErrorQueue antlr(String grammarFileName, String grammarStr, boolean defaultListener, String... extraOptions) {
mkdir(tmpdir);
writeFile(tmpdir, grammarFileName, grammarStr);
return antlr(grammarFileName, defaultListener, extraOptions);
}
protected String execLexer(String grammarFileName,
String grammarStr,
String lexerName,
@ -678,7 +622,7 @@ public class BaseJavaTest implements RuntimeTestSupport {
String... extraOptions)
{
ErrorQueue equeue =
antlr(grammarFileName, grammarStr, defaultListener, extraOptions);
BaseRuntimeTest.antlrOnString(getTmpDir(), "Java", grammarFileName, grammarStr, defaultListener, extraOptions);
if (!equeue.errors.isEmpty()) {
return false;
}
@ -690,11 +634,14 @@ public class BaseJavaTest implements RuntimeTestSupport {
if ( parserName!=null ) {
files.add(parserName+".java");
Set<String> optionsSet = new HashSet<String>(Arrays.asList(extraOptions));
String grammarName = grammarFileName.substring(0, grammarFileName.lastIndexOf('.'));
if (!optionsSet.contains("-no-listener")) {
files.add(grammarFileName.substring(0, grammarFileName.lastIndexOf('.'))+"BaseListener.java");
files.add(grammarName+"Listener.java");
files.add(grammarName+"BaseListener.java");
}
if (optionsSet.contains("-visitor")) {
files.add(grammarFileName.substring(0, grammarFileName.lastIndexOf('.'))+"BaseVisitor.java");
files.add(grammarName+"Visitor.java");
files.add(grammarName+"BaseVisitor.java");
}
}
boolean allIsWell = compile(files.toArray(new String[files.size()]));
@ -808,39 +755,6 @@ public class BaseJavaTest implements RuntimeTestSupport {
return null;
}
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i+=2) {
String input = pairs[i];
String expect = pairs[i+1];
String[] lines = input.split("\n");
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
ErrorQueue equeue = antlr(fileName, input, false);
String actual = equeue.toString(true);
actual = actual.replace(tmpdir + File.separator, "");
// System.err.println(actual);
String msg = input;
msg = msg.replace("\n","\\n");
msg = msg.replace("\r","\\r");
msg = msg.replace("\t","\\t");
assertEquals("error in: "+msg,expect,actual);
}
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
int grIndex = line.lastIndexOf("grammar");
int semi = line.lastIndexOf(';');
if ( grIndex>=0 && semi>=0 ) {
int space = line.indexOf(' ', grIndex);
fileName = line.substring(space+1, semi)+Tool.GRAMMAR_EXTENSION;
}
if ( fileName.length()==Tool.GRAMMAR_EXTENSION.length() ) fileName = "A" + Tool.GRAMMAR_EXTENSION;
return fileName;
}
// void ambig(List<Message> msgs, int[] expectedAmbigAlts, String expectedAmbigInput)
// throws Exception
// {
@ -1061,11 +975,6 @@ public class BaseJavaTest implements RuntimeTestSupport {
}
}
protected void mkdir(String dir) {
File f = new File(dir);
f.mkdirs();
}
protected void writeTestFile(String parserName,
String lexerName,
String parserStartRuleName,

View File

@ -54,13 +54,11 @@ import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.semantics.SemanticPipeline;
import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.DOTGenerator;
import org.antlr.v4.tool.DefaultToolListener;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.antlr.v4.tool.LexerGrammar;
@ -97,7 +95,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import static org.antlr.v4.test.runtime.java.BaseJavaTest.antlrLock;
import static org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -272,54 +270,6 @@ public abstract class BaseBrowserTest implements RuntimeTestSupport {
return tokenTypes;
}
/** Return true if all is ok, no errors */
protected ErrorQueue antlr(String fileName, String grammarFileName, String grammarStr, boolean defaultListener, String... extraOptions) {
mkdir(tmpdir);
writeFile(tmpdir, fileName, grammarStr);
final List<String> options = new ArrayList<String>();
Collections.addAll(options, extraOptions);
options.add("-Dlanguage=JavaScript");
options.add("-o");
options.add(tmpdir);
options.add("-lib");
options.add(tmpdir);
options.add(new File(tmpdir,grammarFileName).toString());
final String[] optionsA = new String[options.size()];
options.toArray(optionsA);
Tool antlr = newTool(optionsA);
ErrorQueue equeue = new ErrorQueue(antlr);
antlr.addListener(equeue);
if (defaultListener) {
antlr.addListener(new DefaultToolListener(antlr));
}
synchronized (antlrLock) {
antlr.processGrammarsOnCommandLine();
}
if ( !defaultListener && !equeue.errors.isEmpty() ) {
for (int i = 0; i < equeue.errors.size(); i++) {
ANTLRMessage msg = equeue.errors.get(i);
antlrToolErrors.append(msg.toString());
}
try {
antlrToolErrors.append(new String(Utils.readFile(tmpdir+"/"+grammarFileName)));
}
catch (IOException ioe) {
antlrToolErrors.append(ioe.toString());
}
}
if ( !defaultListener && !equeue.warnings.isEmpty() ) {
for (int i = 0; i < equeue.warnings.size(); i++) {
ANTLRMessage msg = equeue.warnings.get(i);
// antlrToolErrors.append(msg); warnings are hushed
}
}
return equeue;
}
@Override
public String execLexer(String grammarFileName,
String grammarStr,
@ -399,7 +349,7 @@ public abstract class BaseBrowserTest implements RuntimeTestSupport {
String... extraOptions)
{
ErrorQueue equeue =
antlr(grammarFileName, grammarFileName, grammarStr, defaultListener, extraOptions);
antlrOnString(getTmpDir(), "JavaScript", grammarFileName, grammarStr, defaultListener, extraOptions);
if (!equeue.errors.isEmpty()) {
return false;
}
@ -545,39 +495,6 @@ public abstract class BaseBrowserTest implements RuntimeTestSupport {
return file.getAbsolutePath();
}
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i+=2) {
String input = pairs[i];
String expect = pairs[i+1];
String[] lines = input.split("\n");
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
ErrorQueue equeue = antlr(fileName, fileName, input, false);
String actual = equeue.toString(true);
actual = actual.replace(tmpdir + File.separator, "");
System.err.println(actual);
String msg = input;
msg = msg.replace("\n","\\n");
msg = msg.replace("\r","\\r");
msg = msg.replace("\t","\\t");
assertEquals("error in: "+msg,expect,actual);
}
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
int grIndex = line.lastIndexOf("grammar");
int semi = line.lastIndexOf(';');
if ( grIndex>=0 && semi>=0 ) {
int space = line.indexOf(' ', grIndex);
fileName = line.substring(space+1, semi)+Tool.GRAMMAR_EXTENSION;
}
if ( fileName.length()==Tool.GRAMMAR_EXTENSION.length() ) fileName = "A" + Tool.GRAMMAR_EXTENSION;
return fileName;
}
List<ANTLRMessage> getMessagesOfType(List<ANTLRMessage> msgs, Class<? extends ANTLRMessage> c) {
List<ANTLRMessage> filtered = new ArrayList<ANTLRMessage>();
for (ANTLRMessage m : msgs) {

View File

@ -54,13 +54,11 @@ import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.semantics.SemanticPipeline;
import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.DOTGenerator;
import org.antlr.v4.tool.DefaultToolListener;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.antlr.v4.tool.LexerGrammar;
@ -89,7 +87,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import static org.antlr.v4.test.runtime.java.BaseJavaTest.antlrLock;
import static org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -260,56 +258,6 @@ public class BaseNodeTest implements RuntimeTestSupport {
return tokenTypes;
}
/** Return true if all is ok, no errors */
protected ErrorQueue antlr(String fileName, String grammarFileName,
String grammarStr, boolean defaultListener, String... extraOptions) {
if(grammarStr!=null) {
mkdir(tmpdir);
writeFile(tmpdir, fileName, grammarStr);
}
final List<String> options = new ArrayList<String>();
Collections.addAll(options, extraOptions);
options.add("-Dlanguage=JavaScript");
options.add("-o");
options.add(tmpdir);
options.add("-lib");
options.add(tmpdir);
options.add(new File(tmpdir, grammarFileName).toString());
final String[] optionsA = new String[options.size()];
options.toArray(optionsA);
Tool antlr = newTool(optionsA);
ErrorQueue equeue = new ErrorQueue(antlr);
antlr.addListener(equeue);
if (defaultListener) {
antlr.addListener(new DefaultToolListener(antlr));
}
synchronized (antlrLock) {
antlr.processGrammarsOnCommandLine();
}
if ( !defaultListener && !equeue.errors.isEmpty() ) {
for (int i = 0; i < equeue.errors.size(); i++) {
ANTLRMessage msg = equeue.errors.get(i);
antlrToolErrors.append(msg.toString());
}
try {
antlrToolErrors.append(new String(Utils.readFile(tmpdir+"/"+grammarFileName)));
}
catch (IOException ioe) {
antlrToolErrors.append(ioe.toString());
}
}
if ( !defaultListener && !equeue.warnings.isEmpty() ) {
for (int i = 0; i < equeue.warnings.size(); i++) {
ANTLRMessage msg = equeue.warnings.get(i);
// antlrToolErrors.append(msg); warnings are hushed
}
}
return equeue;
}
protected String execLexer(String grammarFileName, String grammarStr,
String lexerName, String input) {
return execLexer(grammarFileName, grammarStr, lexerName, input, false);
@ -357,8 +305,8 @@ public class BaseNodeTest implements RuntimeTestSupport {
protected boolean rawGenerateAndBuildRecognizer(String grammarFileName,
String grammarStr, String parserName, String lexerName,
boolean defaultListener, String... extraOptions) {
ErrorQueue equeue = antlr(grammarFileName, grammarFileName, grammarStr,
defaultListener, extraOptions);
ErrorQueue equeue = antlrOnString(getTmpDir(), "JavaScript", grammarFileName, grammarStr,
defaultListener, extraOptions);
if (!equeue.errors.isEmpty()) {
return false;
}
@ -497,40 +445,6 @@ public class BaseNodeTest implements RuntimeTestSupport {
return System.getProperty("os.name").toLowerCase().contains("windows");
}
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i += 2) {
String input = pairs[i];
String expect = pairs[i + 1];
String[] lines = input.split("\n");
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
ErrorQueue equeue = antlr(fileName, fileName, input, false);
String actual = equeue.toString(true);
actual = actual.replace(tmpdir + File.separator, "");
System.err.println(actual);
String msg = input;
msg = msg.replace("\n", "\\n");
msg = msg.replace("\r", "\\r");
msg = msg.replace("\t", "\\t");
assertEquals("error in: " + msg, expect, actual);
}
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
int grIndex = line.lastIndexOf("grammar");
int semi = line.lastIndexOf(';');
if (grIndex >= 0 && semi >= 0) {
int space = line.indexOf(' ', grIndex);
fileName = line.substring(space + 1, semi) + Tool.GRAMMAR_EXTENSION;
}
if (fileName.length() == Tool.GRAMMAR_EXTENSION.length())
fileName = "A" + Tool.GRAMMAR_EXTENSION;
return fileName;
}
// void ambig(List<Message> msgs, int[] expectedAmbigAlts, String
// expectedAmbigInput)
// throws Exception

View File

@ -56,14 +56,12 @@ import org.antlr.v4.runtime.atn.LexerATNSimulator;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.IntegerList;
import org.antlr.v4.runtime.misc.Interval;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.semantics.SemanticPipeline;
import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.DOTGenerator;
import org.antlr.v4.tool.DefaultToolListener;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.antlr.v4.tool.LexerGrammar;
@ -95,7 +93,7 @@ import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import static org.antlr.v4.test.runtime.java.BaseJavaTest.antlrLock;
import static org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@ -358,53 +356,6 @@ public abstract class BasePythonTest implements RuntimeTestSupport {
protected abstract String getLanguage();
/** Return true if all is ok, no errors */
protected ErrorQueue antlr(String fileName, String grammarFileName, String grammarStr, boolean defaultListener, String... extraOptions) {
mkdir(tmpdir);
writeFile(tmpdir, fileName, grammarStr);
final List<String> options = new ArrayList<String>();
Collections.addAll(options, extraOptions);
options.add("-Dlanguage=" + getLanguage());
options.add("-o");
options.add(tmpdir);
options.add("-lib");
options.add(tmpdir);
options.add(new File(tmpdir,grammarFileName).toString());
final String[] optionsA = new String[options.size()];
options.toArray(optionsA);
Tool antlr = newTool(optionsA);
ErrorQueue equeue = new ErrorQueue(antlr);
antlr.addListener(equeue);
if (defaultListener) {
antlr.addListener(new DefaultToolListener(antlr));
}
synchronized (antlrLock) {
antlr.processGrammarsOnCommandLine();
}
if ( !defaultListener && !equeue.errors.isEmpty() ) {
for (int i = 0; i < equeue.errors.size(); i++) {
ANTLRMessage msg = equeue.errors.get(i);
antlrToolErrors.append(msg.toString());
}
try {
antlrToolErrors.append(new String(Utils.readFile(tmpdir+"/"+grammarFileName)));
}
catch (IOException ioe) {
antlrToolErrors.append(ioe.toString());
}
}
if ( !defaultListener && !equeue.warnings.isEmpty() ) {
for (int i = 0; i < equeue.warnings.size(); i++) {
ANTLRMessage msg = equeue.warnings.get(i);
// antlrToolErrors.append(msg); warnings are hushed
}
}
return equeue;
}
protected String execLexer(String grammarFileName,
String grammarStr,
String lexerName,
@ -510,7 +461,7 @@ public abstract class BasePythonTest implements RuntimeTestSupport {
String... extraOptions)
{
ErrorQueue equeue =
antlr(grammarFileName, grammarFileName, grammarStr, defaultListener, extraOptions);
antlrOnString(getTmpDir(), getLanguage(), grammarFileName, grammarStr, defaultListener, extraOptions);
if (!equeue.errors.isEmpty()) {
return false;
}
@ -632,39 +583,6 @@ public abstract class BasePythonTest implements RuntimeTestSupport {
return System.getProperty("os.name").toLowerCase().contains("windows");
}
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i+=2) {
String input = pairs[i];
String expect = pairs[i+1];
String[] lines = input.split("\n");
String fileName = getFilenameFromFirstLineOfGrammar(lines[0]);
ErrorQueue equeue = antlr(fileName, fileName, input, false);
String actual = equeue.toString(true);
actual = actual.replace(tmpdir + File.separator, "");
System.err.println(actual);
String msg = input;
msg = msg.replace("\n","\\n");
msg = msg.replace("\r","\\r");
msg = msg.replace("\t","\\t");
assertEquals("error in: "+msg,expect,actual);
}
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "A" + Tool.GRAMMAR_EXTENSION;
int grIndex = line.lastIndexOf("grammar");
int semi = line.lastIndexOf(';');
if ( grIndex>=0 && semi>=0 ) {
int space = line.indexOf(' ', grIndex);
fileName = line.substring(space+1, semi)+Tool.GRAMMAR_EXTENSION;
}
if ( fileName.length()==Tool.GRAMMAR_EXTENSION.length() ) fileName = "A" + Tool.GRAMMAR_EXTENSION;
return fileName;
}
// void ambig(List<Message> msgs, int[] expectedAmbigAlts, String expectedAmbigInput)
// throws Exception
// {

View File

@ -0,0 +1,529 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.Tool;
import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.stringtemplate.v4.ST;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.antlr.v4.test.runtime.BaseRuntimeTest.antlrOnString;
import static org.junit.Assert.assertTrue;
public class BaseSwiftTest implements RuntimeTestSupport {
/**
* The base test directory is the directory where generated files get placed
* during unit test execution.
*/
private static final String BASE_TEST_DIR;
private static String ANTLR_FRAMEWORK_DIR;
/**
* Common routine to setup the ANTLR4 runtime.
*/
static {
String baseTestDir = System.getProperty("antlr-swift-test-dir");
if (baseTestDir == null || baseTestDir.isEmpty()) {
baseTestDir = System.getProperty("java.io.tmpdir");
}
if (!new File(baseTestDir).isDirectory()) {
throw new UnsupportedOperationException("The specified base test directory does not exist: " + baseTestDir);
}
BASE_TEST_DIR = baseTestDir;
//add antlr.swift
final ClassLoader loader = Thread.currentThread().getContextClassLoader();
final URL swiftRuntime = loader.getResource("Swift/Antlr4");
if (swiftRuntime == null) {
throw new RuntimeException("Swift runtime file not found at:" + swiftRuntime.getPath());
}
String swiftRuntimePath = swiftRuntime.getPath();
try {
String commandLine = "find " + swiftRuntimePath + "/ -iname *.swift -not -name merge.swift -exec cat {} ;";
ProcessBuilder builder = new ProcessBuilder(commandLine.split(" "));
builder.redirectError(ProcessBuilder.Redirect.INHERIT);
Process p = builder.start();
StreamVacuum stdoutVacuum = new StreamVacuum(p.getInputStream());
stdoutVacuum.start();
p.waitFor();
stdoutVacuum.join();
String antlrSwift = stdoutVacuum.toString();
//write to Antlr4
ANTLR_FRAMEWORK_DIR = new File(BASE_TEST_DIR, "Antlr4").getAbsolutePath();
mkdir(ANTLR_FRAMEWORK_DIR);
writeFile(ANTLR_FRAMEWORK_DIR, "Antlr4.swift", antlrSwift);
//compile Antlr4 module
buildAntlr4Framework();
String argsString;
}
catch (Exception e) {
e.printStackTrace(System.err);
}
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
// shutdown logic
eraseAntlrFrameWorkDir();
}
});
}
private static void eraseFilesIn(String dirName) {
if (dirName == null) {
return;
}
File dir = new File(dirName);
String[] files = dir.list();
if (files != null) for (String file : files) {
new File(dirName + "/" + file).delete();
}
}
private static void eraseAntlrFrameWorkDir() {
File frameworkdir = new File(ANTLR_FRAMEWORK_DIR);
if (frameworkdir.exists()) {
eraseFilesIn(ANTLR_FRAMEWORK_DIR);
frameworkdir.delete();
}
}
private static boolean buildAntlr4Framework() throws Exception {
String argsString = "xcrun -sdk macosx swiftc -emit-library -emit-module Antlr4.swift -module-name Antlr4 -module-link-name Antlr4 -Xlinker -install_name -Xlinker " + ANTLR_FRAMEWORK_DIR + "/libAntlr4.dylib ";
return runProcess(argsString, ANTLR_FRAMEWORK_DIR);
}
public static class StreamVacuum implements Runnable {
StringBuilder buf = new StringBuilder();
BufferedReader in;
Thread sucker;
public StreamVacuum(InputStream in) {
this.in = new BufferedReader(new InputStreamReader(in));
}
public void start() {
sucker = new Thread(this);
sucker.start();
}
@Override
public void run() {
try {
String line = in.readLine();
while (line != null) {
buf.append(line);
buf.append('\n');
line = in.readLine();
}
}
catch (IOException ioe) {
System.err.println("can't read output from process");
ioe.printStackTrace(System.err);
}
}
/**
* wait for the thread to finish
*/
public void join() throws InterruptedException {
sucker.join();
}
@Override
public String toString() {
return buf.toString();
}
}
public String tmpdir = null;
/**
* Errors found while running antlr
*/
private StringBuilder antlrToolErrors;
/**
* If error during parser execution, store stderr here; can't return
* stdout and stderr. This doesn't trap errors from running antlr.
*/
protected String stderrDuringParse;
@Override
public void testSetUp() throws Exception {
// new output dir for each test
String propName = "antlr-swift-test-dir";
String prop = System.getProperty(propName);
if (prop != null && prop.length() > 0) {
tmpdir = prop;
} else {
tmpdir = new File(System.getProperty("java.io.tmpdir"), getClass().getSimpleName() +
"-" + Thread.currentThread().getName() + "-" + System.currentTimeMillis()).getAbsolutePath();
}
antlrToolErrors = new StringBuilder();
}
@Override
public void testTearDown() throws Exception {
}
@Override
public void eraseTempDir() {
}
@Override
public String getTmpDir() {
return tmpdir;
}
@Override
public String getStdout() {
return null;
}
@Override
public String getParseErrors() {
return stderrDuringParse;
}
@Override
public String getANTLRToolErrors() {
if (antlrToolErrors.length() == 0) {
return null;
}
return antlrToolErrors.toString();
}
@Override
public String execLexer(String grammarFileName, String grammarStr, String lexerName, String input, boolean showDFA) {
boolean success = rawGenerateRecognizer(grammarFileName,
grammarStr,
null,
lexerName);
assertTrue(success);
writeFile(tmpdir, "input", input);
writeLexerTestFile(lexerName, showDFA);
addSourceFiles("main.swift");
compile();
String output = execTest();
return output;
}
private String execTest() {
try {
String exec = tmpdir + "/" + EXEC_NAME;
String[] args =
new String[]{exec, "input"};//new File(tmpdir, "input").getAbsolutePath()
ProcessBuilder pb = new ProcessBuilder(args);
pb.directory(new File(tmpdir));
Process p = pb.start();
StreamVacuum stdoutVacuum = new StreamVacuum(p.getInputStream());
StreamVacuum stderrVacuum = new StreamVacuum(p.getErrorStream());
stdoutVacuum.start();
stderrVacuum.start();
p.waitFor();
stdoutVacuum.join();
stderrVacuum.join();
String output = stdoutVacuum.toString();
if ( output.length()==0 ) {
output = null;
}
if (stderrVacuum.toString().length() > 0) {
this.stderrDuringParse = stderrVacuum.toString();
}
return output;
}
catch (Exception e) {
System.err.println("can't exec recognizer");
e.printStackTrace(System.err);
}
return null;
}
private Set<String> sourceFiles = new HashSet<String>();
private void addSourceFiles(String... files) {
Collections.addAll(this.sourceFiles, files);
}
public boolean compile() {
try {
return buildProject();
} catch (Exception e) {
return false;
}
}
private static final String EXEC_NAME = "Test";
private boolean buildProject() throws Exception {
String fileList = sourceFiles.toString().replace("[", "").replace("]", "")
.replace(", ", " ");
String argsString = "xcrun -sdk macosx swiftc " + fileList + " -o " + EXEC_NAME + " -I " + ANTLR_FRAMEWORK_DIR + " -L " + ANTLR_FRAMEWORK_DIR + " -module-link-name Antlr4 -suppress-warnings";
return runProcess(argsString, tmpdir);
}
private static boolean runProcess(String argsString, String execPath) throws IOException, InterruptedException {
String[] args = argsString.split(" ");
// System.err.println("Starting build " + argsString);//Utils.join(args, " "))
Process process = Runtime.getRuntime().exec(args, null, new File(execPath));
StreamVacuum stdoutVacuum = new StreamVacuum(process.getInputStream());
StreamVacuum stderrVacuum = new StreamVacuum(process.getErrorStream());
stdoutVacuum.start();
stderrVacuum.start();
process.waitFor();
stdoutVacuum.join();
stderrVacuum.join();
if (stderrVacuum.toString().length() > 0) {
//this.stderrDuringParse = stderrVacuum.toString();
System.err.println("buildProject stderrVacuum: " + stderrVacuum);
}
return process.exitValue() == 0;
}
@Override
public String execParser(String grammarFileName, String grammarStr, String parserName, String lexerName, String listenerName, String visitorName, String startRuleName, String input, boolean showDiagnosticErrors) {
return execParser(grammarFileName, grammarStr, parserName,
lexerName, startRuleName, input, showDiagnosticErrors, false);
}
protected String execParser(String grammarFileName,
String grammarStr,
String parserName,
String lexerName,
String startRuleName,
String input, boolean debug,boolean profile)
{
boolean success = rawGenerateRecognizer(grammarFileName,
grammarStr,
parserName,
lexerName,
"-visitor");
assertTrue(success);
writeFile(tmpdir, "input", input);
return rawExecRecognizer(parserName,
lexerName,
startRuleName,
debug,profile);
}
protected String rawExecRecognizer(String parserName,
String lexerName,
String parserStartRuleName,
boolean debug,
boolean profile)
{
this.stderrDuringParse = null;
if ( parserName==null ) {
writeLexerTestFile(lexerName, false);
}
else {
writeParserTestFile(parserName,
lexerName,
parserStartRuleName,
debug,
profile);
}
addSourceFiles("main.swift");
return execRecognizer();
}
public String execRecognizer() {
compile();
return execTest();
}
public static void writeFile(String dir, String fileName, String content) {
try {
File f = new File(dir, fileName);
FileWriter w = new FileWriter(f);
BufferedWriter bw = new BufferedWriter(w);
bw.write(content);
bw.close();
w.close();
} catch (IOException ioe) {
System.err.println("can't write file");
ioe.printStackTrace(System.err);
}
}
protected void writeParserTestFile(String parserName,
String lexerName,
String parserStartRuleName,
boolean debug,
boolean profile) {
ST outputFileST = new ST(
"import Antlr4\n" +
"import Foundation\n" +
"setbuf(__stdoutp, nil)\n" +
"class TreeShapeListener: ParseTreeListener{\n" +
" func visitTerminal(_ node: TerminalNode){ }\n" +
" func visitErrorNode(_ node: ErrorNode){ }\n" +
" func enterEveryRule(_ ctx: ParserRuleContext) throws { }\n" +
" func exitEveryRule(_ ctx: ParserRuleContext) throws {\n" +
" for i in 0..\\<ctx.getChildCount() {\n" +
" let parent = ctx.getChild(i)?.getParent()\n" +
" if (!(parent is RuleNode) || (parent as! RuleNode ).getRuleContext() !== ctx) {\n" +
" throw ANTLRError.illegalState(msg: \"Invalid parse tree shape detected.\")\n" +
" }\n" +
" }\n" +
" }\n" +
"}\n" +
"\n" +
"do {\n" +
"let args = CommandLine.arguments\n" +
"let input = ANTLRFileStream(args[1])\n" +
"let lex = <lexerName>(input)\n" +
"let tokens = CommonTokenStream(lex)\n" +
"<createParser>\n" +
"parser.setBuildParseTree(true)\n" +
"<profile>\n" +
"let tree = try parser.<parserStartRuleName>()\n" +
"<if(profile)>print(profiler.getDecisionInfo().description)<endif>\n" +
"try ParseTreeWalker.DEFAULT.walk(TreeShapeListener(), tree)\n" +
"}catch ANTLRException.cannotInvokeStartRule {\n" +
" print(\"error occur: cannotInvokeStartRule\")\n" +
"}catch ANTLRException.recognition(let e ) {\n" +
" print(\"error occur\\(e)\")\n" +
"}catch {\n" +
" print(\"error occur\")\n" +
"}\n"
);
ST createParserST = new ST(" let parser = try <parserName>(tokens)\n");
if (debug) {
createParserST =
new ST(
" let parser = try <parserName>(tokens)\n" +
" parser.addErrorListener(DiagnosticErrorListener())\n");
}
if (profile) {
outputFileST.add("profile",
"let profiler = ProfilingATNSimulator(parser)\n" +
"parser.setInterpreter(profiler)");
} else {
outputFileST.add("profile", new ArrayList<Object>());
}
outputFileST.add("createParser", createParserST);
outputFileST.add("parserName", parserName);
outputFileST.add("lexerName", lexerName);
outputFileST.add("parserStartRuleName", parserStartRuleName);
writeFile(tmpdir, "main.swift", outputFileST.render());
}
protected void writeLexerTestFile(String lexerName, boolean showDFA) {
ST outputFileST = new ST(
"import Antlr4\n" +
"import Foundation\n" +
"setbuf(__stdoutp, nil)\n" +
"let args = CommandLine.arguments\n" +
"let input = ANTLRFileStream(args[1])\n" +
"let lex = <lexerName>(input)\n" +
"let tokens = CommonTokenStream(lex)\n" +
"do {\n" +
" try tokens.fill()\n" +
"} catch ANTLRException.cannotInvokeStartRule {\n" +
" print(\"error occur: cannotInvokeStartRule\")\n" +
"} catch ANTLRException.recognition(let e ) {\n" +
" print(\"error occur\\(e)\")\n" +
"} catch {\n" +
" print(\"error occur\")\n" +
"}\n" +
"for t in tokens.getTokens() {\n" +
" print(t)\n" +
"}\n" +
(showDFA ? "print(lex.getInterpreter().getDFA(Lexer.DEFAULT_MODE).toLexerString(), terminator: \"\" )\n" : ""));
outputFileST.add("lexerName", lexerName);
writeFile(tmpdir, "main.swift", outputFileST.render());
}
/**
* Return true if all is well
*/
private boolean rawGenerateRecognizer(String grammarFileName,
String grammarStr,
String parserName,
String lexerName,
String... extraOptions) {
return rawGenerateRecognizer(grammarFileName, grammarStr, parserName, lexerName, false, extraOptions);
}
/**
* Return true if all is well
*/
private boolean rawGenerateRecognizer(String grammarFileName,
String grammarStr,
String parserName,
String lexerName,
boolean defaultListener,
String... extraOptions) {
ErrorQueue equeue = antlrOnString(getTmpDir(), "Swift", grammarFileName, grammarStr, defaultListener, extraOptions);
if (!equeue.errors.isEmpty()) {
return false;
}
List<String> files = new ArrayList<String>();
if (lexerName != null) {
files.add(lexerName + ".swift");
files.add(lexerName + "ATN.swift");
}
if (parserName != null) {
files.add(parserName + ".swift");
files.add(parserName + "ATN.swift");
Set<String> optionsSet = new HashSet<String>(Arrays.asList(extraOptions));
String grammarName = grammarFileName.substring(0, grammarFileName.lastIndexOf('.'));
if (!optionsSet.contains("-no-listener")) {
files.add(grammarName + "Listener.swift");
files.add(grammarName + "BaseListener.swift");
}
if (optionsSet.contains("-visitor")) {
files.add(grammarName + "Visitor.swift");
files.add(grammarName + "BaseVisitor.swift");
}
}
addSourceFiles(files.toArray(new String[files.size()]));
return true;
}
protected static void mkdir(String dir) {
File f = new File(dir);
f.mkdirs();
}
protected Tool newTool(String[] args) {
return new Tool(args);
}
protected Tool newTool() {
return new Tool(new String[]{"-o", tmpdir});
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.CompositeLexersDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestCompositeLexers extends BaseRuntimeTest {
public TestCompositeLexers(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(CompositeLexersDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.CompositeParsersDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestCompositeParsers extends BaseRuntimeTest {
public TestCompositeParsers(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(CompositeParsersDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.FullContextParsingDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestFullContextParsing extends BaseRuntimeTest {
public TestFullContextParsing(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(FullContextParsingDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.LeftRecursionDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestLeftRecursion extends BaseRuntimeTest {
public TestLeftRecursion(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(LeftRecursionDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,22 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.LexerErrorsDescriptors;
import org.junit.Test;
import org.junit.Ignore;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestLexerErrors extends BaseRuntimeTest {
public TestLexerErrors(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(LexerErrorsDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.LexerExecDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestLexerExec extends BaseRuntimeTest {
public TestLexerExec(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(LexerExecDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.ListenersDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestListeners extends BaseRuntimeTest {
public TestListeners(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(ListenersDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.ParseTreesDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestParseTrees extends BaseRuntimeTest {
public TestParseTrees(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(ParseTreesDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.ParserErrorsDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestParserErrors extends BaseRuntimeTest {
public TestParserErrors(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(ParserErrorsDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.ParserExecDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestParserExec extends BaseRuntimeTest {
public TestParserExec(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(ParserExecDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.PerformanceDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestPerformance extends BaseRuntimeTest {
public TestPerformance(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(PerformanceDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,21 @@
/* This file is generated by TestGenerator, any edits will be overwritten by the next generation. */
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.SemPredEvalLexerDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestSemPredEvalLexer extends BaseRuntimeTest {
public TestSemPredEvalLexer(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(SemPredEvalLexerDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.SemPredEvalParserDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestSemPredEvalParser extends BaseRuntimeTest {
public TestSemPredEvalParser(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(SemPredEvalParserDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.SetsDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestSets extends BaseRuntimeTest {
public TestSets(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(SetsDescriptors.class, "Swift");
}
}

View File

@ -0,0 +1,20 @@
package org.antlr.v4.test.runtime.swift;
import org.antlr.v4.test.runtime.BaseRuntimeTest;
import org.antlr.v4.test.runtime.RuntimeTestDescriptor;
import org.antlr.v4.test.runtime.descriptors.VisitorsDescriptors;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@RunWith(Parameterized.class)
public class TestVisitors extends BaseRuntimeTest {
public TestVisitors(RuntimeTestDescriptor descriptor) {
super(descriptor,new BaseSwiftTest());
}
@Parameterized.Parameters(name="{0}")
public static RuntimeTestDescriptor[] getAllTestDescriptors() {
return BaseRuntimeTest.getRuntimeTestDescriptors(VisitorsDescriptors.class, "Swift");
}
}

View File

@ -367,7 +367,12 @@ public class ATNSerializer {
// don't adjust the first value since that's the version number
for (int i = 1; i < data.size(); i++) {
if (data.get(i) < Character.MIN_VALUE || data.get(i) > Character.MAX_VALUE) {
throw new UnsupportedOperationException("Serialized ATN data element out of range.");
throw new UnsupportedOperationException("Serialized ATN data element "+
data.get(i)+
" element "+i+" out of range "+
(int)Character.MIN_VALUE+
".."+
(int)Character.MAX_VALUE);
}
int value = (data.get(i) + 2) & 0xFFFF;

View File

@ -58,6 +58,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.antlr.v4.runtime.atn.ATNState.BLOCK_END;
/**
* The embodiment of the adaptive LL(*), ALL(*), parsing strategy.
*
@ -291,6 +293,9 @@ public class ParserATNSimulator extends ATNSimulator {
public static final boolean dfa_debug = false;
public static final boolean retry_debug = false;
/** Just in case this optimization is bad, add an ENV variable to turn it off */
public static final boolean TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT = Boolean.parseBoolean(System.getenv("TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT"));
protected final Parser parser;
public final DFA[] decisionToDFA;
@ -788,7 +793,7 @@ public class ParserATNSimulator extends ATNSimulator {
protected ATNConfigSet computeReachSet(ATNConfigSet closure, int t,
boolean fullCtx)
{
if ( debug )
if ( debug )
System.out.println("in computeReachSet, starting closure: " + closure);
if (mergeCache == null) {
@ -1552,6 +1557,8 @@ public class ParserATNSimulator extends ATNSimulator {
}
for (int i=0; i<p.getNumberOfTransitions(); i++) {
if ( i==0 && canDropLoopEntryEdgeInLeftRecursiveRule(config) ) continue;
Transition t = p.transition(i);
boolean continueCollecting =
!(t instanceof ActionTransition) && collectPredicates;
@ -1603,6 +1610,165 @@ public class ParserATNSimulator extends ATNSimulator {
}
}
/** Implements first-edge (loop entry) elimination as an optimization
* during closure operations. See antlr/antlr4#1398.
*
* The optimization is to avoid adding the loop entry config when
* the exit path can only lead back to the same
* StarLoopEntryState after popping context at the rule end state
* (traversing only epsilon edges, so we're still in closure, in
* this same rule).
*
* We need to detect any state that can reach loop entry on
* epsilon w/o exiting rule. We don't have to look at FOLLOW
* links, just ensure that all stack tops for config refer to key
* states in LR rule.
*
* To verify we are in the right situation we must first check
* closure is at a StarLoopEntryState generated during LR removal.
* Then we check that each stack top of context is a return state
* from one of these cases:
*
* 1. 'not' expr, '(' type ')' expr. The return state points at loop entry state
* 2. expr op expr. The return state is the block end of internal block of (...)*
* 3. 'between' expr 'and' expr. The return state of 2nd expr reference.
* That state points at block end of internal block of (...)*.
* 4. expr '?' expr ':' expr. The return state points at block end,
* which points at loop entry state.
*
* If any is true for each stack top, then closure does not add a
* config to the current config set for edge[0], the loop entry branch.
*
* Conditions fail if any context for the current config is:
*
* a. empty (we'd fall out of expr to do a global FOLLOW which could
* even be to some weird spot in expr) or,
* b. lies outside of expr or,
* c. lies within expr but at a state not the BlockEndState
* generated during LR removal
*
* Do we need to evaluate predicates ever in closure for this case?
*
* No. Predicates, including precedence predicates, are only
* evaluated when computing a DFA start state. I.e., only before
* the lookahead (but not parser) consumes a token.
*
* There are no epsilon edges allowed in LR rule alt blocks or in
* the "primary" part (ID here). If closure is in
* StarLoopEntryState any lookahead operation will have consumed a
* token as there are no epsilon-paths that lead to
* StarLoopEntryState. We do not have to evaluate predicates
* therefore if we are in the generated StarLoopEntryState of a LR
* rule. Note that when making a prediction starting at that
* decision point, decision d=2, compute-start-state performs
* closure starting at edges[0], edges[1] emanating from
* StarLoopEntryState. That means it is not performing closure on
* StarLoopEntryState during compute-start-state.
*
* How do we know this always gives same prediction answer?
*
* Without predicates, loop entry and exit paths are ambiguous
* upon remaining input +b (in, say, a+b). Either paths lead to
* valid parses. Closure can lead to consuming + immediately or by
* falling out of this call to expr back into expr and loop back
* again to StarLoopEntryState to match +b. In this special case,
* we choose the more efficient path, which is to take the bypass
* path.
*
* The lookahead language has not changed because closure chooses
* one path over the other. Both paths lead to consuming the same
* remaining input during a lookahead operation. If the next token
* is an operator, lookahead will enter the choice block with
* operators. If it is not, lookahead will exit expr. Same as if
* closure had chosen to enter the choice block immediately.
*
* Closure is examining one config (some loopentrystate, some alt,
* context) which means it is considering exactly one alt. Closure
* always copies the same alt to any derived configs.
*
* How do we know this optimization doesn't mess up precedence in
* our parse trees?
*
* Looking through expr from left edge of stat only has to confirm
* that an input, say, a+b+c; begins with any valid interpretation
* of an expression. The precedence actually doesn't matter when
* making a decision in stat seeing through expr. It is only when
* parsing rule expr that we must use the precedence to get the
* right interpretation and, hence, parse tree.
*
* @since 4.6
*/
protected boolean canDropLoopEntryEdgeInLeftRecursiveRule(ATNConfig config) {
if ( TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT ) return false;
ATNState p = config.state;
// First check to see if we are in StarLoopEntryState generated during
// left-recursion elimination. For efficiency, also check if
// the context has an empty stack case. If so, it would mean
// global FOLLOW so we can't perform optimization
if ( p.getStateType() != ATNState.STAR_LOOP_ENTRY ||
!((StarLoopEntryState)p).isPrecedenceDecision || // Are we the special loop entry/exit state?
config.context.isEmpty() || // If SLL wildcard
config.context.hasEmptyPath())
{
return false;
}
// Require all return states to return back to the same rule
// that p is in.
int numCtxs = config.context.size();
for (int i = 0; i < numCtxs; i++) { // for each stack context
ATNState returnState = atn.states.get(config.context.getReturnState(i));
if ( returnState.ruleIndex != p.ruleIndex ) return false;
}
BlockStartState decisionStartState = (BlockStartState)p.transition(0).target;
int blockEndStateNum = decisionStartState.endState.stateNumber;
BlockEndState blockEndState = (BlockEndState)atn.states.get(blockEndStateNum);
// Verify that the top of each stack context leads to loop entry/exit
// state through epsilon edges and w/o leaving rule.
for (int i = 0; i < numCtxs; i++) { // for each stack context
int returnStateNumber = config.context.getReturnState(i);
ATNState returnState = atn.states.get(returnStateNumber);
// all states must have single outgoing epsilon edge
if ( returnState.getNumberOfTransitions()!=1 ||
!returnState.transition(0).isEpsilon() )
{
return false;
}
// Look for prefix op case like 'not expr', (' type ')' expr
ATNState returnStateTarget = returnState.transition(0).target;
if ( returnState.getStateType()==BLOCK_END && returnStateTarget==p ) {
continue;
}
// Look for 'expr op expr' or case where expr's return state is block end
// of (...)* internal block; the block end points to loop back
// which points to p but we don't need to check that
if ( returnState==blockEndState ) {
continue;
}
// Look for ternary expr ? expr : expr. The return state points at block end,
// which points at loop entry state
if ( returnStateTarget==blockEndState ) {
continue;
}
// Look for complex prefix 'between expr and expr' case where 2nd expr's
// return state points at block end state of (...)* internal block
if ( returnStateTarget.getStateType() == BLOCK_END &&
returnStateTarget.getNumberOfTransitions()==1 &&
returnStateTarget.transition(0).isEpsilon() &&
returnStateTarget.transition(0).target == p )
{
continue;
}
// anything else ain't conforming
return false;
}
return true;
}
public String getRuleName(int index) {
if ( parser!=null && index>=0 ) return parser.getRuleNames()[index];
@ -2036,4 +2202,4 @@ public class ParserATNSimulator extends ATNSimulator {
public Parser getParser() {
return parser;
}
}
}

View File

@ -117,12 +117,13 @@ public abstract class PredictionContext {
public abstract int getReturnState(int index);
/** This means only the {@link #EMPTY} context is in set. */
/** This means only the {@link #EMPTY} (wildcard? not sure) context is in set. */
public boolean isEmpty() {
return this == EMPTY;
}
public boolean hasEmptyPath() {
// since EMPTY_RETURN_STATE can only appear in the last position, we check last one
return getReturnState(size() - 1) == EMPTY_RETURN_STATE;
}

View File

@ -188,7 +188,7 @@ SingletonPredictionContext.prototype.hashString = function() {
SingletonPredictionContext.prototype.toString = function() {
var up = this.parentCtx === null ? "" : this.parentCtx.toString();
if (up.length === 0) {
if (this.returnState === this.EMPTY_RETURN_STATE) {
if (this.returnState === PredictionContext.EMPTY_RETURN_STATE) {
return "$";
} else {
return "" + this.returnState;

View File

@ -87,11 +87,12 @@ function ParseTreeVisitor() {
}
ParseTreeVisitor.prototype.visit = function(ctx) {
if (Utils.isArray(ctx)) {
var self = this;
return ctx.map(function(child) { return visitAtom(self, child)});
if (Utils.isArray(ctx)) {
return ctx.map(function(child) {
return ctx.accept(this);
}, this);
} else {
return visitAtom(this, ctx);
return ctx.accept(this);
}
};
@ -106,10 +107,6 @@ ParseTreeVisitor.prototype.visitErrorNode = function(node) {
};
var visitAtom = function(visitor, ctx) {
return ctx.accept(visitor);
};
function ParseTreeListener() {
return this;
}

View File

@ -0,0 +1,231 @@
from StringIO import StringIO
from antlr4.Token import Token
from antlr4.CommonTokenStream import CommonTokenStream
class TokenStreamRewriter(object):
DEFAULT_PROGRAM_NAME = "default"
PROGRAM_INIT_SIZE = 100
MIN_TOKEN_INDEX = 0
def __init__(self, tokens):
"""
:type tokens: antlr4.BufferedTokenStream.BufferedTokenStream
:param tokens:
:return:
"""
super(TokenStreamRewriter, self).__init__()
self.tokens = tokens
self.programs = {self.DEFAULT_PROGRAM_NAME: []}
self.lastRewriteTokenIndexes = {}
def getTokenStream(self):
return self.tokens
def rollback(self, instruction_index, program_name):
ins = self.programs.get(program_name, None)
if ins:
self.programs[program_name] = ins[self.MIN_TOKEN_INDEX: instruction_index]
def deleteProgram(self, program_name=DEFAULT_PROGRAM_NAME):
self.rollback(self.MIN_TOKEN_INDEX, program_name)
def insertAfterToken(self, token, text, program_name=DEFAULT_PROGRAM_NAME):
self.insertAfter(token.tokenIndex, text, program_name)
def insertAfter(self, index, text, program_name=DEFAULT_PROGRAM_NAME):
self.insertBefore(program_name, index + 1, text)
def insertBeforeIndex(self, index, text):
self.insertBefore(self.DEFAULT_PROGRAM_NAME, index, text)
def insertBeforeToken(self, token, text, program_name=DEFAULT_PROGRAM_NAME):
self.insertBefore(program_name, token.tokenIndex, text)
def insertBefore(self, program_name, index, text):
op = self.InsertBeforeOp(self.tokens, index, text)
rewrites = self.getProgram(program_name)
op.instructionIndex = len(rewrites)
rewrites.append(op)
def replaceIndex(self, index, text):
self.replace(self.DEFAULT_PROGRAM_NAME, index, index, text)
def replaceRange(self, from_idx, to_idx, text):
self.replace(self.DEFAULT_PROGRAM_NAME, from_idx, to_idx, text)
def replaceSingleToken(self, token, text):
self.replace(self.DEFAULT_PROGRAM_NAME, token.tokenIndex, token.tokenIndex, text)
def replaceRangeTokens(self, from_token, to_token, text, program_name=DEFAULT_PROGRAM_NAME):
self.replace(program_name, from_token.tokenIndex, to_token.tokenIndex, text)
def replace(self, program_name, from_idx, to_idx, text):
if any((from_idx > to_idx, from_idx < 0, to_idx < 0, to_idx >= len(self.tokens.tokens))):
raise ValueError(
'replace: range invalid: {}..{}(size={})'.format(from_idx, to_idx, len(self.tokens.tokens)))
op = self.ReplaceOp(from_idx, to_idx, self.tokens, text)
rewrites = self.getProgram(program_name)
op.instructionIndex = len(rewrites)
rewrites.append(op)
def deleteToken(self, token):
self.delete(self.DEFAULT_PROGRAM_NAME, token, token)
def deleteIndex(self, index):
self.delete(self.DEFAULT_PROGRAM_NAME, index, index)
def delete(self, program_name, from_idx, to_idx):
if isinstance(from_idx, Token):
self.replace(program_name, from_idx.tokenIndex, to_idx.tokenIndex, None)
self.replace(program_name, from_idx, to_idx, None)
def lastRewriteTokenIndex(self, program_name=DEFAULT_PROGRAM_NAME):
return self.lastRewriteTokenIndexes.get(program_name, -1)
def setLastRewriteTokenIndex(self, program_name, i):
self.lastRewriteTokenIndexes[program_name] = i
def getProgram(self, program_name):
return self.programs.setdefault(program_name, [])
def getText(self, program_name, interval):
"""
:type interval: Interval.Interval
:param program_name:
:param interval:
:return:
"""
rewrites = self.programs.get(program_name)
start = interval.start
stop = interval.stop
# ensure start/end are in range
if stop > len(self.tokens.tokens) - 1: stop = len(self.tokens.tokens) - 1
if start < 0: start = 0
# if no instructions to execute
if not rewrites: return self.tokens.getText(interval)
buf = StringIO()
indexToOp = self._reduceToSingleOperationPerIndex(rewrites)
i = start
while all((i <= stop, i < len(self.tokens.tokens))):
op = indexToOp.get(i)
token = self.tokens.get(i)
if op is None:
if token.type != Token.EOF: buf.write(token.text)
i += 1
else:
i = op.execute(buf)
if stop == len(self.tokens.tokens)-1:
for op in indexToOp.itervalues():
if op.index >= len(self.tokens.tokens)-1: buf.write(op.text)
return buf.getvalue()
def _reduceToSingleOperationPerIndex(self, rewrites):
# Walk replaces
for i, rop in enumerate(rewrites):
if any((rop is None, not isinstance(rop, TokenStreamRewriter.ReplaceOp))):
continue
# Wipe prior inserts within range
inserts = [op for op in rewrites[:i] if isinstance(rop, TokenStreamRewriter.InsertBeforeOp)]
for iop in inserts:
if iop.index == rop.index:
rewrites[iop.instructionIndex] = None
rop.text = '{}{}'.format(iop.text, rop.text)
elif all((iop.index > rop.index, iop.index <= rop.last_index)):
rewrites[iop.instructionIndex] = None
# Drop any prior replaces contained within
prevReplaces = [op for op in rewrites[:i] if isinstance(op, TokenStreamRewriter.ReplaceOp)]
for prevRop in prevReplaces:
if all((prevRop.index >= rop.index, prevRop.last_index <= rop.last_index)):
rewrites[prevRop.instructioIndex] = None
continue
isDisjoint = any((prevRop.last_index<rop.index, prevRop.index>rop))
isSame = all((prevRop.index == rop.index, prevRop.last_index == rop.last_index))
if all((prevRop.text is None, rop.text is None, not isDisjoint)):
rewrites[prevRop.instructioIndex] = None
rop.index = min(prevRop.index, rop.index)
rop.last_index = min(prevRop.last_index, rop.last_index)
print('New rop {}'.format(rop))
elif not all((isDisjoint, isSame)):
raise ValueError("replace op boundaries of {} overlap with previous {}".format(rop, prevRop))
# Walk inserts
for i, iop in enumerate(rewrites):
if any((iop is None, not isinstance(iop, TokenStreamRewriter.InsertBeforeOp))):
continue
prevInserts = [op for op in rewrites[:i] if isinstance(iop, TokenStreamRewriter.InsertBeforeOp)]
for prevIop in prevInserts:
if prevIop.index == iop.index:
iop.text += prevIop.text
rewrites[i] = None
# look for replaces where iop.index is in range; error
prevReplaces = [op for op in rewrites[:i] if isinstance(rop, TokenStreamRewriter.ReplaceOp)]
for rop in prevReplaces:
if iop.index == rop.index:
rop.text = iop.text + rop.text
rewrites[i] = None
continue
if all((iop.index >= rop.index, iop.index <= rop.index)):
raise ValueError("insert op {} within boundaries of previous {}".format(iop, rop))
reduced = {}
for i, op in enumerate(rewrites):
if op is None: continue
if reduced.get(op.index): raise ValueError('should be only one op per index')
reduced[op.index] = op
return reduced
class RewriteOperation(object):
def __init__(self, tokens, index, text=""):
"""
:type tokens: CommonTokenStream
:param tokens:
:param index:
:param text:
:return:
"""
self.tokens = tokens
self.index = index
self.text = text
self.instructionIndex = 0
def execute(self, buf):
"""
:type buf: StringIO.StringIO
:param buf:
:return:
"""
return self.index
def __str__(self):
pass
class InsertBeforeOp(RewriteOperation):
def __init__(self, tokens, index, text=""):
super(TokenStreamRewriter.InsertBeforeOp, self).__init__(tokens, index, text)
def execute(self, buf):
buf.write(self.text)
if self.tokens.get(self.index).type != Token.EOF:
buf.write(self.tokens.get(self.index).text)
return self.index + 1
class ReplaceOp(RewriteOperation):
def __init__(self, from_idx, to_idx, tokens, text):
super(TokenStreamRewriter.ReplaceOp, self).__init__(tokens, from_idx, text)
self.last_index = to_idx
def execute(self, buf):
if self.text:
buf.write(self.text)
return self.last_index + 1

View File

@ -186,9 +186,13 @@ class ATNConfigSet(object):
def __contains__(self, config):
if self.configLookup is None:
raise UnsupportedOperationException("This method is not implemented for readonly sets.")
h = hash(config)
h = config.hashCodeForConfigSet()
l = self.configLookup.get(h, None)
return l is not None and config in l
if l is not None:
for c in l:
if config.equalsForConfigSet(c):
return True
return False
def clear(self):
if self.readonly:

View File

@ -0,0 +1,231 @@
from io import StringIO
from antlr4.Token import Token
from antlr4.CommonTokenStream import CommonTokenStream
class TokenStreamRewriter(object):
DEFAULT_PROGRAM_NAME = "default"
PROGRAM_INIT_SIZE = 100
MIN_TOKEN_INDEX = 0
def __init__(self, tokens):
"""
:type tokens: antlr4.BufferedTokenStream.BufferedTokenStream
:param tokens:
:return:
"""
super(TokenStreamRewriter, self).__init__()
self.tokens = tokens
self.programs = {self.DEFAULT_PROGRAM_NAME: []}
self.lastRewriteTokenIndexes = {}
def getTokenStream(self):
return self.tokens
def rollback(self, instruction_index, program_name):
ins = self.programs.get(program_name, None)
if ins:
self.programs[program_name] = ins[self.MIN_TOKEN_INDEX: instruction_index]
def deleteProgram(self, program_name=DEFAULT_PROGRAM_NAME):
self.rollback(self.MIN_TOKEN_INDEX, program_name)
def insertAfterToken(self, token, text, program_name=DEFAULT_PROGRAM_NAME):
self.insertAfter(token.tokenIndex, text, program_name)
def insertAfter(self, index, text, program_name=DEFAULT_PROGRAM_NAME):
self.insertBefore(program_name, index + 1, text)
def insertBeforeIndex(self, index, text):
self.insertBefore(self.DEFAULT_PROGRAM_NAME, index, text)
def insertBeforeToken(self, token, text, program_name=DEFAULT_PROGRAM_NAME):
self.insertBefore(program_name, token.tokenIndex, text)
def insertBefore(self, program_name, index, text):
op = self.InsertBeforeOp(self.tokens, index, text)
rewrites = self.getProgram(program_name)
op.instructionIndex = len(rewrites)
rewrites.append(op)
def replaceIndex(self, index, text):
self.replace(self.DEFAULT_PROGRAM_NAME, index, index, text)
def replaceRange(self, from_idx, to_idx, text):
self.replace(self.DEFAULT_PROGRAM_NAME, from_idx, to_idx, text)
def replaceSingleToken(self, token, text):
self.replace(self.DEFAULT_PROGRAM_NAME, token.tokenIndex, token.tokenIndex, text)
def replaceRangeTokens(self, from_token, to_token, text, program_name=DEFAULT_PROGRAM_NAME):
self.replace(program_name, from_token.tokenIndex, to_token.tokenIndex, text)
def replace(self, program_name, from_idx, to_idx, text):
if any((from_idx > to_idx, from_idx < 0, to_idx < 0, to_idx >= len(self.tokens.tokens))):
raise ValueError(
'replace: range invalid: {}..{}(size={})'.format(from_idx, to_idx, len(self.tokens.tokens)))
op = self.ReplaceOp(from_idx, to_idx, self.tokens, text)
rewrites = self.getProgram(program_name)
op.instructionIndex = len(rewrites)
rewrites.append(op)
def deleteToken(self, token):
self.delete(self.DEFAULT_PROGRAM_NAME, token, token)
def deleteIndex(self, index):
self.delete(self.DEFAULT_PROGRAM_NAME, index, index)
def delete(self, program_name, from_idx, to_idx):
if isinstance(from_idx, Token):
self.replace(program_name, from_idx.tokenIndex, to_idx.tokenIndex, None)
self.replace(program_name, from_idx, to_idx, None)
def lastRewriteTokenIndex(self, program_name=DEFAULT_PROGRAM_NAME):
return self.lastRewriteTokenIndexes.get(program_name, -1)
def setLastRewriteTokenIndex(self, program_name, i):
self.lastRewriteTokenIndexes[program_name] = i
def getProgram(self, program_name):
return self.programs.setdefault(program_name, [])
def getText(self, program_name, interval):
"""
:type interval: Interval.Interval
:param program_name:
:param interval:
:return:
"""
rewrites = self.programs.get(program_name)
start = interval.start
stop = interval.stop
# ensure start/end are in range
if stop > len(self.tokens.tokens) - 1: stop = len(self.tokens.tokens) - 1
if start < 0: start = 0
# if no instructions to execute
if not rewrites: return self.tokens.getText(interval)
buf = StringIO()
indexToOp = self._reduceToSingleOperationPerIndex(rewrites)
i = start
while all((i <= stop, i < len(self.tokens.tokens))):
op = indexToOp.get(i)
token = self.tokens.get(i)
if op is None:
if token.type != Token.EOF: buf.write(token.text)
i += 1
else:
i = op.execute(buf)
if stop == len(self.tokens.tokens)-1:
for op in indexToOp.values():
if op.index >= len(self.tokens.tokens)-1: buf.write(op.text)
return buf.getvalue()
def _reduceToSingleOperationPerIndex(self, rewrites):
# Walk replaces
for i, rop in enumerate(rewrites):
if any((rop is None, not isinstance(rop, TokenStreamRewriter.ReplaceOp))):
continue
# Wipe prior inserts within range
inserts = [op for op in rewrites[:i] if isinstance(rop, TokenStreamRewriter.InsertBeforeOp)]
for iop in inserts:
if iop.index == rop.index:
rewrites[iop.instructionIndex] = None
rop.text = '{}{}'.format(iop.text, rop.text)
elif all((iop.index > rop.index, iop.index <= rop.last_index)):
rewrites[iop.instructionIndex] = None
# Drop any prior replaces contained within
prevReplaces = [op for op in rewrites[:i] if isinstance(op, TokenStreamRewriter.ReplaceOp)]
for prevRop in prevReplaces:
if all((prevRop.index >= rop.index, prevRop.last_index <= rop.last_index)):
rewrites[prevRop.instructioIndex] = None
continue
isDisjoint = any((prevRop.last_index<rop.index, prevRop.index>rop))
isSame = all((prevRop.index == rop.index, prevRop.last_index == rop.last_index))
if all((prevRop.text is None, rop.text is None, not isDisjoint)):
rewrites[prevRop.instructioIndex] = None
rop.index = min(prevRop.index, rop.index)
rop.last_index = min(prevRop.last_index, rop.last_index)
print('New rop {}'.format(rop))
elif not all((isDisjoint, isSame)):
raise ValueError("replace op boundaries of {} overlap with previous {}".format(rop, prevRop))
# Walk inserts
for i, iop in enumerate(rewrites):
if any((iop is None, not isinstance(iop, TokenStreamRewriter.InsertBeforeOp))):
continue
prevInserts = [op for op in rewrites[:i] if isinstance(iop, TokenStreamRewriter.InsertBeforeOp)]
for prevIop in prevInserts:
if prevIop.index == iop.index:
iop.text += prevIop.text
rewrites[i] = None
# look for replaces where iop.index is in range; error
prevReplaces = [op for op in rewrites[:i] if isinstance(op, TokenStreamRewriter.ReplaceOp)]
for rop in prevReplaces:
if iop.index == rop.index:
rop.text = iop.text + rop.text
rewrites[i] = None
continue
if all((iop.index >= rop.index, iop.index <= rop.index)):
raise ValueError("insert op {} within boundaries of previous {}".format(iop, rop))
reduced = {}
for i, op in enumerate(rewrites):
if op is None: continue
if reduced.get(op.index): raise ValueError('should be only one op per index')
reduced[op.index] = op
return reduced
class RewriteOperation(object):
def __init__(self, tokens, index, text=""):
"""
:type tokens: CommonTokenStream
:param tokens:
:param index:
:param text:
:return:
"""
self.tokens = tokens
self.index = index
self.text = text
self.instructionIndex = 0
def execute(self, buf):
"""
:type buf: StringIO.StringIO
:param buf:
:return:
"""
return self.index
def __str__(self):
pass
class InsertBeforeOp(RewriteOperation):
def __init__(self, tokens, index, text=""):
super(TokenStreamRewriter.InsertBeforeOp, self).__init__(tokens, index, text)
def execute(self, buf):
buf.write(self.text)
if self.tokens.get(self.index).type != Token.EOF:
buf.write(self.tokens.get(self.index).text)
return self.index + 1
class ReplaceOp(RewriteOperation):
def __init__(self, from_idx, to_idx, tokens, text):
super(TokenStreamRewriter.ReplaceOp, self).__init__(tokens, from_idx, text)
self.last_index = to_idx
def execute(self, buf):
if self.text:
buf.write(self.text)
return self.last_index + 1

View File

@ -189,9 +189,13 @@ class ATNConfigSet(object):
def __contains__(self, config):
if self.configLookup is None:
raise UnsupportedOperationException("This method is not implemented for readonly sets.")
h = hash(config)
h = config.hashCodeForConfigSet()
l = self.configLookup.get(h, None)
return l is not None and config in l
if l is not None:
for c in l:
if config.equalsForConfigSet(c):
return True
return False
def clear(self):
if self.readonly:

1
runtime/Swift/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
xcuserdata/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F9A422F71BCCD47300A9CD35"
BuildableName = "Antlr4.framework"
BlueprintName = "Antlr4 IOS"
ReferencedContainer = "container:Antlr4.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F9A422F71BCCD47300A9CD35"
BuildableName = "Antlr4.framework"
BlueprintName = "Antlr4 IOS"
ReferencedContainer = "container:Antlr4.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F9A422F71BCCD47300A9CD35"
BuildableName = "Antlr4.framework"
BlueprintName = "Antlr4 IOS"
ReferencedContainer = "container:Antlr4.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F9A4211B1BCCC35000A9CD35"
BuildableName = "Antlr4.framework"
BlueprintName = "Antlr4 OSX"
ReferencedContainer = "container:Antlr4.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F9A424A71BCD348C00A9CD35"
BuildableName = "Antlr4Tests.xctest"
BlueprintName = "Antlr4Tests"
ReferencedContainer = "container:Antlr4.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F9A4211B1BCCC35000A9CD35"
BuildableName = "Antlr4.framework"
BlueprintName = "Antlr4 OSX"
ReferencedContainer = "container:Antlr4.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F9A4211B1BCCC35000A9CD35"
BuildableName = "Antlr4.framework"
BlueprintName = "Antlr4 OSX"
ReferencedContainer = "container:Antlr4.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "F9A4211B1BCCC35000A9CD35"
BuildableName = "Antlr4.framework"
BlueprintName = "Antlr4 OSX"
ReferencedContainer = "container:Antlr4.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@ -0,0 +1,197 @@
/*
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 Sam Harwell
* Copyright (c) 2015 Janyou
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** How to emit recognition errors. */
public protocol ANTLRErrorListener: class {
/**
* Upon syntax error, notify any interested parties. This is not how to
* recover from errors or compute error messages. {@link org.antlr.v4.runtime.ANTLRErrorStrategy}
* specifies how to recover from syntax errors and how to compute error
* messages. This listener's job is simply to emit a computed message,
* though it has enough information to create its own message in many cases.
*
* <p>The {@link org.antlr.v4.runtime.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).</p>
*
* @param recognizer
* What parser got the error. From this
* object, you can access the context as well
* as the input stream.
* @param offendingSymbol
* The offending token in the input token
* stream, unless recognizer is a lexer (then it's null). If
* no viable alternative error, {@code e} has token at which we
* started production for the decision.
* @param line
* The line number in the input where the error occurred.
* @param charPositionInLine
* The character position within that line where the error occurred.
* @param msg
* The message to emit.
* @param e
* The exception generated by the parser that led to
* the reporting of an error. It is null in the case where
* the parser was able to recover in line without exiting the
* surrounding rule.
*/
func syntaxError<T:ATNSimulator>(_ recognizer: Recognizer<T>,
_ offendingSymbol: AnyObject?,
_ line: Int,
_ charPositionInLine: Int,
_ msg: String,
_ e: AnyObject?// RecognitionException?
)
/**
* This method is called by the parser when a full-context prediction
* results in an ambiguity.
*
* <p>Each full-context prediction which does not result in a syntax error
* will call either {@link #reportContextSensitivity} or
* {@link #reportAmbiguity}.</p>
*
* <p>When {@code 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.</p>
*
* <p>When {@code exact} is {@code true}, <em>all</em> of the potentially
* viable alternatives are truly viable, i.e. this is reporting an exact
* ambiguity. When {@code exact} is {@code false}, <em>at least two</em> 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 <em>minimum</em> potentially viable alternative is truly
* viable.</p>
*
* <p>When the {@link 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}.</p>
*
* <p>This method is not used by lexers.</p>
*
* @param recognizer the parser instance
* @param dfa the DFA for the current decision
* @param startIndex the input index where the decision started
* @param stopIndex the input input where the ambiguity was identified
* @param exact {@code true} if the ambiguity is exactly known, otherwise
* {@code false}. This is always {@code true} when
* {@link org.antlr.v4.runtime.atn.PredictionMode#LL_EXACT_AMBIG_DETECTION} is used.
* @param ambigAlts the potentially ambiguous alternatives, or {@code null}
* to indicate that the potentially ambiguous alternatives are the complete
* set of represented alternatives in {@code configs}
* @param configs the ATN configuration set where the ambiguity was
* identified
*/
func reportAmbiguity(_ recognizer: Parser,
_ dfa: DFA,
_ startIndex: Int,
_ stopIndex: Int,
_ exact: Bool,
_ ambigAlts: BitSet,
_ configs: ATNConfigSet) throws
/**
* This method is called when an SLL conflict occurs and the parser is about
* to use the full context information to make an LL decision.
*
* <p>If one or more configurations in {@code 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}.</p>
*
* <p>This method is not used by lexers.</p>
*
* @param recognizer the parser instance
* @param dfa the DFA for the current decision
* @param startIndex the input index where the decision started
* @param stopIndex the input index where the SLL conflict occurred
* @param conflictingAlts The specific conflicting alternatives. If this is
* {@code null}, the conflicting alternatives are all alternatives
* represented in {@code configs}. At the moment, conflictingAlts is non-null
* (for the reference implementation, but Sam's optimized version can see this
* as null).
* @param configs the ATN configuration set where the SLL conflict was
* detected
*/
func reportAttemptingFullContext(_ recognizer: Parser,
_ dfa: DFA,
_ startIndex: Int,
_ stopIndex: Int,
_ conflictingAlts: BitSet?,
_ configs: ATNConfigSet) throws
/**
* This method is called by the parser when a full-context prediction has a
* unique result.
*
* <p>Each full-context prediction which does not result in a syntax error
* will call either {@link #reportContextSensitivity} or
* {@link #reportAmbiguity}.</p>
*
* <p>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
* 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.</p>
*
* <p>{@code 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.</p>
*
* <p>Note that the definition of "context sensitivity" in this method
* differs from the concept in {@link 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.</p>
*
* <p>This method is not used by lexers.</p>
*
* @param recognizer the parser instance
* @param dfa the DFA for the current decision
* @param startIndex the input index where the decision started
* @param stopIndex the input index where the context sensitivity was
* finally determined
* @param prediction the unambiguous result of the full-context prediction
* @param configs the ATN configuration set where the unambiguous prediction
* was determined
*/
func reportContextSensitivity(_ recognizer: Parser,
_ dfa: DFA,
_ startIndex: Int,
_ stopIndex: Int,
_ prediction: Int,
_ configs: ATNConfigSet) throws
}

View File

@ -0,0 +1,141 @@
/*
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 Sam Harwell
* Copyright (c) 2015 Janyou
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* The interface for defining strategies to deal with syntax errors encountered
* during a parse by ANTLR-generated parsers. We distinguish between three
* different kinds of errors:
*
* <ul>
* <li>The parser could not figure out which path to take in the ATN (none of
* the available alternatives could possibly match)</li>
* <li>The current input does not match what we were looking for</li>
* <li>A predicate evaluated to false</li>
* </ul>
*
* Implementations of this interface report syntax errors by calling
* {@link org.antlr.v4.runtime.Parser#notifyErrorListeners}.
*
* <p>TODO: what to do about lexers</p>
*/
public protocol ANTLRErrorStrategy {
/**
* Reset the error handler state for the specified {@code recognizer}.
* @param recognizer the parser instance
*/
func reset(_ recognizer: Parser)
/**
* This method is called when an unexpected symbol is encountered during an
* inline match operation, such as {@link org.antlr.v4.runtime.Parser#match}. If the error
* strategy successfully recovers from the match failure, this method
* returns the {@link org.antlr.v4.runtime.Token} instance which should be treated as the
* successful result of the match.
*
* <p>This method handles the consumption of any tokens - the caller should
* <b>not</b> call {@link org.antlr.v4.runtime.Parser#consume} after a successful recovery.</p>
*
* <p>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.</p>
*
* @param recognizer the parser instance
* @throws org.antlr.v4.runtime.RecognitionException if the error strategy was not able to
* recover from the unexpected input symbol
*/
@discardableResult
func recoverInline(_ recognizer: Parser) throws -> Token // RecognitionException;
/**
* This method is called to recover from exception {@code e}. This method is
* called after {@link #reportError} by the default exception handler
* generated for a rule method.
*
* @see #reportError
*
* @param recognizer the parser instance
* @param e the recognition exception to recover from
* @throws org.antlr.v4.runtime.RecognitionException if the error strategy could not recover from
* the recognition exception
*/
func recover(_ recognizer: Parser, _ e: AnyObject) throws // RecognitionException;
/**
* This method provides the error handler with an opportunity to handle
* syntactic or semantic errors in the input stream before they result in a
* {@link org.antlr.v4.runtime.RecognitionException}.
*
* <p>The generated code currently contains calls to {@link #sync} after
* entering the decision state of a closure block ({@code (...)*} or
* {@code (...)+}).</p>
*
* <p>For an implementation based on Jim Idle's "magic sync" mechanism, see
* {@link org.antlr.v4.runtime.DefaultErrorStrategy#sync}.</p>
*
* @see org.antlr.v4.runtime.DefaultErrorStrategy#sync
*
* @param recognizer the parser instance
* @throws org.antlr.v4.runtime.RecognitionException if an error is detected by the error
* strategy but cannot be automatically recovered at the current state in
* the parsing process
*/
func sync(_ recognizer: Parser) throws // RecognitionException;
/**
* Tests whether or not {@code recognizer} is in the process of recovering
* from an error. In error recovery mode, {@link org.antlr.v4.runtime.Parser#consume} adds
* symbols to the parse tree by calling
* {@link org.antlr.v4.runtime.ParserRuleContext#addErrorNode(org.antlr.v4.runtime.Token)} instead of
* {@link org.antlr.v4.runtime.ParserRuleContext#addChild(org.antlr.v4.runtime.Token)}.
*
* @param recognizer the parser instance
* @return {@code true} if the parser is currently recovering from a parse
* error, otherwise {@code false}
*/
func inErrorRecoveryMode(_ recognizer: Parser) -> Bool
/**
* This method is called by when the parser successfully matches an input
* symbol.
*
* @param recognizer the parser instance
*/
func reportMatch(_ recognizer: Parser)
/**
* Report any kind of {@link org.antlr.v4.runtime.RecognitionException}. This method is called by
* the default exception handler generated for a rule method.
*
* @param recognizer the parser instance
* @param e the recognition exception to report
*/
func reportError(_ recognizer: Parser, _ e: AnyObject)
}

Some files were not shown because too many files have changed in this diff Show More