diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..e186fb288d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/tool/target/ +/runtime/Java/target/ +/gunit/target/ \ No newline at end of file diff --git a/CHANGES.txt b/CHANGES.txt index e504138bb1..28fbc2c9bd 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,9 @@ ANTLR v4 Honey Badger early access +Feb 14, 2012 + +* Fixed https://github.com/antlr/antlr4/issues/8 and lots of other little things. + Jan 30, 2012 * Moving to github. diff --git a/gunit/pom.xml b/gunit/pom.xml new file mode 100644 index 0000000000..ebd21cb791 --- /dev/null +++ b/gunit/pom.xml @@ -0,0 +1,80 @@ + + + 4.0.0 + + org.antlr + antlr4-gunit + 4.0-SNAPSHOT + jar + + antlr4-gunit + http://www.antlr.org + + + UTF-8 + + + + + junit + junit + 4.10 + test + + + org.antlr + antlr4-runtime + 4.0-SNAPSHOT + + + org.antlr + antlr-runtime + 3.4.1-SNAPSHOT + + + org.antlr + ST4 + 4.0.4 + + + + + + src + + + resources + + + + + + org.antlr + antlr3-maven-plugin + 3.4 + + src + true + + + + + antlr + + + + + + + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + diff --git a/runtime/Java/pom.xml b/runtime/Java/pom.xml new file mode 100644 index 0000000000..d0e95cf412 --- /dev/null +++ b/runtime/Java/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + org.antlr + antlr4-runtime + 4.0-SNAPSHOT + jar + + antlr4-runtime + http://www.antlr.org + + + UTF-8 + + + + + org.antlr + ST4 + 4.0.4-SNAPSHOT + compile + + + org.abego + treelayout.core + 1.0 + system + ${project.basedir}/lib/org.abego.treelayout.core.jar + + + + + + src + + + + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + diff --git a/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorStrategy.java b/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorStrategy.java index 5d3a515de6..b78cedb507 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorStrategy.java +++ b/runtime/Java/src/org/antlr/v4/runtime/ANTLRErrorStrategy.java @@ -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 @@ void reportError(@NotNull Parser recognizer, */ void reportAmbiguity(@NotNull Parser recognizer, DFA dfa, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts, - @NotNull OrderedHashSet configs); + @NotNull ATNConfigSet configs); void reportAttemptingFullContext(@NotNull Parser recognizer, @NotNull DFA dfa, int startIndex, int stopIndex, - @NotNull OrderedHashSet 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 @@ void reportAttemptingFullContext(@NotNull Parser recognizer, void reportContextSensitivity(@NotNull Parser recognizer, @NotNull DFA dfa, int startIndex, int stopIndex, - @NotNull OrderedHashSet 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 @@ void reportInsufficientPredicates(@NotNull Parser recognizer, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts, DecisionState decState, @NotNull SemanticContext[] altToPred, - @NotNull OrderedHashSet configs, boolean fullContextParse); + @NotNull ATNConfigSet configs, boolean fullContextParse); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/BufferedTokenStream.java b/runtime/Java/src/org/antlr/v4/runtime/BufferedTokenStream.java index bfe0b4dbd9..5e0b08d353 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/BufferedTokenStream.java +++ b/runtime/Java/src/org/antlr/v4/runtime/BufferedTokenStream.java @@ -81,9 +81,7 @@ public BufferedTokenStream(TokenSource tokenSource) { @Override public int mark() { - if ( p == -1 ) setup(); - lastMarker = index(); - return lastMarker; + return 0; } @Override @@ -91,14 +89,6 @@ public void release(int marker) { // no resources to release } - public void rewind(int marker) { - seek(marker); - } - - public void rewind() { - seek(lastMarker); - } - public void reset() { p = 0; lastMarker = 0; diff --git a/runtime/Java/src/org/antlr/v4/runtime/CommonToken.java b/runtime/Java/src/org/antlr/v4/runtime/CommonToken.java index 18564fbebc..7e591dcf5a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/CommonToken.java +++ b/runtime/Java/src/org/antlr/v4/runtime/CommonToken.java @@ -64,8 +64,10 @@ public CommonToken(TokenSource source, int type, int channel, int start, int sto this.channel = channel; this.start = start; this.stop = stop; - this.line = source.getLine(); - this.charPositionInLine = source.getCharPositionInLine(); + if (source != null) { + this.line = source.getLine(); + this.charPositionInLine = source.getCharPositionInLine(); + } } public CommonToken(int type, String text) { @@ -190,7 +192,7 @@ public TokenSource getTokenSource() { } public CharStream getInputStream() { - return source.getInputStream(); + return source != null ? source.getInputStream() : null; } public String toString() { diff --git a/runtime/Java/src/org/antlr/v4/runtime/CommonTokenStream.java b/runtime/Java/src/org/antlr/v4/runtime/CommonTokenStream.java index 3d7ee8bab2..808fd01382 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/CommonTokenStream.java +++ b/runtime/Java/src/org/antlr/v4/runtime/CommonTokenStream.java @@ -83,6 +83,12 @@ public void seek(int index) { } } + @Override + public void reset() { + super.reset(); + p = skipOffTokenChannels(p); + } + @Override protected CommonToken LB(int k) { if ( k==0 || (p-k)<0 ) return null; diff --git a/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java b/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java index a02d2ffcc9..8b6b0e643a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java +++ b/runtime/Java/src/org/antlr/v4/runtime/DefaultErrorStrategy.java @@ -554,7 +554,7 @@ public void consumeUntil(Parser recognizer, IntervalSet set) { @Override public void reportAmbiguity(@NotNull Parser recognizer, DFA dfa, int startIndex, int stopIndex, @NotNull IntervalSet ambigAlts, - @NotNull OrderedHashSet configs) + @NotNull ATNConfigSet configs) { } @@ -562,13 +562,13 @@ public void reportAmbiguity(@NotNull Parser recognizer, public void reportAttemptingFullContext(@NotNull Parser recognizer, @NotNull DFA dfa, int startIndex, int stopIndex, - @NotNull OrderedHashSet configs) + @NotNull ATNConfigSet configs) { } @Override public void reportContextSensitivity(@NotNull Parser recognizer, @NotNull DFA dfa, - int startIndex, int stopIndex, @NotNull OrderedHashSet configs) + int startIndex, int stopIndex, @NotNull ATNConfigSet configs) { } @@ -579,7 +579,7 @@ public void reportInsufficientPredicates(@NotNull Parser recognizer, @NotNull IntervalSet ambigAlts, DecisionState decState, @NotNull SemanticContext[] altToPred, - @NotNull OrderedHashSet configs, boolean fullContextParse) + @NotNull ATNConfigSet configs, boolean fullContextParse) { } } diff --git a/runtime/Java/src/org/antlr/v4/runtime/DiagnosticErrorStrategy.java b/runtime/Java/src/org/antlr/v4/runtime/DiagnosticErrorStrategy.java index 56f3daf840..a66e6e0b98 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/DiagnosticErrorStrategy.java +++ b/runtime/Java/src/org/antlr/v4/runtime/DiagnosticErrorStrategy.java @@ -30,6 +30,7 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 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 configs) + @NotNull ATNConfigSet configs) { recognizer.notifyErrorListeners("reportAmbiguity d=" + dfa.decision + ": ambigAlts=" + ambigAlts + ":" + configs + ", input='" + recognizer.getInputString(startIndex, stopIndex) + "'"); @@ -53,7 +54,7 @@ public void reportAmbiguity(@NotNull Parser recognizer, public void reportAttemptingFullContext(@NotNull Parser recognizer, @NotNull DFA dfa, int startIndex, int stopIndex, - @NotNull OrderedHashSet configs) + @NotNull ATNConfigSet configs) { recognizer.notifyErrorListeners("reportAttemptingFullContext d=" + dfa.decision + ": " + configs + ", input='" + recognizer.getInputString(startIndex, stopIndex) + "'"); @@ -61,7 +62,7 @@ public void reportAttemptingFullContext(@NotNull Parser recognizer, @Override public void reportContextSensitivity(@NotNull Parser recognizer, @NotNull DFA dfa, - int startIndex, int stopIndex, @NotNull OrderedHashSet 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 void reportInsufficientPredicates(@NotNull Parser recognizer, @NotNull IntervalSet ambigAlts, DecisionState decState, @NotNull SemanticContext[] altToPred, - @NotNull OrderedHashSet configs, boolean fullContextParse) + @NotNull ATNConfigSet configs, boolean fullContextParse) { recognizer.notifyErrorListeners("reportInsufficientPredicates d=" + dfa.decision + ", decState=" + decState + ", ambigAlts=" + ambigAlts + ":" + Arrays.toString(altToPred) + diff --git a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java index aada783d86..6d4132782a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Lexer.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Lexer.java @@ -88,7 +88,7 @@ public abstract class Lexer extends Recognizer /** The token type for the current token */ public int _type; - public ArrayDeque _modeStack; + public ArrayDeque _modeStack = new ArrayDeque(); public int _mode = Lexer.DEFAULT_MODE; /** You can set the text for the current token to override what is in @@ -115,9 +115,7 @@ public void reset() { _hitEOF = false; _mode = Lexer.DEFAULT_MODE; - if (_modeStack != null) { - _modeStack.clear(); - } + _modeStack.clear(); getInterpreter().reset(); } @@ -184,14 +182,13 @@ public void mode(int m) { public void pushMode(int m) { if ( LexerATNSimulator.debug ) System.out.println("pushMode "+m); - if ( _modeStack ==null ) _modeStack = new ArrayDeque(); getInterpreter().tracePushMode(m); _modeStack.push(_mode); mode(m); } public int popMode() { - if ( _modeStack ==null ) throw new EmptyStackException(); + if ( _modeStack.isEmpty() ) throw new EmptyStackException(); if ( LexerATNSimulator.debug ) System.out.println("popMode back to "+ _modeStack.peek()); getInterpreter().tracePopMode(); mode( _modeStack.pop() ); diff --git a/runtime/Java/src/org/antlr/v4/runtime/LexerNoViableAltException.java b/runtime/Java/src/org/antlr/v4/runtime/LexerNoViableAltException.java index ffa59a80ff..9644389f7b 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/LexerNoViableAltException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/LexerNoViableAltException.java @@ -29,20 +29,19 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 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 deadEndConfigs; + public ATNConfigSet deadEndConfigs; public LexerNoViableAltException(Lexer lexer, CharStream input, int startIndex, - OrderedHashSet deadEndConfigs) { + ATNConfigSet deadEndConfigs) { super(lexer, input, null); this.startIndex = startIndex; this.deadEndConfigs = deadEndConfigs; diff --git a/runtime/Java/src/org/antlr/v4/runtime/NoViableAltException.java b/runtime/Java/src/org/antlr/v4/runtime/NoViableAltException.java index d68fc5849d..6b9cc102c3 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/NoViableAltException.java +++ b/runtime/Java/src/org/antlr/v4/runtime/NoViableAltException.java @@ -28,15 +28,14 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT */ 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 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 NoViableAltException(Parser recognizer, SymbolStream input, Token startToken, Token offendingToken, - OrderedHashSet deadEndConfigs, - ParserRuleContext ctx) + ATNConfigSet deadEndConfigs, + ParserRuleContext ctx) { super(recognizer, input, ctx); this.deadEndConfigs = deadEndConfigs; diff --git a/runtime/Java/src/org/antlr/v4/runtime/Parser.java b/runtime/Java/src/org/antlr/v4/runtime/Parser.java index cc36f2be6e..16fb7e20a8 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/Parser.java +++ b/runtime/Java/src/org/antlr/v4/runtime/Parser.java @@ -80,7 +80,7 @@ public void visitTerminal(ParserRuleContext ctx, Token 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 Token consume() { } 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 void enterOuterAlt(ParserRuleContext localctx, int altNum) { // 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 boolean inContext(String context) { 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 boolean isExpectedToken(int symbol) { return true; } - ctx = (ParserRuleContext)ctx.parent; + ctx = (ParserRuleContext)ctx.parent; } if ( following.contains(Token.EPSILON) && symbol == Token.EOF ) { @@ -417,7 +417,7 @@ public boolean isExpectedToken(int symbol) { */ 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 IntervalSet getExpectedTokens() { 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); diff --git a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java index c51775dd2f..cb438bd2ff 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java @@ -131,17 +131,6 @@ public ParserRuleContext(@Nullable ParserRuleContext parent, int stateNu this(parent, parent!=null ? parent.s : -1 /* invoking state */, stateNumber); } -// @Override -// public int hashCode() { -// return super.hashCode() + s; -// } -// -// @Override -// public boolean equals(Object o) { -// if ( !super.equals(o) ) return false; -// return s != ((RuleContext)o).s; // must be parsing the same location in the ATN -// } - // Double dispatch methods public void enterRule(ParseTreeListener listener) { } @@ -190,6 +179,61 @@ public ParseTree getChild(int i) { return children!=null ? children.get(i) : null; } + public Object getChild(Class ctxType, int i) { + if ( children==null ) throw new UnsupportedOperationException("there are no children"); + int j = -1; // what element have we found with ctxType? + for (Object o : children) { + if ( ctxType.isAssignableFrom(o.getClass()) ) { + j = j+1; + if ( j == i ) return o; + } + } + return null; + } + + public Token getToken(int ttype, int i) { + if ( children==null ) throw new UnsupportedOperationException("there are no children"); + int j = -1; // what token with ttype have we found? + for (Object o : children) { + if ( o instanceof TerminalNode ) { + TerminalNode tnode = (TerminalNode)o; + if ( tnode.getSymbol().getType()==ttype ) { + j++; + if ( j == i ) return tnode.getSymbol(); + } + } + } + return null; + } + + public List getTokens(int ttype) { + if ( children==null ) throw new UnsupportedOperationException("there are no children"); + List tokens = null; + for (Object o : children) { + if ( o instanceof Token ) { + if ( tokens==null ) tokens = new ArrayList(); + tokens.add((Token)o); + } + } + return tokens; + } + + public ParserRuleContext getRuleContext(Class ctxType, int i) { + return (ParserRuleContext)getChild(ctxType, i); + } + + public List getRuleContexts(Class ctxType) { + if ( children==null ) throw new UnsupportedOperationException("there are no children"); + List contexts = null; + for (Object o : children) { + if ( o.getClass().isInstance(ctxType) ) { + if ( contexts==null ) contexts = new ArrayList(); + contexts.add((ParserRuleContext)o); + } + } + return contexts; + } + @Override public int getChildCount() { return children!=null ? children.size() : 0; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java index 2d0113178d..b762eb516a 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/RuleContext.java @@ -80,16 +80,6 @@ public class RuleContext implements ParseTree.RuleNode { public RuleContext() {} -// public RuleContext(RuleContext parent) { -// this(parent, -1); -// } -// -// public RuleContext(RuleContext parent, int stateNumber) { -// // capture state that called us as we create this context; use later for -// // return state in closure -// this(parent, parent != null ? parent.s : -1, stateNumber); -// } - public RuleContext(RuleContext parent, int invokingState) { this.parent = parent; //if ( parent!=null ) System.out.println("invoke "+stateNumber+" from "+parent); @@ -103,13 +93,6 @@ public RuleContext(RuleContext parent, int invokingState) { @Override public int hashCode() { -// int h = 0; -// RuleContext p = this; -// while ( p!=null ) { -// h += p.stateNumber; -// p = p.parent; -// } -// return h; return cachedHashCode; // works with tests; don't recompute. } diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfig.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfig.java index b759482136..5e5f7b2809 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfig.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ATNConfig.java @@ -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 ATNConfig(@NotNull ATNConfig c, @NotNull ATNState state) { 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 ATNConfig(@NotNull ATNConfig c, @NotNull ATNState state, @Nullable RuleCo } 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 ATNConfig(@NotNull ATNConfig c, @NotNull ATNState state, @Nullable RuleCo 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 diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java b/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java index 73cf638793..3000c99b57 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/LexerATNSimulator.java @@ -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; @@ -139,6 +139,21 @@ public LexerATNSimulator(@Nullable Lexer recog, @NotNull ATN atn) { this.recog = recog; } + public void copyState(@NotNull LexerATNSimulator simulator) { + this.charPositionInLine = simulator.charPositionInLine; + this.line = simulator.line; + this.mode = simulator.mode; + this.startIndex = simulator.startIndex; + + this.trace = simulator.trace; + this.traceStream = simulator.traceStream; + this.traceFailed = simulator.traceFailed; + } + + public OutputStream getTraceStream() { + return this.traceStream; + } + public void setTraceStream(OutputStream traceStream) { this.traceStream = traceStream; this.trace = traceStream != null; @@ -288,8 +303,7 @@ protected int exec(@NotNull CharStream input, @NotNull ATNConfigSet s0) { System.out.format("in reach starting closure: %s\n", closure); } - for (int ci=0; ci NUM_EDGES) { + if (t < 0 || t > MAX_DFA_EDGE) { return; } @@ -594,10 +608,10 @@ protected void addDFAEdge(@NotNull ATNConfigSet p, } 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"); diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNPathFinder.java b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNPathFinder.java index ab04bb0a3e..c19d757781 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNPathFinder.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/ParserATNPathFinder.java @@ -32,6 +32,7 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 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 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT import java.util.List; import java.util.Set; -public class ParserATNPathFinder extends ParserATNSimulator { +public class ParserATNPathFinder extends ParserATNSimulator { public ParserATNPathFinder(@Nullable Parser parser, @NotNull ATN atn) { super(parser, atn); } diff --git a/runtime/Java/src/org/antlr/v4/runtime/atn/SemanticContext.java b/runtime/Java/src/org/antlr/v4/runtime/atn/SemanticContext.java index 7ca0d8e0f9..5050115795 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/atn/SemanticContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/atn/SemanticContext.java @@ -83,6 +83,7 @@ public Predicate(int ruleIndex, int predIndex, boolean isCtxDependent) { 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 boolean eval(Recognizer parser, RuleContext outerContext) { @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 boolean equals(Object obj) { this.isCtxDependent == p.isCtxDependent; } + @Override public String toString() { return "{"+ruleIndex+":"+predIndex+"}?"; } @@ -131,6 +137,7 @@ public int hashCode() { 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 boolean eval(Recognizer parser, RuleContext outerContext) { return true; } + @Override public String toString() { return Utils.join(opnds.iterator(), "&&"); } @@ -166,6 +174,7 @@ public int hashCode() { 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; diff --git a/runtime/Java/src/org/antlr/v4/runtime/dfa/DFAState.java b/runtime/Java/src/org/antlr/v4/runtime/dfa/DFAState.java index 5248ba330b..7ed0be9526 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/dfa/DFAState.java +++ b/runtime/Java/src/org/antlr/v4/runtime/dfa/DFAState.java @@ -150,7 +150,7 @@ public Set getAltSet() { for (ATNConfig c : configset) { alts.add(c.alt); } - if ( alts.size()==0 ) return null; + if ( alts.isEmpty() ) return null; return alts; } diff --git a/runtime/Java/src/org/antlr/v4/runtime/misc/IntervalSet.java b/runtime/Java/src/org/antlr/v4/runtime/misc/IntervalSet.java index d7a45e9a88..8f28fe2c1e 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/misc/IntervalSet.java +++ b/runtime/Java/src/org/antlr/v4/runtime/misc/IntervalSet.java @@ -28,8 +28,7 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT */ package org.antlr.v4.runtime.misc; -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.*; import java.util.*; @@ -56,11 +55,6 @@ public class IntervalSet implements IntSet { protected boolean readonly; - /** Create a set with no elements */ - public IntervalSet() { - intervals = new ArrayList(2); // most sets are 1 or 2 elements - } - public IntervalSet(List intervals) { this.intervals = intervals; } @@ -70,6 +64,16 @@ public IntervalSet(IntervalSet set) { addAll(set); } + public IntervalSet(int... els) { + if ( els==null ) { + intervals = new ArrayList(2); // most sets are 1 or 2 elements + } + else { + intervals = new ArrayList(els.length); + for (int e : els) add(e); + } + } + /** Create a set with a single element, el. */ @NotNull public static IntervalSet of(int a) { @@ -363,7 +367,7 @@ public boolean contains(int el) { /** 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 +426,7 @@ public int hashCode() { * 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 +435,12 @@ public boolean equals(Object obj) { 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 +453,12 @@ public String toString(boolean elemAreChar) { int b = I.b; if ( a==b ) { if ( a==-1 ) buf.append(""); - 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 +471,8 @@ public String toString(boolean elemAreChar) { } 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 ) { diff --git a/tool/playground/A.g4 b/tool/playground/A.g4 index 5787ce9729..9c2d6ea73d 100644 --- a/tool/playground/A.g4 +++ b/tool/playground/A.g4 @@ -1,16 +1,12 @@ grammar A; -s : q=e {System.out.println("result = "+$e.v);} ; +s : e ; -e returns [int v] - : a=e op='*' b=e {$v = $a.v * $b.v;} -> mult - | a=e '+' b=e {$v = $a.v + $b.v;} -> add - | INT {$v = $INT.int;} - | '(' x=e ')' {$v = $x.v;} - | e '++' -> inc - | e '--' - | ID -> anID +e : e '*' e -> Mult + | e '+' e -> Add + | INT -> Int + | '(' e ')' -> Parens ; -INT : '0'..'9'+ ; -WS : (' '|'\n')+ {skip();} ; +INT : [0-9]+ ; +WS : [ \t\n]+ -> skip ; diff --git a/tool/playground/A2.g4 b/tool/playground/A2.g4 new file mode 100644 index 0000000000..77ba120774 --- /dev/null +++ b/tool/playground/A2.g4 @@ -0,0 +1,13 @@ +grammar A2; + +s : e {System.out.println($e.v);} ; + +e returns [int v] + : a=e '*' b=e {$v = $a.v * $b.v;} -> Mult + | a=e '+' b=e {$v = $a.v + $b.v;} -> Add + | INT {$v = $INT.int;} -> Int + | '(' x=e ')' {$v = $x.v;} -> Parens + ; + +INT : [0-9]+ ; +WS : [ \t\n]+ -> skip ; diff --git a/tool/playground/R.g4 b/tool/playground/R.g4 index 51257c616b..551228c4ec 100644 --- a/tool/playground/R.g4 +++ b/tool/playground/R.g4 @@ -77,6 +77,7 @@ prog : expr_or_assign* ; //prog : expr_or_assign prog | ; expr_or_assign +@after {System.out.println(getRuleInvocationStack());} : expr '++' | expr // match ID a, fall out, reenter, match "(i)<-x" via alt 1 // it thinks it's same context from prog, but it's not; it's diff --git a/tool/playground/TestA.java b/tool/playground/TestA.java index 5b5fc3cc15..5548162731 100644 --- a/tool/playground/TestA.java +++ b/tool/playground/TestA.java @@ -27,41 +27,70 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import org.antlr.v4.runtime.*; -import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.ANTLRFileStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ParseTreeWalker; +import java.util.Stack; + public class TestA { - public static class Do extends BlankAListener { - Parser p; - public Do(Parser p ) { this.p = p; } - @Override - public void exitEveryRule(ParserRuleContext ctx) { - System.out.println("exit "+ctx.toStringTree(p)); - } + /** An example listener that uses a stack to store return values + * so that exit methods executed on notes further up the parse tree + * can see the results of these computations. + * + * Because we are using only the exit routines, the same listener works + * as a parse listener and is a parse tree listener. It generates + * the following output from input 3+4*5: + + Int: 3 + Int: 4 + Int: 5 + Mult: 20 + Add: 23 + tree = (s (e (e 3) + (e (e 4) * (e 5)))) + Int: 3 + Int: 4 + Int: 5 + Mult: 20 + Add: 23 + result from tree walk = 23 + + * The key things to notice are that there are no actions + * and the labels in the grammar--it is completely language neutral. + * Also, I have labeled each alternative so that we get a different + * context object. That way we get a listener method for each + * alternative. + * + * Compare this to A2.g4, which adds a field to the context objects + * by using a "returns [int v]" on the expression rule. + */ + public static class Do extends ABaseListener { + Stack results = new Stack(); @Override - public void enterRule(AParser.eContext ctx) { - System.out.println("enter alt w/o -> label: "+ctx.toInfoString(p)); + public void exit(AParser.AddContext ctx) { + results.push( results.pop() + results.pop() ); + System.out.println("Add: " + results.peek()); } @Override - public void visitTerminal(ParserRuleContext ctx, Token symbol) { - if ( ctx instanceof AParser.eContext && symbol.getType()==AParser.INT ) { - AParser.eContext ectx = (AParser.eContext)ctx; - ectx.v = Integer.valueOf(symbol.getText()); - } + public void exit(AParser.IntContext ctx) { + results.push( Integer.valueOf(ctx.INT().getText()) ); + System.out.println("Int: "+results.peek()); } @Override - public void exitRule(AParser.multContext ctx) { - System.out.println("mult "+ctx.a.v+" * "+ctx.b.v); - ctx.v = ctx.a.v * ctx.b.v; // repeat of what parser did--set return value + public void exit(AParser.MultContext ctx) { + results.push( results.pop() * results.pop() ); + System.out.println("Mult: " + results.peek()); } + @Override - public void exitRule(AParser.addContext ctx) { - System.out.println("add "+ctx.a.v+" + "+ctx.b.v); - ctx.v = ctx.a.v + ctx.b.v; + public void exit(AParser.ParensContext ctx) { + // result already on stack + System.out.println("Parens: "+results.peek()); } } public static void main(String[] args) throws Exception { @@ -69,14 +98,13 @@ public static void main(String[] args) throws Exception { CommonTokenStream tokens = new CommonTokenStream(lexer); AParser p = new AParser(tokens); p.setBuildParseTree(true); -// p.addParseListener(new Do(p)); + p.addParseListener(new Do()); ParserRuleContext t = p.s(); System.out.println("tree = "+t.toStringTree(p)); ParseTreeWalker walker = new ParseTreeWalker(); - Do doer = new Do(p); + Do doer = new Do(); walker.walk(doer, t); - AParser.eContext ectx = (AParser.eContext)t.getChild(0); - System.out.println("result from tree walk = "+ ectx.v); + System.out.println("result from tree walk = "+ doer.results.pop()); } } diff --git a/tool/playground/TestA2.java b/tool/playground/TestA2.java new file mode 100644 index 0000000000..0c36d13478 --- /dev/null +++ b/tool/playground/TestA2.java @@ -0,0 +1,84 @@ +/* + [The "BSD license"] + Copyright (c) 2011 Terence Parr + 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. + */ + +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.tree.ParseTreeWalker; + +public class TestA2 { + /** An example listener that squirrels away a return value in a field + * called v that we get added to the expression context objects + * by adding a return value to rule e. This is a version of A.g4 + * that performs actions during the parse with user-defined actions. + * AND, we pass in a listener that gets executed during the parse + * and we use a listener on a tree walk that executes after the parse. + * So, it affect, we compute the result of the expression 3 times. + */ + public static class Do extends A2BaseListener { + A2Parser p; + public Do(A2Parser p) { this.p = p; } + @Override + public void exit(A2Parser.AddContext ctx) { + ctx.v = ctx.e(0).v + ctx.e(1).v; + System.out.println("Add: " + ctx.v); + } + + @Override + public void exit(A2Parser.IntContext ctx) { + ctx.v = Integer.valueOf(ctx.INT().getText()); + System.out.println("Int: "+ctx.v); + } + + @Override + public void exit(A2Parser.MultContext ctx) { + ctx.v = ctx.e(0).v * ctx.e(1).v; + System.out.println("Mult: " + ctx.v); + } + + @Override + public void exit(A2Parser.ParensContext ctx) { + ctx.v = ctx.e().v; + System.out.println("Parens: "+ctx.v); + } + } + public static void main(String[] args) throws Exception { + A2Lexer lexer = new A2Lexer(new ANTLRFileStream(args[0])); + CommonTokenStream tokens = new CommonTokenStream(lexer); + A2Parser p = new A2Parser(tokens); + p.setBuildParseTree(true); + p.addParseListener(new Do(p)); + ParserRuleContext t = p.s(); + System.out.println("tree = "+t.toStringTree(p)); + + ParseTreeWalker walker = new ParseTreeWalker(); + Do doer = new Do(p); + walker.walk(doer, t); + A2Parser.eContext ectx = (A2Parser.eContext)t.getChild(0); + System.out.println("result from tree walk = "+ ectx.v); + } +} diff --git a/tool/playground/TestJava.java b/tool/playground/TestJava.java index 2c46fd6980..33f5990ab5 100644 --- a/tool/playground/TestJava.java +++ b/tool/playground/TestJava.java @@ -2,7 +2,7 @@ import org.antlr.v4.runtime.ANTLRFileStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.atn.LexerATNSimulator; -import org.antlr.v4.runtime.atn.v2ParserATNSimulator; +import org.antlr.v4.runtime.atn.ParserATNSimulator; import java.io.File; @@ -41,10 +41,10 @@ static void doAll(String[] args) { System.out.println("finished parsing OK"); System.out.println(LexerATNSimulator.ATN_failover+" lexer failovers"); System.out.println(LexerATNSimulator.match_calls+" lexer match calls"); - System.out.println(v2ParserATNSimulator.ATN_failover+" parser failovers"); - System.out.println(v2ParserATNSimulator.predict_calls +" parser predict calls"); - System.out.println(v2ParserATNSimulator.retry_with_context +" retry_with_context after SLL conflict"); - System.out.println(v2ParserATNSimulator.retry_with_context_indicates_no_conflict +" retry sees no conflict"); + System.out.println(ParserATNSimulator.ATN_failover+" parser failovers"); + System.out.println(ParserATNSimulator.predict_calls +" parser predict calls"); + System.out.println(ParserATNSimulator.retry_with_context +" retry_with_context after SLL conflict"); + System.out.println(ParserATNSimulator.retry_with_context_indicates_no_conflict +" retry sees no conflict"); if ( profile ) { System.out.println("num decisions "+profiler.numDecisions); } diff --git a/tool/playground/TestJavaLR.java b/tool/playground/TestJavaLR.java index 71d188e1d8..20a53768d4 100644 --- a/tool/playground/TestJavaLR.java +++ b/tool/playground/TestJavaLR.java @@ -33,7 +33,7 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.atn.LexerATNSimulator; -import org.antlr.v4.runtime.atn.v2ParserATNSimulator; +import org.antlr.v4.runtime.atn.ParserATNSimulator; import java.io.File; @@ -71,10 +71,10 @@ public static void doAll(String[] args) { System.out.println("finished parsing OK"); System.out.println(LexerATNSimulator.ATN_failover+" lexer failovers"); System.out.println(LexerATNSimulator.match_calls+" lexer match calls"); - System.out.println(v2ParserATNSimulator.ATN_failover+" parser failovers"); - System.out.println(v2ParserATNSimulator.predict_calls +" parser predict calls"); - System.out.println(v2ParserATNSimulator.retry_with_context +" retry_with_context after SLL conflict"); - System.out.println(v2ParserATNSimulator.retry_with_context_indicates_no_conflict +" retry sees no conflict"); + System.out.println(ParserATNSimulator.ATN_failover+" parser failovers"); + System.out.println(ParserATNSimulator.predict_calls +" parser predict calls"); + System.out.println(ParserATNSimulator.retry_with_context +" retry_with_context after SLL conflict"); + System.out.println(ParserATNSimulator.retry_with_context_indicates_no_conflict +" retry sees no conflict"); if ( profile ) { System.out.println("num decisions "+profiler.numDecisions); } diff --git a/tool/playground/TestYang.java b/tool/playground/TestYang.java index 8aede931c4..2862a7a804 100644 --- a/tool/playground/TestYang.java +++ b/tool/playground/TestYang.java @@ -2,7 +2,7 @@ import org.antlr.v4.runtime.ANTLRFileStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.atn.LexerATNSimulator; -import org.antlr.v4.runtime.atn.v2ParserATNSimulator; +import org.antlr.v4.runtime.atn.ParserATNSimulator; import java.io.File; @@ -34,8 +34,8 @@ public static void main(String[] args) { System.out.println("finished parsing OK"); System.out.println(LexerATNSimulator.ATN_failover+" lexer failovers"); System.out.println(LexerATNSimulator.match_calls+" lexer match calls"); - System.out.println(v2ParserATNSimulator.ATN_failover+" parser failovers"); - System.out.println(v2ParserATNSimulator.predict_calls +" parser predict calls"); + System.out.println(ParserATNSimulator.ATN_failover+" parser failovers"); + System.out.println(ParserATNSimulator.predict_calls +" parser predict calls"); if ( profile ) { System.out.println("num decisions "+profiler.numDecisions); } diff --git a/tool/pom.xml b/tool/pom.xml new file mode 100644 index 0000000000..2fb24e25eb --- /dev/null +++ b/tool/pom.xml @@ -0,0 +1,87 @@ + + + 4.0.0 + + org.antlr + antlr4 + 4.0-SNAPSHOT + jar + + antlr4 + http://www.antlr.org + + + UTF-8 + + + + + junit + junit + 4.10 + test + + + org.antlr + antlr4-runtime + ${project.version} + + + org.antlr + antlr-runtime + 3.4.1-SNAPSHOT + + + org.antlr + ST4 + 4.0.4 + + + org.antlr + antlr4-gunit + ${project.version} + + + + + + src + + + resources + + + + test + + + + org.antlr + antlr3-maven-plugin + 3.4 + + src + true + + + + + antlr + + + + + + + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + + + + + + diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index 2be14e5651..898b35e280 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -34,25 +34,25 @@ import org.antlr.v4.runtime.Token; public interface Listener extends ParseTreeListener\<\> { .Context ctx); -void exitRule(.Context ctx);}; separator="\n"> +void enter(.Context ctx); +void exit(.Context ctx);}; separator="\n"> } >> -BlankListenerFile(file, header) ::= << +BaseListenerFile(file, header) ::= <<
import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Token; -public class BlankListener implements Listener { +public class BaseListener implements Listener { .Context ctx) { \} -@Override public void exitRule(.Context ctx) { \}}; separator="\n"> +@Override public void enter(.Context ctx) { \} +@Override public void exit(.Context ctx) { \}}; separator="\n"> - @Override public void enterEveryRule(ParserRuleContext\< > ctx) { } - @Override public void exitEveryRule(ParserRuleContext\< > ctx) { } - @Override public void visitTerminal(ParserRuleContext\< > ctx, symbol) { } + @Override public void enterEveryRule(ParserRuleContext\<\> ctx) { } + @Override public void exitEveryRule(ParserRuleContext\<\> ctx) { } + @Override public void visitTerminal(ParserRuleContext\<\> ctx, 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 extends { public static final int @@ -130,7 +130,7 @@ case : return _sempred(()_localctx, predIndex); parser_ctor(p) ::= << public (TokenStream input) { super(input); - _interp = new v2ParserATNSimulator\(this,_ATN); + _interp = new ParserATNSimulator\(this,_ATN); } >> @@ -156,7 +156,7 @@ case : return ;}; separator="\n"> RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble) ::= << - +}; separator="\n"> }>public final () throws RecognitionException { _localctx = new (_ctx, }>); @@ -182,22 +182,22 @@ RuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAc >> LeftRecursiveRuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs, - namedActions,finallyAction,postamble) ::= + namedActions,finallyAction,postamble) ::= << - +}; separator="\n"> }>public final () throws RecognitionException { - ParserRuleContext\ _parentctx = _ctx; + ParserRuleContext\ _parentctx = _ctx; _localctx = new (_ctx, }>); _prevctx = _localctx; int _startState = ; - pushNewRecursionContext(_localctx, RULE_); + pushNewRecursionContext(_localctx, RULE_); try { - + _localctx.stop = _input.LT(-1); @@ -214,13 +214,13 @@ LeftRecursiveRuleFunction(currentRule,code,locals,ruleCtx,altLabelCtxs, } >> -CodeBlockForOuterMostAlt(c, locals, preamble, ops) ::= << -_localctx = new Context(_localctx); -enterOuterAlt(_localctx, ); - +CodeBlockForOuterMostAlt(currentOuterMostAltCodeBlock, locals, preamble, ops) ::= << +_localctx = new Context(_localctx); +enterOuterAlt(_localctx, ); + >> -CodeBlockForAlt(c, locals, preamble, ops) ::= << +CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= << { @@ -355,10 +355,10 @@ setState(); _errHandler.sync(this); int _alt = getInterpreter().adaptivePredict(_input,,_ctx); while ( _alt!= && _alt!=-1 ) { - if ( _alt==1 ) { - - - } + if ( _alt==1 ) { + + + } setState(); _errHandler.sync(this); _alt = getInterpreter().adaptivePredict(_input,,_ctx); @@ -425,7 +425,7 @@ setState(); // ACTION STUFF -Action(a, chunks) ::= "" +Action(a, foo, chunks) ::= "" ArgAction(a, chunks) ::= "" @@ -448,32 +448,33 @@ LexerPushModeCommand(arg) ::= "pushMode();" DefaultParserSuperClass(s) ::= "Parser" ActionText(t) ::= "" +ActionTemplate(t) ::= "" ArgRef(a) ::= "_localctx." LocalRef(a) ::= "_localctx." RetValueRef(a) ::= "_localctx." -QRetValueRef(a) ::= "_localctx.." +QRetValueRef(a) ::= ".." /** How to translate $tokenLabel */ -TokenRef(t) ::= "_localctx." -LabelRef(t) ::= "_localctx." -ListLabelRef(t) ::= "_localctx." -SetAttr(s,rhsChunks) ::= "_localctx. = ;" +TokenRef(t) ::= "." +LabelRef(t) ::= "." +ListLabelRef(t) ::= "." +SetAttr(s,rhsChunks) ::= ". = ;" LexerSetAttr(s,rhsChunks) ::= "_ = ;" // _type etc... TokenLabelType() ::= "" InputSymbolType() ::= "" -TokenPropertyRef_text(t) ::= "(_localctx.!=null?_localctx..getText():null)" -TokenPropertyRef_type(t) ::= "(_localctx.!=null?_localctx..getType():0)" -TokenPropertyRef_line(t) ::= "(_localctx.!=null?_localctx..getLine():0)" -TokenPropertyRef_pos(t) ::= "(_localctx.!=null?_localctx..getCharPositionInLine():0)" -TokenPropertyRef_channel(t) ::= "(_localctx.!=null?_localctx..getChannel():0)" -TokenPropertyRef_index(t) ::= "(_localctx.!=null?_localctx..getTokenIndex():0)" -TokenPropertyRef_int(t) ::= "(_localctx.!=null?Integer.valueOf(_localctx..getText()):0)" +TokenPropertyRef_text(t) ::= "(.!=null?..getText():null)" +TokenPropertyRef_type(t) ::= "(.!=null?..getType():0)" +TokenPropertyRef_line(t) ::= "(.!=null?..getLine():0)" +TokenPropertyRef_pos(t) ::= "(.!=null?..getCharPositionInLine():0)" +TokenPropertyRef_channel(t) ::= "(.!=null?..getChannel():0)" +TokenPropertyRef_index(t) ::= "(.!=null?..getTokenIndex():0)" +TokenPropertyRef_int(t) ::= "(.!=null?Integer.valueOf(..getText()):0)" -RulePropertyRef_start(r) ::= "(_localctx.!=null?(_localctx..start):null)" -RulePropertyRef_stop(r) ::= "(_localctx.!=null?(_localctx..stop):null)" -RulePropertyRef_text(r) ::= "(_localctx.!=null?_input.toString(_localctx..start,_localctx..stop):null)" -RulePropertyRef_ctx(r) ::= "_localctx." +RulePropertyRef_start(r) ::= "(.!=null?(..start):null)" +RulePropertyRef_stop(r) ::= "(.!=null?(..stop):null)" +RulePropertyRef_text(r) ::= "(.!=null?_input.toString(..start,..stop):null)" +RulePropertyRef_ctx(r) ::= "." ThisRulePropertyRef_start(r) ::= "_localctx.start" ThisRulePropertyRef_stop(r) ::= "_localctx.stop" @@ -484,13 +485,38 @@ NonLocalAttrRef(s) ::= "((Context)getInvokingContext( SetNonLocalAttr(s, rhsChunks) ::= "((Context)getInvokingContext()). = ;" -AddToLabelList(a) ::= "_localctx..add();" +AddToLabelList(a) ::= "..add();" -TokenDecl(t) ::= "Token ;" +TokenDecl(t) ::= "public Token ;" TokenTypeDecl(t) ::= "int ;" -TokenListDecl(t) ::= "List\ = new ArrayList\();" -RuleContextDecl(r) ::= " ;" -RuleContextListDecl(rdecl) ::= "List\<> = new ArrayList\<>();" +TokenListDecl(t) ::= "public List\ = new ArrayList\();" +RuleContextDecl(r) ::= "public ;" +RuleContextListDecl(rdecl) ::= "public List\<> = new ArrayList\<>();" + +ContextTokenGetterDecl(t) ::= + "public Token () { return getToken(., 0); }" +ContextTokenListGetterDecl(t) ::= + "public List\ () { return getTokens(.); }" +ContextTokenListIndexedGetterDecl(t) ::= << +public Token (int i) { + return getToken(., i); +} +>> +ContextRuleGetterDecl(r) ::= << +public () { + return ()getRuleContext(.class,0); +} +>> +ContextRuleListGetterDecl(r) ::= << +public List\<\> () { + return (List\<\>)getRuleContexts(.class); +} +>> +ContextRuleListIndexedGetterDecl(r) ::= << +public (int i) { + return ()getRuleContext(.class,i); +} +>> LexerRuleContext() ::= "RuleContext" @@ -499,20 +525,21 @@ LexerRuleContext() ::= "RuleContext" */ RuleContextNameSuffix() ::= "Context" -ImplicitTokenLabel(tokenName) ::= "_t" -ImplicitRuleLabel(ruleName) ::= "_r" +ImplicitTokenLabel(tokenName) ::= "" +ImplicitRuleLabel(ruleName) ::= "" ImplicitSetLabel(id) ::= "_tset" -ListLabelName(label) ::= "