Merge pull request #144 from sharwell/maven-and-javadoc-updates

Maven and javadoc updates
This commit is contained in:
Terence Parr 2013-01-21 11:34:01 -08:00
commit 625c504f36
29 changed files with 1069 additions and 274 deletions

View File

@ -2,6 +2,10 @@ ANTLR v4 Honey Badger
January 21, 2013 -- Release 4.0
* Updated PredictionContext Javadocs
* Updated Maven site documentation
* Minor tweaks in Java.stg
January 15, 2013
* Tweak error messages

View File

@ -49,6 +49,7 @@
<name>ANTLR 4 Maven plugin</name>
<description>Maven plugin for ANTLR 4 grammars</description>
<url>http://www.antlr.org</url>
<prerequisites>
<maven>3.0</maven>
@ -179,4 +180,22 @@
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<configuration>
<quiet>true</quiet>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>2.3</version>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -66,15 +66,14 @@ import java.util.Map;
import java.util.Set;
/**
* Goal that picks up all the ANTLR grammars in a project and moves those that
* are required for generation of the compilable sources into the location
* that we use to compile them, such as {@code target/generated-sources/antlr4}.
* Parses ANTLR 4 grammar files {@code *.g4} and transforms them into Java
* source files.
*
* @author Sam Harwell
*/
@Mojo(
name = "antlr",
defaultPhase = LifecyclePhase.PROCESS_SOURCES,
name = "antlr4",
defaultPhase = LifecyclePhase.GENERATE_SOURCES,
requiresDependencyResolution = ResolutionScope.COMPILE,
requiresProject = true)
public class Antlr4Mojo extends AbstractMojo {
@ -84,8 +83,8 @@ public class Antlr4Mojo extends AbstractMojo {
//
/**
* If set to true then the ANTLR tool will generate a description of the atn
* for each rule in <a href="http://www.graphviz.org">Dot format</a>
* If set to true then the ANTLR tool will generate a description of the ATN
* for each rule in <a href="http://www.graphviz.org">Dot format</a>.
*/
@Parameter(property = "antlr4.atn", defaultValue = "false")
protected boolean atn;
@ -93,29 +92,29 @@ public class Antlr4Mojo extends AbstractMojo {
/**
* specify grammar file encoding; e.g., euc-jp
*/
@Parameter
@Parameter(property = "project.build.sourceEncoding")
protected String encoding;
/**
* generate parse tree listener (default)
* Generate parse tree listener interface and base class.
*/
@Parameter(property = "antlr4.listener", defaultValue = "true")
protected boolean listener;
/**
* generate parse tree visitor
* Generate parse tree visitor interface and base class.
*/
@Parameter(property = "antlr4.visitor", defaultValue = "false")
protected boolean visitor;
/**
* treat warnings as errors
* Treat warnings as errors.
*/
@Parameter(property = "antlr4.treatWarningsAsErrors", defaultValue = "false")
protected boolean treatWarningsAsErrors;
/**
* use the ATN simulator for all predictions
* Use the ATN simulator for all predictions.
*/
@Parameter(property = "antlr4.forceATN", defaultValue = "false")
protected boolean forceATN;
@ -135,50 +134,49 @@ public class Antlr4Mojo extends AbstractMojo {
protected List<String> arguments;
/* --------------------------------------------------------------------
* The following are Maven specific parameters, rather than specificlly
* The following are Maven specific parameters, rather than specific
* options that the ANTLR tool can use.
*/
/**
* Provides an explicit list of all the grammars that should
* be included in the generate phase of the plugin. Note that the plugin
* is smart enough to realize that imported grammars should be included but
* not acted upon directly by the ANTLR Tool.
*
* Unless otherwise specified, the include list scans for and includes all
* files that end in ".g" in any directory beneath src/main/antlr4. Note that
* this version of the plugin looks for the directory antlr4 and not the directory
* antlr, so as to avoid clashes and confusion for projects that use both v3 and v4 grammars
* such as ANTLR itself.
* Provides an explicit list of all the grammars that should be included in
* the generate phase of the plugin. Note that the plugin is smart enough to
* realize that imported grammars should be included but not acted upon
* directly by the ANTLR Tool.
* <p/>
* A set of Ant-like inclusion patterns used to select files from the source
* directory for processing. By default, the pattern
* <code>**&#47;*.g4</code> is used to select grammar files.
*/
@Parameter
protected Set<String> includes = new HashSet<String>();
/**
* Provides an explicit list of any grammars that should be excluded from
* the generate phase of the plugin. Files listed here will not be sent for
* processing by the ANTLR tool.
* A set of Ant-like exclusion patterns used to prevent certain files from
* being processed. By default, this set is empty such that no files are
* excluded.
*/
@Parameter
protected Set<String> excludes = new HashSet<String>();
/**
* The current Maven project.
*/
@Parameter(property = "project", required = true, readonly = true)
protected MavenProject project;
/**
* Specifies the ANTLR directory containing grammar files.
* The directory where the ANTLR grammar files ({@code *.g4}) are located.
*/
@Parameter(defaultValue = "${basedir}/src/main/antlr4", required = true)
@Parameter(defaultValue = "${basedir}/src/main/antlr4")
private File sourceDirectory;
/**
* Specify output directory where the Java files are generated.
*/
@Parameter(defaultValue = "${project.build.directory}/generated-sources/antlr4", required = true)
@Parameter(defaultValue = "${project.build.directory}/generated-sources/antlr4")
private File outputDirectory;
/**
* Specify location of grammars and tokens files.
* Specify location of imported grammars and tokens files.
*/
@Parameter(defaultValue = "${basedir}/src/main/antlr4/imports")
private File libDirectory;
@ -208,41 +206,27 @@ public class Antlr4Mojo extends AbstractMojo {
* The main entry point for this Mojo, it is responsible for converting
* ANTLR 4.x grammars into the target language specified by the grammar.
*
* @throws MojoExecutionException When something is discovered such as a missing source
* @throws MojoFailureException When something really bad happens such as not being able to create the ANTLR Tool
* @throws MojoExecutionException if a configuration or grammar error causes
* the code generation process to fail
* @throws MojoFailureException if an instance of the ANTLR 4 {@link Tool}
* cannot be created
*/
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
Log log = getLog();
// Check to see if the user asked for debug information, then dump all the
// parameters we have picked up if they did.
//
if (log.isDebugEnabled()) {
// Excludes
//
for (String e : excludes) {
log.debug("ANTLR: Exclude: " + e);
}
// Includes
//
for (String e : includes) {
log.debug("ANTLR: Include: " + e);
}
// Output location
//
log.debug("ANTLR: Output: " + outputDirectory);
// Library directory
//
log.debug("ANTLR: Library: " + libDirectory);
// Flags
//
}
if (!sourceDirectory.isDirectory()) {
@ -363,7 +347,7 @@ public class Antlr4Mojo extends AbstractMojo {
/**
*
* @param sourceDirectory
* @throws org.codehaus.plexus.compiler.util.scan.InclusionScanException
* @throws InclusionScanException
*/
@NotNull
private List<List<String>> processGrammarFiles(List<String> args, File sourceDirectory) throws InclusionScanException {
@ -445,7 +429,7 @@ public class Antlr4Mojo extends AbstractMojo {
* relative to the base of the output directory and reflect the input
* organization of the grammar files.
*
* @param sourceDirectory The source directory File object
* @param sourceDirectory The source directory {@link File} object
* @param grammarFileName The full path to the input grammar file
* @return The path to the grammar file relative to the source directory
*/

View File

@ -1,8 +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
as imports in your main <<<.g4>>> files, you need to place the imported grammar
files in the <<<imports>>> directory beneath the root directory of your grammar
files (which is <<<src/main/antlr4>>> by default of course).
For a default layout, place your import grammars in the directory: <<<src/main/antlr4/imports>>>

View File

@ -2,23 +2,23 @@ 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 vocab files (<<<xxx.tokens>>>) can also
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 vocab file then you will need to locate
the grammar that generates the .tokens file alongside the grammar that uses it. This
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 vocab files in
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, whereever 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 geenrated .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 <<<.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:
@ -30,7 +30,6 @@ Libraries
<version>4.0-SNAPSHOT</version>
<executions>
<execution>
<configuration>
<goals>

View File

@ -1,7 +1,7 @@
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
then configuring the <<<pom.xml>>> file for your project is as simple as adding this to it
+--
<plugins>
@ -21,12 +21,12 @@ Simple configuration
</plugins>
+--
When the mvn command is executed all grammar files under <<<src/main/antlr4>>>, except any
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>>>.
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:
reflect the package structure of your java parsers. If your grammar file <<<parser.g4>>> contains:
+---
@header {
@ -34,7 +34,7 @@ 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
Then the <<<.g4>>> file should be stored in: <<<src/main/antlr4/org/jimi/themuss/parser.g4>>>. This way
the generated <<<.java>>> files will correctly reflect the package structure in which they will
finally rest as classes.

View File

@ -0,0 +1 @@
FAQ

View File

@ -49,10 +49,10 @@ ANTLR v4 Maven plugin
+--- 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
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
<<<.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.
@ -60,4 +60,3 @@ ANTLR v4 Maven plugin
any grammar files that are imported by other grammar files (do not make subdirectories here.)
Such files are never built on their own, but the plugin will automatically tell the ANTLR
tool to look in this directory for library files.

View File

@ -1,193 +1,59 @@
Usage
The Maven plugin for antlr is simple to use but is at its simplest when you use the default
layouts for your grammars, as so:
The ANTLR 4 plugin for Maven can generate parsers for any number of grammars in
your project.
* Compiling Grammars into Parsers
By default, the <<<{{{./antlr-mojo.html}antlr}}>>> 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 <<<{{{./antlr-mojo.html}antlr}}>>> 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/ .g4 files that are imported by other grammars.
+--- imports/ user-created .tokens files and .g4 files that are imported by other grammars
+--
However, if you are not able to use this structure for whatever reason, you
can configure the locations of the grammar files, where library/import files
are located and where the output files should be generated.
* Plugin Descriptor
The current version of the plugin is shown at the top of this page after the <<Last Deployed>> date.
The full layout of the descriptor (at least, those parts that are not standard Maven things),
showing the default values of the configuration options, is as follows:
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>4.0-SNAPSHOT</version>
<version>${project.version}</version>
<executions>
<execution>
<configuration>
<id>antlr</id>
<goals>
<goal>antlr</goal>
</goals>
<conversionTimeout>10000</conversionTimeout>
<debug>false</debug>
<dfa>false</dfa>
<nfa>false</nfa>
<excludes><exclude/></excludes>
<includes><include/></includes>
<libDirectory>src/main/antlr4/imports</libDirectory>
<messageFormat>antlr</messageFormat>
<outputDirectory>target/generated-sources/antlr4</outputDirectory>
<printGrammar>false</printGrammar>
<profile>false</profile>
<report>false</report>
<sourceDirectory>src/main/antlr4</sourceDirectory>
<trace>false</trace>
<verbose>true</verbose>
</configuration>
</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).
** Configuration parameters
*** report
If set to true, then after the tool has processed an input grammar file
it will report variaous statistics about the parser, such as information
on cyclic DFAs, which rules may use backtracking, and so on.
default-value="false"
*** printGrammar
If set to true, then the ANTLR tool will print a version of the input
grammar which is devoid of any actions that may be present in the input file.
default-value = "false"
*** debug
If set to true, then the code generated by the ANTLR code generator will
be set to debug mode. This means that when run, the code will 'hang' and
wait for a debug connection on a TCP port (49100 by default).
default-value="false"
*** profile
If set to true, then then the generated parser will compute and report on
profile information at runtime.
default-value="false"
*** nfa
If set to true then the ANTLR tool will generate a description of the nfa
for each rule in <a href="http://www.graphviz.org">Dot format</a>
default-value="false"
protected boolean nfa;
*** dfa
If set to true then the ANTLR tool will generate a description of the DFA
for each decision in the grammar in <a href="http://www.graphviz.org">Dot format</a>
default-value="false"
*** trace
If set to true, the generated parser code will log rule entry and exit points
to stdout as an aid to debugging.
default-value="false"
*** messageFormat
If this parameter is set, it indicates that any warning or error messages returned
by ANLTR, shoould be formatted in the specified way. Currently, ANTLR supports the
built-in formats of antlr, gnu and vs2005.
default-value="antlr"
*** verbose
If this parameter is set to true, then ANTLR will report all sorts of things
about what it is doing such as the names of files and the version of ANTLR and so on.
default-value="true"
*** conversionTimeout
The number of milliseconds ANTLR will wait for analysis of each
alternative in the grammar to complete before giving up. You may raise
this value if ANTLR gives up on a complicated alt and tells you that
there are lots of ambiguties, but you know that it just needed to spend
more time on it. Note that this is an absolute time and not CPU time.
default-value="10000"
*** includes
Provides an explicit list of all the grammars that should
be included in the generate phase of the plugin. Note that the plugin
is smart enough to realize that imported grammars should be included but
not acted upon directly by the ANTLR Tool.
Unless otherwise specified, the include list scans for and includes all
files that end in ".g4" in any directory beneath src/main/antlr4. Note that
this version of the plugin looks for the directory antlr4 and not the directory
antlr, so as to avoid clashes and confusion for projects that use both v3 and v4 grammars
such as ANTLR itself.
*** excludes
Provides an explicit list of any grammars that should be excluded from
the generate phase of the plugin. Files listed here will not be sent for
processing by the ANTLR tool.
*** sourceDirectory
Specifies the Antlr directory containing grammar files. For
antlr version 4.x we default this to a directory in the tree
called antlr4 because the antlr directory is occupied by version
2.x grammars.
<<NB>> Take careful note that the default location for antlr grammars
is now <<antlr4>> and NOT <<antlr>>
default-value="<<<${basedir}/src/main/antlr4>>>"
*** outputDirectory
Location for generated Java files. For antlr version 4.x we default
this to a directory in the tree called antlr4 because the antlr
directory is occupied by version 2.x grammars.
default-value="<<<${project.build.directory}/generated-sources/antlr4>>>"
*** libDirectory
Location for imported token files, e.g. <code>.tokens</code> and imported grammars.
Note that ANTLR will not try to process grammars that it finds in this directory, but
will include this directory in the search for .tokens files and import grammars.
<<NB>> If you change the lib directory from the default but the directory is
still under<<<${basedir}/src/main/antlr4>>>, then you will need to exclude
the grammars from processing specifically, using the <<<<excludes>>>> option.
default-value="<<<${basedir}/src/main/antlr4/imports>>>"
Note that you can create multiple executions, and thus build some grammars with
different options to others (such as setting the <<<debug>>> option for
instance).

View File

@ -17,7 +17,9 @@
<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">

14
pom.xml
View File

@ -16,6 +16,11 @@
<name>ANTLR 4</name>
<description>ANTLR 4 Master Build POM</description>
<url>http://www.antlr.org</url>
<inceptionYear>1992</inceptionYear>
<organization>
<name>ANTLR</name>
<url>http://www.antlr.org</url>
</organization>
<licenses>
<license>
@ -63,13 +68,20 @@
<antlr.testinprocess>true</antlr.testinprocess>
</properties>
<mailingLists>
<mailingList>
<name>antlr-discussion</name>
<archive>https://groups.google.com/forum/?fromgroups#!forum/antlr-discussion</archive>
</mailingList>
</mailingLists>
<issueManagement>
<system>GitHub Issues</system>
<url>https://github.com/antlr/antlr4/issues</url>
</issueManagement>
<scm>
<url>git://github.com/antlr/antlr4.git</url>
<url>https://github.com/antlr/antlr4/tree/master</url>
<connection>scm:git:git://github.com/antlr/antlr4.git</connection>
<developerConnection>scm:git:git@github.com:antlr/antlr4.git</developerConnection>
</scm>

View File

@ -0,0 +1,77 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph clusterA {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_u1[label="u"];
A_v1[label="v"];
}
A_left[shape="record";label="{<a> | a} | {<b> | b}"];
{ edge[dir="back"];
A_u1:s -> A_left:a:n;
A_v1:s -> A_left:b:n;
}
}
subgraph AB {
temp0[color="invis";shape="point";label=""];
temp1[shape="none";label="+"];
temp0 -> temp1[style="invisible";dir="none"];
}
subgraph clusterB {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_w1[label="w"];
A_x1[label="x"];
}
A_right[shape="record";label="{<c> | c} | {<d> | d}"];
{ edge[dir="back"];
A_w1:s -> A_right:c:n;
A_x1:s -> A_right:d:n;
}
}
subgraph BC {
node[color="invis";shape="point"];
temp2a;
{ rank="same";
temp2b;
temp2c;
}
temp2a -> temp2b[style="invisible";dir="none"];
temp2a -> temp2c[style="invisible";dir="none"];
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph clusterC {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_u2[label="u"];
A_v2[label="v"];
A_w2[label="w"];
A_x2[label="x"];
}
A_result[shape="record";label="{<a> | a} | {<b> | b} | {<c> | c} | {<d> | d}"];
{ edge[dir="back"];
A_u2:s -> A_result:a:n;
A_v2:s -> A_result:b:n;
A_w2:s -> A_result:c:n;
A_x2:s -> A_result:d:n;
}
}
}

View File

@ -0,0 +1,72 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph clusterA {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_u1[label="x"];
}
A_left[shape="record";label="{<a> | a}"];
{ edge[dir="back"];
A_u1:s -> A_left:a:n;
}
}
subgraph AB {
temp0[color="invis";shape="point";label=""];
temp1[shape="none";label="+"];
temp0 -> temp1[style="invisible";dir="none"];
}
subgraph clusterB {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_w1[label="y"];
}
A_right[shape="record";label="{<a> | a}"];
{ edge[dir="back"];
A_w1:s -> A_right:a:n;
}
}
subgraph BC {
node[color="invis";shape="point"];
temp2a;
{ rank="same";
temp2b;
temp2c;
}
temp2a -> temp2b[style="invisible";dir="none"];
temp2a -> temp2c[style="invisible";dir="none"];
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph clusterC {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_u2[label=""];
A_v2[label=""];
}
A_result[shape="record";label="{<x> | x} | {<y> | y}"];
A_ap[label="a'";shape="none"];
{ edge[dir="back"];
A_u2:s -> A_result:x:n;
A_v2:s -> A_result:y:n;
A_result:s -> A_ap:n;
}
}
}

View File

@ -0,0 +1,83 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph clusterA {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_u1[label="u"];
A_v1[label="v"];
}
A_left[shape="record";label="{<a> | a} | {<b> | b}"];
{ edge[dir="back"];
A_u1:s -> A_left:a:n;
A_v1:s -> A_left:b:n;
}
}
subgraph AB {
temp0[color="invis";shape="point";label=""];
temp1[shape="none";label="+"];
temp0 -> temp1[style="invisible";dir="none"];
}
subgraph clusterB {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_w1[label="w"];
A_x1[label="x"];
}
A_right[shape="record";label="{<b> | b} | {<d> | d}"];
{ edge[dir="back"];
A_w1:s -> A_right:b:n;
A_x1:s -> A_right:d:n;
}
}
subgraph BC {
node[color="invis";shape="point"];
temp2a;
{ rank="same";
temp2b;
temp2c;
}
temp2a -> temp2b[style="invisible";dir="none"];
temp2a -> temp2c[style="invisible";dir="none"];
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph clusterC {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_u2[label="u"];
A_vw[shape="record";label="{<v> | v} | {<w> | w}"];
A_x2[label="x"];
}
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_vp[label=""];
A_wp[label=""];
}
A_result[shape="record";label="{<a> | a} | {<b> | b'} | {<d> | d}"];
{ edge[dir="back"];
A_u2:s -> A_result:a:n;
A_vw:s -> A_result:b:n;
A_x2:s -> A_result:d:n;
A_vp:s -> A_vw:v:n;
A_wp:s -> A_vw:w:n;
}
}
}

