Rewrite test generator as a Maven plugin that generates tests as part of the build
This commit only updates the "TestSets" collection of tests to use the new framework.
This commit is contained in:
parent
8cc929f942
commit
90763e5ae2
|
@ -88,7 +88,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.codehaus.plexus</groupId>
|
<groupId>org.codehaus.plexus</groupId>
|
||||||
<artifactId>plexus-compiler-api</artifactId>
|
<artifactId>plexus-compiler-api</artifactId>
|
||||||
<version>2.2</version>
|
<version>2.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project-shared-configuration>
|
||||||
|
<!--
|
||||||
|
This file contains additional configuration written by modules in the NetBeans IDE.
|
||||||
|
The configuration is intended to be shared among all the users of project and
|
||||||
|
therefore it is assumed to be part of version control checkout.
|
||||||
|
Without this configuration present, some functionality in the IDE may be limited or fail altogether.
|
||||||
|
-->
|
||||||
|
<properties xmlns="http://www.netbeans.org/ns/maven-properties-data/1">
|
||||||
|
<!--
|
||||||
|
Properties that influence various parts of the IDE, especially code formatting and the like.
|
||||||
|
You can copy and paste the single properties, into the pom.xml file and the IDE will pick them up.
|
||||||
|
That way multiple projects can share the same settings (useful for formatting rules for example).
|
||||||
|
Any value defined here will override the pom.xml file value but is only applicable to the current project.
|
||||||
|
-->
|
||||||
|
<org-netbeans-modules-editor-indent.CodeStyle.usedProfile>project</org-netbeans-modules-editor-indent.CodeStyle.usedProfile>
|
||||||
|
<org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab>4</org-netbeans-modules-editor-indent.CodeStyle.project.spaces-per-tab>
|
||||||
|
<org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>4</org-netbeans-modules-editor-indent.CodeStyle.project.tab-size>
|
||||||
|
<org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width>4</org-netbeans-modules-editor-indent.CodeStyle.project.indent-shift-width>
|
||||||
|
<org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs>true</org-netbeans-modules-editor-indent.CodeStyle.project.expand-tabs>
|
||||||
|
<org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.CodeStyle.project.text-limit-width>
|
||||||
|
<org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap>none</org-netbeans-modules-editor-indent.CodeStyle.project.text-line-wrap>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indentCasesFromSwitch>false</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indentCasesFromSwitch>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaces-per-tab>4</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.spaces-per-tab>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.tab-size>4</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.tab-size>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indent-shift-width>4</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.indent-shift-width>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.expand-tabs>false</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.expand-tabs>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-limit-width>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-line-wrap>none</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.text-line-wrap>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.continuationIndentSize>4</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.continuationIndentSize>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.allowConvertToStarImport>false</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.allowConvertToStarImport>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.allowConvertToStaticStarImport>false</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.allowConvertToStaticStarImport>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.importGroupsOrder>*;java</org-netbeans-modules-editor-indent.text.x-java.CodeStyle.project.importGroupsOrder>
|
||||||
|
<netbeans.compile.on.save>test</netbeans.compile.on.save>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.text-line-wrap>none</org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.text-line-wrap>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.indent-shift-width>4</org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.indent-shift-width>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.spaces-per-tab>4</org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.spaces-per-tab>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.tab-size>4</org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.tab-size>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.text-limit-width>80</org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.text-limit-width>
|
||||||
|
<org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.expand-tabs>false</org-netbeans-modules-editor-indent.text.x-stringtemplate4.CodeStyle.project.expand-tabs>
|
||||||
|
</properties>
|
||||||
|
</project-shared-configuration>
|
|
@ -0,0 +1,210 @@
|
||||||
|
<!--
|
||||||
|
|
||||||
|
[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>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.antlr</groupId>
|
||||||
|
<artifactId>antlr4-master</artifactId>
|
||||||
|
<version>4.4-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- ============================================================================= -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
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>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
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>
|
|
@ -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>
|
|
@ -0,0 +1,7 @@
|
||||||
|
//TestFolders ::= [
|
||||||
|
//]
|
||||||
|
|
||||||
|
TestTemplates ::= [
|
||||||
|
"LexerDelegatorInvokesDelegateRule": [],
|
||||||
|
"LexerDelegatorRuleOverridesDelegate": []
|
||||||
|
]
|
|
@ -0,0 +1,31 @@
|
||||||
|
TestType() ::= "CompositeLexer"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"M.g4": {<masterGrammar("M", "S")>},
|
||||||
|
"S.g4": {<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' ;
|
||||||
|
>>
|
|
@ -0,0 +1,31 @@
|
||||||
|
TestType() ::= "CompositeLexer"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"M.g4": {<masterGrammar("M", "S")>},
|
||||||
|
"S.g4": {<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>;
|
||||||
|
A : 'a' B {<writeln("\"M.A\"")>};
|
||||||
|
WS : (' '|'\n') -> skip ;
|
||||||
|
>>
|
||||||
|
|
||||||
|
slaveGrammar(grammarName) ::= <<
|
||||||
|
lexer grammar <grammarName>;
|
||||||
|
A : 'a' {<writeln("\"S.A\"")>};
|
||||||
|
B : 'b' {<writeln("\"S.B\"")>};
|
||||||
|
>>
|
|
@ -0,0 +1,6 @@
|
||||||
|
TestFolders ::= [
|
||||||
|
"CompositeLexers": []
|
||||||
|
]
|
||||||
|
|
||||||
|
//TestTemplates ::= [
|
||||||
|
//]
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
[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.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 org.stringtemplate.v4.ST;
|
||||||
|
import org.stringtemplate.v4.STGroup;
|
||||||
|
import org.stringtemplate.v4.STGroupFile;
|
||||||
|
import org.stringtemplate.v4.gui.STViz;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@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", required = true, readonly = true)
|
||||||
|
private MavenProject project;
|
||||||
|
|
||||||
|
@Parameter(required = true)
|
||||||
|
private File runtimeTemplates;
|
||||||
|
|
||||||
|
@Parameter(defaultValue = "${project.build.directory}/generated-test-sources/antlr4-tests")
|
||||||
|
private File outputDirectory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||||
|
STGroup targetGroup = new STGroupFile(runtimeTemplates.getPath());
|
||||||
|
targetGroup.registerModelAdaptor(STGroup.class, new STGroupModelAdaptor());
|
||||||
|
targetGroup.defineDictionary("escape", new JavaEscapeStringMap());
|
||||||
|
|
||||||
|
String rootFolder = "org/antlr4/runtime/test/templates";
|
||||||
|
STGroup index = new STGroupFile(rootFolder + "/Index.stg");
|
||||||
|
generateCodeForFolder(targetGroup, rootFolder, index);
|
||||||
|
|
||||||
|
project.addTestCompileSourceRoot(outputDirectory.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateCodeForFolder(STGroup targetGroup, String folder, STGroup index) {
|
||||||
|
// make sure the index group is loaded since we call rawGetDictionary
|
||||||
|
index.load();
|
||||||
|
|
||||||
|
Map<String, Object> folders = index.rawGetDictionary("TestFolders");
|
||||||
|
if (folders != null) {
|
||||||
|
for (String key : folders.keySet()) {
|
||||||
|
String subfolder = folder + "/" + key;
|
||||||
|
STGroup subindex = new STGroupFile(subfolder + "/Index.stg");
|
||||||
|
generateCodeForFolder(targetGroup, folder + "/" + key, subindex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> templates = index.rawGetDictionary("TestTemplates");
|
||||||
|
if (templates != null && !templates.isEmpty()) {
|
||||||
|
generateTestFile(targetGroup, folder.substring(folder.lastIndexOf('/') + 1), folder, new ArrayList<String>(templates.keySet()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateTestFile(STGroup targetGroup, String testFile, String templateFolder, Collection<String> testTemplates) {
|
||||||
|
List<ST> templates = new ArrayList<ST>();
|
||||||
|
for (String template : testTemplates) {
|
||||||
|
STGroup testGroup = new STGroupFile(templateFolder + "/" + template + STGroup.GROUP_FILE_EXTENSION);
|
||||||
|
testGroup.importTemplates(targetGroup);
|
||||||
|
ST testType = testGroup.getInstanceOf("TestType");
|
||||||
|
if (testType == null) {
|
||||||
|
getLog().warn(String.format("Unable to generate tests for %s: no TestType specified.", template));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ST testMethodTemplate = targetGroup.getInstanceOf(testType.render() + "TestMethod");
|
||||||
|
if (testMethodTemplate == null) {
|
||||||
|
getLog().warn(String.format("Unable to generate tests for %s: TestType '%s' is not supported by the current runtime.", template, testType.render()));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
testMethodTemplate.add(testMethodTemplate.impl.formalArguments.keySet().iterator().next(), testGroup);
|
||||||
|
templates.add(testMethodTemplate);
|
||||||
|
}
|
||||||
|
|
||||||
|
ST testFileTemplate = targetGroup.getInstanceOf("TestFile");
|
||||||
|
testFileTemplate.addAggr("file.{importErrorQueue,importGrammar,name,tests}", false, false, testFile, templates);
|
||||||
|
STViz viz = testFileTemplate.inspect();
|
||||||
|
try {
|
||||||
|
viz.waitForClose();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
|
||||||
|
File targetFolder = new File(outputDirectory, templateFolder.substring(0, templateFolder.indexOf("/templates")));
|
||||||
|
File targetFile = new File(targetFolder, "Test" + testFile + ".java");
|
||||||
|
try {
|
||||||
|
writeFile(targetFile, testFileTemplate.render());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
getLog().error(String.format("Failed to write output file: %s", targetFile), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeFile(File file, String content) throws IOException {
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
|
||||||
|
FileOutputStream fos = new FileOutputStream(file);
|
||||||
|
OutputStreamWriter osw = new OutputStreamWriter(fos, encoding != null ? encoding : "UTF-8");
|
||||||
|
try {
|
||||||
|
osw.write(content);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
osw.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.antlr.mojo.antlr4.testgen;
|
||||||
|
|
||||||
|
import java.util.AbstractMap;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Sam Harwell
|
||||||
|
*/
|
||||||
|
public class JavaEscapeStringMap extends AbstractMap<String, Object> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object get(Object key) {
|
||||||
|
if (key instanceof String) {
|
||||||
|
String str = (String)key;
|
||||||
|
StringBuilder builder = new StringBuilder(str.length());
|
||||||
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
switch (str.charAt(i)) {
|
||||||
|
case '\\':
|
||||||
|
builder.append("\\\\");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\r':
|
||||||
|
// normalize \r\n to just \n
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\n':
|
||||||
|
builder.append("\\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
builder.append("\\\"");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
builder.append(str.charAt(i));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsKey(Object key) {
|
||||||
|
return key instanceof String;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Entry<String, Object>> entrySet() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* To change this license header, choose License Headers in Project Properties.
|
||||||
|
* To change this template file, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package org.antlr.mojo.antlr4.testgen;
|
||||||
|
|
||||||
|
import org.stringtemplate.v4.Interpreter;
|
||||||
|
import org.stringtemplate.v4.ST;
|
||||||
|
import org.stringtemplate.v4.STGroup;
|
||||||
|
import org.stringtemplate.v4.misc.ObjectModelAdaptor;
|
||||||
|
import org.stringtemplate.v4.misc.STNoSuchPropertyException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author sam
|
||||||
|
*/
|
||||||
|
public class STGroupModelAdaptor extends ObjectModelAdaptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getProperty(Interpreter interp, ST self, Object o, Object property, String propertyName) throws STNoSuchPropertyException {
|
||||||
|
STGroup group = (STGroup)o;
|
||||||
|
if (group.isDictionary(propertyName)) {
|
||||||
|
return group.rawGetDictionary(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
ST template = group.getInstanceOf(propertyName);
|
||||||
|
if (template != null) {
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.getProperty(interp, self, o, property, propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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>>>
|
|
@ -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>
|
||||||
|
+--
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
FAQ
|
|
@ -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.
|
|
@ -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).
|
|
@ -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>
|
292
bild.py
292
bild.py
|
@ -1,292 +0,0 @@
|
||||||
# !/usr/bin/env python
|
|
||||||
import os
|
|
||||||
import string
|
|
||||||
|
|
||||||
"""
|
|
||||||
This script uses my experimental build tool http://www.bildtool.org
|
|
||||||
|
|
||||||
In order to build the complete ANTLR4 product with Java, CSharp, Python 2/3, and JavaScript
|
|
||||||
targets, do the following from a UNIX command line. Windows build using this script
|
|
||||||
is not yet supported. Please use the mvn build or ant build.
|
|
||||||
|
|
||||||
You will also need python 2.7, python 3.4, node.js and mono (on Mac/Linux)
|
|
||||||
|
|
||||||
!!!You must set path values in test_properties dictionary below to ensure non Java targets tests run.!!!
|
|
||||||
|
|
||||||
mkdir -p /usr/local/antlr # somewhere appropriate where you want to install stuff
|
|
||||||
cd /usr/local/antlr
|
|
||||||
git clone git@github.com:antlr/antlr4.git
|
|
||||||
git clone git@github.com:antlr/antlr4-python3.git
|
|
||||||
git clone git@github.com:antlr/antlr4-python2.git
|
|
||||||
git clone git@github.com:antlr/antlr4-csharp.git
|
|
||||||
git clone git@github.com:antlr/antlr4-javascript.git
|
|
||||||
cd antlr4
|
|
||||||
./bild.py tests
|
|
||||||
"""
|
|
||||||
|
|
||||||
# bootstrap by downloading bilder.py if not found
|
|
||||||
import urllib
|
|
||||||
import os
|
|
||||||
|
|
||||||
if not os.path.exists("bilder.py"):
|
|
||||||
print "bootstrapping; downloading bilder.py"
|
|
||||||
urllib.urlretrieve(
|
|
||||||
"https://raw.githubusercontent.com/parrt/bild/master/src/python/bilder.py",
|
|
||||||
"bilder.py")
|
|
||||||
|
|
||||||
# assumes bilder.py is in current directory
|
|
||||||
from bilder import *
|
|
||||||
|
|
||||||
VERSION = "4.4"
|
|
||||||
JAVA_TARGET = "."
|
|
||||||
PYTHON2_TARGET = "../antlr4-python2"
|
|
||||||
PYTHON3_TARGET = "../antlr4-python3"
|
|
||||||
CSHARP_TARGET = "../antlr4-csharp"
|
|
||||||
JAVASCRIPT_TARGET = "../antlr4-javascript"
|
|
||||||
|
|
||||||
# Properties needed to run Python[23] tests
|
|
||||||
test_properties = {
|
|
||||||
"antlr-python2-runtime": uniformpath(PYTHON2_TARGET) + "/src",
|
|
||||||
"antlr-python3-runtime": uniformpath(PYTHON3_TARGET) + "/src",
|
|
||||||
"antlr-javascript-runtime": uniformpath(JAVASCRIPT_TARGET) + "/src",
|
|
||||||
"antlr-csharp-runtime-project": uniformpath(CSHARP_TARGET) + "/runtime/CSharp/Antlr4.Runtime/Antlr4.Runtime.mono.csproj"
|
|
||||||
}
|
|
||||||
|
|
||||||
TARGETS = {
|
|
||||||
"Java": uniformpath(JAVA_TARGET),
|
|
||||||
"CSharp":uniformpath(CSHARP_TARGET),
|
|
||||||
"Python2": uniformpath(PYTHON2_TARGET),
|
|
||||||
"Python3": uniformpath(PYTHON3_TARGET),
|
|
||||||
"JavaScript":uniformpath(JAVASCRIPT_TARGET)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def parsers():
|
|
||||||
antlr3("tool/src/org/antlr/v4/parse", "gen3", package="org.antlr.v4.parse")
|
|
||||||
antlr3("tool/src/org/antlr/v4/codegen", "gen3", package="org.antlr.v4.codegen",
|
|
||||||
args=["-lib", uniformpath("gen3/org/antlr/v4/parse")])
|
|
||||||
antlr4("runtime/Java/src/org/antlr/v4/runtime/tree/xpath", "gen4", package="org.antlr.v4.runtime.tree.xpath")
|
|
||||||
|
|
||||||
def compile():
|
|
||||||
require(parsers)
|
|
||||||
cp = uniformpath("out") + os.pathsep + \
|
|
||||||
os.path.join(JARCACHE, "antlr-3.5.1-complete.jar") + os.pathsep + \
|
|
||||||
"runtime/Java/lib/org.abego.treelayout.core.jar" + os.pathsep
|
|
||||||
if os.path.exists(JARCACHE + "/antlr-" + VERSION + "-complete.jar"):
|
|
||||||
cp += JARCACHE + "/antlr-" + VERSION + "-complete.jar"
|
|
||||||
srcpath = ["gen3", "gen4", "runtime/JavaAnnotations/src", "runtime/Java/src", "tool/src"]
|
|
||||||
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
|
|
||||||
for t in TARGETS:
|
|
||||||
javac(TARGETS[t] + "/tool/src", "out", version="1.6", cp=cp, args=args)
|
|
||||||
|
|
||||||
|
|
||||||
def mkjar_complete():
|
|
||||||
require(compile)
|
|
||||||
copytree(src="tool/resources", trg="out") # messages, Java code gen, etc...
|
|
||||||
manifest = \
|
|
||||||
"Main-Class: org.antlr.v4.Tool\n" +\
|
|
||||||
"Implementation-Title: ANTLR 4 Tool\n" +\
|
|
||||||
"Implementation-Version: %s\n" +\
|
|
||||||
"Implementation-Vendor: ANTLR\n" +\
|
|
||||||
"Implementation-Vendor-Id: org.antlr\n" +\
|
|
||||||
"Built-By: %s\n" +\
|
|
||||||
"Build-Jdk: 1.6\n" +\
|
|
||||||
"Created-By: http://www.bildtool.org\n" +\
|
|
||||||
"\n"
|
|
||||||
manifest = manifest % (VERSION, os.getlogin())
|
|
||||||
# unjar required libraries
|
|
||||||
unjar("runtime/Java/lib/org.abego.treelayout.core.jar", trgdir="out")
|
|
||||||
download("http://www.antlr3.org/download/antlr-3.5.1-runtime.jar", JARCACHE)
|
|
||||||
unjar(os.path.join(JARCACHE, "antlr-3.5.1-runtime.jar"), trgdir="out")
|
|
||||||
download("http://www.stringtemplate.org/download/ST-4.0.8.jar", JARCACHE)
|
|
||||||
unjar(os.path.join(JARCACHE, "ST-4.0.8.jar"), trgdir="out")
|
|
||||||
# pull in target templates
|
|
||||||
for t in TARGETS:
|
|
||||||
trgdir = "out/org/antlr/v4/tool/templates/codegen/" + t
|
|
||||||
mkdir(trgdir)
|
|
||||||
copyfile(TARGETS[t] + "/tool/resources/org/antlr/v4/tool/templates/codegen/" + t + "/" + t + ".stg",
|
|
||||||
trgdir)
|
|
||||||
jarfile = "dist/antlr4-" + VERSION + "-complete.jar"
|
|
||||||
jar(jarfile, srcdir="out", manifest=manifest)
|
|
||||||
print "Generated " + jarfile
|
|
||||||
|
|
||||||
|
|
||||||
def mkjar_runtime():
|
|
||||||
# out/... dir is full of tool-related stuff, make special dir out/runtime
|
|
||||||
# unjar required library
|
|
||||||
unjar("runtime/Java/lib/org.abego.treelayout.core.jar", trgdir="out/runtime")
|
|
||||||
cp = uniformpath("out/runtime") + os.pathsep + \
|
|
||||||
"runtime/Java/lib/org.abego.treelayout.core.jar"
|
|
||||||
srcpath = ["gen4", "runtime/JavaAnnotations/src", "runtime/Java/src"]
|
|
||||||
args = ["-nowarn", "-Xlint", "-Xlint:-serial", "-g", "-sourcepath", string.join(srcpath, os.pathsep)]
|
|
||||||
for sp in srcpath:
|
|
||||||
javac(sp, "out/runtime", version="1.6", cp=cp, args=args)
|
|
||||||
manifest = \
|
|
||||||
"Implementation-Vendor: ANTLR\n" +\
|
|
||||||
"Implementation-Vendor-Id: org.antlr\n" +\
|
|
||||||
"Implementation-Title: ANTLR 4 Runtime\n" +\
|
|
||||||
"Implementation-Version: %s\n" +\
|
|
||||||
"Built-By: %s\n" +\
|
|
||||||
"Build-Jdk: 1.6\n" +\
|
|
||||||
"Created-By: http://www.bildtool.org\n" +\
|
|
||||||
"\n"
|
|
||||||
manifest = manifest % (VERSION, os.getlogin())
|
|
||||||
jarfile = "dist/antlr4-" + VERSION + ".jar"
|
|
||||||
jar(jarfile, srcdir="out/runtime", manifest=manifest)
|
|
||||||
print "Generated " + jarfile
|
|
||||||
|
|
||||||
def mkjar():
|
|
||||||
mkjar_complete()
|
|
||||||
# put it in JARCARCHE too so bild can find it during antlr4()
|
|
||||||
copyfile(src="dist/antlr4-" + VERSION + "-complete.jar", trg=JARCACHE)
|
|
||||||
# rebuild/bootstrap XPath with 4.4 so it can use 4.4 runtime (gen'd with 4.3 at this point)
|
|
||||||
rmdir("gen4/org/antlr/v4/runtime/tree/xpath") # kill 4.3-generated version
|
|
||||||
antlr4("runtime/Java/src/org/antlr/v4/runtime/tree/xpath", "gen4", version=VERSION,
|
|
||||||
package="org.antlr.v4.runtime.tree.xpath")
|
|
||||||
compile()
|
|
||||||
mkjar_complete() # make it again with up to date XPath lexer
|
|
||||||
mkjar_runtime() # now build the runtime jar
|
|
||||||
|
|
||||||
|
|
||||||
def tests():
|
|
||||||
require(mkjar)
|
|
||||||
junit_jar, hamcrest_jar = load_junitjars()
|
|
||||||
cp = uniformpath("dist/antlr4-" + VERSION + "-complete.jar") \
|
|
||||||
+ os.pathsep + uniformpath("out/test/Java") \
|
|
||||||
+ os.pathsep + junit_jar \
|
|
||||||
+ os.pathsep + hamcrest_jar
|
|
||||||
juprops = ["-D%s=%s" % (p, test_properties[p]) for p in test_properties]
|
|
||||||
args = ["-nowarn", "-Xlint", "-Xlint:-serial", "-g"]
|
|
||||||
# don't compile generator
|
|
||||||
skip = [ uniformpath(TARGETS['Java'] + "/tool/test/org/antlr/v4/test/rt/gen/") ]
|
|
||||||
javac("tool/test", "out/test/Java", version="1.6", cp=cp, args=args, skip=skip) # all targets can use org.antlr.v4.test.*
|
|
||||||
for t in TARGETS:
|
|
||||||
print "Testing %s ..." % t
|
|
||||||
try:
|
|
||||||
test(t, cp, juprops, args)
|
|
||||||
print t + " tests complete"
|
|
||||||
except:
|
|
||||||
print t + " tests failed"
|
|
||||||
|
|
||||||
def test(t, cp, juprops, args):
|
|
||||||
srcdir = uniformpath(TARGETS[t] + "/tool/test")
|
|
||||||
dstdir = uniformpath( "out/test/" + t)
|
|
||||||
# Prefix CLASSPATH with individual target tests
|
|
||||||
thiscp = dstdir + os.pathsep + cp
|
|
||||||
skip = []
|
|
||||||
if t=='Java':
|
|
||||||
# don't test generator
|
|
||||||
skip = [ "/org/antlr/v4/test/rt/gen/", "TestPerformance" ]
|
|
||||||
elif t=='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=thiscp, args=args, skip=skip)
|
|
||||||
skip = []
|
|
||||||
elif t=='JavaScript':
|
|
||||||
# don't test browsers automatically, this is overkilling and unreliable
|
|
||||||
browsers = ["safari","chrome","firefox","explorer"]
|
|
||||||
skip = [ uniformpath(srcdir + "/org/antlr/v4/test/rt/js/" + b) for b in browsers ]
|
|
||||||
javac(srcdir, "out/test/" + t, version="1.6", cp=thiscp, 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)
|
|
||||||
|
|
||||||
def all():
|
|
||||||
clean(True)
|
|
||||||
mkjar()
|
|
||||||
tests()
|
|
||||||
mkdoc()
|
|
||||||
mksrc()
|
|
||||||
install()
|
|
||||||
clean()
|
|
||||||
|
|
||||||
def install():
|
|
||||||
mvn_install("dist/antlr4-" + VERSION + "-complete.jar",
|
|
||||||
"dist/antlr4-" + VERSION + "-complete-sources.jar",
|
|
||||||
"dist/antlr4-" + VERSION + "-complete-javadoc.jar",
|
|
||||||
"org.antlr",
|
|
||||||
"antlr4",
|
|
||||||
VERSION)
|
|
||||||
mvn_install("dist/antlr4-" + VERSION + ".jar",
|
|
||||||
"dist/antlr4-" + VERSION + "-sources.jar",
|
|
||||||
"dist/antlr4-" + VERSION + "-javadoc.jar",
|
|
||||||
"org.antlr",
|
|
||||||
"antlr4-runtime",
|
|
||||||
VERSION)
|
|
||||||
|
|
||||||
def clean(dist=False):
|
|
||||||
if dist:
|
|
||||||
rmdir("dist")
|
|
||||||
rmdir("out")
|
|
||||||
rmdir("gen3")
|
|
||||||
rmdir("gen4")
|
|
||||||
rmdir("doc")
|
|
||||||
|
|
||||||
|
|
||||||
def mksrc():
|
|
||||||
srcpath = "runtime/Java/src/org"
|
|
||||||
jarfile = "dist/antlr4-" + VERSION + "-sources.jar"
|
|
||||||
zip(jarfile, srcpath)
|
|
||||||
print "Generated " + jarfile
|
|
||||||
jarfile = "dist/antlr4-" + VERSION + "-complete-sources.jar"
|
|
||||||
srcpaths = [ srcpath, "gen3/org", "gen4/org", "runtime/JavaAnnotations/src/org", "tool/src/org"]
|
|
||||||
zip(jarfile, srcpaths)
|
|
||||||
print "Generated " + jarfile
|
|
||||||
|
|
||||||
|
|
||||||
def mkdoc():
|
|
||||||
# add a few source dirs to reduce the number of javadoc errors
|
|
||||||
# JavaDoc needs antlr annotations source code
|
|
||||||
mkdir("out/Annotations")
|
|
||||||
download("http://search.maven.org/remotecontent?filepath=org/antlr/antlr4-annotations/4.3/antlr4-annotations-4.3-sources.jar", "out/Annotations")
|
|
||||||
unjar("out/Annotations/antlr4-annotations-4.3-sources.jar", trgdir="out/Annotations")
|
|
||||||
# JavaDoc needs abego treelayout source code
|
|
||||||
mkdir("out/TreeLayout")
|
|
||||||
download("http://search.maven.org/remotecontent?filepath=org/abego/treelayout/org.abego.treelayout.core/1.0.1/org.abego.treelayout.core-1.0.1-sources.jar", "out/TreeLayout")
|
|
||||||
unjar("out/TreeLayout/org.abego.treelayout.core-1.0.1-sources.jar", trgdir="out/TreeLayout")
|
|
||||||
# JavaDoc needs antlr runtime 3.5.2 source code
|
|
||||||
mkdir("out/Antlr352Runtime")
|
|
||||||
download("http://search.maven.org/remotecontent?filepath=org/antlr/antlr-runtime/3.5.2/antlr-runtime-3.5.2-sources.jar", "out/Antlr352Runtime")
|
|
||||||
unjar("out/Antlr352Runtime/antlr-runtime-3.5.2-sources.jar", trgdir="out/Antlr352Runtime")
|
|
||||||
# JavaDoc needs antlr ST4 source code
|
|
||||||
mkdir("out/ST4")
|
|
||||||
download("http://search.maven.org/remotecontent?filepath=org/antlr/ST4/4.0.8/ST4-4.0.8-sources.jar", "out/ST4")
|
|
||||||
unjar("out/ST4/ST4-4.0.8-sources.jar", trgdir="out/ST4")
|
|
||||||
# go!
|
|
||||||
mkdir("doc/Java")
|
|
||||||
mkdir("doc/JavaTool")
|
|
||||||
dirs = ["runtime/Java/src"]
|
|
||||||
dirs += ["out/Annotations"]
|
|
||||||
dirs += ["out/TreeLayout"]
|
|
||||||
exclude = ["org/antlr/runtime",
|
|
||||||
"org/abego",
|
|
||||||
"org/stringtemplate",
|
|
||||||
"org/antlr/stringtemplate"]
|
|
||||||
javadoc(srcdir=dirs, trgdir="doc/Java", packages="org.antlr.v4.runtime", exclude=exclude)
|
|
||||||
dirs += ["gen3"]
|
|
||||||
dirs += [TARGETS[t] + "/tool/src" for t in TARGETS]
|
|
||||||
dirs += ["out/Antlr352Runtime"]
|
|
||||||
dirs += ["out/ST4"]
|
|
||||||
javadoc(srcdir=dirs, trgdir="doc/JavaTool", packages="org.antlr.v4", exclude=exclude)
|
|
||||||
# build stack merge PredictionContext and ATNState images from DOT
|
|
||||||
# DOT Images are in runtime/Java/src/main/dot/org/antlr/v4/runtime/atn/images/
|
|
||||||
# Gen into E.g., doc/Java/org/antlr/v4/runtime/atn/images/SingletonMerge_DiffRootSamePar.svg
|
|
||||||
mkdir("doc/Java/org/antlr/v4/runtime/atn/images")
|
|
||||||
for f in glob.glob("runtime/Java/src/main/dot/org/antlr/v4/runtime/atn/images/*.dot"):
|
|
||||||
dot(f, "doc/Java/org/antlr/v4/runtime/atn/images", format="svg")
|
|
||||||
zip("dist/antlr4-" + VERSION + "-javadoc.jar", "doc/Java")
|
|
||||||
zip("dist/antlr4-" + VERSION + "-complete-javadoc.jar", "doc/JavaTool")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
processargs(globals()) # E.g., "python bild.py all"
|
|
285
build.xml
285
build.xml
|
@ -1,285 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project name="ANTLR4" default="distribute" basedir=".">
|
|
||||||
<target name="basic-init">
|
|
||||||
<property file="user.build.properties"/>
|
|
||||||
<property name="dist.dir" value="${basedir}/dist" />
|
|
||||||
<property name="build.dir" value="${basedir}/build" />
|
|
||||||
<property name="lib.dir" value="${basedir}/lib" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="antlr3-init" depends="basic-init">
|
|
||||||
<property name="antlr3.version" value="3.5.2"/>
|
|
||||||
<property name="antlr3.jar.name" value="antlr-${antlr3.version}-complete-no-st3.jar"/>
|
|
||||||
<property name="antlr3.jar" value="${lib.dir}/${antlr3.jar.name}"/>
|
|
||||||
<mkdir dir="${lib.dir}"/>
|
|
||||||
<get src="http://www.antlr3.org/download/${antlr3.jar.name}" dest="${antlr3.jar}" skipexisting="true"/>
|
|
||||||
<path id="cp.antlr3" path="${antlr3.jar}"/>
|
|
||||||
|
|
||||||
<property name="build.antlr3.dir" value="${build.dir}/generated-sources/antlr3" />
|
|
||||||
<property name="antlr3.touch" value="${build.dir}/antlr3-${antlr3.version}.touch"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="antlr4-init" depends="basic-init">
|
|
||||||
<property name="antlr4.version" value="4.3"/>
|
|
||||||
<property name="antlr4.jar.name" value="antlr-${antlr4.version}-complete.jar"/>
|
|
||||||
<property name="antlr4.jar" value="${lib.dir}/${antlr4.jar.name}"/>
|
|
||||||
<mkdir dir="${lib.dir}"/>
|
|
||||||
<get src="http://www.antlr.org/download/${antlr4.jar.name}" dest="${antlr4.jar}" skipexisting="true"/>
|
|
||||||
<path id="cp.antlr4" path="${antlr4.jar}"/>
|
|
||||||
|
|
||||||
<property name="build.antlr4.dir" value="${build.dir}/generated-sources/antlr4" />
|
|
||||||
<property name="antlr4.touch" value="${build.dir}/antlr4-${antlr4.version}.touch"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="build-init" depends="basic-init">
|
|
||||||
<property name="version" value="4.4"/>
|
|
||||||
<property name="build.sysclasspath" value="ignore"/>
|
|
||||||
<property name="install.root.dir" value="${dist.dir}/antlr-${version}" />
|
|
||||||
<property name="jar.file" value="${dist.dir}/antlr-${version}-complete.jar" />
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="clean" depends="basic-init">
|
|
||||||
<delete dir="${build.dir}" includeemptydirs="true"/>
|
|
||||||
<delete dir="${dist.dir}" includeemptydirs="true"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="clean-all" depends="clean">
|
|
||||||
<delete dir="${lib.dir}" includeemptydirs="true"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="antlr3-up-to-date" depends="basic-init,antlr3-init">
|
|
||||||
<uptodate targetfile="${antlr3.touch}" property="is.antlr3.uptodate">
|
|
||||||
<srcfiles dir="${basedir}/tool/src">
|
|
||||||
<include name="**/*.g"/>
|
|
||||||
<include name="**/*.tokens"/>
|
|
||||||
</srcfiles>
|
|
||||||
<srcfiles file="${antlr3.jar}"/>
|
|
||||||
</uptodate>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="antlr4-up-to-date" depends="basic-init,antlr4-init">
|
|
||||||
<uptodate targetfile="${antlr4.touch}" property="is.antlr4.uptodate">
|
|
||||||
<srcfiles dir="${basedir}/tool/src">
|
|
||||||
<include name="**/*.g4"/>
|
|
||||||
<include name="**/*.tokens"/>
|
|
||||||
</srcfiles>
|
|
||||||
<srcfiles file="${antlr4.jar}"/>
|
|
||||||
</uptodate>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="up-to-date" depends="antlr3-up-to-date,antlr4-up-to-date,build-init">
|
|
||||||
<uptodate targetfile="${jar.file}" property="is.source.uptodate">
|
|
||||||
<srcfiles dir="${basedir}/tool/src">
|
|
||||||
<include name="**/*.java"/>
|
|
||||||
<include name="**/*.g"/>
|
|
||||||
<include name="**/*.tokens"/>
|
|
||||||
</srcfiles>
|
|
||||||
<srcfiles dir="${basedir}/tool/resources">
|
|
||||||
<include name="**/*.st"/>
|
|
||||||
<include name="**/*.stg"/>
|
|
||||||
</srcfiles>
|
|
||||||
<srcfiles dir="${basedir}/runtime/Java/src/">
|
|
||||||
<include name="**/*.java"/>
|
|
||||||
<include name="**/*.g"/>
|
|
||||||
<include name="**/*.st"/>
|
|
||||||
<include name="**/*.stg"/>
|
|
||||||
</srcfiles>
|
|
||||||
<srcfiles dir="${build.antlr3.dir}"/>
|
|
||||||
<srcfiles file="${basedir}/runtime/Java/lib/org.abego.treelayout.core.jar"/>
|
|
||||||
<srcfiles file="${antlr3.jar}"/>
|
|
||||||
</uptodate>
|
|
||||||
|
|
||||||
<condition property="is.jar.uptodate">
|
|
||||||
<and>
|
|
||||||
<istrue value="${is.source.uptodate}"/>
|
|
||||||
<istrue value="${is.antlr3.uptodate}"/>
|
|
||||||
</and>
|
|
||||||
</condition>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<macrodef name="antlr3">
|
|
||||||
<attribute name="srcpath"/>
|
|
||||||
<element name="args" optional="true"/>
|
|
||||||
<sequential>
|
|
||||||
<local name="path.antlr3.local"/>
|
|
||||||
<local name="sources.antlr3.local"/>
|
|
||||||
<path id="path.antlr3.local">
|
|
||||||
<fileset dir="${basedir}/tool/src/@{srcpath}" includes="*.g"/>
|
|
||||||
</path>
|
|
||||||
<pathconvert pathsep=" " property="sources.antlr3.local" refid="path.antlr3.local">
|
|
||||||
<map from="${basedir}/tool/src/@{srcpath}/" to=""/>
|
|
||||||
</pathconvert>
|
|
||||||
<mkdir dir="${build.antlr3.dir}/@{srcpath}"/>
|
|
||||||
<java classname="org.antlr.Tool" fork="true" failonerror="true" maxmemory="300m"
|
|
||||||
dir="${basedir}/tool/src/@{srcpath}">
|
|
||||||
<arg value="-o"/>
|
|
||||||
<arg value="${build.antlr3.dir}/@{srcpath}"/>
|
|
||||||
<args/>
|
|
||||||
<arg line="${sources.antlr3.local}"/>
|
|
||||||
<classpath>
|
|
||||||
<path refid="cp.antlr3"/>
|
|
||||||
<pathelement location="${java.class.path}"/>
|
|
||||||
</classpath>
|
|
||||||
</java>
|
|
||||||
</sequential>
|
|
||||||
</macrodef>
|
|
||||||
|
|
||||||
<macrodef name="antlr4">
|
|
||||||
<attribute name="srcpath"/>
|
|
||||||
<element name="args" optional="true"/>
|
|
||||||
<sequential>
|
|
||||||
<local name="path.antlr4.local"/>
|
|
||||||
<local name="sources.antlr4.local"/>
|
|
||||||
<path id="path.antlr4.local">
|
|
||||||
<fileset dir="${basedir}/runtime/Java/src/@{srcpath}" includes="*.g4"/>
|
|
||||||
</path>
|
|
||||||
<pathconvert pathsep=" " property="sources.antlr4.local" refid="path.antlr4.local">
|
|
||||||
<map from="${basedir}/runtime/Java/src/@{srcpath}/" to=""/>
|
|
||||||
</pathconvert>
|
|
||||||
<mkdir dir="${build.antlr4.dir}/@{srcpath}"/>
|
|
||||||
<java classname="org.antlr.v4.Tool" fork="true" failonerror="true" maxmemory="300m"
|
|
||||||
dir="${basedir}/runtime/Java/src/@{srcpath}">
|
|
||||||
<arg value="-o"/>
|
|
||||||
<arg value="${build.antlr4.dir}/@{srcpath}"/>
|
|
||||||
<args/>
|
|
||||||
<arg line="${sources.antlr4.local}"/>
|
|
||||||
<classpath>
|
|
||||||
<path refid="cp.antlr4"/>
|
|
||||||
<pathelement location="${java.class.path}"/>
|
|
||||||
</classpath>
|
|
||||||
</java>
|
|
||||||
</sequential>
|
|
||||||
</macrodef>
|
|
||||||
|
|
||||||
<target name="antlr3" depends="build-init,antlr3-init,antlr3-up-to-date" unless="is.antlr3.uptodate">
|
|
||||||
<mkdir dir="${build.antlr3.dir}" />
|
|
||||||
|
|
||||||
<path id="sources.antlr3">
|
|
||||||
<fileset dir="${basedir}/tool/src" includes="**/*.g"/>
|
|
||||||
</path>
|
|
||||||
<pathconvert pathsep="${line.separator} " property="echo.sources.antlr3" refid="sources.antlr3">
|
|
||||||
<map from="${basedir}/tool/src/" to=""/>
|
|
||||||
</pathconvert>
|
|
||||||
<echo message="Generating ANTLR 3 grammars:${line.separator} ${echo.sources.antlr3}"/>
|
|
||||||
|
|
||||||
<antlr3 srcpath="org/antlr/v4/parse"/>
|
|
||||||
|
|
||||||
<antlr3 srcpath="org/antlr/v4/codegen">
|
|
||||||
<args>
|
|
||||||
<arg value="-lib"/>
|
|
||||||
<arg value="${build.antlr3.dir}/org/antlr/v4/parse"/>
|
|
||||||
</args>
|
|
||||||
</antlr3>
|
|
||||||
|
|
||||||
<touch file="${antlr3.touch}" mkdirs="true"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="antlr4" depends="build-init,antlr4-init,antlr4-up-to-date" unless="is.antlr4.uptodate">
|
|
||||||
<mkdir dir="${build.antlr4.dir}" />
|
|
||||||
|
|
||||||
<path id="sources.antlr4">
|
|
||||||
<fileset dir="${basedir}/runtime/Java/src" includes="**/*.g4"/>
|
|
||||||
</path>
|
|
||||||
<pathconvert pathsep="${line.separator} " property="echo.sources.antlr4" refid="sources.antlr4">
|
|
||||||
<map from="${basedir}/runtime/Java/src/" to=""/>
|
|
||||||
</pathconvert>
|
|
||||||
<echo message="Generating ANTLR 4 grammars:${line.separator} ${echo.sources.antlr4}"/>
|
|
||||||
|
|
||||||
<antlr4 srcpath="org/antlr/v4/runtime/tree/xpath">
|
|
||||||
<args>
|
|
||||||
<arg value="-package"/>
|
|
||||||
<arg value="org.antlr.v4.runtime.tree.xpath"/>
|
|
||||||
</args>
|
|
||||||
</antlr4>
|
|
||||||
|
|
||||||
<touch file="${antlr4.touch}" mkdirs="true"/>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="compile" depends="build-init,antlr3,antlr4,up-to-date" description="Compile for generic OS" unless="is.jar.uptodate">
|
|
||||||
<mkdir dir="${build.dir}/classes"/>
|
|
||||||
<javac
|
|
||||||
destdir="${build.dir}/classes"
|
|
||||||
source="1.6"
|
|
||||||
target="1.6"
|
|
||||||
debug="true"
|
|
||||||
excludes="org/antlr/v4/test/**">
|
|
||||||
<compilerarg value="-Xlint"/>
|
|
||||||
<compilerarg value="-Xlint:-serial"/>
|
|
||||||
<classpath>
|
|
||||||
<path refid="cp.antlr3"/>
|
|
||||||
<pathelement location="${basedir}/runtime/Java/lib/org.abego.treelayout.core.jar"/>
|
|
||||||
</classpath>
|
|
||||||
<src path="${basedir}/tool/src:${basedir}/runtime/JavaAnnotations/src:${basedir}/runtime/Java/src:${build.antlr3.dir}:${build.antlr4.dir}"/>
|
|
||||||
</javac>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="build-jar" depends="up-to-date,compile" description="Build ANTLR 4.jar" unless="is.jar.uptodate">
|
|
||||||
<mkdir dir="${dist.dir}"/>
|
|
||||||
|
|
||||||
<jar jarfile="${jar.file}">
|
|
||||||
<fileset dir="${build.dir}/classes" includes="**/*.class"/>
|
|
||||||
<fileset dir="${basedir}/tool/resources">
|
|
||||||
<include name="**/*.st"/>
|
|
||||||
<include name="**/*.stg"/>
|
|
||||||
</fileset>
|
|
||||||
<zipfileset includes="org/antlr/**, org/antlr/stringtemplate/**, org/stringtemplate/v4/**" src="${antlr3.jar}"/>
|
|
||||||
<zipfileset includes="**/*.class" src="${basedir}/runtime/Java/lib/org.abego.treelayout.core.jar"/>
|
|
||||||
<manifest>
|
|
||||||
<attribute name="Version" value="${version}"/>
|
|
||||||
<attribute name="Main-Class" value="org.antlr.v4.Tool"/>
|
|
||||||
</manifest>
|
|
||||||
</jar>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="zip-source" depends="compile">
|
|
||||||
<mkdir dir="${install.root.dir}"/>
|
|
||||||
|
|
||||||
<mkdir dir="${install.root.dir}/src"/>
|
|
||||||
<copy todir="${install.root.dir}/src">
|
|
||||||
<fileset dir="${basedir}/tool/src/">
|
|
||||||
<include name="**/*.java"/>
|
|
||||||
<include name="**/*.g"/>
|
|
||||||
<include name="**/*.st"/>
|
|
||||||
<include name="**/*.stg"/>
|
|
||||||
</fileset>
|
|
||||||
<fileset dir="${basedir}/tool/resources/">
|
|
||||||
<include name="**/*.st"/>
|
|
||||||
<include name="**/*.stg"/>
|
|
||||||
</fileset>
|
|
||||||
<fileset dir="${basedir}/runtime/JavaAnnotations/resources/">
|
|
||||||
<include name="**/*.Processor"/>
|
|
||||||
</fileset>
|
|
||||||
<fileset dir="${basedir}/runtime/JavaAnnotations/src/">
|
|
||||||
<include name="**/*.java"/>
|
|
||||||
</fileset>
|
|
||||||
<fileset dir="${basedir}/runtime/Java/src/">
|
|
||||||
<include name="**/*.java"/>
|
|
||||||
<include name="**/*.g"/>
|
|
||||||
<include name="**/*.st"/>
|
|
||||||
<include name="**/*.stg"/>
|
|
||||||
</fileset>
|
|
||||||
<fileset dir="${build.antlr3.dir}"/>
|
|
||||||
</copy>
|
|
||||||
|
|
||||||
<copy todir="${install.root.dir}">
|
|
||||||
<fileset dir=".">
|
|
||||||
<include name="build.properties"/>
|
|
||||||
<include name="build.xml"/>
|
|
||||||
<include name="LICENSE.txt"/>
|
|
||||||
<include name="README.md"/>
|
|
||||||
<include name="doxyfile"/>
|
|
||||||
</fileset>
|
|
||||||
</copy>
|
|
||||||
|
|
||||||
<copy todir="${install.root.dir}/lib" file="${antlr3.jar}">
|
|
||||||
</copy>
|
|
||||||
|
|
||||||
<zip destfile="${dist.dir}/antlr-${version}-src.zip">
|
|
||||||
<zipfileset dir="${install.root.dir}" prefix="antlr-${version}"/>
|
|
||||||
</zip>
|
|
||||||
</target>
|
|
||||||
|
|
||||||
<target name="distribute" depends="clean, zip-source, build-jar">
|
|
||||||
</target>
|
|
||||||
|
|
||||||
</project>
|
|
1
pom.xml
1
pom.xml
|
@ -63,6 +63,7 @@
|
||||||
<module>runtime/JavaAnnotations</module>
|
<module>runtime/JavaAnnotations</module>
|
||||||
<module>tool</module>
|
<module>tool</module>
|
||||||
<module>antlr4-maven-plugin</module>
|
<module>antlr4-maven-plugin</module>
|
||||||
|
<module>antlr4-testgen-maven-plugin</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
|
|
@ -1,35 +1,20 @@
|
||||||
digraph "" {
|
digraph "" {
|
||||||
graph[fontname="CourierNew";rankdir="LR";pad="0.25"];
|
graph[fontname="Consolas";rankdir="LR";pad="0.25"];
|
||||||
node[fontname="CourierNew";target="_parent"];
|
node[fontname="Consolas";target="_parent"];
|
||||||
edge[fontname="CourierNew"];
|
edge[fontname="Consolas"];
|
||||||
subgraph clusterA {
|
|
||||||
color="invis";
|
|
||||||
{ node[shape="record"];
|
|
||||||
BasicBlockStartState[URL="../BasicBlockStartState.html";label="{BasicBlockStartState | {<alt1> alt 1 |<alt2> alt 2 | ·\n·\n· |<altn> alt n}}"];
|
|
||||||
BlockEndState[URL="../BlockEndState.html"];
|
|
||||||
}
|
|
||||||
|
|
||||||
{ node[style="dashed"];
|
net35client[label="net35-client"]
|
||||||
content1[label="alt 1"];
|
net40client[label="net40-client"]
|
||||||
content2[label="alt 2"];
|
portablenet40[label="portable-net40"]
|
||||||
more[label="alt n"];
|
portablenet45[label="portable-net45"]
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{ node[style="dashed"];
|
net20 -> net30
|
||||||
begin;
|
net30 -> net35client
|
||||||
end;
|
net35client -> net40client[style="dashed"]
|
||||||
}
|
net40client -> net45
|
||||||
|
|
||||||
begin -> BasicBlockStartState[style="dashed"];
|
portablenet40 -> net40client
|
||||||
BlockEndState -> end[label="ε"];
|
portablenet40 -> portablenet45
|
||||||
|
portablenet45 -> win
|
||||||
BasicBlockStartState:alt1 -> content1[label="ε"];
|
win -> net45
|
||||||
content1 -> BlockEndState[style="dashed"];
|
|
||||||
|
|
||||||
BasicBlockStartState:alt2 -> content2[label="ε"];
|
|
||||||
content2 -> BlockEndState[style="dashed"];
|
|
||||||
|
|
||||||
BasicBlockStartState:altn -> more[label="ε"];
|
|
||||||
more -> BlockEndState[style="dashed"];
|
|
||||||
}
|
}
|
||||||
|
|
16
tool/pom.xml
16
tool/pom.xml
|
@ -154,6 +154,22 @@
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.antlr</groupId>
|
||||||
|
<artifactId>antlr4-testgen-maven-plugin</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>antlr4.testgen</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<runtimeTemplates>test/org/antlr/v4/test/runtime/java/Java.test.stg</runtimeTemplates>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
|
|
@ -162,105 +162,9 @@ public class Generator {
|
||||||
list.add(buildParseTrees());
|
list.add(buildParseTrees());
|
||||||
list.add(buildSemPredEvalLexer());
|
list.add(buildSemPredEvalLexer());
|
||||||
list.add(buildSemPredEvalParser());
|
list.add(buildSemPredEvalParser());
|
||||||
list.add(buildSets());
|
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JUnitTestFile buildSets() throws Exception {
|
|
||||||
JUnitTestFile file = new JUnitTestFile("Sets");
|
|
||||||
// this must return A not I to the parser; calling a nonfragment rule
|
|
||||||
// from a nonfragment rule does not set the overall token.
|
|
||||||
file.addParserTest(input, "SeqDoesNotBecomeSet", "T", "a",
|
|
||||||
"34",
|
|
||||||
"34\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "ParserSet", "T", "a",
|
|
||||||
"x",
|
|
||||||
"x\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "ParserNotSet", "T", "a",
|
|
||||||
"zz",
|
|
||||||
"z\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "ParserNotToken", "T", "a",
|
|
||||||
"zz",
|
|
||||||
"zz\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "ParserNotTokenWithLabel", "T", "a",
|
|
||||||
"zz",
|
|
||||||
"z\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "RuleAsSet", "T", "a",
|
|
||||||
"b",
|
|
||||||
"b\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "NotChar", "T", "a",
|
|
||||||
"x",
|
|
||||||
"x\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "OptionalSingleElement", "T", "a",
|
|
||||||
"bc",
|
|
||||||
"bc\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "OptionalLexerSingleElement", "T", "a",
|
|
||||||
"bc",
|
|
||||||
"bc\n",
|
|
||||||
null);
|
|
||||||
file.addParserTests(input, "StarLexerSingleElement", "T", "a",
|
|
||||||
"bbbbc", "bbbbc\n",
|
|
||||||
"c", "c\n");
|
|
||||||
file.addParserTest(input, "PlusLexerSingleElement", "T", "a",
|
|
||||||
"bbbbc",
|
|
||||||
"bbbbc\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "OptionalSet", "T", "a",
|
|
||||||
"ac",
|
|
||||||
"ac\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "StarSet", "T", "a",
|
|
||||||
"abaac",
|
|
||||||
"abaac\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "PlusSet", "T", "a",
|
|
||||||
"abaac",
|
|
||||||
"abaac\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "LexerOptionalSet", "T", "a",
|
|
||||||
"ac",
|
|
||||||
"ac\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "LexerStarSet", "T", "a",
|
|
||||||
"abaac",
|
|
||||||
"abaac\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "LexerPlusSet", "T", "a",
|
|
||||||
"abaac",
|
|
||||||
"abaac\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "NotCharSet", "T", "a",
|
|
||||||
"x",
|
|
||||||
"x\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "NotCharSetWithLabel", "T", "a",
|
|
||||||
"x",
|
|
||||||
"x\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "NotCharSetWithRuleRef3", "T", "a",
|
|
||||||
"x",
|
|
||||||
"x\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "CharSetLiteral", "T", "a",
|
|
||||||
"A a B b",
|
|
||||||
"A\n" + "a\n" + "B\n" + "b\n",
|
|
||||||
null);
|
|
||||||
file.addParserTest(input, "ComplementSet", "T", "parse",
|
|
||||||
"a",
|
|
||||||
"",
|
|
||||||
"line 1:0 token recognition error at: 'a'\n" +
|
|
||||||
"line 1:1 missing {} at '<EOF>'\n");
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
private JUnitTestFile buildSemPredEvalParser() throws Exception {
|
private JUnitTestFile buildSemPredEvalParser() throws Exception {
|
||||||
JUnitTestFile file = new JUnitTestFile("SemPredEvalParser");
|
JUnitTestFile file = new JUnitTestFile("SemPredEvalParser");
|
||||||
JUnitTestMethod tm = file.addParserTest(input, "SimpleValidate", "T", "s",
|
JUnitTestMethod tm = file.addParserTest(input, "SimpleValidate", "T", "s",
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : (A {<writeln("$A.text")>})+ ;
|
|
||||||
A : [AaBb] ;
|
|
||||||
WS : (' '|'\n')+ -> skip ;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
parse : ~NEW_LINE;
|
|
||||||
NEW_LINE: '\\r'? '\\n';
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<InputText():writeln()>} ;
|
|
||||||
A : ('a'|'b')? 'c' ;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<InputText():writeln()>} ;
|
|
||||||
A : ('a'|'b')+ 'c' ;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<InputText():writeln()>} ;
|
|
||||||
A : ('a'|'b')* 'c' ;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<writeln("$A.text")>} ;
|
|
||||||
A : ~'b' ;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<writeln("$A.text")>} ;
|
|
||||||
A : ~('b'|'c') ;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<writeln("$A.text")>} ;
|
|
||||||
A : h=~('b'|'c') ;
|
|
|
@ -1,5 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<writeln("$A.text")>} ;
|
|
||||||
A : ('a'|B) ; // this doesn't collapse to set but works
|
|
||||||
fragment
|
|
||||||
B : ~('a'|'c') ;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<InputText():writeln()>} ;
|
|
||||||
A : 'b'? 'c' ;
|
|
|
@ -1,2 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : ('a'|'b')? 'c' {<InputText():writeln()>} ;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A? 'c' {<InputText():writeln()>} ;
|
|
||||||
A : 'b' ;
|
|
|
@ -1,2 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : t=~('x'|'y') 'z' {<writeln("$t.text")>} ;
|
|
|
@ -1,2 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : ~'x' 'z' {<InputText():writeln()>} ;
|
|
|
@ -1,2 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : t=~'x' 'z' {<writeln("$t.text")>} ;
|
|
|
@ -1,2 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : t=('x'|'y') {<writeln("$t.text")>} ;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<InputText():writeln()>} ;
|
|
||||||
A : 'b'+ 'c' ;
|
|
|
@ -1,2 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : ('a'|'b')+ 'c' {<InputText():writeln()>} ;
|
|
|
@ -1,2 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a @after {<InputText():writeln()>} : 'a' | 'b' |'c' ;
|
|
|
@ -1,5 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : C {<InputText():writeln()>} ;
|
|
||||||
fragment A : '1' | '2';
|
|
||||||
fragment B : '3' '4';
|
|
||||||
C : A | B;
|
|
|
@ -1,3 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : A {<InputText():writeln()>} ;
|
|
||||||
A : 'b'* 'c' ;
|
|
|
@ -1,2 +0,0 @@
|
||||||
grammar <grammarName>;
|
|
||||||
a : ('a'|'b')* 'c' {<InputText():writeln()>} ;
|
|
|
@ -1,261 +0,0 @@
|
||||||
package org.antlr.v4.test.rt.java;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
public class TestSets extends BaseTest {
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testSeqDoesNotBecomeSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : C {System.out.println(this._input.getText());} ;\n" +
|
|
||||||
"fragment A : '1' | '2';\n" +
|
|
||||||
"fragment B : '3' '4';\n" +
|
|
||||||
"C : A | B;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "34", false);
|
|
||||||
assertEquals("34\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testParserSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : t=('x'|'y') {System.out.println($t.text);} ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "x", false);
|
|
||||||
assertEquals("x\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testParserNotSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : t=~('x'|'y') 'z' {System.out.println($t.text);} ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "zz", false);
|
|
||||||
assertEquals("z\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testParserNotToken() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : ~'x' 'z' {System.out.println(this._input.getText());} ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "zz", false);
|
|
||||||
assertEquals("zz\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testParserNotTokenWithLabel() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : t=~'x' 'z' {System.out.println($t.text);} ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "zz", false);
|
|
||||||
assertEquals("z\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testRuleAsSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a @after {System.out.println(this._input.getText());} : 'a' | 'b' |'c' ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "b", false);
|
|
||||||
assertEquals("b\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testNotChar() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println($A.text);} ;\n" +
|
|
||||||
"A : ~'b' ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "x", false);
|
|
||||||
assertEquals("x\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testOptionalSingleElement() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A? 'c' {System.out.println(this._input.getText());} ;\n" +
|
|
||||||
"A : 'b' ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "bc", false);
|
|
||||||
assertEquals("bc\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testOptionalLexerSingleElement() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println(this._input.getText());} ;\n" +
|
|
||||||
"A : 'b'? 'c' ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "bc", false);
|
|
||||||
assertEquals("bc\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
String testStarLexerSingleElement(String input) throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println(this._input.getText());} ;\n" +
|
|
||||||
"A : 'b'* 'c' ;";
|
|
||||||
return execParser("T.g4", grammar, "TParser", "TLexer", "a", input, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testStarLexerSingleElement_1() throws Exception {
|
|
||||||
String found = testStarLexerSingleElement("bbbbc");
|
|
||||||
assertEquals("bbbbc\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testStarLexerSingleElement_2() throws Exception {
|
|
||||||
String found = testStarLexerSingleElement("c");
|
|
||||||
assertEquals("c\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testPlusLexerSingleElement() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println(this._input.getText());} ;\n" +
|
|
||||||
"A : 'b'+ 'c' ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "bbbbc", false);
|
|
||||||
assertEquals("bbbbc\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testOptionalSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : ('a'|'b')? 'c' {System.out.println(this._input.getText());} ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "ac", false);
|
|
||||||
assertEquals("ac\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testStarSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : ('a'|'b')* 'c' {System.out.println(this._input.getText());} ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "abaac", false);
|
|
||||||
assertEquals("abaac\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testPlusSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : ('a'|'b')+ 'c' {System.out.println(this._input.getText());} ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "abaac", false);
|
|
||||||
assertEquals("abaac\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testLexerOptionalSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println(this._input.getText());} ;\n" +
|
|
||||||
"A : ('a'|'b')? 'c' ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "ac", false);
|
|
||||||
assertEquals("ac\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testLexerStarSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println(this._input.getText());} ;\n" +
|
|
||||||
"A : ('a'|'b')* 'c' ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "abaac", false);
|
|
||||||
assertEquals("abaac\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testLexerPlusSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println(this._input.getText());} ;\n" +
|
|
||||||
"A : ('a'|'b')+ 'c' ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "abaac", false);
|
|
||||||
assertEquals("abaac\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testNotCharSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println($A.text);} ;\n" +
|
|
||||||
"A : ~('b'|'c') ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "x", false);
|
|
||||||
assertEquals("x\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testNotCharSetWithLabel() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println($A.text);} ;\n" +
|
|
||||||
"A : h=~('b'|'c') ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "x", false);
|
|
||||||
assertEquals("x\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testNotCharSetWithRuleRef3() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : A {System.out.println($A.text);} ;\n" +
|
|
||||||
"A : ('a'|B) ; // this doesn't collapse to set but works\n" +
|
|
||||||
"fragment\n" +
|
|
||||||
"B : ~('a'|'c') ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "x", false);
|
|
||||||
assertEquals("x\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testCharSetLiteral() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"a : (A {System.out.println($A.text);})+ ;\n" +
|
|
||||||
"A : [AaBb] ;\n" +
|
|
||||||
"WS : (' '|'\\n')+ -> skip ;";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "a", "A a B b", false);
|
|
||||||
assertEquals("A\na\nB\nb\n", found);
|
|
||||||
assertNull(this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this file and method are generated, any edit will be overwritten by the next generation */
|
|
||||||
@Test
|
|
||||||
public void testComplementSet() throws Exception {
|
|
||||||
String grammar = "grammar T;\n" +
|
|
||||||
"parse : ~NEW_LINE;\n" +
|
|
||||||
"NEW_LINE: '\\r'? '\\n';";
|
|
||||||
String found = execParser("T.g4", grammar, "TParser", "TLexer", "parse", "a", false);
|
|
||||||
assertEquals("", found);
|
|
||||||
assertEquals("line 1:0 token recognition error at: 'a'\nline 1:1 missing {} at '<EOF>'\n", this.stderrDuringParse);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,353 @@
|
||||||
|
TestFile(file) ::= <<
|
||||||
|
package org.antlr.v4.test.rt.java;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
<if(file.importErrorQueue)>
|
||||||
|
import org.antlr.v4.test.tool.ErrorQueue;
|
||||||
|
<endif>
|
||||||
|
<if(file.importGrammar)>
|
||||||
|
import org.antlr.v4.tool.Grammar;
|
||||||
|
<endif>
|
||||||
|
|
||||||
|
public class Test<file.name> extends BaseTest {
|
||||||
|
|
||||||
|
<file.tests:{test | <test>}; separator="\n", wrap, anchor>
|
||||||
|
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
LexerTestMethod(test) ::= <<
|
||||||
|
@Test
|
||||||
|
public void test<test.name>() throws Exception {
|
||||||
|
<test.slaveGrammars:{ grammar |
|
||||||
|
String slave_<grammar.grammarName> = <grammar.lines:{ line | "<line>};separator="\\n\" +\n", wrap, anchor>";
|
||||||
|
mkdir(tmpdir);
|
||||||
|
writeFile(tmpdir, "<grammar.grammarName>.g4", slave_<grammar.grammarName>);
|
||||||
|
};separator="\n", wrap, anchor>
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
<test.grammar.lines:{ line | sb.append("<line>\\n");};separator="\n", wrap, anchor>
|
||||||
|
String grammar = sb.toString();
|
||||||
|
<test.afterGrammar>
|
||||||
|
String found = execLexer("<test.grammar.grammarName>.g4", grammar, "<test.grammar.grammarName><if(!test.lexerOnly)>Lexer<endif>", "<test.input>", <test.showDFA>);
|
||||||
|
assertEquals(<test.outputLines:{ line | "<line>\\n"};separator=" + \n", wrap, anchor>, found);
|
||||||
|
<if(test.expectedErrors)>
|
||||||
|
assertEquals("<test.expectedErrors>", this.stderrDuringParse);
|
||||||
|
<else>
|
||||||
|
assertNull(this.stderrDuringParse);
|
||||||
|
<endif>
|
||||||
|
}
|
||||||
|
|
||||||
|
>>
|
||||||
|
|
||||||
|
CompositeLexerTestMethod(test) ::= <<
|
||||||
|
<LexerTestMethod(test)>
|
||||||
|
>>
|
||||||
|
|
||||||
|
|
||||||
|
ParserTestMethod(test) ::= <<
|
||||||
|
@Test
|
||||||
|
public void test<test.name>() throws Exception {
|
||||||
|
<!<test.slaveGrammars:{ grammar |
|
||||||
|
String slave_<grammar.grammarName> = <grammar.lines:{ line | "<line>};separator="\\n\" +\n", wrap, anchor>";
|
||||||
|
<if(test.slaveIsLexer)>
|
||||||
|
rawGenerateAndBuildRecognizer("<grammar.grammarName>.g4", slave_<grammar.grammarName>, null, "<grammar.grammarName>");
|
||||||
|
<else>
|
||||||
|
mkdir(tmpdir);
|
||||||
|
writeFile(tmpdir, "<grammar.grammarName>.g4", slave_<grammar.grammarName>);
|
||||||
|
<endif>
|
||||||
|
};separator="\n", wrap, anchor>!>
|
||||||
|
|
||||||
|
mkdir(tmpdir);
|
||||||
|
<test.Grammars: {grammarFileName | writeFile("<grammarFileName>", <string(test.Grammars.(grammarFileName))>);}; separator="\n", anchor>
|
||||||
|
writeFile(tmpdir, "<test.Grammars.keys>"
|
||||||
|
|
||||||
|
String grammar = <test.grammar.lines:{ line | "<line>};separator="\\n\" +\n", wrap, anchor>";
|
||||||
|
<test.afterGrammar>
|
||||||
|
String found = execParser("<test.grammar.grammarName>.g4", grammar, "<test.grammar.grammarName><if(!test.slaveIsLexer)>Parser<endif>", "<if(test.slaveIsLexer)><first(test.slaveGrammars).grammarName><else><test.grammar.grammarName>Lexer<endif>", "<test.startRule>", "<test.input>", <test.debug>);
|
||||||
|
assertEquals("<test.expectedOutput>", found);
|
||||||
|
<if(test.expectedErrors)>
|
||||||
|
assertEquals("<test.expectedErrors>", this.stderrDuringParse);
|
||||||
|
<else>
|
||||||
|
assertNull(this.stderrDuringParse);
|
||||||
|
<endif>
|
||||||
|
}
|
||||||
|
|
||||||
|
>>
|
||||||
|
|
||||||
|
string(text) ::= <<
|
||||||
|
"<escape.(text)>"
|
||||||
|
>>
|
||||||
|
|
||||||
|
CompositeParserTestMethod(test) ::= <<
|
||||||
|
<ParserTestMethod(test)>
|
||||||
|
>>
|
||||||
|
|
||||||
|
AbstractParserTestMethod(test) ::= <<
|
||||||
|
String test<test.name>(String input) throws Exception {
|
||||||
|
String grammar = <test.grammar.lines:{ line | "<line>};separator="\\n\" +\n", wrap, anchor>";
|
||||||
|
return execParser("<test.grammar.grammarName>.g4", grammar, "<test.grammar.grammarName>Parser", "<test.grammar.grammarName>Lexer", "<test.startRule>", input, <test.debug>);
|
||||||
|
}
|
||||||
|
|
||||||
|
>>
|
||||||
|
|
||||||
|
ConcreteParserTestMethod(test) ::= <<
|
||||||
|
@Test
|
||||||
|
public void test<test.name>() throws Exception {
|
||||||
|
String found = test<test.baseName>("<test.input>");
|
||||||
|
assertEquals("<test.expectedOutput>", found);
|
||||||
|
<if(test.expectedErrors)>
|
||||||
|
assertEquals("<test.expectedErrors>", this.stderrDuringParse);
|
||||||
|
<else>
|
||||||
|
assertNull(this.stderrDuringParse);
|
||||||
|
<endif>
|
||||||
|
}
|
||||||
|
|
||||||
|
>>
|
||||||
|
|
||||||
|
writeln(s) ::= <<System.out.println(<s>);>>
|
||||||
|
|
||||||
|
write(s) ::= <<System.out.print(<s>);>>
|
||||||
|
|
||||||
|
False() ::= "false"
|
||||||
|
|
||||||
|
True() ::= "true"
|
||||||
|
|
||||||
|
Not(v) ::= "!<v>"
|
||||||
|
|
||||||
|
Assert(s) ::= <<assert(<s>);>>
|
||||||
|
|
||||||
|
Cast(t,v) ::= "((<t>)<v>)"
|
||||||
|
|
||||||
|
Append(a,b) ::= "<a> + <b>"
|
||||||
|
|
||||||
|
Concat(a,b) ::= "<a><b>"
|
||||||
|
|
||||||
|
DeclareLocal(s,v) ::= "Object <s> = <v>;"
|
||||||
|
|
||||||
|
AssignLocal(s,v) ::= "<s> = <v>;"
|
||||||
|
|
||||||
|
InitIntMember(n,v) ::= <%int <n> = <v>;%>
|
||||||
|
|
||||||
|
InitBooleanMember(n,v) ::= <%boolean <n> = <v>;%>
|
||||||
|
|
||||||
|
GetMember(n) ::= <%this.<n>%>
|
||||||
|
|
||||||
|
SetMember(n,v) ::= <%this.<n> = <v>;%>
|
||||||
|
|
||||||
|
AddMember(n,v) ::= <%this.<n> += <v>;%>
|
||||||
|
|
||||||
|
PlusMember(v,n) ::= <%<v> + this.<n>%>
|
||||||
|
|
||||||
|
MemberEquals(n,v) ::= <%this.<n> == <v>%>
|
||||||
|
|
||||||
|
ModMemberEquals(n,m,v) ::= <%this.<n> % <m> == <v>%>
|
||||||
|
|
||||||
|
ModMemberNotEquals(n,m,v) ::= <%this.<n> % <m> != <v>%>
|
||||||
|
|
||||||
|
DumpDFA() ::= "this.dumpDFA();"
|
||||||
|
|
||||||
|
Pass() ::= ""
|
||||||
|
|
||||||
|
StringList() ::= "List\<String>"
|
||||||
|
|
||||||
|
BuildParseTrees() ::= "setBuildParseTree(true);"
|
||||||
|
|
||||||
|
BailErrorStrategy() ::= <%setErrorHandler(new BailErrorStrategy());%>
|
||||||
|
|
||||||
|
ToStringTree(s) ::= <%<s>.toStringTree(this)%>
|
||||||
|
|
||||||
|
Column() ::= "this.getCharPositionInLine()"
|
||||||
|
|
||||||
|
Text() ::= "this.getText()"
|
||||||
|
|
||||||
|
ValEquals(a,b) ::= <%<a>==<b>%>
|
||||||
|
|
||||||
|
TextEquals(a) ::= <%this.getText().equals("<a>")%>
|
||||||
|
|
||||||
|
PlusText(a) ::= <%"<a>" + this.getText()%>
|
||||||
|
|
||||||
|
InputText() ::= "this._input.getText()"
|
||||||
|
|
||||||
|
LTEquals(i, v) ::= <%this._input.LT(<i>).getText().equals(<v>)%>
|
||||||
|
|
||||||
|
LANotEquals(i, v) ::= <%this._input.LA(<i>)!=<v>%>
|
||||||
|
|
||||||
|
TokenStartColumnEquals(i) ::= <%this._tokenStartCharPositionInLine==<i>%>
|
||||||
|
|
||||||
|
ImportListener(X) ::= ""
|
||||||
|
|
||||||
|
GetExpectedTokenNames() ::= "this.getExpectedTokens().toString(this.tokenNames)"
|
||||||
|
|
||||||
|
RuleInvocationStack() ::= "getRuleInvocationStack()"
|
||||||
|
|
||||||
|
LL_EXACT_AMBIG_DETECTION() ::= <<_interp.setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);>>
|
||||||
|
|
||||||
|
PositionAdjustingLexer() ::= <<
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token nextToken() {
|
||||||
|
if (!(_interp instanceof PositionAdjustingLexerATNSimulator)) {
|
||||||
|
_interp = new PositionAdjustingLexerATNSimulator(this, _ATN, _decisionToDFA, _sharedContextCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.nextToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token emit() {
|
||||||
|
switch (_type) {
|
||||||
|
case TOKENS:
|
||||||
|
handleAcceptPositionForKeyword("tokens");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LABEL:
|
||||||
|
handleAcceptPositionForIdentifier();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleAcceptPositionForIdentifier() {
|
||||||
|
String tokenText = getText();
|
||||||
|
int identifierLength = 0;
|
||||||
|
while (identifierLength \< tokenText.length() && isIdentifierChar(tokenText.charAt(identifierLength))) {
|
||||||
|
identifierLength++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getInputStream().index() > _tokenStartCharIndex + identifierLength) {
|
||||||
|
int offset = identifierLength - 1;
|
||||||
|
getInterpreter().resetAcceptPosition(getInputStream(), _tokenStartCharIndex + offset, _tokenStartLine, _tokenStartCharPositionInLine + offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean handleAcceptPositionForKeyword(String keyword) {
|
||||||
|
if (getInputStream().index() > _tokenStartCharIndex + keyword.length()) {
|
||||||
|
int offset = keyword.length() - 1;
|
||||||
|
getInterpreter().resetAcceptPosition(getInputStream(), _tokenStartCharIndex + offset, _tokenStartLine, _tokenStartCharPositionInLine + offset);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PositionAdjustingLexerATNSimulator getInterpreter() {
|
||||||
|
return (PositionAdjustingLexerATNSimulator)super.getInterpreter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isIdentifierChar(char c) {
|
||||||
|
return Character.isLetterOrDigit(c) || c == '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static class PositionAdjustingLexerATNSimulator extends LexerATNSimulator {
|
||||||
|
|
||||||
|
public PositionAdjustingLexerATNSimulator(Lexer recog, ATN atn,
|
||||||
|
DFA[] decisionToDFA,
|
||||||
|
PredictionContextCache sharedContextCache)
|
||||||
|
{
|
||||||
|
super(recog, atn, decisionToDFA, sharedContextCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void resetAcceptPosition(CharStream input, int index, int line, int charPositionInLine) {
|
||||||
|
input.seek(index);
|
||||||
|
this.line = line;
|
||||||
|
this.charPositionInLine = charPositionInLine;
|
||||||
|
consume(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
>>
|
||||||
|
|
||||||
|
BasicListener(X) ::= <<
|
||||||
|
public static class LeafListener extends TBaseListener {
|
||||||
|
public void visitTerminal(TerminalNode node) {
|
||||||
|
System.out.println(node.getSymbol().getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
WalkListener(s) ::= <<
|
||||||
|
ParseTreeWalker walker = new ParseTreeWalker();
|
||||||
|
walker.walk(new LeafListener(), <s>);
|
||||||
|
>>
|
||||||
|
|
||||||
|
TokenGetterListener(X) ::= <<
|
||||||
|
public static class LeafListener extends TBaseListener {
|
||||||
|
public void exitA(TParser.AContext ctx) {
|
||||||
|
if (ctx.getChildCount()==2)
|
||||||
|
System.out.printf("%s %s %s",ctx.INT(0).getSymbol().getText(),
|
||||||
|
ctx.INT(1).getSymbol().getText(),ctx.INT());
|
||||||
|
else
|
||||||
|
System.out.println(ctx.ID().getSymbol());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
RuleGetterListener(X) ::= <<
|
||||||
|
public static class LeafListener extends TBaseListener {
|
||||||
|
public void exitA(TParser.AContext ctx) {
|
||||||
|
if (ctx.getChildCount()==2) {
|
||||||
|
System.out.printf("%s %s %s",ctx.b(0).start.getText(),
|
||||||
|
ctx.b(1).start.getText(),ctx.b().get(0).start.getText());
|
||||||
|
} else
|
||||||
|
System.out.println(ctx.b(0).start.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
|
||||||
|
LRListener(X) ::= <<
|
||||||
|
public static class LeafListener extends TBaseListener {
|
||||||
|
public void exitE(TParser.EContext ctx) {
|
||||||
|
if (ctx.getChildCount()==3) {
|
||||||
|
System.out.printf("%s %s %s\n",ctx.e(0).start.getText(),
|
||||||
|
ctx.e(1).start.getText(), ctx.e().get(0).start.getText());
|
||||||
|
} else
|
||||||
|
System.out.println(ctx.INT().getSymbol().getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
LRWithLabelsListener(X) ::= <<
|
||||||
|
public static class LeafListener extends TBaseListener {
|
||||||
|
public void exitCall(TParser.CallContext ctx) {
|
||||||
|
System.out.printf("%s %s",ctx.e().start.getText(),ctx.eList());
|
||||||
|
}
|
||||||
|
public void exitInt(TParser.IntContext ctx) {
|
||||||
|
System.out.println(ctx.INT().getSymbol().getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
DeclareContextListGettersFunction() ::= <<
|
||||||
|
void foo() {
|
||||||
|
SContext s = null;
|
||||||
|
List\<? extends AContext> a = s.a();
|
||||||
|
List\<? extends BContext> b = s.b();
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
Declare_foo() ::= <<public void foo() {System.out.println("foo");}>>
|
||||||
|
|
||||||
|
Invoke_foo() ::= "this.foo();"
|
||||||
|
|
||||||
|
Declare_pred() ::= <<boolean pred(boolean v) {
|
||||||
|
System.out.println("eval="+v);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
|
Invoke_pred(v) ::= <<this.pred(<v>)>>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "A a B b"
|
||||||
|
|
||||||
|
Output() ::= <<
|
||||||
|
A
|
||||||
|
a
|
||||||
|
B
|
||||||
|
b<\n>
|
||||||
|
>>
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : (A {<writeln("$A.text")>})+ ;
|
||||||
|
A : [AaBb] ;
|
||||||
|
WS : (' '|'\n')+ -> skip ;
|
||||||
|
>>
|
|
@ -0,0 +1,22 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "parse"
|
||||||
|
|
||||||
|
Input() ::= "a"
|
||||||
|
|
||||||
|
Output() ::= ""
|
||||||
|
|
||||||
|
Errors() ::= <<
|
||||||
|
line 1:0 token recognition error at: 'a'
|
||||||
|
line 1:1 missing {} at '\<EOF>'<\n>
|
||||||
|
>>
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : ~NEW_LINE;
|
||||||
|
NEW_LINE: '\\r'? '\\n';
|
||||||
|
>>
|
|
@ -0,0 +1,19 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "ac"
|
||||||
|
|
||||||
|
Output() ::= "ac<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<InputText():writeln()>} ;
|
||||||
|
A : ('a'|'b')? 'c' ;
|
||||||
|
>>
|
|
@ -0,0 +1,19 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "abaac"
|
||||||
|
|
||||||
|
Output() ::= "abaac<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<InputText():writeln()>} ;
|
||||||
|
A : ('a'|'b')+ 'c' ;
|
||||||
|
>>
|
|
@ -0,0 +1,19 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "abaac"
|
||||||
|
|
||||||
|
Output() ::= "abaac<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<InputText():writeln()>} ;
|
||||||
|
A : ('a'|'b')* 'c' ;
|
||||||
|
>>
|
|
@ -0,0 +1,19 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "x"
|
||||||
|
|
||||||
|
Output() ::= "x<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<writeln("$A.text")>} ;
|
||||||
|
A : ~'b' ;
|
||||||
|
>>
|
|
@ -0,0 +1,19 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "x"
|
||||||
|
|
||||||
|
Output() ::= "x<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<writeln("$A.text")>} ;
|
||||||
|
A : ~('b'|'c') ;
|
||||||
|
>>
|
|
@ -0,0 +1,19 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "x"
|
||||||
|
|
||||||
|
Output() ::= "x<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<writeln("$A.text")>} ;
|
||||||
|
A : h=~('b'|'c') ;
|
||||||
|
>>
|
|
@ -0,0 +1,21 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "x"
|
||||||
|
|
||||||
|
Output() ::= "x<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<writeln("$A.text")>} ;
|
||||||
|
A : ('a'|B) ; // this doesn't collapse to set but works
|
||||||
|
fragment
|
||||||
|
B : ~('a'|'c') ;
|
||||||
|
>>
|
|
@ -0,0 +1,19 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "bc"
|
||||||
|
|
||||||
|
Output() ::= "bc<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<InputText():writeln()>} ;
|
||||||
|
A : 'b'? 'c' ;
|
||||||
|
>>
|
|
@ -0,0 +1,18 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "ac"
|
||||||
|
|
||||||
|
Output() ::= "ac<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : ('a'|'b')? 'c' {<InputText():writeln()>} ;
|
||||||
|
>>
|
|
@ -0,0 +1,19 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "bc"
|
||||||
|
|
||||||
|
Output() ::= "bc<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A? 'c' {<InputText():writeln()>} ;
|
||||||
|
A : 'b' ;
|
||||||
|
>>
|
|
@ -0,0 +1,18 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "zz"
|
||||||
|
|
||||||
|
Output() ::= "z<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : t=~('x'|'y') 'z' {<writeln("$t.text")>} ;
|
||||||
|
>>
|
|
@ -0,0 +1,18 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "zz"
|
||||||
|
|
||||||
|
Output() ::= "zz<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : ~'x' 'z' {<InputText():writeln()>} ;
|
||||||
|
>>
|
|
@ -0,0 +1,18 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "zz"
|
||||||
|
|
||||||
|
Output() ::= "z<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : t=~'x' 'z' {<writeln("$t.text")>} ;
|
||||||
|
>>
|
|
@ -0,0 +1,18 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "x"
|
||||||
|
|
||||||
|
Output() ::= "x<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : t=('x'|'y') {<writeln("$t.text")>} ;
|
||||||
|
>>
|
|
@ -0,0 +1,19 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "bbbbc"
|
||||||
|
|
||||||
|
Output() ::= "bbbbc<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<InputText():writeln()>} ;
|
||||||
|
A : 'b'+ 'c' ;
|
||||||
|
>>
|
|
@ -0,0 +1,18 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "abaac"
|
||||||
|
|
||||||
|
Output() ::= "abaac<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : ('a'|'b')+ 'c' {<InputText():writeln()>} ;
|
||||||
|
>>
|
|
@ -0,0 +1,18 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "b"
|
||||||
|
|
||||||
|
Output() ::= "b<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> @after {<InputText():writeln()>} : 'a' | 'b' |'c' ;
|
||||||
|
>>
|
|
@ -0,0 +1,21 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "34"
|
||||||
|
|
||||||
|
Output() ::= "34<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : C {<InputText():writeln()>} ;
|
||||||
|
fragment A : '1' | '2';
|
||||||
|
fragment B : '3' '4';
|
||||||
|
C : A | B;
|
||||||
|
>>
|
|
@ -0,0 +1,28 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input ::= [
|
||||||
|
"1": "bbbbc",
|
||||||
|
"2": "c"
|
||||||
|
]
|
||||||
|
|
||||||
|
Output ::= [
|
||||||
|
"1": {bbbbc<\n>},
|
||||||
|
"2": {c<\n>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Errors ::= [
|
||||||
|
"1": "",
|
||||||
|
"2": ""
|
||||||
|
]
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : A {<InputText():writeln()>} ;
|
||||||
|
A : 'b'* 'c' ;
|
||||||
|
>>
|
|
@ -0,0 +1,18 @@
|
||||||
|
TestType() ::= "Parser"
|
||||||
|
|
||||||
|
Grammars ::= [
|
||||||
|
"T.g4": {<grammar("T")>}
|
||||||
|
]
|
||||||
|
|
||||||
|
Rule() ::= "a"
|
||||||
|
|
||||||
|
Input() ::= "abaac"
|
||||||
|
|
||||||
|
Output() ::= "abaac<\n>"
|
||||||
|
|
||||||
|
Errors() ::= ""
|
||||||
|
|
||||||
|
grammar(grammarName) ::= <<
|
||||||
|
grammar <grammarName>;
|
||||||
|
<Rule()> : ('a'|'b')* 'c' {<InputText():writeln()>} ;
|
||||||
|
>>
|
Loading…
Reference in New Issue