forked from jasder/antlr
Merge branch 'master_upstream'
This commit is contained in:
commit
a6161326e1
|
@ -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
|
|
@ -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!
|
41
.travis.yml
41
.travis.yml
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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", "");
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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] ;
|
|
@ -0,0 +1,7 @@
|
|||
grammar Hello;
|
||||
|
||||
import HelloBase;
|
||||
|
||||
r : 'hello' ID ;
|
||||
ID : [a-z]+ ;
|
||||
WS : [ \r\t\n]+ -> skip ;
|
|
@ -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>
|
|
@ -0,0 +1,3 @@
|
|||
ID=1
|
||||
INT=2
|
||||
SEMI=3
|
|
@ -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 ;
|
|
@ -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>
|
|
@ -0,0 +1,4 @@
|
|||
grammar Hello;
|
||||
r : 'hello' ID ;
|
||||
ID : [a-z]+ ;
|
||||
WS : [ \r\t\n]+ -> skip ;
|
|
@ -0,0 +1,6 @@
|
|||
lexer grammar TestLexer;
|
||||
|
||||
import TestBaseLexer;
|
||||
|
||||
WS : Whitespace+ -> skip;
|
||||
TEXT : ~[<&]+ ; // match any 16 bit char other than < and &
|
|
@ -0,0 +1,5 @@
|
|||
parser grammar TestParser;
|
||||
|
||||
options { tokenVocab=TestLexer; }
|
||||
|
||||
document : (Comment | Name) EOF ;
|
|
@ -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] ;
|
|
@ -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>
|
|
@ -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] ;
|
|
@ -0,0 +1,4 @@
|
|||
grammar Hello;
|
||||
r : 'hello' ID ;
|
||||
ID : [a-z]+ ;
|
||||
WS : [ \r\t\n]+ -> skip ;
|
|
@ -0,0 +1,6 @@
|
|||
lexer grammar TestLexer;
|
||||
|
||||
import TestBaseLexer;
|
||||
|
||||
WS : Whitespace+ -> skip;
|
||||
TEXT : ~[<&]+ ; // match any 16 bit char other than < and &
|
|
@ -0,0 +1,5 @@
|
|||
parser grammar TestParser;
|
||||
|
||||
options { tokenVocab=TestLexer; }
|
||||
|
||||
document : (Comment | Name) EOF ;
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
```
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
>>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>"
|
||||
|
|
|
@ -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}>"
|
||||
|
|
|
@ -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>"
|
|
@ -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");
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
// {
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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:
|
||||
|
|
|
@ -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
|
|
@ -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:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
xcuserdata/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
||||
}
|
|
@ -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
Loading…
Reference in New Issue