View File

@ -0,0 +1,75 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph clusterA {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_u1[label="u"];
A_v1[label="v"];
}
A_left[shape="record";label="{<a> | a} | {<b> | b}"];
{ edge[dir="back"];
A_u1:s -> A_left:a:n;
A_v1:s -> A_left:b:n;
}
}
subgraph AB {
temp0[color="invis";shape="point";label=""];
temp1[shape="none";label="+"];
temp0 -> temp1[style="invisible";dir="none"];
}
subgraph clusterB {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_w1[label="v"];
A_x1[label="x"];
}
A_right[shape="record";label="{<b> | b} | {<d> | d}"];
{ edge[dir="back"];
A_w1:s -> A_right:b:n;
A_x1:s -> A_right:d:n;
}
}
subgraph BC {
node[color="invis";shape="point"];
temp2a;
{ rank="same";
temp2b;
temp2c;
}
temp2a -> temp2b[style="invisible";dir="none"];
temp2a -> temp2c[style="invisible";dir="none"];
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph clusterC {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_u2[label="u"];
A_v2[label="v"];
A_x2[label="x"];
}
A_result[shape="record";label="{<a> | a} | {<b> | b} | {<d> | d}"];
{ edge[dir="back"];
A_u2:s -> A_result:a:n;
A_v2:s -> A_result:b:n;
A_x2:s -> A_result:d:n;
}
}
}

