Merge pull request #885 from parrt/intermediate-test-generation

Intermediate test generation
This commit is contained in:
Terence Parr 2015-06-03 10:40:19 -07:00
commit 44664e8647
412 changed files with 15759 additions and 356 deletions

View File

@ -7,7 +7,7 @@
<component name="ProjectKey">
<option name="state" value="project://e2804f05-5315-4fc6-a121-c522a6c26470" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.7" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" default="false" assert-keyword="true" jdk-15="true">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -2,8 +2,6 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/../antlr4-csharp/tool/csharp.iml" filepath="$PROJECT_DIR$/../antlr4-csharp/tool/csharp.iml" />
<module fileurl="file://$PROJECT_DIR$/../antlr4-javascript/tool/javascript.iml" filepath="$PROJECT_DIR$/../antlr4-javascript/tool/javascript.iml" />
<module fileurl="file://$PROJECT_DIR$/../antlr4-python2/tool/python2.iml" filepath="$PROJECT_DIR$/../antlr4-python2/tool/python2.iml" />
<module fileurl="file://$PROJECT_DIR$/../antlr4-python3/tool/python3.iml" filepath="$PROJECT_DIR$/../antlr4-python3/tool/python3.iml" />
<module fileurl="file://$PROJECT_DIR$/runtime/Java/runtime.iml" filepath="$PROJECT_DIR$/runtime/Java/runtime.iml" />

View File

@ -0,0 +1,216 @@
<!--
[The "BSD license"]
ANTLR - Copyright (c) 2005-2010 Terence Parr
Maven Plugin - Copyright (c) 2009 Jim Idle
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.
-->
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.antlr</groupId>
<version>4.5.1-SNAPSHOT</version>
<artifactId>antlr4-testgen-maven-plugin</artifactId>
<packaging>maven-plugin</packaging>
<name>ANTLR 4 Test Generator Maven plugin</name>
<description>Maven plugin for generating ANTLR 4 runtime tests</description>
<url>http://www.antlr.org</url>
<prerequisites>
<maven>3.0</maven>
</prerequisites>
<!-- Ancilliary information for completeness
-->
<inceptionYear>2009</inceptionYear>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<!-- ============================================================================= -->
<!--
What are we depedent on for the Mojos to execute? We need the
plugin API itself and of course we need the ANTLR Tool and runtime
and any of their dependencies, which we inherit. The Tool itself provides
us with all the dependencies, so we need only name it here.
-->
<dependencies>
<!--
The things we need to build the target language recognizer
-->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<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>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.sonatype.plexus</groupId>
<artifactId>plexus-build-api</artifactId>
<version>0.0.7</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>ST4</artifactId>
<version>4.0.8</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>runtime-testsuite</artifactId>
<version>${project.version}</version>
</dependency>
<!--
Testing requirements...
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<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>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<resources>
<resource>
<directory>resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.3</version>
<configuration>
<!-- see http://jira.codehaus.org/browse/MNG-5346 -->
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
<execution>
<id>help-goal</id>
<goals>
<goal>helpmojo</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.7</version>
<configuration>
<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<configuration>
<quiet>true</quiet>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>2.3</version>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<goals>
<goal>antlr4</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
<runOnConfiguration>true</runOnConfiguration>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>

View File

