Merge pull request #1 from sharwell/master

Many small changes here.
This commit is contained in:
Terence Parr 2012-02-08 17:54:55 -08:00
commit 460e4495b4
23 changed files with 364 additions and 170 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/tool/target/
/runtime/Java/target/
/gunit/target/

80
gunit/pom.xml Normal file
View File

@ -0,0 +1,80 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.antlr</groupId>
<artifactId>antlr4-gunit</artifactId>
<version>4.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>antlr4-gunit</name>
<url>http://www.antlr.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-runtime</artifactId>
<version>3.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>ST4</artifactId>
<version>4.0.4</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr3-maven-plugin</artifactId>
<version>3.4</version>
<configuration>
<sourceDirectory>src</sourceDirectory>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<goals>
<goal>antlr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

50
runtime/Java/pom.xml Normal file
View File

@ -0,0 +1,50 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>4.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>antlr4-runtime</name>
<url>http://www.antlr.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>ST4</artifactId>
<version>4.0.4-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.abego</groupId>
<artifactId>treelayout.core</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/org.abego.treelayout.core.jar</systemPath>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,6 +1,7 @@
package org.antlr.v4.runtime;
import org.antlr.v4.runtime.atn.ATNConfig;
import org.antlr.v4.runtime.atn.ATNConfigSet;
import org.antlr.v4.runtime.atn.DecisionState;
import org.antlr.v4.runtime.atn.SemanticContext;
import org.antlr.v4.runtime.dfa.DFA;
@ -125,12 +126,12 @@ public interface ANTLRErrorStrategy {
*/
void reportAmbiguity(@NotNull Parser recognizer,
DFA dfa, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
@NotNull OrderedHashSet<ATNConfig> configs);
@NotNull ATNConfigSet configs);
void reportAttemptingFullContext(@NotNull Parser recognizer,
@NotNull DFA dfa,
int startIndex, int stopIndex,
@NotNull OrderedHashSet<ATNConfig> configs);
@NotNull ATNConfigSet configs);
/** Called by the parser when it find a conflict that is resolved by retrying the parse
* with full context. This is not a warning; it simply notifies you that your grammar
@ -140,7 +141,7 @@ public interface ANTLRErrorStrategy {
void reportContextSensitivity(@NotNull Parser recognizer,
@NotNull DFA dfa,
int startIndex, int stopIndex,
@NotNull OrderedHashSet<ATNConfig> configs);
@NotNull ATNConfigSet configs);
/** Called by the parser when it finds less than n-1 predicates for n ambiguous alternatives.
* If there are n-1, we assume that the missing predicate is !(the "or" of the other predicates).
@ -152,5 +153,5 @@ public interface ANTLRErrorStrategy {
int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
DecisionState decState,
@NotNull SemanticContext[] altToPred,
@NotNull OrderedHashSet<ATNConfig> configs, boolean fullContextParse);
@NotNull ATNConfigSet configs, boolean fullContextParse);
}

View File

@ -81,9 +81,7 @@ public class BufferedTokenStream<T extends Token> implements TokenStream {
@Override
public int mark() {
if ( p == -1 ) setup();
lastMarker = index();
return lastMarker;
return 0;
}
@Override
@ -91,14 +89,6 @@ public class BufferedTokenStream<T extends Token> implements TokenStream {
// no resources to release
}
public void rewind(int marker) {
seek(marker);
}
public void rewind() {
seek(lastMarker);
}
public void reset() {
p = 0;
lastMarker = 0;

View File

@ -83,6 +83,12 @@ public class CommonTokenStream extends BufferedTokenStream<CommonToken> {
}
}
@Override
public void reset() {
super.reset();
p = skipOffTokenChannels(p);
}
@Override
protected CommonToken LB(int k) {
if ( k==0 || (p-k)<0 ) return null;

View File

@ -554,7 +554,7 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
@Override
public void reportAmbiguity(@NotNull Parser recognizer,
DFA dfa, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
@NotNull OrderedHashSet<ATNConfig> configs)
@NotNull ATNConfigSet configs)
{
}
@ -562,13 +562,13 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
public void reportAttemptingFullContext(@NotNull Parser recognizer,
@NotNull DFA dfa,
int startIndex, int stopIndex,
@NotNull OrderedHashSet<ATNConfig> configs)
@NotNull ATNConfigSet configs)
{
}
@Override
public void reportContextSensitivity(@NotNull Parser recognizer, @NotNull DFA dfa,
int startIndex, int stopIndex, @NotNull OrderedHashSet<ATNConfig> configs)
int startIndex, int stopIndex, @NotNull ATNConfigSet configs)
{
}
@ -579,7 +579,7 @@ public class DefaultErrorStrategy implements ANTLRErrorStrategy {
@NotNull IntervalSet ambigAlts,
DecisionState decState,
@NotNull SemanticContext[] altToPred,
@NotNull OrderedHashSet<ATNConfig> configs, boolean fullContextParse)
@NotNull ATNConfigSet configs, boolean fullContextParse)
{
}
}

View File

@ -30,6 +30,7 @@
package org.antlr.v4.runtime;
import org.antlr.v4.runtime.atn.ATNConfig;
import org.antlr.v4.runtime.atn.ATNConfigSet;
import org.antlr.v4.runtime.atn.DecisionState;
import org.antlr.v4.runtime.atn.SemanticContext;
import org.antlr.v4.runtime.dfa.DFA;
@ -43,7 +44,7 @@ public class DiagnosticErrorStrategy extends DefaultErrorStrategy {
@Override
public void reportAmbiguity(@NotNull Parser recognizer,
DFA dfa, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts,
@NotNull OrderedHashSet<ATNConfig> configs)
@NotNull ATNConfigSet configs)
{
recognizer.notifyErrorListeners("reportAmbiguity d=" + dfa.decision + ": ambigAlts=" + ambigAlts + ":" + configs + ", input='" +
recognizer.getInputString(startIndex, stopIndex) + "'");
@ -53,7 +54,7 @@ public class DiagnosticErrorStrategy extends DefaultErrorStrategy {
public void reportAttemptingFullContext(@NotNull Parser recognizer,
@NotNull DFA dfa,
int startIndex, int stopIndex,
@NotNull OrderedHashSet<ATNConfig> configs)
@NotNull ATNConfigSet configs)
{
recognizer.notifyErrorListeners("reportAttemptingFullContext d=" + dfa.decision + ": " + configs + ", input='" +
recognizer.getInputString(startIndex, stopIndex) + "'");
@ -61,7 +62,7 @@ public class DiagnosticErrorStrategy extends DefaultErrorStrategy {
@Override
public void reportContextSensitivity(@NotNull Parser recognizer, @NotNull DFA dfa,
int startIndex, int stopIndex, @NotNull OrderedHashSet<ATNConfig> configs)
int startIndex, int stopIndex, @NotNull ATNConfigSet configs)
{
recognizer.notifyErrorListeners("reportContextSensitivity d=" + dfa.decision + ": " + configs + ", input='" +
recognizer.getInputString(startIndex, stopIndex) + "'");
@ -74,7 +75,7 @@ public class DiagnosticErrorStrategy extends DefaultErrorStrategy {
@NotNull IntervalSet ambigAlts,
DecisionState decState,
@NotNull SemanticContext[] altToPred,
@NotNull OrderedHashSet<ATNConfig> configs, boolean fullContextParse)
@NotNull ATNConfigSet configs, boolean fullContextParse)
{
recognizer.notifyErrorListeners("reportInsufficientPredicates d=" + dfa.decision + ", decState=" + decState +
", ambigAlts=" + ambigAlts + ":" + Arrays.toString(altToPred) +

View File

@ -29,20 +29,19 @@
package org.antlr.v4.runtime;
import org.antlr.v4.runtime.atn.ATNConfig;
import org.antlr.v4.runtime.misc.OrderedHashSet;
import org.antlr.v4.runtime.atn.ATNConfigSet;
public class LexerNoViableAltException extends RecognitionException {
/** Matching attempted at what input index? */
public int startIndex;
/** Which configurations did we try at input.index() that couldn't match input.LA(1)? */
public OrderedHashSet<ATNConfig> deadEndConfigs;
public ATNConfigSet deadEndConfigs;
public LexerNoViableAltException(Lexer lexer,
CharStream input,
int startIndex,
OrderedHashSet<ATNConfig> deadEndConfigs) {
ATNConfigSet deadEndConfigs) {
super(lexer, input, null);
this.startIndex = startIndex;
this.deadEndConfigs = deadEndConfigs;

View File

@ -28,15 +28,14 @@
*/
package org.antlr.v4.runtime;
import org.antlr.v4.runtime.atn.ATNConfig;
import org.antlr.v4.runtime.misc.OrderedHashSet;
import org.antlr.v4.runtime.atn.ATNConfigSet;
/** The parser could not decide which path in the decision to take based
* upon the remaining input.
*/
public class NoViableAltException extends RecognitionException {
/** Which configurations did we try at input.index() that couldn't match input.LT(1)? */
public OrderedHashSet<ATNConfig> deadEndConfigs;
public ATNConfigSet deadEndConfigs;
/** The token object at the start index; the input stream might
* not be buffering tokens so get a reference to it. (At the
@ -57,8 +56,8 @@ public class NoViableAltException extends RecognitionException {
SymbolStream<Symbol> input,
Token startToken,
Token offendingToken,
OrderedHashSet<ATNConfig> deadEndConfigs,
ParserRuleContext ctx)
ATNConfigSet deadEndConfigs,
ParserRuleContext<?> ctx)
{
super(recognizer, input, ctx);
this.deadEndConfigs = deadEndConfigs;

View File

@ -80,7 +80,7 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator<Token>
/** Did the recognizer encounter a syntax error? Track how many. */
protected int _syntaxErrors = 0;
public Parser(IntStream input) {
public Parser(TokenStream input) {
setInputStream(input);
}
@ -299,7 +299,7 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator<Token>
}
protected void addContextToParseTree() {
ParserRuleContext parent = (ParserRuleContext)_ctx.parent;
ParserRuleContext<?> parent = (ParserRuleContext<?>)_ctx.parent;
// add current context to parent if we have a parent
if ( parent!=null ) {
parent.addChild(_ctx);
@ -331,7 +331,7 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator<Token>
// if we have new localctx, make sure we replace existing ctx
// that is previous child of parse tree
if ( _buildParseTrees && _ctx != localctx ) {
ParserRuleContext parent = (ParserRuleContext)_ctx.parent;
ParserRuleContext<?> parent = (ParserRuleContext<?>)_ctx.parent;
parent.removeLastChild();
if ( parent!=null ) parent.addChild(localctx);
}
@ -385,7 +385,7 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator<Token>
public boolean isExpectedToken(int symbol) {
// return getInterpreter().atn.nextTokens(_ctx);
ATN atn = getInterpreter().atn;
ParserRuleContext ctx = _ctx;
ParserRuleContext<?> ctx = _ctx;
ATNState s = atn.states.get(ctx.s);
IntervalSet following = atn.nextTokens(s);
if (following.contains(symbol)) {
@ -402,7 +402,7 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator<Token>
return true;
}
ctx = (ParserRuleContext)ctx.parent;
ctx = (ParserRuleContext<?>)ctx.parent;
}
if ( following.contains(Token.EPSILON) && symbol == Token.EOF ) {
@ -417,7 +417,7 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator<Token>
*/
public IntervalSet getExpectedTokens() {
ATN atn = getInterpreter().atn;
ParserRuleContext ctx = _ctx;
ParserRuleContext<?> ctx = _ctx;
ATNState s = atn.states.get(ctx.s);
IntervalSet following = atn.nextTokens(s);
// System.out.println("following "+s+"="+following);
@ -431,7 +431,7 @@ public abstract class Parser extends Recognizer<Token, ParserATNSimulator<Token>
following = atn.nextTokens(rt.followState);
expected.addAll(following);
expected.remove(Token.EPSILON);
ctx = (ParserRuleContext)ctx.parent;
ctx = (ParserRuleContext<?>)ctx.parent;
}
if ( following.contains(Token.EPSILON) ) {
expected.add(Token.EOF);

View File

@ -74,21 +74,19 @@ public class ATNConfig {
public int lexerActionIndex = -1; // TOOD: move to subclass
@NotNull
public SemanticContext semanticContext = SemanticContext.NONE;
public final SemanticContext semanticContext;
public ATNConfig(@NotNull ATNState state,
int alt,
@Nullable RuleContext context)
{
this.state = state;
this.alt = alt;
this.context = context;
this(state, alt, context, SemanticContext.NONE);
}
public ATNConfig(@NotNull ATNState state,
int alt,
@Nullable RuleContext context,
SemanticContext semanticContext)
@NotNull SemanticContext semanticContext)
{
this.state = state;
this.alt = alt;
@ -100,7 +98,7 @@ public class ATNConfig {
this(c, state, c.context, c.semanticContext);
}
public ATNConfig(@NotNull ATNConfig c, @NotNull ATNState state, SemanticContext semanticContext) {
public ATNConfig(@NotNull ATNConfig c, @NotNull ATNState state, @NotNull SemanticContext semanticContext) {
this(c, state, c.context, semanticContext);
}
@ -109,7 +107,7 @@ public class ATNConfig {
}
public ATNConfig(@NotNull ATNConfig c, @NotNull ATNState state, @Nullable RuleContext context,
SemanticContext semanticContext)
@NotNull SemanticContext semanticContext)
{
this.state = state;
this.alt = c.alt;
@ -119,36 +117,40 @@ public class ATNConfig {
this.lexerActionIndex = c.lexerActionIndex;
}
// public ATNConfig(@NotNull ATNConfig c, @Nullable RuleContext context) {
// this(c, c.state, context);
// }
/** An ATN configuration is equal to another if both have
* the same state, they predict the same alternative, and
* syntactic/semantic contexts are the same.
*/
@Override
public boolean equals(Object o) {
if ( o==null ) return false;
if ( this==o ) return true;
if (!(o instanceof ATNConfig)) {
return false;
}
ATNConfig other = (ATNConfig)o;
return
this.state.stateNumber==other.state.stateNumber &&
this.alt==other.alt &&
(this.context==other.context || (this.context != null && this.context.equals(other.context))) &&
(this.semanticContext==other.semanticContext || (this.semanticContext != null && this.semanticContext.equals(other.semanticContext)));
return this.equals((ATNConfig)o);
}
}
public boolean equals(ATNConfig other) {
if (this == other) {
return true;
} else if (other == null) {
return false;
}
@Override
public int hashCode() {
int h = state.stateNumber + alt + (semanticContext!=null ? semanticContext.hashCode() : 0);
if ( context!=null ) h += context.hashCode();
return h;
return this.state.stateNumber==other.state.stateNumber
&& this.alt==other.alt
&& (this.context==other.context || (this.context != null && this.context.equals(other.context)))
&& this.semanticContext.equals(other.semanticContext);
}
@Override
public int hashCode() {
int hashCode = 7;
hashCode = 5 * hashCode + state.stateNumber;
hashCode = 5 * hashCode + alt;
hashCode = 5 * hashCode + (context != null ? context.hashCode() : 0);
hashCode = 5 * hashCode + semanticContext.hashCode();
return hashCode;
}
@Override

View File

@ -44,7 +44,7 @@ public class LexerATNSimulator extends ATNSimulator {
public static boolean debug = false;
public static boolean dfa_debug = false;
public static final int NUM_EDGES = 255; // forces unicode to stay in ATN
public static final int MAX_DFA_EDGE = 127; // forces unicode to stay in ATN
private boolean trace = false;
private OutputStream traceStream = null;
@ -288,8 +288,7 @@ public class LexerATNSimulator extends ATNSimulator {
System.out.format("in reach starting closure: %s\n", closure);
}
for (int ci=0; ci<closure.size(); ci++) { // TODO: foreach
ATNConfig c = closure.get(ci);
for (ATNConfig c : closure) {
if ( debug ) {
System.out.format("testing %s at %s\n", getTokenName(t), c.toString(recog, true));
}
@ -304,7 +303,7 @@ public class LexerATNSimulator extends ATNSimulator {
}
}
if ( reach.size()==0 ) {
if ( reach.isEmpty() ) {
// we reached state associated with closure for sure, so
// make sure it's defined. worst case, we define s0 from
// start state configs.
@ -575,7 +574,7 @@ public class LexerATNSimulator extends ATNSimulator {
@NotNull ATNConfigSet q)
{
// even if we can add the states, we can't add an edge for labels out of range
if (t < 0 || t > NUM_EDGES) {
if (t < 0 || t > MAX_DFA_EDGE) {
return;
}
@ -594,10 +593,10 @@ public class LexerATNSimulator extends ATNSimulator {
}
protected void addDFAEdge(@NotNull DFAState p, int t, @NotNull DFAState q) {
if (t < 0 || t > NUM_EDGES) return; // Only track edges within the DFA bounds
if (t < 0 || t > MAX_DFA_EDGE) return; // Only track edges within the DFA bounds
if ( p.edges==null ) {
// make room for tokens 1..n and -1 masquerading as index 0
p.edges = new DFAState[NUM_EDGES+1]; // TODO: make adaptive
p.edges = new DFAState[MAX_DFA_EDGE+1]; // TODO: make adaptive
}
// if ( t==Token.EOF ) {
// System.out.println("state "+p+" has EOF edge");

View File

@ -32,6 +32,7 @@ package org.antlr.v4.runtime.atn;
import org.antlr.v4.runtime.Parser;
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.RuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.runtime.misc.NotNull;
@ -43,7 +44,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ParserATNPathFinder extends ParserATNSimulator {
public class ParserATNPathFinder extends ParserATNSimulator<Token> {
public ParserATNPathFinder(@Nullable Parser parser, @NotNull ATN atn) {
super(parser, atn);
}

View File

@ -83,6 +83,7 @@ public abstract class SemanticContext {
this.isCtxDependent = isCtxDependent;
}
@Override
public boolean eval(Recognizer<?,?> parser, RuleContext outerContext) {
RuleContext localctx = isCtxDependent ? outerContext : null;
return parser.sempred(localctx, ruleIndex, predIndex);
@ -90,7 +91,11 @@ public abstract class SemanticContext {
@Override
public int hashCode() {
return ruleIndex + predIndex;
int hashCode = 1;
hashCode = 31 * hashCode + ruleIndex;
hashCode = 31 * hashCode + predIndex;
hashCode = 31 * hashCode + (isCtxDependent ? 1 : 0);
return hashCode;
}
@Override
@ -103,6 +108,7 @@ public abstract class SemanticContext {
this.isCtxDependent == p.isCtxDependent;
}
@Override
public String toString() {
return "{"+ruleIndex+":"+predIndex+"}?";
}
@ -131,6 +137,7 @@ public abstract class SemanticContext {
return opnds.hashCode();
}
@Override
public boolean eval(Recognizer<?,?> parser, RuleContext outerContext) {
for (SemanticContext opnd : opnds) {
if ( !opnd.eval(parser, outerContext) ) return false;
@ -138,6 +145,7 @@ public abstract class SemanticContext {
return true;
}
@Override
public String toString() {
return Utils.join(opnds.iterator(), "&&");
}
@ -166,6 +174,7 @@ public abstract class SemanticContext {
return opnds.hashCode() + 1; // differ from AND slightly
}
@Override
public boolean eval(Recognizer<?,?> parser, RuleContext outerContext) {
for (SemanticContext opnd : opnds) {
if ( opnd.eval(parser, outerContext) ) return true;

View File

@ -150,7 +150,7 @@ public class DFAState {
for (ATNConfig c : configset) {
alts.add(c.alt);
}
if ( alts.size()==0 ) return null;
if ( alts.isEmpty() ) return null;
return alts;
}

View File

@ -363,7 +363,7 @@ public class IntervalSet implements IntSet {
/** return true if this set has no members */
@Override
public boolean isNil() {
return intervals==null || intervals.size()==0;
return intervals==null || intervals.isEmpty();
}
/** If this set is a single integer, return it otherwise Token.INVALID_TYPE */
@ -422,6 +422,7 @@ public class IntervalSet implements IntSet {
* to make sure they are the same. Interval.equals() is used
* by the List.equals() method to check the ranges.
*/
@Override
public boolean equals(Object obj) {
if ( obj==null || !(obj instanceof IntervalSet) ) {
return false;
@ -430,11 +431,12 @@ public class IntervalSet implements IntSet {
return this.intervals.equals(other.intervals);
}
@Override
public String toString() { return toString(false); }
public String toString(boolean elemAreChar) {
StringBuffer buf = new StringBuffer();
if ( this.intervals==null || this.intervals.size()==0 ) {
StringBuilder buf = new StringBuilder();
if ( this.intervals==null || this.intervals.isEmpty() ) {
return "{}";
}
if ( this.size()>1 ) {
@ -447,12 +449,12 @@ public class IntervalSet implements IntSet {
int b = I.b;
if ( a==b ) {
if ( a==-1 ) buf.append("<EOF>");
else if ( elemAreChar ) buf.append("'"+(char)a+"'");
else if ( elemAreChar ) buf.append("'").append((char)a).append("'");
else buf.append(a);
}
else {
if ( elemAreChar ) buf.append("'"+(char)a+"'..'"+(char)b+"'");
else buf.append(a+".."+b);
if ( elemAreChar ) buf.append("'").append((char)a).append("'..'").append((char)b).append("'");
else buf.append(a).append("..").append(b);
}
if ( iter.hasNext() ) {
buf.append(", ");
@ -465,8 +467,8 @@ public class IntervalSet implements IntSet {
}
public String toString(String[] tokenNames) {
StringBuffer buf = new StringBuffer();
if ( this.intervals==null || this.intervals.size()==0 ) {
StringBuilder buf = new StringBuilder();
if ( this.intervals==null || this.intervals.isEmpty() ) {
return "{}";
}
if ( this.size()>1 ) {

87
tool/pom.xml Normal file
View File

@ -0,0 +1,87 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.antlr</groupId>
<artifactId>antlr4</artifactId>
<version>4.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>antlr4</name>
<url>http://www.antlr.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-runtime</artifactId>
<version>3.4.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>ST4</artifactId>
<version>4.0.4</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-gunit</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>resources</directory>
</resource>
</resources>
<testSourceDirectory>test</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.antlr</groupId>
<artifactId>antlr3-maven-plugin</artifactId>
<version>3.4</version>
<configuration>
<sourceDirectory>src</sourceDirectory>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<goals>
<goal>antlr</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -50,9 +50,9 @@ public class Blank<file.grammarName>Listener implements <file.grammarName>Listen
@Override public void enterRule(<file.parserName>.<lname>Context ctx) { \}
@Override public void exitRule(<file.parserName>.<lname>Context ctx) { \}}; separator="\n">
@Override public void enterEveryRule(ParserRuleContext\<<InputSymbolType()> > ctx) { }
@Override public void exitEveryRule(ParserRuleContext\<<InputSymbolType()> > ctx) { }
@Override public void visitTerminal(ParserRuleContext\<<InputSymbolType()> > ctx, <InputSymbolType()> symbol) { }
@Override public void enterEveryRule(ParserRuleContext\<<InputSymbolType()>\> ctx) { }
@Override public void exitEveryRule(ParserRuleContext\<<InputSymbolType()>\> ctx) { }
@Override public void visitTerminal(ParserRuleContext\<<InputSymbolType()>\> ctx, <InputSymbolType()> symbol) { }
}
>>
@ -61,7 +61,7 @@ Parser(parser, funcs, atn, sempredFuncs, superclass) ::= <<
>>
Parser_(parser, funcs, atn, sempredFuncs, ctor, extras, superclass) ::= <<
@SuppressWarnings({"all", "warnings", "unchecked", "unused"})
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class <parser.name> extends <superclass> {
<if(parser.tokens)>
public static final int
@ -182,22 +182,22 @@ RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAc
>>
LeftRecursiveRuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,
namedActions,finallyAction,postamble) ::=
namedActions,finallyAction,postamble) ::=
<<
<ruleCtx>
<altLabelCtxs; separator="\n">
<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.name>(<currentRule.args; separator=",">) throws RecognitionException {
ParserRuleContext\<Token> _parentctx = _ctx;
ParserRuleContext\<Token> _parentctx = _ctx;
<currentRule.ctxType> _localctx = new <currentRule.ctxType>(_ctx, <currentRule.startState><currentRule.args:{a | , <a.name>}>);
<currentRule.ctxType> _prevctx = _localctx;
int _startState = <currentRule.startState>;
pushNewRecursionContext(_localctx, RULE_<currentRule.name>);
pushNewRecursionContext(_localctx, RULE_<currentRule.name>);
<namedActions.init>
<locals; separator="\n">
try {
<code>
<code>
_localctx.stop = _input.LT(-1);
<postamble; separator="\n">
<namedActions.after>
@ -355,10 +355,10 @@ setState(<choice.stateNumber>);
_errHandler.sync(this);
int _alt<choice.uniqueID> = getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx);
while ( _alt<choice.uniqueID>!=<choice.exitAlt> && _alt<choice.uniqueID>!=-1 ) {
if ( _alt<choice.uniqueID>==1 ) {
<iteration>
<alts> <! should only be one !>
}
if ( _alt<choice.uniqueID>==1 ) {
<iteration>
<alts> <! should only be one !>
}
setState(<choice.loopBackStateNumber>);
_errHandler.sync(this);
_alt<choice.uniqueID> = getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx);
@ -511,8 +511,8 @@ StructDecl(s,attrs,visitorDispatchMethods,interfaces,extensionMembers,
superClass={ParserRuleContext\<<InputSymbolType()>>}) ::= <<
public static class <s.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> {
<attrs:{a | public <a>;}; separator="\n">
<if(s.ctorAttrs)>public <s.name>(ParserRuleContext parent, int state) { super(parent, state); }<endif>
public <s.name>(ParserRuleContext parent, int state<s.ctorAttrs:{a | , <a>}>) {
<if(s.ctorAttrs)>public <s.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state) { super(parent, state); }<endif>
public <s.name>(ParserRuleContext\<<InputSymbolType()>\> parent, int state<s.ctorAttrs:{a | , <a>}>) {
super(parent, state);
<s.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n">
}
@ -560,6 +560,7 @@ _localctx = new <ctxName>Context(_parentctx, _startState, _p);
_localctx.addChild(_prevctx);
<if(label)>_localctx.<label> = _prevctx;<endif>
pushNewRecursionContext(_localctx, RULE_<ruleName>);
_localctx.start = _prevctx.start;
>>
recRuleLabeledAltStartAction(ruleName, ctxName, label) ::= <<
@ -567,6 +568,7 @@ _localctx = new <ctxName>Context(new <ruleName>Context(_parentctx, _startState,
_localctx.addChild(_prevctx);
<if(label)>_localctx.<label> = _prevctx;<endif>
pushNewRecursionContext(_localctx, RULE_<ruleName>);
_localctx.start = _prevctx.start;
>>
recRuleReplaceContext(ctxName) ::= <<
@ -578,6 +580,7 @@ _prevctx = _localctx;
recRuleSetPrevCtx() ::= <<
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
_prevctx.stop = _input.LT(-1);
>>
@ -597,14 +600,14 @@ import org.antlr.v4.runtime.misc.*;
>>
Lexer(lexer, atn, actionFuncs, sempredFuncs) ::= <<
@SuppressWarnings({"all", "warnings", "unchecked", "unused"})
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class <lexer.name> extends Lexer {
public static final int
<lexer.tokens:{k | <k>=<lexer.tokens.(k)>}; separator=", ", wrap, anchor>;
<rest(lexer.modes):{m| public static final int <m> = <i>;}; separator="\n">
public static String[] modeNames = {
<lexer.modes:{m| "<m>"}; separator=", ", wrap, anchor>
};
public static String[] modeNames = {
<lexer.modes:{m| "<m>"}; separator=", ", wrap, anchor>
};
public static final String[] tokenNames = {
"\<INVALID>", "\<INVALID>", "\<INVALID>",
@ -645,7 +648,7 @@ public class <lexer.name> extends Lexer {
SerializedATN(model) ::= <<
public static final String _serializedATN =
"<model.serialized; wrap={"+<\n>"}, anchor>";
"<model.serialized; wrap={"+<\n><\t>"}>";
public static final ATN _ATN =
ATNSimulator.deserialize(_serializedATN.toCharArray());
static {

View File

@ -32,10 +32,11 @@ package org.antlr.v4.analysis;
import org.antlr.v4.runtime.atn.DecisionState;
import org.antlr.v4.runtime.atn.LL1Analyzer;
import org.antlr.v4.runtime.misc.IntervalSet;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.tool.Grammar;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Vector;
public class AnalysisPipeline {
public Grammar g;
@ -56,14 +57,14 @@ public class AnalysisPipeline {
void processParserOrTreeParser() {
g.decisionLOOK =
new Vector<IntervalSet[]>(g.atn.getNumberOfDecisions()+1);
new ArrayList<IntervalSet[]>(g.atn.getNumberOfDecisions()+1);
for (DecisionState s : g.atn.decisionToState) {
g.tool.log("LL1", "\nDECISION "+s.decision+" in rule "+g.getRule(s.ruleIndex).name);
LL1Analyzer anal = new LL1Analyzer(g.atn);
IntervalSet[] look = anal.getDecisionLookahead(s);
g.tool.log("LL1", "look=" + Arrays.toString(look));
g.decisionLOOK.setSize(s.decision+1);
Utils.setSize(g.decisionLOOK, s.decision+1);
g.decisionLOOK.set(s.decision, look);
g.tool.log("LL1", "LL(1)? " + disjoint(look));
}

View File

@ -109,11 +109,11 @@ public class DOTGenerator {
protected String getStateLabel(DFAState s) {
if ( s==null ) return "null";
StringBuffer buf = new StringBuffer(250);
StringBuilder buf = new StringBuilder(250);
buf.append('s');
buf.append(s.stateNumber);
if ( s.isAcceptState ) {
buf.append("=>"+s.prediction);
buf.append("=>").append(s.prediction);
}
if ( grammar!=null && grammar.tool.verbose_dfa ) {
Set<Integer> alts = s.getAltSet();
@ -135,8 +135,8 @@ public class DOTGenerator {
// get a list of configs for just this alt
// it will help us print better later
List<ATNConfig> configsInAlt = new ArrayList<ATNConfig>();
for (Iterator it = configurations.iterator(); it.hasNext();) {
ATNConfig c = (ATNConfig) it.next();
for (Iterator<ATNConfig> it = configurations.iterator(); it.hasNext();) {
ATNConfig c = it.next();
if ( c.alt!=alt ) continue;
configsInAlt.add(c);
}
@ -179,9 +179,8 @@ public class DOTGenerator {
if ( startState==null ) return null;
// The output DOT graph for visualization
ST dot = null;
Set<ATNState> markedStates = new HashSet<ATNState>();
dot = stlib.getInstanceOf("atn");
ST dot = stlib.getInstanceOf("atn");
dot.add("startState", startState.stateNumber);
dot.add("rankdir", rankdir);
@ -211,7 +210,7 @@ public class DOTGenerator {
// }
// make a DOT edge for each transition
ST edgeST = null;
ST edgeST;
for (int i = 0; i < s.getNumberOfTransitions(); i++) {
Transition edge = s.transition(i);
if ( edge instanceof RuleTransition ) {

View File

@ -36,6 +36,7 @@ import org.antlr.runtime.tree.TreeWizard;
import org.antlr.v4.Tool;
import org.antlr.v4.misc.CharSupport;
import org.antlr.v4.misc.OrderedHashMap;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.parse.GrammarASTAdaptor;
import org.antlr.v4.parse.GrammarTreeVisitor;
@ -105,7 +106,7 @@ public class Grammar implements AttributeResolver {
public Map<Integer, DFA> decisionDFAs = new HashMap<Integer, DFA>();
public Vector<IntervalSet[]> decisionLOOK;
public List<IntervalSet[]> decisionLOOK;
@NotNull
public final Tool tool;
@ -130,12 +131,12 @@ public class Grammar implements AttributeResolver {
public Map<String, Integer> stringLiteralToTypeMap = new LinkedHashMap<String, Integer>();
/** Reverse index for stringLiteralToTypeMap. Indexed with raw token type.
* 0 is invalid. */
public Vector<String> typeToStringLiteralList = new Vector<String>();
public List<String> typeToStringLiteralList = new ArrayList<String>();
/** Map a token type to its token name. Indexed with raw token type.
* 0 is invalid.
*/
public Vector<String> typeToTokenList = new Vector<String>();
public List<String> typeToTokenList = new ArrayList<String>();
/** Map a name to an action.
* The code generator will use this to fill holes in the output files.
@ -538,7 +539,7 @@ public class Grammar implements AttributeResolver {
// this.tokenNameToTypeMap.putAll( importG.tokenNameToTypeMap );
// this.stringLiteralToTypeMap.putAll( importG.stringLiteralToTypeMap );
int max = Math.max(this.typeToTokenList.size(), importG.typeToTokenList.size());
this.typeToTokenList.setSize(max);
Utils.setSize(typeToTokenList, max);
for (int ttype=0; ttype<importG.typeToTokenList.size(); ttype++) {
maxTokenType = Math.max(maxTokenType, ttype);
this.typeToTokenList.set(ttype, importG.typeToTokenList.get(ttype));
@ -573,7 +574,7 @@ public class Grammar implements AttributeResolver {
stringLiteralToTypeMap.put(lit, ttype);
// track in reverse index too
if ( ttype>=typeToStringLiteralList.size() ) {
typeToStringLiteralList.setSize(ttype+1);
Utils.setSize(typeToStringLiteralList, ttype+1);
}
typeToStringLiteralList.set(ttype, lit);
@ -592,7 +593,7 @@ public class Grammar implements AttributeResolver {
public void setTokenForType(int ttype, String text) {
if ( ttype>=typeToTokenList.size() ) {
typeToTokenList.setSize(ttype+1);
Utils.setSize(typeToTokenList, ttype+1);
}
String prevToken = typeToTokenList.get(ttype);
if ( prevToken==null || prevToken.charAt(0)=='\'' ) {

View File

@ -292,7 +292,7 @@ public abstract class BaseTest {
fileManager.getJavaFileObjectsFromFiles(files);
Iterable<String> compileOptions =
Arrays.asList("-d", tmpdir, "-cp", tmpdir+pathSep+CLASSPATH);
Arrays.asList("-g", "-d", tmpdir, "-cp", tmpdir+pathSep+CLASSPATH);
JavaCompiler.CompilationTask task =
compiler.getTask(null, fileManager, null, compileOptions, null,
@ -538,49 +538,10 @@ public abstract class BaseTest {
}
public String execRecognizer() {
try {
String inputFile = new File(tmpdir, "input").getAbsolutePath();
String[] args = new String[] {
"java", "-classpath", tmpdir+pathSep+CLASSPATH,
"Test", inputFile
};
//String cmdLine = "java -classpath "+CLASSPATH+pathSep+tmpdir+" Test " + new File(tmpdir, "input").getAbsolutePath();
//System.out.println("execParser: "+cmdLine);
Process process =
Runtime.getRuntime().exec(args, null, new File(tmpdir));
StreamVacuum stdoutVacuum = new StreamVacuum(process.getInputStream());
StreamVacuum stderrVacuum = new StreamVacuum(process.getErrorStream());
stdoutVacuum.start();
stderrVacuum.start();
process.waitFor();
stdoutVacuum.join();
stderrVacuum.join();
String output = stdoutVacuum.toString();
if ( stderrVacuum.toString().length()>0 ) {
this.stderrDuringParse = stderrVacuum.toString();
System.err.println("exec stderrVacuum: "+ stderrVacuum);
}
return output;
}
catch (Exception e) {
System.err.println("can't exec recognizer");
e.printStackTrace(System.err);
}
return null;
return execClass("Test");
}
public String execClass(String className) {
/* HOW TO GET STDOUT?
try {
ClassLoader cl_new = new DirectoryLoader(new File(tmpdir));
Class compiledClass = cl_new.loadClass(className);
Method m = compiledClass.getMethod("main");
m.invoke(null);
} catch (Exception ex) {
ex.printStackTrace(System.err);
}
*/
if (TEST_IN_SAME_PROCESS) {
PrintStream originalOut = System.out;
PrintStream originalErr = System.err;
@ -1097,22 +1058,22 @@ public abstract class BaseTest {
// override to track errors
public void assertEquals(String msg, Object a, Object b) { try {Assert.assertEquals(msg,a,b);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertEquals(Object a, Object b) { try {Assert.assertEquals(a,b);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertEquals(String msg, long a, long b) { try {Assert.assertEquals(msg,a,b);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertEquals(long a, long b) { try {Assert.assertEquals(a,b);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertEquals(String msg, Object expected, Object actual) { try {Assert.assertEquals(msg,expected,actual);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertEquals(Object expected, Object actual) { try {Assert.assertEquals(expected,actual);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertEquals(String msg, long expected, long actual) { try {Assert.assertEquals(msg,expected,actual);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertEquals(long expected, long actual) { try {Assert.assertEquals(expected,actual);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertTrue(String msg, boolean b) { try {Assert.assertTrue(msg,b);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertTrue(boolean b) { try {Assert.assertTrue(b);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertTrue(String message, boolean condition) { try {Assert.assertTrue(message,condition);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertTrue(boolean condition) { try {Assert.assertTrue(condition);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertFalse(String msg, boolean b) { try {Assert.assertFalse(msg,b);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertFalse(boolean b) { try {Assert.assertFalse(b);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertFalse(String message, boolean condition) { try {Assert.assertFalse(message,condition);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertFalse(boolean condition) { try {Assert.assertFalse(condition);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertNotNull(String msg, Object p) { try {Assert.assertNotNull(msg, p);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertNotNull(Object p) { try {Assert.assertNotNull(p);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertNotNull(String message, Object object) { try {Assert.assertNotNull(message, object);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertNotNull(Object object) { try {Assert.assertNotNull(object);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertNull(String msg, Object p) { try {Assert.assertNull(msg, p);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertNull(Object p) { try {Assert.assertNull(p);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertNull(String message, Object object) { try {Assert.assertNull(message, object);} catch (Error e) {lastTestFailed=true; throw e;} }
public void assertNull(Object object) { try {Assert.assertNull(object);} catch (Error e) {lastTestFailed=true; throw e;} }
public static class IntTokenStream implements TokenStream {
List<Integer> types;