View File

@ -0,0 +1,87 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph clusterA {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_u1[label="u"];
A_v1[label="v"];
}
A_left[shape="record";label="{<a> | a} | {<b> | b}"];
{ edge[dir="back"];
A_u1:s -> A_left:a:n;
A_v1:s -> A_left:b:n;
}
}
subgraph AB {
temp0[color="invis";shape="point";label=""];
temp1[shape="none";label="+"];
temp0 -> temp1[style="invisible";dir="none"];
}
subgraph clusterB {
label="";
color="invis";
{ rank="same";
node[shape="invtriangle";margin="0.01,0.01"];
A_w1[label="v"];
A_x1[label="u"];
}
A_right[shape="record";label="{<b> | b} | {<d> | d}"];
{ edge[dir="back"];
A_w1:s -> A_right:b:n;
A_x1:s -> A_right:d:n;
}
}
subgraph BC {
node[color="invis";shape="point"];
temp2a;
{ rank="same";
temp2b;
temp2c;
}
temp2a -> temp2b[style="invisible";dir="none"];
temp2a -> temp2c[style="invisible";dir="none"];
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph clusterC {
label="";
color="invis";
subgraph clusterSubC {
node[group="";shape="invtriangle";margin="0.01,0.01"];
A_u2[label="u"];
{ rank="same";
A_ut1[color="invis";shape="point";width="0.00000001"];
A_v2[label="v"];
A_ut2[color="invis";shape="point";width="0.00000001"];
}
A_ut1 -> A_v2 -> A_ut2[style="invisible",dir="none"];
A_u2 -> A_v2[style="invisible",dir="none"];
}
A_result[shape="record";label="{<a> | a} | {<b> | b} | {<d> | d}"];
{ edge[dir="back"];
A_u2:sw -> A_ut1:n;
A_v2:s -> A_result:b:n;
A_u2:se -> A_ut2:n;
A_v2:s -> A_result:n[style="invisible",dir="none"];
}
{ edge[dir="none";constraint="false"];
A_ut1:s -> A_result:a:n;
A_ut2:s -> A_result:d:n;
}
}
}