@ -0,0 +1,94 @@
/*
[The "BSD license"]
Copyright (c) 2014 Sam Harwell
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.mojo.antlr4.testgen;
import org.antlr.v4.testgen.TestGenerator;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import java.io.File;
@Mojo(
name = "antlr4.testgen",
defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES,
requiresDependencyResolution = ResolutionScope.TEST,
requiresProject = true)
public class Antlr4TestGeneratorMojo extends AbstractMojo {
// This project uses UTF-8, but the plugin might be used in another project
// which is not. Always load templates with UTF-8, but write using the
// specified encoding.
@Parameter(property = "project.build.sourceEncoding")
private String encoding;
@Parameter(property = "project", readonly = true)
private MavenProject project;
@Parameter(property = "runtimeTemplates", required = true)
private File runtimeTemplates;
@Parameter(defaultValue = "${project.build.directory}/generated-test-sources/antlr4-tests")
private File outputDirectory;
@Parameter
private boolean visualize;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
TestGenerator testGenerator = new MavenTestGenerator(encoding, runtimeTemplates, outputDirectory, visualize);
testGenerator.execute();
if (project != null) {
project.addTestCompileSourceRoot(outputDirectory.getPath());
}
}
private class MavenTestGenerator extends TestGenerator {
public MavenTestGenerator(String encoding, File runtimeTemplates, File outputDirectory, boolean visualize) {
super(encoding, runtimeTemplates, outputDirectory, visualize);
}
@Override
protected void warn(String message) {
getLog().warn(message);
}
@Override
protected void error(String message, Throwable throwable) {
getLog().error(message, throwable);
}
}
}

View File

@ -0,0 +1,8 @@
Imported Grammar Files
In order to have the ANTLR plugin automatically locate and use grammars used
as imports in your main <<<.g4>>> files, you need to place the imported grammar
files in the <<<imports>>> directory beneath the root directory of your grammar
files (which is <<<src/main/antlr4>>> by default of course).
For a default layout, place your import grammars in the directory: <<<src/main/antlr4/imports>>>

View File

@ -0,0 +1,46 @@
Libraries
The introduction of the import directive in a grammar allows reuse of common grammar files
as well as the ability to divide up functional components of large grammars. However it has
caused some confusion in regard to the fact that generated vocabulary files (<<<*.tokens>>>) can also
be searched for with the <<<<libDirectory>>>> directive.
This has confused two separate functions and imposes a structure upon the layout of
your grammar files in certain cases. If you have grammars that both use the import
directive and also require the use of a vocabulary file then you will need to locate
the grammar that generates the <<<.tokens>>> file alongside the grammar that uses it. This
is because you will need to use the <<<<libDirectory>>>> directive to specify the
location of your imported grammars and ANTLR will not find any vocabulary files in
this directory.
The <<<.tokens>>> files for any grammars are generated within the same output directory structure
as the <<<.java>>> files. So, wherever the <<<.java>>> files are generated, you will also find the <<<.tokens>>>
files. ANTLR looks for <<<.tokens>>> files in both the <<<<libDirectory>>>> and the output directory
where it is placing the generated <<<.java>>> files. Hence when you locate the grammars that generate
<<<.tokens>>> files in the same source directory as the ones that use the <<<.tokens>>> files, then
the Maven plugin will find the expected <<<.tokens>>> files.
The <<<<libDirectory>>>> is specified like any other directory parameter in Maven. Here is an
example:
+--
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<configuration>
<goals>
<goal>antlr4</goal>
</goals>
<libDirectory>src/main/antlr4_imports</libDirectory>
</configuration>
</execution>
</executions>
</plugin>
+--

View File

@ -0,0 +1,40 @@
Simple configuration
If your grammar files are organized into the default locations as described in the {{{../index.html}introduction}},
then configuring the <<<pom.xml>>> file for your project is as simple as adding this to it
+--
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
+--
When the <<<mvn>>> command is executed all grammar files under <<<src/main/antlr4>>>, except any
import grammars under <<<src/main/antlr4/imports>>> will be analyzed and converted to
Java source code in the output directory <<<target/generated-sources/antlr4>>>.
Your input files under <<<antlr4>>> should be stored in sub directories that
reflect the package structure of your java parsers. If your grammar file <<<parser.g4>>> contains:
+---
@header {
package org.jimi.themuss;
}
+---
Then the <<<.g4>>> file should be stored in: <<<src/main/antlr4/org/jimi/themuss/parser.g4>>>. This way
the generated <<<.java>>> files will correctly reflect the package structure in which they will
finally rest as classes.

View File

@ -0,0 +1 @@
FAQ

View File

@ -0,0 +1,62 @@
-------------
ANTLR v4 Maven Plugin
-------------
Jim Idle
-------------
March 2009
-------------
ANTLR v4 Maven plugin
The ANTLR v4 Maven plugin is completely re-written as of version 4.0; if you are familiar
with prior versions, you should note that there are some behavioral differences that make
it worthwhile reading this documentation.
The job of the plugin is essentially to tell the standard ANTLR parser generator where the
input grammar files are and where the output files should be generated. As with all Maven
plugins, there are defaults, which you are advised to comply to, but are not forced to
comply to.
This version of the plugin allows full control over ANTLR and allows configuration of all
options that are useful for a build system. The code required to calculate dependencies,
check the build order, and otherwise work with your grammar files is built into the ANTLR
tool as of version 4.0 of ANTLR and this plugin.
* Plugin Versioning
The plugin version tracks the version of the ANTLR tool that it controls. Hence if you
use version 4.0 of the plugin, you will build your grammars using version 4.0 of the
ANTLR tool, version 4.2 of the plugin will use version 4.2 of the ANTLR tool and so on.
You may also find that there are patch versions of the plugin such as 4.0-1 4.0-2 and
so on. Use the latest patch release of the plugin.
The current version of the plugin is shown at the top of this page after the <<Last Deployed>> date.
* Default directories
As with all Maven plugins, this plugin will automatically default to standard locations
for your grammar and import files. Organizing your source code to reflect this standard
layout will greatly reduce the configuration effort required. The standard layout lookd
like this:
+--
src/main/
|
+--- antlr4/... .g4 files organized in the required package structure
|
+--- imports/ .g4 files that are imported by other grammars.
+--
If your grammar is intended to be part of a package called <<<org.foo.bar>>> then you would
place it in the directory <<<src/main/antlr4/org/foo/bar>>>. The plugin will then produce
<<<.java>>> and <<<.tokens>>> files in the output directory <<<target/generated-sources/antlr4/org/foo/bar>>>
When the Java files are compiled they will be in the correct location for the Javac
compiler without any special configuration. The generated java files are automatically
submitted for compilation by the plugin.
The <<<src/main/antlr4/imports>>> directory is treated in a special way. It should contain
any grammar files that are imported by other grammar files (do not make subdirectories here.)
Such files are never built on their own, but the plugin will automatically tell the ANTLR
tool to look in this directory for library files.

View File

@ -0,0 +1,59 @@
Usage
The ANTLR 4 plugin for Maven can generate parsers for any number of grammars in
your project.
* Compiling Grammars into Parsers
By default, the <<<{{{./antlr4-mojo.html}antlr4}}>>> goal will search for grammar
files in the directory <<<$\{basedir\}/src/main/antlr4>>> and any additional
<<<.tokens>>> files in the directory <<<$\{basedir\}/src/main/antlr4/imports>>>.
This can be configured to search other directories using the plugin configuration
parameters as described in the <<<{{{./antlr4-mojo.html}antlr4}}>>> goal
documentation.
The following figure shows the expected layout of files for the default
configuration of this plugin.
+--
src/main/
|
+--- antlr4/... .g4 files organized in the required package structure
|
+--- imports/ user-created .tokens files and .g4 files that are imported by other grammars
+--
The next step is to configure your POM to call the plugin. The goals will
normally run during the generate-sources phase of the build. Examples of how to
configure your POM can be found on the various examples pages, reachable via
the page menu. If you stick with the default values, the snippet below will
suffice:
+--
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<id>antlr</id>
<goals>
<goal>antlr4</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>
+--
Note that you can create multiple executions, and thus build some grammars with
different options to others (such as setting the <<<debug>>> option for
instance).

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="ANTLR v4 Maven plugin">
<publishDate position="left"/>
<version position="left"/>
<poweredBy>
<logo name="ANTLR Web Site" href="http://antlr.org/"
img="http://www.antlr.org/wiki/download/attachments/292/ANTLR4"/>
</poweredBy>
<body>
<links>
<item name="Antlr Web Site" href="http://www.antlr.org/"/>
</links>
<menu name="Overview">
<item name="Introduction" href="index.html"/>
<item name="Goals" href="plugin-info.html"/>
<item name="Usage" href="usage.html"/>
<item name="FAQ" href="faq.html"/>
</menu>
<menu name="Examples">
<item name="Simple configurations" href="examples/simple.html"/>
<item name="Using library directories" href="examples/libraries.html"/>
<item name="Using imported grammars" href="examples/import.html"/>
</menu>
<menu ref="reports" />
<menu ref="modules" />
</body>
</project>

124
bild.py
View File

@ -1,8 +1,5 @@
#!/usr/bin/env python
import os
import string
from collections import OrderedDict
import shutil
"""
This script uses my experimental build tool http://www.bildtool.org
@ -65,6 +62,19 @@ TARGETS = OrderedDict([
("JavaScript",uniformpath(JAVASCRIPT_TARGET))
])
# Base templates specific to targets needed by tests in TestFolders
RUNTIME_TEST_TEMPLATES = {
"Java" : uniformpath(JAVA_TARGET)+"/tool/test/org/antlr/v4/test/runtime/java/Java.test.stg",
"CSharp" : uniformpath(CSHARP_TARGET)+"/tool/test/org/antlr/v4/test/runtime/csharp/CSharp.test.stg",
# "Python2" : uniformpath(PYTHON2_TARGET)+"/tool/test/org/antlr/v4/test/rt/py2/Python2.test.stg",
# "Python3" : uniformpath(PYTHON3_TARGET)+"/tool/test/org/antlr/v4/test/rt/py3/Python3.test.stg",
# "NodeJS" : uniformpath(JAVASCRIPT_TARGET)+"/tool/test/org/antlr/v4/test/rt/js/node/NodeJS.test.stg",
# "Safari" : uniformpath(JAVASCRIPT_TARGET)+"/tool/test/org/antlr/v4/test/rt/js/safari/Safari.test.stg",
# "Firefox" : uniformpath(JAVASCRIPT_TARGET)+"/tool/test/org/antlr/v4/test/rt/js/firefox/Firefox.test.stg",
# "Chrome" : uniformpath(JAVASCRIPT_TARGET)+"/tool/test/org/antlr/v4/test/rt/js/chrome/Chrome.test.stg",
# "Explorer" : uniformpath(JAVASCRIPT_TARGET)+"/tool/test/org/antlr/v4/test/rt/js/explorer/Explorer.test.stg"
}
def parsers():
antlr3("tool/src/org/antlr/v4/parse", "gen3", version="3.5.2", package="org.antlr.v4.parse")
@ -74,7 +84,12 @@ def parsers():
version=BOOTSTRAP_VERSION, package="org.antlr.v4.runtime.tree.xpath")
def compile():
"""
Compile tool, runtime, tool tests, runtime tests into ./out dir
Depends on treelayout jar, antlr v3, junit/hamcrest
"""
require(parsers)
require(regen_tests)
cp = uniformpath("out") + os.pathsep + \
os.path.join(JARCACHE, "antlr-3.5.2-complete.jar") + os.pathsep + \
"runtime/Java/lib/org.abego.treelayout.core.jar" + os.pathsep
@ -82,9 +97,17 @@ def compile():
args = ["-Xlint", "-Xlint:-serial", "-g", "-sourcepath", string.join(srcpath, os.pathsep)]
for sp in srcpath:
javac(sp, "out", version="1.6", cp=cp, args=args)
# pull in targets
junit_jar, hamcrest_jar = load_junitjars()
cp += os.pathsep + uniformpath("out") \
+ os.pathsep + junit_jar \
+ os.pathsep + hamcrest_jar
# pull in targets' code gen
for t in TARGETS:
javac(TARGETS[t] + "/tool/src", "out", version="1.6", cp=cp, args=args)
javac(TARGETS[t] + "/tool/src", "out", version="1.6", cp=cp, args=args)
# pull in generated runtime tests and runtime test support code
for t in RUNTIME_TEST_TEMPLATES:
javac(TARGETS[t] + "/tool/test", "out", version="1.6", cp=cp, args=args)
javac('gen/test/'+t, "out", version="1.6", cp=cp, args=args)
def mkjar_complete():
@ -238,15 +261,27 @@ def python_sdist():
def regen_tests():
require(_mkjar)
"""
Generate all runtime Test*.java files for all targets into ./gen/TargetName
They will all get compiled in compile() so we have all together but
can drop from final jar in mkjar().
"""
# first compile runtime-testsuite; only needs ST and junit
junit_jar, hamcrest_jar = load_junitjars()
cp = uniformpath("dist/antlr4-" + VERSION + "-complete.jar") \
+ os.pathsep + uniformpath("out/test") \
download("http://www.stringtemplate.org/download/ST-4.0.8.jar", JARCACHE)
cp = os.path.join(JARCACHE, "ST-4.0.8.jar") \
+ os.pathsep + junit_jar \
+ os.pathsep + hamcrest_jar
args = ["-nowarn", "-Xlint", "-Xlint:-serial", "-g"]
javac("tool/test", "out/test", version="1.6", cp=cp, args=args) # all targets can use org.antlr.v4.test.*
java(classname="org.antlr.v4.test.rt.gen.Generator", cp="out/test:dist/antlr4-"+VERSION+"-complete.jar")
javac("runtime-testsuite/src", "out/testsuite", version="1.6", cp=cp, args=args)
# now use TestGenerator to generate Test*.java for each target using
# runtime templates and test templates themselves:
# runtime-testsuite/resources/org/antlr/v4/test/runtime/templates
# generate into gen/test/Java, gen/test/CSharp, ...
for targetName in RUNTIME_TEST_TEMPLATES:
java(classname="org.antlr.v4.testgen.TestGenerator", cp="out/testsuite:"+cp,
progargs=['-o', 'gen/test/'+targetName, '-templates', RUNTIME_TEST_TEMPLATES[targetName]])
print_and_log("test generation complete")
@ -277,50 +312,51 @@ def test_javascript():
def test_target(t):
require(regen_tests)
cp = uniformpath("dist/antlr4-" + VERSION + "-complete.jar") \
+ os.pathsep + uniformpath("out/test")
require(_mkjar)
juprops = ["-D%s=%s" % (p, test_properties[p]) for p in test_properties]
args = ["-nowarn", "-Xlint", "-Xlint:-serial", "-g"]
print_and_log("Testing %s ..." % t)
try:
test(t, cp, juprops, args)
test(t, juprops, args)
print t + " tests complete"
except:
print t + " tests failed"
except Exception as e:
print t + " tests failed: ", e
def test(t, cp, juprops, args):
def test(target, juprops, args):
junit_jar, hamcrest_jar = load_junitjars()
srcdir = uniformpath(TARGETS[t] + "/tool/test")
dstdir = uniformpath( "out/test/" + t)
srcdir = uniformpath('gen/test/'+target)
dstdir = uniformpath("out/test/"+target)
# Prefix CLASSPATH with individual target tests
thiscp = dstdir + os.pathsep + cp
thisjarwithjunit = thiscp + os.pathsep + hamcrest_jar + os.pathsep + junit_jar
cp = dstdir + os.pathsep + uniformpath("dist/antlr4-" + VERSION + "-complete.jar")
thisjarwithjunit = cp + os.pathsep + hamcrest_jar + os.pathsep + junit_jar
skip = []
if t=='Java':
if target=='Java':
# don't test generator
skip = [ "/org/antlr/v4/test/rt/gen/", "TestPerformance" ]
elif t=='Python2':
skip = [ "/org/antlr/v4/test/rt/gen/", "TestPerformance.java", "TestGenerator.java" ]
elif target=='Python2':
# need BaseTest located in Py3 target
base = uniformpath(TARGETS['Python3'] + "/tool/test")
skip = [ "/org/antlr/v4/test/rt/py3/" ]
javac(base, "out/test/" + t, version="1.6", cp=thisjarwithjunit, args=args, skip=skip)
javac(base, "out/test/"+target, version="1.6", cp=thisjarwithjunit, args=args, skip=skip)
skip = []
elif t=='JavaScript':
# don't test browsers automatically, this is overkilling and unreliable
elif target=='JavaScript':
# don't test browsers automatically, this is overkill and unreliable
browsers = ["safari","chrome","firefox","explorer"]
skip = [ uniformpath(srcdir + "/org/antlr/v4/test/rt/js/" + b) for b in browsers ]
javac(srcdir, trgdir="out/test/" + t, version="1.6", cp=thisjarwithjunit, args=args, skip=skip)
# copy resource files required for testing
files = allfiles(srcdir)
for src in files:
if not ".java" in src and not ".stg" in src and not ".DS_Store" in src:
dst = src.replace(srcdir, uniformpath("out/test/" + t))
# only copy files from test dirs
if os.path.exists(os.path.split(dst)[0]):
shutil.copyfile(src, dst)
junit("out/test/" + t, cp=thiscp, verbose=False, args=juprops)
javac(srcdir, trgdir="out/test/"+target, version="1.6", cp=thisjarwithjunit, args=args, skip=skip)
# copy any resource files required for testing
for t in TARGETS:
root = TARGETS[t] + "/tool/test"
files = allfiles(root)
for src in files:
if not ".java" in src and not ".stg" in src and not os.path.basename(src).startswith("."):
dst = uniformpath(src.replace(root, "out"))
# print src, dst
if os.path.exists(os.path.split(dst)[0]):
shutil.copyfile(src, dst)
junit("out/test/"+target, cp='/Users/parrt/antlr/code/antlr4/out:'+uniformpath("dist/antlr4-" + VERSION + "-complete.jar"),
verbose=False, args=juprops)
def install(): # mvn installed locally in ~/.m2, java jar to /usr/local/lib if present
@ -422,10 +458,11 @@ def target_artifacts():
csharp()
def clean(dist=False):
def clean(dist=True):
if dist:
rmdir("dist")
rmdir("out")
rmdir("gen")
rmdir("gen3")
rmdir("gen4")
rmdir("doc")
@ -441,5 +478,16 @@ def all():
install()
clean()
# def duh():
# for t in TARGETS:
# root = TARGETS[t] + "/tool/test"
# files = allfiles(root)
# print t
# for src in files:
# if not ".java" in src and not ".stg" in src and not os.path.basename(src).startswith("."):
# dst = uniformpath(src.replace(root, "out"));
# print src, dst
# if os.path.exists(os.path.split(dst)[0]):
# shutil.copyfile(src, dst)
processargs(globals()) # E.g., "python bild.py all"

57
runtime-testsuite/pom.xml Normal file
View File

@ -0,0 +1,57 @@
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.antlr</groupId>
<version>4.5.1-SNAPSHOT</version>
<artifactId>runtime-testsuite</artifactId>
<packaging>jar</packaging>
<name>ANTLR 4 Runtime Test Generator</name>
<description>A collection of tests for ANTLR 4 Runtime libraries.</description>
<url>http://www.antlr.org</url>
<prerequisites>
<maven>3.0</maven>
</prerequisites>
<inceptionYear>2009</inceptionYear>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>ST4</artifactId>
<version>4.0.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<defaultGoal>install</defaultGoal>
<resources>
<resource>
<directory>resources</directory>
</resource>
</resources>
<plugins>
</plugins>
</build>
</project>

View File

@ -0,0 +1,7 @@
//TestFolders ::= [
//]
TestTemplates ::= [
"LexerDelegatorInvokesDelegateRule": [],
"LexerDelegatorRuleOverridesDelegate": []
]

View File

@ -0,0 +1,34 @@
TestType() ::= "CompositeLexer"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Input() ::= "abc"
Output() ::= <<
S.A
[@0,0:0='a',\<3>,1:0]
[@1,1:1='b',\<1>,1:1]
[@2,2:2='c',\<4>,1:2]
[@3,3:2='\<EOF>',\<-1>,1:3]<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
lexer grammar <grammarName>;
import <slaveGrammarName>;
B : 'b';
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
lexer grammar <grammarName>;
A : 'a' {<writeln("\"S.A\"")>};
C : 'c' ;
>>

View File

@ -0,0 +1,32 @@
TestType() ::= "CompositeLexer"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Input() ::= "ab"
Output() ::= <<
M.A
[@0,0:1='ab',\<1>,1:0]
[@1,2:1='\<EOF>',\<-1>,1:2]<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
lexer grammar <grammarName>;
import <slaveGrammarName>;
A : 'a' B {<writeln("\"M.A\"")>};
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
lexer grammar <grammarName>;
A : 'a' {<writeln("\"S.A\"")>};
B : 'b' {<writeln("\"S.B\"")>};
>>

View File

@ -0,0 +1,31 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "s"
Input() ::= "=a"
Output() ::= <<
S.a<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
s : a ;
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
a : '=' 'a' {<write("\"S.a\"")>};
>>

View File

@ -0,0 +1,40 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
AfterGrammar() ::= <<
writeFile(tmpdir, "M.g4", grammar);
ErrorQueue equeue = new ErrorQueue();
new Grammar(tmpdir+"/M.g4", grammar, equeue);
assertEquals("unexpected errors: " + equeue, 0, equeue.errors.size());<\n>
>>
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "s"
Input() ::= "x 34 9"
Output() ::= <<
S.x<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
s : x INT;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
tokens { A, B, C }
x : 'x' INT {<writeln("\"S.x\"")>};
INT : '0'..'9'+ ;
WS : (' '|'\n') -> skip ;
>>

View File

@ -0,0 +1,66 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", ["S", "T"])>}
]
AfterGrammar() ::= <<
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());<\n>
>>
SlaveGrammars ::= [
"S": {<slaveGrammarS("S")>},
"T": {<slaveGrammarT("T")>}
]
Rule() ::= "s"
Input() ::= "aa"
Output() ::= <<
S.x
T.y<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
// The lexer will create rules to match letters a, b, c.
// The associated token types A, B, C must have the same value
// and all import'd parsers. Since ANTLR regenerates all imports
// for use with the delegator M, it can generate the same token type
// mapping in each parser:
// public static final int C=6;
// public static final int EOF=-1;
// public static final int B=5;
// public static final int WS=7;
// public static final int A=4;
grammar M;
import S,T;
s : x y ; // matches AA, which should be 'aa'
B : 'b' ; // another order: B, A, C
A : 'a' ;
C : 'c' ;
WS : (' '|'\n') -> skip ;
>>
slaveGrammarS(grammarName) ::= <<
parser grammar S;
tokens { A, B, C }
x : A {<writeln("\"S.x\"")>};
>>
slaveGrammarT(grammarName) ::= <<
parser grammar S;
tokens { C, B, A } // reverse order
y : A {<writeln("\"T.y\"")>};
>>

View File

@ -0,0 +1,34 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "s"
Input() ::= "b"
Output() ::= <<
foo<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M; // uses no rules from the import
import S;
s : 'b'{<Invoke_foo()>}; // gS is import pointer
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
@members {
<Declare_foo()>
}
a : B;
>>

View File

@ -0,0 +1,32 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "s"
Input() ::= "b"
Output() ::= <<
S.a<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
s : a ;
B : 'b' ; // defines B from inherited token space
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
a : B {<writeln("\"S.a\"")>};
>>

View File

@ -0,0 +1,32 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "s"
Input() ::= "b"
Output() ::= <<
S.a1000<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
s : label=a[3] {<writeln("$label.y")>} ;
B : 'b' ; // defines B from inherited token space
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
a[int x] returns [int y] : B {<write("\"S.a\"")>;$y=1000;};
>>

View File

@ -0,0 +1,32 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "s"
Input() ::= "b"
Output() ::= <<
S.ab<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
s : a {<write("$a.text")>} ;
B : 'b' ; // defines B from inherited token space
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
a : B {<write("\"S.a\"")>};
>>

View File

@ -0,0 +1,39 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", ["S", "T"])>}
]
SlaveGrammars ::= [
"S": {<slaveGrammarS("S")>},
"T": {<slaveGrammarT("T")>}
]
Rule() ::= "s"
Input() ::= "b"
Output() ::= <<
S.a<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S,T;
s : a ;
B : 'b' ; // defines B from inherited token space
WS : (' '|'\n') -> skip ;
>>
slaveGrammarS(grammarName) ::= <<
parser grammar S;
a : B {<writeln("\"S.a\"")>};
b : B;
>>
slaveGrammarT(grammarName) ::= <<
parser grammar T;
a : B {<writeln("\"T.a\"")>};
>>

View File

@ -0,0 +1,32 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "a"
Input() ::= "c"
Output() ::= <<
S.a<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
b : 'b'|'c';
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
a : b {<write("\"S.a\"")>};
b : B ;
>>

View File

@ -0,0 +1,40 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammarS("S")>},
"T": {<slaveGrammarT("T")>}
]
Rule() ::= "a"
Input() ::= "c"
Output() ::= <<
M.b
S.a<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S, T;
b : 'b'|'c' {<writeln("\"M.b\"")>}|B|A;
WS : (' '|'\n') -> skip ;
>>
slaveGrammarS(grammarName) ::= <<
parser grammar S;
a : b {<writeln("\"S.a\"")>};
b : 'b' ;
>>
slaveGrammarT(grammarName) ::= <<
parser grammar S;
tokens { A }
b : 'b' {<writeln("\"T.b\"")>};
>>

View File

@ -0,0 +1,37 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "prog"
Input() ::= "float x = 3;"
Output() ::= <<
Decl: floatx=3;<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
prog : decl ;
type_ : 'int' | 'float' ;
ID : 'a'..'z'+ ;
INT : '0'..'9'+ ;
WS : (' '|'\n') -> skip;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
type_ : 'int' ;
decl : type_ ID ';'
| type_ ID init ';' {<write("\"Decl: \" + $text")>};
init : '=' INT;
>>

View File

@ -0,0 +1,34 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "program"
Input() ::= "test test"
Output() ::= <<
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
program : 'test' 'test';
WS : (UNICODE_CLASS_Zs)+ -> skip;
>>
slaveGrammar(grammarName) ::= <<
lexer grammar S;
fragment
UNICODE_CLASS_Zs : '\u0020' | '\u00A0' | '\u1680' | '\u180E'
| '\u2000'..'\u200A'
| '\u202F' | '\u205F' | '\u3000'
;
>>

View File

@ -0,0 +1,32 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "s"
Input() ::= "b"
Output() ::= <<
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
s : a;
B : 'b';
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
options {}
a : B;
>>

View File

@ -0,0 +1,31 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "s"
Input() ::= "b"
Output() ::= <<
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
s : a;
B : 'b';
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
parser grammar S;
a @after {} : B;
>>

View File

@ -0,0 +1,25 @@
//TestFolders ::= [
//]
TestTemplates ::= [
"DelegatorInvokesDelegateRule": [],
"BringInLiteralsFromDelegate": [],
"DelegatorInvokesDelegateRuleWithArgs": [],
"DelegatorInvokesDelegateRuleWithReturnStruct": [],
"DelegatorAccessesDelegateMembers": [],
"DelegatorInvokesFirstVersionOfDelegateRule": [],
"DelegatesSeeSameTokenType": [],
"CombinedImportsCombined": [],
"DelegatorRuleOverridesDelegate": [],
"DelegatorRuleOverridesLookaheadInDelegate": [],
"DelegatorRuleOverridesDelegates": [],
"KeywordVSIDOrder": [],
"ImportedRuleWithAction": [],
"ImportedGrammarWithEmptyOptions": [],
"ImportLexerWithOnlyFragmentRules": []
]
Options ::= [
"ImportErrorQueue": true,
"ImportGrammar": true
]

View File

@ -0,0 +1,33 @@
TestType() ::= "CompositeParser"
Grammar ::= [
"M": {<masterGrammar("M", "S")>}
]
SlaveGrammars ::= [
"S": {<slaveGrammar("S")>}
]
Rule() ::= "a"
Input() ::= "abc"
Output() ::= <<
M.A
M.a: [@0,0:2='abc',\<1>,1:0]<\n>
>>
Errors() ::= ""
masterGrammar(grammarName, slaveGrammarName) ::= <<
grammar M;
import S;
a : A {<Append("\"M.a: \"","$A"):writeln()>};
A : 'abc' {<writeln("\"M.A\"")>};
WS : (' '|'\n') -> skip ;
>>
slaveGrammar(grammarName) ::= <<
lexer grammar S;
ID : 'a'..'z'+;
>>

View File

@ -0,0 +1,30 @@
TestType() ::= "Parser"
Options ::= [
"Debug": true
]
Grammar ::= [
"T": {<grammar("T")>}
]
Input() ::= "abc"
Rule() ::= "s"
Output() ::= <<
Decision 0:
s0-ID->:s1^=>1<\n>
>>
Errors() ::= <<
line 1:0 reportAttemptingFullContext d=0 (s), input='abc'<\n>
>>
grammar(grammarName) ::= <<
grammar <grammarName>;
s @after {<DumpDFA()>}
: ID | ID {} ;
ID : 'a'..'z'+;
WS : (' '|'\t'|'\n')+ -> skip ;
>>

View File

@ -0,0 +1,39 @@
TestType() ::= "Parser"
Options ::= [
"Debug": true
]
Grammar ::= [
"T": {<grammar("T")>}
]
Input() ::= "a@"
Rule() ::= "prog"
Output() ::= <<
alt 1<\n>
>>
Errors() ::= <<
line 1:2 reportAttemptingFullContext d=0 (prog), input='a@'
line 1:2 reportAmbiguity d=0 (prog): ambigAlts={1, 2}, input='a@'
line 1:2 reportAttemptingFullContext d=1 (expr), input='a@'
line 1:2 reportContextSensitivity d=1 (expr), input='a@'<\n>
>>
grammar(grammarName) ::= <<
grammar <grammarName>;
prog
@init {<LL_EXACT_AMBIG_DETECTION()>}
: expr expr {<writeln("\"alt 1\"")>}
| expr
;
expr: '@'
| ID '@'
| ID
;
ID : [a-z]+ ;
WS : [ \r\n\t]+ -> skip ;
>>

View File

@ -0,0 +1,23 @@
TestType() ::= "Parser"
Options ::= [
"Debug": true
]
Grammar ::= [
"T": {<grammar("T")>}
]
Rule() ::= "s"
grammar(grammarName) ::= <<
grammar <grammarName>;
s @after {<DumpDFA()>}
: '$' a | '@' b ;
a : e ID ;
b : e INT ID ;
e : INT | ;
ID : 'a'..'z'+ ;
INT : '0'..'9'+ ;
WS : (' '|'\t'|'\n')+ -> skip ;
>>

View File

@ -0,0 +1,39 @@
TestType() ::= "Parser"
Options ::= [
"Debug": true
]
Grammar ::= [
"T": {<grammar("T")>}
]
Input() ::= "$ 34 abc @ 34 abc"
Rule() ::= "s"
Output() ::= <<
Decision 2:
s0-INT->s1
s1-ID->:s2^=>1<\n>
>>
Errors() ::= <<
line 1:5 reportAttemptingFullContext d=2 (e), input='34abc'
line 1:2 reportContextSensitivity d=2 (e), input='34'
line 1:14 reportAttemptingFullContext d=2 (e), input='34abc'
line 1:14 reportContextSensitivity d=2 (e), input='34abc'<\n>
>>
grammar(grammarName) ::= <<
grammar <grammarName>;
s @after {<DumpDFA()>}
: ('$' a | '@' b)+ ;
a : e ID ;
b : e INT ID ;
e : INT | ;
ID : 'a'..'z'+ ;
INT : '0'..'9'+ ;
WS : (' '|'\t'|'\n')+ -> skip ;
>>

View File

@ -0,0 +1,14 @@
import "CtxSensitiveDFA.stg"
Input() ::= "$ 34 abc"
Output() ::= <<
Decision 1:
s0-INT->s1
s1-ID->:s2^=>1<\n>
>>
Errors() ::= <<
line 1:5 reportAttemptingFullContext d=1 (e), input='34abc'
line 1:2 reportContextSensitivity d=1 (e), input='34'<\n>
>>

View File

@ -0,0 +1,14 @@
import "CtxSensitiveDFA.stg"
Input() ::= "@ 34 abc"
Output() ::= <<
Decision 1:
s0-INT->s1
s1-ID->:s2^=>1<\n>
>>
Errors() ::= <<
line 1:5 reportAttemptingFullContext d=1 (e), input='34abc'
line 1:5 reportContextSensitivity d=1 (e), input='34abc'<\n>
>>

View File

@ -0,0 +1,28 @@
TestType() ::= "Parser"
Options ::= [
"Debug": true
]
Grammar ::= [
"T": {<grammar("T")>}
]
Rule() ::= "s"
grammar(grammarName) ::= <<
grammar <grammarName>;
s
@init {<LL_EXACT_AMBIG_DETECTION()>}
: expr[0] {<ToStringTree("$expr.ctx"):writeln()>};
expr[int _p]
: ID
(
{5 >= $_p}? '*' expr[6]
| {4 >= $_p}? '+' expr[5]
)*
;
ID : [a-zA-Z]+ ;
WS : [ \r\n\t]+ -> skip ;
>>

View File

@ -0,0 +1,12 @@
import "ExprAmbiguity.stg"
Input() ::= "a+b"
Output() ::= <<
(expr a + (expr b))<\n>
>>
Errors() ::= <<
line 1:1 reportAttemptingFullContext d=1 (expr), input='+'
line 1:2 reportContextSensitivity d=1 (expr), input='+b'<\n>
>>

View File

@ -0,0 +1,14 @@
import "ExprAmbiguity.stg"
Input() ::= "a+b*c"
Output() ::= <<
(expr a + (expr b * (expr c)))<\n>
>>
Errors() ::= <<
line 1:1 reportAttemptingFullContext d=1 (expr), input='+'
line 1:2 reportContextSensitivity d=1 (expr), input='+b'
line 1:3 reportAttemptingFullContext d=1 (expr), input='*'
line 1:5 reportAmbiguity d=1 (expr): ambigAlts={1, 2}, input='*c'<\n>
>>

View File

@ -0,0 +1,24 @@
TestType() ::= "Parser"
Options ::= [
"Debug": true
]
Grammar ::= [
"T": {<grammar("T")>}
]
Rule() ::= "s"
grammar(grammarName) ::= <<
grammar <grammarName>;
s
@init {<LL_EXACT_AMBIG_DETECTION()>}
@after {<DumpDFA()>}
: '{' stat* '}' ;
stat: 'if' ID 'then' stat ('else' ID)?
| 'return'
;
ID : 'a'..'z'+ ;
WS : (' '|'\t'|'\n')+ -> skip ;
>>

View File

@ -0,0 +1,10 @@
import "FullContextIF_THEN_ELSEParse.stg"
Input() ::= "{ if x then return }"
Output() ::= <<
Decision 1:
s0-'}'->:s1=>2<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,13 @@
import "FullContextIF_THEN_ELSEParse.stg"
Input() ::= "{ if x then return else foo }"
Output() ::= <<
Decision 1:
s0-'else'->:s1^=>1<\n>
>>
Errors() ::= <<
line 1:19 reportAttemptingFullContext d=1 (stat), input='else'
line 1:19 reportContextSensitivity d=1 (stat), input='else'<\n>
>>

View File

@ -0,0 +1,14 @@
import "FullContextIF_THEN_ELSEParse.stg"
Input() ::= "{ if x then if y then return else foo }"
Output() ::= <<
Decision 1:
s0-'}'->:s2=>2
s0-'else'->:s1^=>1<\n>
>>
Errors() ::= <<
line 1:29 reportAttemptingFullContext d=1 (stat), input='else'
line 1:38 reportAmbiguity d=1 (stat): ambigAlts={1, 2}, input='elsefoo}'<\n>
>>

View File

@ -0,0 +1,19 @@
import "FullContextIF_THEN_ELSEParse.stg"
// should not be ambiguous because the second 'else bar' clearly
// indicates that the first else should match to the innermost if.
// LL_EXACT_AMBIG_DETECTION makes us keep going to resolve
Input() ::= "{ if x then if y then return else foo else bar }"
Output() ::= <<
Decision 1:
s0-'else'->:s1^=>1<\n>
>>
Errors() ::= <<
line 1:29 reportAttemptingFullContext d=1 (stat), input='else'
line 1:38 reportContextSensitivity d=1 (stat), input='elsefooelse'
line 1:38 reportAttemptingFullContext d=1 (stat), input='else'
line 1:38 reportContextSensitivity d=1 (stat), input='else'<\n>
>>

View File

@ -0,0 +1,19 @@
import "FullContextIF_THEN_ELSEParse.stg"
Input() ::= <<
{ if x then return else foo
if x then if y then return else foo }
>>
Output() ::= <<
Decision 1:
s0-'}'->:s2=>2
s0-'else'->:s1^=>1<\n>
>>
Errors() ::= <<
line 1:19 reportAttemptingFullContext d=1 (stat), input='else'
line 1:19 reportContextSensitivity d=1 (stat), input='else'
line 2:27 reportAttemptingFullContext d=1 (stat), input='else'
line 2:36 reportAmbiguity d=1 (stat): ambigAlts={1, 2}, input='elsefoo}'<\n>
>>

View File

@ -0,0 +1,19 @@
import "FullContextIF_THEN_ELSEParse.stg"
Input() ::= <<
{ if x then return else foo
if x then if y then return else foo }
>>
Output() ::= <<
Decision 1:
s0-'}'->:s2=>2
s0-'else'->:s1^=>1<\n>
>>
Errors() ::= <<
line 1:19 reportAttemptingFullContext d=1 (stat), input='else'
line 1:19 reportContextSensitivity d=1 (stat), input='else'
line 2:27 reportAttemptingFullContext d=1 (stat), input='else'
line 2:36 reportAmbiguity d=1 (stat): ambigAlts={1, 2}, input='elsefoo}'<\n>
>>

View File

@ -0,0 +1,20 @@
//TestFolders ::= [
//]
TestTemplates ::= [
"AmbigYieldsCtxSensitiveDFA": [],
"CtxSensitiveDFA_1": [],
"CtxSensitiveDFA_2": [],
"CtxSensitiveDFATwoDiffInput": [],
"SLLSeesEOFInLLGrammar": [],
"FullContextIF_THEN_ELSEParse_1": [],
"FullContextIF_THEN_ELSEParse_2": [],
"FullContextIF_THEN_ELSEParse_3": [],
"FullContextIF_THEN_ELSEParse_4": [],
"FullContextIF_THEN_ELSEParse_5": [],
"FullContextIF_THEN_ELSEParse_6": [],
"LoopsSimulateTailRecursion": [],
"AmbiguityNoLoop": [],
"ExprAmbiguity_1": [],
"ExprAmbiguity_2": []
]

View File

@ -0,0 +1,40 @@
TestType() ::= "Parser"
Options ::= [
"Debug": true
]
Grammar ::= [
"T": {<grammar("T")>}
]
Input() ::= "a(i)\<-x"
Rule() ::= "prog"
Output() ::= <<
pass: a(i)\<-x<\n>
>>
Errors() ::= <<
line 1:3 reportAttemptingFullContext d=3 (expr_primary), input='a(i)'
line 1:7 reportAmbiguity d=3 (expr_primary): ambigAlts={2, 3}, input='a(i)\<-x'<\n>
>>
grammar(grammarName) ::= <<
grammar <grammarName>;
prog
@init {<LL_EXACT_AMBIG_DETECTION()>}
: expr_or_assign*;
expr_or_assign
: expr '++' {<writeln("\"fail.\"")>}
| expr {<writeln("\"pass: \"+$expr.text")>}
;
expr: expr_primary ('\<-' ID)?;
expr_primary
: '(' ID ')'
| ID '(' ID ')'
| ID
;
ID : [a-z]+ ;
>>

View File

@ -0,0 +1,36 @@
TestType() ::= "Parser"
Options ::= [
"Debug": true
]
Grammar ::= [
"T": {<grammar("T")>}
]
Input() ::= "34 abc"
Rule() ::= "s"
Output() ::= <<
Decision 0:
s0-INT->s1
s1-ID->:s2^=>1<\n>
>>
Errors() ::= <<
line 1:3 reportAttemptingFullContext d=0 (e), input='34abc'
line 1:0 reportContextSensitivity d=0 (e), input='34'<\n>
>>
grammar(grammarName) ::= <<
grammar <grammarName>;
s @after {<DumpDFA()>}
: a;
a : e ID ;
b : e INT ID ;
e : INT | ;
ID : 'a'..'z'+ ;
INT : '0'..'9'+ ;
WS : (' '|'\t'|'\n')+ -> skip ;
>>

View File

@ -0,0 +1,15 @@
TestFolders ::= [
"CompositeLexers": [],
"CompositeParsers": [],
"FullContextParsing": [],
"LeftRecursion": [],
"LexerErrors": [],
"LexerExec": [],
"Listeners": [],
"ParserErrors": [],
"ParserExec": [],
"ParseTrees": [],
"SemPredEvalLexer": [],
"SemPredEvalParser": [],
"Sets": []
]

View File

@ -0,0 +1,35 @@
TestType() ::= "Parser"
Options ::= [
"Debug": false
]
Grammar ::= [
"Expr": {<grammar("Expr")>}
]
Rule() ::= "prog"
grammar(grammarName) ::= <<
grammar <grammarName>;
prog: stat ;
stat: expr NEWLINE # printExpr
| ID '=' expr NEWLINE # assign
| NEWLINE # blank
;
expr: expr ('*'|'/') expr # MulDiv
| expr ('+'|'-') expr # AddSub
| INT # int
| ID # id
| '(' expr ')' # parens
;
MUL : '*' ; // assigns token name to '*' used above in grammar
DIV : '/' ;
ADD : '+' ;
SUB : '-' ;
ID : [a-zA-Z]+ ; // match identifiers
INT : [0-9]+ ; // match integers
NEWLINE:'\r'? '\n' ; // return newlines to parser (is end-statement signal)
WS : [ \t]+ -> skip ; // toss out whitespace
>>

View File

@ -0,0 +1,7 @@
import "AmbigLR.stg"
Input() ::= "1<\n>"
Output() ::= ""
Errors() ::= ""

View File

@ -0,0 +1,7 @@
import "AmbigLR.stg"
Input() ::= "a = 5<\n>"
Output() ::= ""
Errors() ::= ""

View File

@ -0,0 +1,7 @@
import "AmbigLR.stg"
Input() ::= "b = 6<\n>"
Output() ::= ""
Errors() ::= ""

View File

@ -0,0 +1,7 @@
import "AmbigLR.stg"
Input() ::= "a+b*2<\n>"
Output() ::= ""
Errors() ::= ""

View File

@ -0,0 +1,7 @@
import "AmbigLR.stg"
Input() ::= "(1+2)*3<\n>"
Output() ::= ""
Errors() ::= ""

View File

@ -0,0 +1,28 @@
TestType() ::= "Parser"
Options ::= [
"Debug": false
]
Grammar ::= [
"T": {<grammar("T")>}
]
Rule() ::= "s"
grammar(grammarName) ::= <<
grammar <grammarName>;
s @after {<ToStringTree("$ctx"):writeln()>} : declarator EOF ; // must indicate EOF can follow
declarator
: declarator '[' e ']'
| declarator '[' ']'
| declarator '(' ')'
| '*' declarator // binds less tight than suffixes
| '(' declarator ')'
| ID
;
e : INT ;
ID : 'a'..'z'+ ;
INT : '0'..'9'+ ;
WS : (' '|'\n') -> skip ;
>>

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "a"
Output() ::= <<
(s (declarator a) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "(*a)[]"
Output() ::= <<
(s (declarator (declarator ( (declarator * (declarator a)) )) [ ]) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "*a"
Output() ::= <<
(s (declarator * (declarator a)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "**a"
Output() ::= <<
(s (declarator * (declarator * (declarator a))) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "a[3]"
Output() ::= <<
(s (declarator (declarator a) [ (e 3) ]) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "b[]"
Output() ::= <<
(s (declarator (declarator b) [ ]) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "(a)"
Output() ::= <<
(s (declarator ( (declarator a) )) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "a[]()"
Output() ::= <<
(s (declarator (declarator (declarator a) [ ]) ( )) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "a[][]"
Output() ::= <<
(s (declarator (declarator (declarator a) [ ]) [ ]) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Declarations.stg"
Input() ::= "*a[]"
Output() ::= <<
(s (declarator * (declarator (declarator a) [ ])) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,26 @@
/**
* This is a regression test for "Support direct calls to left-recursive
* rules".
* https://github.com/antlr/antlr4/issues/161
*/
TestType() ::= "Parser"
Options ::= [
"Debug": false
]
Grammar ::= [
"T": {<grammar("T")>}
]
Rule() ::= "a"
grammar(grammarName) ::= <<
grammar <grammarName>;
a @after {<ToStringTree("$ctx"):writeln()>} : a ID
| ID
;
ID : 'a'..'z'+ ;
WS : (' '|'\n') -> skip ;
>>