View File

@ -0,0 +1,46 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
node[shape="none"];
lefttree[label=""];
left[label="$"];
lefttree -> left[style="invisible";dir="none"];
}
subgraph AB {
optree[shape="none";label=""];
temp1[shape="none";label="+"];
optree -> temp1[style="invisible";dir="none"];
}
subgraph R {
righttree[shape="none";label=""];
right[shape="invtriangle";label="x"];
righttree -> right[style="invisible";dir="none"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2a;
{ rank="same";
temp2b;
temp2c;
}
temp2a -> temp2b[style="invisible";dir="none"];
temp2a -> temp2c[style="invisible";dir="none"];
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph Res {
node[shape="none"];
resulttree[shape="invtriangle";label=""];
result[shape="record";label="{ | $} | {<x> | x}"];
resulttree -> result:x:n[dir="back"];
}
}

View File

@ -0,0 +1,27 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
left[shape="none";label="$"];
}
subgraph AB {
temp1[shape="none";label="+"];
}
subgraph R {
right[shape="none";label="$"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2b;
temp2c;
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph Res {
result[shape="none";label="$"];
}
}

View File

@ -0,0 +1,52 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
node[shape="none"];
lefttree[label=""];
left[label="$"];
leftroot[label="a"];
lefttree -> left[style="invisible";dir="none"];
left -> leftroot[dir="back"];
}
subgraph AB {
optree[shape="none";label=""];
temp1[shape="none";label="+"];
optree -> temp1[style="invisible";dir="none"];
}
subgraph R {
righttree[shape="none";label=""];
right[shape="invtriangle";label="x"];
rightroot[shape="none";label="a"];
righttree -> right[style="invisible";dir="none"];
right -> rightroot[dir="back"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2a;
{ rank="same";
temp2b;
temp2c;
}
temp2a -> temp2b[style="invisible";dir="none"];
temp2a -> temp2c[style="invisible";dir="none"];
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph Res {
node[shape="none"];
resulttree[shape="invtriangle";label=""];
result[shape="record";label="{ | $} | {<x> | x}"];
resultroot[label="a'"];
resulttree -> result:x:n[dir="back"];
result -> resultroot[dir="back"];
}
}

View File

@ -0,0 +1,39 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
node[shape="none"];
left[label="$"];
leftroot[label="a"];
left -> leftroot[dir="back"];
}
subgraph AB {
temp1[shape="none";label="+"];
}
subgraph R {
right[shape="invtriangle";label="x"];
rightroot[shape="none";label="b"];
right -> rightroot[dir="back"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2b;
temp2c;
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph Res {
node[shape="none"];
result[label="$"];
resultroot[shape="record";label="{<a> | a} | {<b> | b}"];
result -> resultroot:a:n[dir="back"];
result -> resultroot:b:n[dir="back"];
}
}

View File

@ -0,0 +1,38 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
node[shape="none"];
left[label="$"];
leftroot[label="a"];
left -> leftroot[dir="back"];
}
subgraph AB {
temp1[shape="none";label="+"];
}
subgraph R {
right[shape="invtriangle";label="x"];
rightroot[shape="none";label="a"];
right -> rightroot[dir="back"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2b;
temp2c;
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph Res {
node[shape="none"];
result[label="$"];
resultroot[label="a"];
result -> resultroot[dir="back"];
}
}

View File

@ -0,0 +1,27 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
left[shape="none";label="$"];
}
subgraph AB {
temp1[shape="none";label="+"];
}
subgraph R {
right[shape="invtriangle";label="x"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2b;
temp2c;
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph Res {
result[shape="none";label="$"];
}
}

View File

@ -0,0 +1,40 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
node[shape="none"];
left[shape="invtriangle";label="x"];
leftroot[label="a"];
left -> leftroot[dir="back"];
}
subgraph AB {
temp1[shape="none";label="+"];
}
subgraph R {
right[shape="invtriangle";label="y"];
rightroot[shape="none";label="b"];
right -> rightroot[dir="back"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2b;
temp2c;
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph clusterRes {
color="invis";
resulttree1[shape="invtriangle";label="x"];
resulttree2[shape="invtriangle";label="y"];
result[shape="record";label="{<a> | a} | {<b> | b}"];
resulttree1:s -> result:a:n[dir="back"];
resulttree2:s -> result:b:n[dir="back"];
}
}

View File

@ -0,0 +1,39 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
node[shape="none"];
left[shape="invtriangle";label="x"];
leftroot[label="a"];
left -> leftroot[dir="back"];
}
subgraph AB {
temp1[shape="none";label="+"];
}
subgraph R {
right[shape="invtriangle";label="x"];
rightroot[shape="none";label="b"];
right -> rightroot[dir="back"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2b;
temp2c;
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph clusterRes {
color="invis";
resulttree[shape="invtriangle";label="x"];
result[shape="record";label="{<a> | a} | {<b> | b}"];
resulttree -> result:a:n[dir="back"];
resulttree -> result:b:n[dir="back"];
}
}

View File

@ -0,0 +1,54 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
node[shape="none"];
lefttree[label=""];
left[shape="invtriangle";label="x"];
leftroot[label="a"];
lefttree -> left[style="invisible";dir="none"];
left -> leftroot[dir="back"];
}
subgraph AB {
optree[shape="none";label=""];
temp1[shape="none";label="+"];
optree -> temp1[style="invisible";dir="none"];
}
subgraph R {
righttree[shape="none";label=""];
right[shape="invtriangle";label="y"];
rightroot[shape="none";label="a"];
righttree -> right[style="invisible";dir="none"];
right -> rightroot[dir="back"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2a;
{ rank="same";
temp2b;
temp2c;
}
temp2a -> temp2b[style="invisible";dir="none"];
temp2a -> temp2c[style="invisible";dir="none"];
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph clusterRes {
color="invis";
resulttree1[shape="invtriangle";label=""];
resulttree2[shape="invtriangle";label=""];
result[shape="record";label="{<x> | x} | {<y> | y}"];
resultroot[shape="none";label="a'"];
resulttree1:s -> result:x:n[dir="back"];
resulttree2:s -> result:y:n[dir="back"];
result -> resultroot[dir="back"];
}
}

View File

@ -0,0 +1,38 @@
digraph "" {
graph[dpi="60";compound="true"];
subgraph L {
node[shape="none"];
left[shape="invtriangle";label="x"];
leftroot[label="a"];
left -> leftroot[dir="back"];
}
subgraph AB {
temp1[shape="none";label="+"];
}
subgraph R {
right[shape="invtriangle";label="x"];
rightroot[shape="none";label="a"];
right -> rightroot[dir="back"];
}
subgraph BC {
node[color="invis";shape="point"];
temp2b;
temp2c;
temp2b -> temp2c[constraint="false";label="wwwwwww"];
}
subgraph clusterRes {
color="invis";
result[shape="invtriangle";label="x"];
resultroot[shape="none";label="a"];
result -> resultroot[dir="back"];
}
}

View File

@ -112,7 +112,7 @@ public interface IntStream {
* If {@code i} represents a position at or beyond the end of the stream,
* this method returns {@link #EOF}.
* <p/>
* The return value is unspecified if {@code i&lt;0} and fewer than {@code -i}
* The return value is unspecified if {@code i<0} and fewer than {@code -i}
* calls to {@link #consume consume()} have occurred from the beginning of
* the stream before calling this method.
*

View File

@ -48,11 +48,16 @@ import java.util.Map;
public abstract class PredictionContext implements Iterable<SingletonPredictionContext>,
Comparable<PredictionContext> // to sort node lists by id
{
/** Represents $ in local ctx prediction, which means wildcard. *+x = *. */
/**
* Represents {@code $} in local context prediction, which means wildcard.
* {@code *+x = *}.
*/
public static final EmptyPredictionContext EMPTY = new EmptyPredictionContext();
/** Represents $ in an array in full ctx mode, when $ doesn't mean wildcard:
* $ + x = [$,x]. Here, $ = EMPTY_RETURN_STATE.
/**
* Represents {@code $} in an array in full context mode, when {@code $}
* doesn't mean wildcard: {@code $ + x = [$,x]}. Here,
* {@code $} = {@link #EMPTY_RETURN_STATE}.
*/
public static final int EMPTY_RETURN_STATE = Integer.MAX_VALUE;
@ -97,7 +102,7 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
public abstract int getReturnState(int index);
/** This means only the {@link #EMPTY} context is in set */
/** This means only the {@link #EMPTY} context is in set. */
public boolean isEmpty() {
return this == EMPTY;
}
@ -153,7 +158,42 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
rootIsWildcard, mergeCache);
}
// http://www.antlr.org/wiki/download/attachments/32014352/singleton-merge.png
/**
* Merge two {@link SingletonPredictionContext} instances.
*
* <p/>
*
* Stack tops equal, parents merge is same; return left graph.<br/>
* <embed src="images/SingletonMerge_SameRootSamePar.svg" type="image/svg+xml"/>
*
* <p/>
*
* Same stack top, parents differ; merge parents giving array node, then
* remainders of those graphs. A new root node is created to point to the
* merged parents.<br/>
* <embed src="images/SingletonMerge_SameRootDiffPar.svg" type="image/svg+xml"/>
*
* <p/>
*
* Different stack tops pointing to same parent. Make array node for the
* root where both element in the root point to the same (original)
* parent.<br/>
* <embed src="images/SingletonMerge_DiffRootSamePar.svg" type="image/svg+xml"/>
*
* <p/>
*
* Different stack tops pointing to different parents. Make array node for
* the root where each element points to the corresponding original
* parent.<br/>
* <embed src="images/SingletonMerge_DiffRootDiffPar.svg" type="image/svg+xml"/>
*
* @param a the first {@link SingletonPredictionContext}
* @param b the second {@link SingletonPredictionContext}
* @param rootIsWildcard {@code true} if this is a local-context merge,
* otherwise false to indicate a full-context merge
* @param mergeCache
* @return
*/
public static PredictionContext mergeSingletons(
SingletonPredictionContext a,
SingletonPredictionContext b,
@ -220,9 +260,56 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
}
}
// http://www.antlr.org/wiki/download/attachments/32014352/local-ctx-root-merge.png
// http://www.antlr.org/wiki/download/attachments/32014352/full-ctx-root-merge.png
/** Handle case where at least one of a or b is $ (EMPTY) */
/**
* Handle case where at least one of {@code a} or {@code b} is
* {@link #EMPTY}. In the following diagrams, the symbol {@code $} is used
* to represent {@link #EMPTY}.
*
* <h2>Local-Context Merges</h2>
*
* These local-context merge operations are used when {@code rootIsWildcard}
* is true.
*
* <p/>
*
* {@link #EMPTY} is superset of any graph; return {@link #EMPTY}.<br/>
* <embed src="images/LocalMerge_EmptyRoot.svg" type="image/svg+xml"/>
*
* <p/>
*
* {@link #EMPTY} and anything is {@code #EMPTY}, so merged parent is
* {@code #EMPTY}; return left graph.<br/>
* <embed src="images/LocalMerge_EmptyParent.svg" type="image/svg+xml"/>
*
* <p/>
*
* Special case of last merge if local context.<br/>
* <embed src="images/LocalMerge_DiffRoots.svg" type="image/svg+xml"/>
*
* <h2>Full-Context Merges</h2>
*
* These full-context merge operations are used when {@code rootIsWildcard}
* is false.
*
* <p/>
*
* <embed src="images/FullMerge_EmptyRoots.svg" type="image/svg+xml"/>
*
* <p/>
*
* Must keep all contexts; {@link #EMPTY} in array is a special value (and
* null parent).<br/>
* <embed src="images/FullMerge_EmptyRoot.svg" type="image/svg+xml"/>
*
* <p/>
*
* <embed src="images/FullMerge_SameRoot.svg" type="image/svg+xml"/>
*
* @param a the first {@link SingletonPredictionContext}
* @param b the second {@link SingletonPredictionContext}
* @param rootIsWildcard {@code true} if this is a local-context merge,
* otherwise false to indicate a full-context merge
*/
public static PredictionContext mergeRoot(SingletonPredictionContext a,
SingletonPredictionContext b,
boolean rootIsWildcard)
@ -251,7 +338,35 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
return null;
}
// http://www.antlr.org/wiki/download/attachments/32014352/array-merge.png
/**
* Merge two {@link ArrayPredictionContext} instances.
*
* <p/>
*
* Different tops, different parents.<br/>
* <embed src="images/ArrayMerge_DiffTopDiffPar.svg" type="image/svg+xml"/>
*
* <p/>
*
* Shared top, same parents.<br/>
* <embed src="images/ArrayMerge_ShareTopSamePar.svg" type="image/svg+xml"/>
*
* <p/>
*
* Shared top, different parents.<br/>
* <embed src="images/ArrayMerge_ShareTopDiffPar.svg" type="image/svg+xml"/>
*
* <p/>
*
* Shared top, all shared parents.<br/>
* <embed src="images/ArrayMerge_ShareTopSharePar.svg" type="image/svg+xml"/>
*
* <p/>
*
* Equal tops, merge parents and reduce top to
* {@link SingletonPredictionContext}.<br/>
* <embed src="images/ArrayMerge_EqualTop.svg" type="image/svg+xml"/>
*/
public static PredictionContext mergeArrays(
ArrayPredictionContext a,
ArrayPredictionContext b,
@ -361,7 +476,10 @@ public abstract class PredictionContext implements Iterable<SingletonPredictionC
return M;
}
/** make pass over all M parents; merge any equals() ones */
/**
* Make pass over all <em>M</em> {@code parents}; merge any {@code equals()}
* ones.
*/
protected static void combineCommonParents(PredictionContext[] parents) {
Map<PredictionContext, PredictionContext> uniqueParents =
new HashMap<PredictionContext, PredictionContext>();

View File

@ -835,6 +835,3 @@ initValue(typeName) ::= <<
>>
codeFileExtension() ::= ".java"
true() ::= "true"
false() ::= "false"