View File

@ -0,0 +1,9 @@
import "DirectCallToLeftRecursiveRule.stg"
Input() ::= "x"
Output() ::= <<
(a x)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "DirectCallToLeftRecursiveRule.stg"
Input() ::= "x y"
Output() ::= <<
(a (a x) y)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "DirectCallToLeftRecursiveRule.stg"
Input() ::= "x y z"
Output() ::= <<
(a (a (a x) y) z)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,27 @@
TestType() ::= "Parser"
Options ::= [
"Debug": false
]
Grammar ::= [
"T": {<grammar("T")>}
]
Rule() ::= "s"
grammar(grammarName) ::= <<
grammar <grammarName>;
s @after {<ToStringTree("$ctx"):writeln()>} : e EOF ; // must indicate EOF can follow
e : e '.' ID
| e '.' 'this'
| '-' e
| e '*' e
| e ('+'|'-') e
| INT
| ID
;
ID : 'a'..'z'+ ;
INT : '0'..'9'+ ;
WS : (' '|'\n') -> skip ;
>>

View File

@ -0,0 +1,9 @@
import "Expressions.stg"
Input() ::= "a"
Output() ::= <<
(s (e a) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Expressions.stg"
Input() ::= "1"
Output() ::= <<
(s (e 1) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Expressions.stg"
Input() ::= "a-1"
Output() ::= <<
(s (e (e a) - (e 1)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Expressions.stg"
Input() ::= "a.b"
Output() ::= <<
(s (e (e a) . b) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Expressions.stg"
Input() ::= "a.this"
Output() ::= <<
(s (e (e a) . this) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Expressions.stg"
Input() ::= "-a"
Output() ::= <<
(s (e - (e a)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "Expressions.stg"
Input() ::= "-a+b"
Output() ::= <<
(s (e (e - (e a)) + (e b)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,100 @@
//TestFolders ::= [
//]
TestTemplates ::= [
"Simple_1": [],
"Simple_2": [],
"Simple_3": [],
"DirectCallToLeftRecursiveRule_1": [],
"DirectCallToLeftRecursiveRule_2": [],
"DirectCallToLeftRecursiveRule_3": [],
"SemPred": [],
"TernaryExpr_1": [],
"TernaryExpr_2": [],
"TernaryExpr_3": [],
"TernaryExpr_4": [],
"TernaryExpr_5": [],
"TernaryExpr_6": [],
"TernaryExpr_7": [],
"TernaryExpr_8": [],
"TernaryExpr_9": [],
"Expressions_1": [],
"Expressions_2": [],
"Expressions_3": [],
"Expressions_4": [],
"Expressions_5": [],
"Expressions_6": [],
"Expressions_7": [],
"JavaExpressions_1": [],
"JavaExpressions_2": [],
"JavaExpressions_3": [],
"JavaExpressions_4": [],
"JavaExpressions_5": [],
"JavaExpressions_6": [],
"JavaExpressions_7": [],
"JavaExpressions_8": [],
"JavaExpressions_9": [],
"JavaExpressions_10": [],
"JavaExpressions_11": [],
"JavaExpressions_12": [],
"Declarations_1": [],
"Declarations_2": [],
"Declarations_3": [],
"Declarations_4": [],
"Declarations_5": [],
"Declarations_6": [],
"Declarations_7": [],
"Declarations_8": [],
"Declarations_9": [],
"Declarations_10": [],
"ReturnValueAndActions_1": [],
"ReturnValueAndActions_2": [],
"ReturnValueAndActions_3": [],
"ReturnValueAndActions_4": [],
"LabelsOnOpSubrule_1": [],
"LabelsOnOpSubrule_2": [],
"LabelsOnOpSubrule_3": [],
"ReturnValueAndActionsAndLabels_1": [],
"ReturnValueAndActionsAndLabels_2": [],
"ReturnValueAndActionsAndLabels_3": [],
"ReturnValueAndActionsAndLabels_4": [],
"MultipleAlternativesWithCommonLabel_1": [],
"MultipleAlternativesWithCommonLabel_2": [],
"MultipleAlternativesWithCommonLabel_3": [],
"MultipleAlternativesWithCommonLabel_4": [],
"PrefixOpWithActionAndLabel_1": [],
"PrefixOpWithActionAndLabel_2": [],
"PrefixOpWithActionAndLabel_3": [],
"AmbigLR_1": [],
"AmbigLR_2": [],
"AmbigLR_3": [],
"AmbigLR_4": [],
"AmbigLR_5": [],
"WhitespaceInfluence_1": [],
"WhitespaceInfluence_2": [],
"PrecedenceFilterConsidersContext": [],
"MultipleActions_1": [],
"MultipleActions_2": [],
"MultipleActions_3": [],
"MultipleActionsPredicatesOptions_1": [],
"MultipleActionsPredicatesOptions_2": [],
"MultipleActionsPredicatesOptions_3": [],
"SemPredFailOption": [],
"TernaryExprExplicitAssociativity_1": [],
"TernaryExprExplicitAssociativity_2": [],
"TernaryExprExplicitAssociativity_3": [],
"TernaryExprExplicitAssociativity_4": [],
"TernaryExprExplicitAssociativity_5": [],
"TernaryExprExplicitAssociativity_6": [],
"TernaryExprExplicitAssociativity_7": [],
"TernaryExprExplicitAssociativity_8": [],
"TernaryExprExplicitAssociativity_9": [],
"ReturnValueAndActionsList1_1": [],
"ReturnValueAndActionsList1_2": [],
"ReturnValueAndActionsList1_3": [],
"ReturnValueAndActionsList1_4": [],
"ReturnValueAndActionsList2_1": [],
"ReturnValueAndActionsList2_2": [],
"ReturnValueAndActionsList2_3": [],
"ReturnValueAndActionsList2_4": []
]

View File

@ -0,0 +1,70 @@
TestType() ::= "Parser"
Options ::= [
"Debug": false
]
Grammar ::= [
"T": {<grammar("T")>}
]
Rule() ::= "s"
grammar(grammarName) ::= <<
grammar <grammarName>;
s @after {<ToStringTree("$ctx"):writeln()>} : e EOF ; // must indicate EOF can follow
expressionList
: e (',' e)*
;
e : '(' e ')'
| 'this'
| 'super'
| INT
| ID
| type_ '.' 'class'
| e '.' ID
| e '.' 'this'
| e '.' 'super' '(' expressionList? ')'
| e '.' 'new' ID '(' expressionList? ')'
| 'new' type_ ( '(' expressionList? ')' | ('[' e ']')+)
| e '[' e ']'
| '(' type_ ')' e
| e ('++' | '--')
| e '(' expressionList? ')'
| ('+'|'-'|'++'|'--') e
| ('~'|'!') e
| e ('*'|'/'|'%') e
| e ('+'|'-') e
| e ('\<\<' | '>\>>' | '\>>') e
| e ('\<=' | '>=' | '>' | '\<') e
| e 'instanceof' e
| e ('==' | '!=') e
| e '&' e
|\<assoc=right> e '^' e
| e '|' e
| e '&&' e
| e '||' e
| e '?' e ':' e
|\<assoc=right>
e ('='
|'+='
|'-='
|'*='
|'/='
|'&='
|'|='
|'^='
|'\>>='
|'>\>>='
|'\<\<='
|'%=') e
;
type_: ID
| ID '[' ']'
| 'int'
| 'int' '[' ']'
;
ID : ('a'..'z'|'A'..'Z'|'_'|'$')+;
INT : '0'..'9'+ ;
WS : (' '|'\n') -> skip ;
>>

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "a|b&c"
Output() ::= <<
(s (e (e a) | (e (e b) & (e c))) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "a.f(x)==T.c"
Output() ::= <<
(s (e (e (e (e a) . f) ( (expressionList (e x)) )) == (e (e T) . c)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "a.f().g(x,1)"
Output() ::= <<
(s (e (e (e (e (e a) . f) ( )) . g) ( (expressionList (e x) , (e 1)) )) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "new T[((n-1) * x) + 1]"
Output() ::= <<
(s (e new (type_ T) [ (e (e ( (e (e ( (e (e n) - (e 1)) )) * (e x)) )) + (e 1)) ]) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "(a|b)&c"
Output() ::= <<
(s (e (e ( (e (e a) | (e b)) )) & (e c)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "a > b"
Output() ::= <<
(s (e (e a) > (e b)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "a >> b"
Output() ::= <<
(s (e (e a) \>> (e b)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "a=b=c"
Output() ::= <<
(s (e (e a) = (e (e b) = (e c))) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "a^b^c"
Output() ::= <<
(s (e (e a) ^ (e (e b) ^ (e c))) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "(T)x"
Output() ::= <<
(s (e ( (type_ T) ) (e x)) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "new A().b"
Output() ::= <<
(s (e (e new (type_ A) ( )) . b) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "JavaExpressions.stg"
Input() ::= "(T)t.f()"
Output() ::= <<
(s (e (e ( (type_ T) ) (e (e t) . f)) ( )) \<EOF>)<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,22 @@
TestType() ::= "Parser"
Options ::= [
"Debug": false
]
Grammar ::= [
"T": {<grammar("T")>}
]
Rule() ::= "s"
grammar(grammarName) ::= <<
grammar <grammarName>;
s @after {<ToStringTree("$ctx"):writeln()>} : e;
e : a=e op=('*'|'/') b=e {}
| INT {}
| '(' x=e ')' {}
;
INT : '0'..'9'+ ;
WS : (' '|'\n') -> skip ;
>>

View File

@ -0,0 +1,9 @@
import "LabelsOnOpSubrule.stg"
Input() ::= "4"
Output() ::= <<
(s (e 4))<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "LabelsOnOpSubrule.stg"
Input() ::= "1*2/3"
Output() ::= <<
(s (e (e (e 1) * (e 2)) / (e 3)))<\n>
>>
Errors() ::= ""

View File

@ -0,0 +1,9 @@
import "LabelsOnOpSubrule.stg"
Input() ::= "(1/2)*3"
Output() ::= <<
(s (e (e ( (e (e 1) / (e 2)) )) * (e 3)))<\n>
>>
Errors() ::= ""

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