all tests pass!

This commit is contained in:
Eric Vergnaud 2016-12-12 21:36:41 +08:00
parent 0170c9a064
commit 2fc33d97cd
11 changed files with 100 additions and 261 deletions

View File

@ -76,7 +76,7 @@ GetExpectedTokenNames() ::= "this.GetExpectedTokens().ToString(this.Vocabulary)"
RuleInvocationStack() ::= "GetRuleInvocationStackAsString()" RuleInvocationStack() ::= "GetRuleInvocationStackAsString()"
LL_EXACT_AMBIG_DETECTION() ::= <<Interpreter.PredictionMode = PredictionMode.LlExactAmbigDetection;>> LL_EXACT_AMBIG_DETECTION() ::= <<Interpreter.PredictionMode = PredictionMode.LL_EXACT_AMBIG_DETECTION;>>
ParserToken(parser, token) ::= <%<parser>.<token>%> ParserToken(parser, token) ::= <%<parser>.<token>%>

View File

@ -13,7 +13,6 @@ import org.antlr.v4.runtime.WritableToken;
import org.antlr.v4.runtime.misc.Utils; import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.test.runtime.ErrorQueue; import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport; import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.test.runtime.SpecialRuntimeTestAssert;
import org.antlr.v4.tool.ANTLRMessage; import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.GrammarSemanticsMessage; import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.junit.rules.TestRule; import org.junit.rules.TestRule;
@ -54,7 +53,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
public class BaseCSharpTest implements RuntimeTestSupport, SpecialRuntimeTestAssert { public class BaseCSharpTest implements RuntimeTestSupport /*, SpecialRuntimeTestAssert*/ {
public static final String newline = System.getProperty("line.separator"); public static final String newline = System.getProperty("line.separator");
public static final String pathSep = System.getProperty("path.separator"); public static final String pathSep = System.getProperty("path.separator");
@ -788,64 +787,8 @@ public class BaseCSharpTest implements RuntimeTestSupport, SpecialRuntimeTestAss
org.junit.Assert.assertEquals(msg, a, b); org.junit.Assert.assertEquals(msg, a, b);
} }
@Override
public void assertEqualStrings(String a, String b) {
assertEquals(a, b);
}
protected static void assertEquals(String a, String b) { protected static void assertEquals(String a, String b) {
a = absorbExpectedDifferences(a);
b = absorbActualDifferences(b);
org.junit.Assert.assertEquals(a, b); org.junit.Assert.assertEquals(a, b);
} }
protected static void assertNull(String a) {
a = absorbActualDifferences(a);
org.junit.Assert.assertNull(a);
}
private static String absorbExpectedDifferences(String a) {
if(a==null)
return a;
// work around the lack of requiresFullContext field in DFAState
if(a.startsWith("Decision"))
a = a.replaceAll("\\^", "");
// work around the algo difference for full context
a = stripOutUnwantedLinesWith(a, "reportAttemptingFullContext","reportContextSensitivity", "reportAmbiguity");
if(a.isEmpty()) {
a = null;
}
return a;
}
private static String absorbActualDifferences(String a) {
if(a==null) return a;
// work around the algo difference for full context
// work around the algo difference for semantic predicates
a = stripOutUnwantedLinesWith(a, "reportContextSensitivity","eval=false");
if(a.isEmpty()) {
a = null;
}
return a;
}
private static String stripOutUnwantedLinesWith(String a, String ... unwanteds) {
String[] lines = a.split("\n");
StringBuilder sb = new StringBuilder();
for(String line : lines) {
boolean wanted = true;
for(String unwanted : unwanteds) {
if(line.contains(unwanted) ) {
wanted = false;
break;
}
}
if(!wanted)
continue;
sb.append(line);
sb.append("\n");
}
return sb.toString();
}
} }

View File

@ -107,8 +107,7 @@ public class PerformanceDescriptors {
@Override @Override
public boolean ignore(String targetName) { public boolean ignore(String targetName) {
// return !Arrays.asList("Java", "Python2", "Python3", "Node").contains(targetName); return !Arrays.asList("Java", "CSharp", "Python2", "Python3", "Node").contains(targetName);
return !Arrays.asList("Java").contains(targetName);
} }
} }
@ -190,6 +189,12 @@ public class PerformanceDescriptors {
*/ */
@CommentHasStringValue @CommentHasStringValue
public String input; public String input;
@Override
public boolean ignore(String targetName) {
// passes, but still too slow in Python and JavaScript
return !Arrays.asList("Java", "CSharp").contains(targetName);
}
} }
public static class DropLoopEntryBranchInLRRule_5 extends DropLoopEntryBranchInLRRule { public static class DropLoopEntryBranchInLRRule_5 extends DropLoopEntryBranchInLRRule {

View File

@ -139,9 +139,8 @@ namespace Antlr4.Runtime.Atn
/// 's rule. /// 's rule.
/// </summary> /// </summary>
[return: NotNull] [return: NotNull]
public virtual IntervalSet NextTokens(ATNState s, PredictionContext ctx) public virtual IntervalSet NextTokens(ATNState s, RuleContext ctx)
{ {
Args.NotNull("ctx", ctx);
LL1Analyzer anal = new LL1Analyzer(this); LL1Analyzer anal = new LL1Analyzer(this);
IntervalSet next = anal.Look(s, ctx); IntervalSet next = anal.Look(s, ctx);
return next; return next;
@ -163,7 +162,7 @@ namespace Antlr4.Runtime.Atn
{ {
return s.nextTokenWithinRule; return s.nextTokenWithinRule;
} }
s.nextTokenWithinRule = NextTokens(s, PredictionContext.EMPTY); s.nextTokenWithinRule = NextTokens(s, null);
s.nextTokenWithinRule.SetReadonly(true); s.nextTokenWithinRule.SetReadonly(true);
return s.nextTokenWithinRule; return s.nextTokenWithinRule;
} }

View File

@ -138,9 +138,9 @@ namespace Antlr4.Runtime.Atn
/// . /// .
/// </returns> /// </returns>
[return: NotNull] [return: NotNull]
public virtual IntervalSet Look(ATNState s, PredictionContext ctx) public virtual IntervalSet Look(ATNState s, RuleContext ctx)
{ {
return Look(s, s.atn.ruleToStopState[s.ruleIndex], ctx); return Look(s, null, ctx);
} }
/// <summary> /// <summary>
@ -189,13 +189,12 @@ namespace Antlr4.Runtime.Atn
/// . /// .
/// </returns> /// </returns>
[return: NotNull] [return: NotNull]
public virtual IntervalSet Look(ATNState s, ATNState stopState, PredictionContext ctx) public virtual IntervalSet Look(ATNState s, ATNState stopState, RuleContext ctx)
{ {
IntervalSet r = new IntervalSet(); IntervalSet r = new IntervalSet();
bool seeThruPreds = true; bool seeThruPreds = true;
// ignore preds; get all lookahead PredictionContext lookContext = ctx != null ? PredictionContext.FromRuleContext(s.atn, ctx) : null;
bool addEOF = true; Look(s, stopState, lookContext, r, new HashSet<ATNConfig>(), new BitSet(), seeThruPreds, true);
Look(s, stopState, ctx, r, new HashSet<ATNConfig>(), new BitSet(), seeThruPreds, addEOF);
return r; return r;
} }
@ -301,36 +300,37 @@ namespace Antlr4.Runtime.Atn
} }
if (s is RuleStopState) if (s is RuleStopState)
{ {
if (ctx.IsEmpty && !ctx.IsEmpty) if (ctx == null)
{
look.Add(TokenConstants.EPSILON);
return;
}
else if (ctx.IsEmpty && addEOF)
{ {
if (addEOF) look.Add(TokenConstants.EOF);
{
look.Add(TokenConstants.EOF);
}
return; return;
} }
bool removed = calledRuleStack.Get(s.ruleIndex); if (ctx != PredictionContext.EMPTY)
try {
{ for (int i = 0; i < ctx.Size; i++)
calledRuleStack.Clear(s.ruleIndex); {
for (int i = 0; i < ctx.Size; i++) ATNState returnState = atn.states[ctx.GetReturnState(i)];
{ bool removed = calledRuleStack.Get(returnState.ruleIndex);
if (ctx.GetReturnState(i) == PredictionContext.EMPTY_RETURN_STATE) try
{ {
continue; calledRuleStack.Clear(returnState.ruleIndex);
} Look(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
ATNState returnState = atn.states[ctx.GetReturnState(i)]; }
// System.out.println("popping back to "+retState); finally
Look(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF); {
} if (removed)
} {
finally calledRuleStack.Set(returnState.ruleIndex);
{ }
if (removed) }
{ }
calledRuleStack.Set(s.ruleIndex); return;
} }
}
} }
int n = s.NumberOfTransitions; int n = s.NumberOfTransitions;
for (int i_1 = 0; i_1 < n; i_1++) for (int i_1 = 0; i_1 < n; i_1++)
@ -343,15 +343,15 @@ namespace Antlr4.Runtime.Atn
{ {
continue; continue;
} }
PredictionContext newContext = ctx.GetChild(ruleTransition.followState.stateNumber); PredictionContext newContext = SingletonPredictionContext.Create(ctx, ruleTransition.followState.stateNumber);
try try
{ {
calledRuleStack.Set(ruleTransition.ruleIndex); calledRuleStack.Set(ruleTransition.target.ruleIndex);
Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF); Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
} }
finally finally
{ {
calledRuleStack.Clear(ruleTransition.ruleIndex); calledRuleStack.Clear(ruleTransition.target.ruleIndex);
} }
} }
else else
@ -375,13 +375,12 @@ namespace Antlr4.Runtime.Atn
} }
else else
{ {
if (t.GetType() == typeof(WildcardTransition)) if (t is WildcardTransition)
{ {
look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType)); look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
} }
else else
{ {
// System.out.println("adding "+ t);
IntervalSet set = t.Label; IntervalSet set = t.Label;
if (set != null) if (set != null)
{ {

View File

@ -1,16 +1,34 @@
using System; using System;
using System.Collections.Generic;
namespace Antlr4.Runtime.Atn namespace Antlr4.Runtime.Atn
{ {
public class MergeCache public class MergeCache
{ {
Dictionary<PredictionContext, Dictionary<PredictionContext, PredictionContext>> data = new Dictionary<PredictionContext, Dictionary<PredictionContext, PredictionContext>>();
public PredictionContext Get(PredictionContext a, PredictionContext b) public PredictionContext Get(PredictionContext a, PredictionContext b)
{ {
throw new NotImplementedException(); Dictionary<PredictionContext, PredictionContext> first;
if (!data.TryGetValue(a, out first))
return null;
PredictionContext value;
if (first.TryGetValue(b, out value))
return value;
else
return null;
} }
public void Put(PredictionContext a, PredictionContext b, PredictionContext value) public void Put(PredictionContext a, PredictionContext b, PredictionContext value)
{ {
throw new NotImplementedException(); Dictionary<PredictionContext, PredictionContext> first;
if (!data.TryGetValue(a, out first))
{
first = new Dictionary<PredictionContext, PredictionContext>();
data[a] = first;
}
first[b] = value;
} }
} }
} }

View File

@ -1230,11 +1230,14 @@ namespace Antlr4.Runtime.Atn
* filter the prediction context for alternatives predicting alt>1 * filter the prediction context for alternatives predicting alt>1
* (basically a graph subtraction algorithm). * (basically a graph subtraction algorithm).
*/ */
PredictionContext context = statesFromAlt1[config.state.stateNumber]; PredictionContext ctx;
if (context != null && context.Equals(config.context)) if (statesFromAlt1.TryGetValue(config.state.stateNumber, out ctx))
{ {
// eliminated if (ctx != null && ctx.Equals(config.context))
continue; {
// eliminated
continue;
}
} }
} }
@ -1275,7 +1278,7 @@ namespace Antlr4.Runtime.Atn
{ {
if (ambigAlts[c.alt]) if (ambigAlts[c.alt])
{ {
altToPred[c.alt] = SemanticContext.Or(altToPred[c.alt], c.semanticContext); altToPred[c.alt] = SemanticContext.OrOp(altToPred[c.alt], c.semanticContext);
} }
} }
@ -1556,7 +1559,8 @@ namespace Antlr4.Runtime.Atn
int depth, int depth,
bool treatEofAsEpsilon) bool treatEofAsEpsilon)
{ {
if (debug) Console.WriteLine("closure(" + config.ToString(parser, true) + ")"); if (debug)
Console.WriteLine("closure(" + config.ToString(parser, true) + ")");
if (config.state is RuleStopState) if (config.state is RuleStopState)
{ {
@ -1960,7 +1964,7 @@ namespace Antlr4.Runtime.Atn
} }
} }
else { else {
SemanticContext newSemCtx = SemanticContext.And(config.semanticContext, pt.Predicate); SemanticContext newSemCtx = SemanticContext.AndOp(config.semanticContext, pt.Predicate);
c = new ATNConfig(config, pt.target, newSemCtx); c = new ATNConfig(config, pt.target, newSemCtx);
} }
} }
@ -2011,7 +2015,7 @@ namespace Antlr4.Runtime.Atn
} }
} }
else { else {
SemanticContext newSemCtx = SemanticContext.And(config.semanticContext, pt.Predicate); SemanticContext newSemCtx = SemanticContext.AndOp(config.semanticContext, pt.Predicate);
c = new ATNConfig(config, pt.target, newSemCtx); c = new ATNConfig(config, pt.target, newSemCtx);
} }
} }
@ -2324,20 +2328,19 @@ namespace Antlr4.Runtime.Atn
exact, ambigAlts, configs); exact, ambigAlts, configs);
} }
public void SetPredictionMode(PredictionMode mode) public PredictionMode PredictionMode
{ {
this.mode = mode; get
{
return this.mode;
}
set
{
this.mode = value;
}
} }
public PredictionMode GetPredictionMode()
{
return mode;
}
/**
* @since 4.3
*/
public Parser getParser() public Parser getParser()
{ {
return parser; return parser;

View File

@ -30,99 +30,19 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc; using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen; using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn namespace Antlr4.Runtime.Atn
{ {
/// <summary>
/// A tree structure used to record the semantic context in which
/// an ATN configuration is valid.
/// </summary>
/// <remarks>
/// A tree structure used to record the semantic context in which
/// an ATN configuration is valid. It's either a single predicate,
/// a conjunction
/// <c>p1&amp;&amp;p2</c>
/// , or a sum of products
/// <c>p1||p2</c>
/// .
/// <p>I have scoped the
/// <see cref="AND"/>
/// ,
/// <see cref="OR"/>
/// , and
/// <see cref="Predicate"/>
/// subclasses of
/// <see cref="SemanticContext"/>
/// within the scope of this outer class.</p>
/// </remarks>
public abstract class SemanticContext public abstract class SemanticContext
{ {
/// <summary>
/// The default
/// <see cref="SemanticContext"/>
/// , which is semantically equivalent to
/// a predicate of the form
/// <c/>
///
/// true}?}.
/// </summary>
public static readonly SemanticContext NONE = new SemanticContext.Predicate(); public static readonly SemanticContext NONE = new SemanticContext.Predicate();
/// <summary>
/// For context independent predicates, we evaluate them without a local
/// context (i.e., null context).
/// </summary>
/// <remarks>
/// For context independent predicates, we evaluate them without a local
/// context (i.e., null context). That way, we can evaluate them without
/// having to create proper rule-specific context during prediction (as
/// opposed to the parser, which creates them naturally). In a practical
/// sense, this avoids a cast exception from RuleContext to myruleContext.
/// <p>For context dependent predicates, we must pass in a local context so that
/// references such as $arg evaluate properly as _localctx.arg. We only
/// capture context dependent predicates in the context in which we begin
/// prediction, so we passed in the outer context here in case of context
/// dependent predicate evaluation.</p>
/// </remarks>
public abstract bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack) public abstract bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
where ATNInterpreter : ATNSimulator; where ATNInterpreter : ATNSimulator;
/// <summary>Evaluate the precedence predicates for the context and reduce the result.</summary>
/// <remarks>Evaluate the precedence predicates for the context and reduce the result.</remarks> public virtual SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
/// <param name="parser">The parser instance.</param>
/// <param name="parserCallStack"/>
/// <returns>
/// The simplified semantic context after precedence predicates are
/// evaluated, which will be one of the following values.
/// <ul>
/// <li>
/// <see cref="NONE"/>
/// : if the predicate simplifies to
/// <see langword="true"/>
/// after
/// precedence predicates are evaluated.</li>
/// <li>
/// <see langword="null"/>
/// : if the predicate simplifies to
/// <see langword="false"/>
/// after
/// precedence predicates are evaluated.</li>
/// <li>
/// <c>this</c>
/// : if the semantic context is not changed as a result of
/// precedence predicate evaluation.</li>
/// <li>A non-
/// <see langword="null"/>
///
/// <see cref="SemanticContext"/>
/// : the new simplified
/// semantic context after precedence predicates are evaluated.</li>
/// </ul>
/// </returns>
public virtual SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
where ATNInterpreter : ATNSimulator where ATNInterpreter : ATNSimulator
{ {
return this; return this;
@ -251,26 +171,8 @@ namespace Antlr4.Runtime.Atn
} }
} }
/// <summary>
/// This is the base class for semantic context "operators", which operate on
/// a collection of semantic context "operands".
/// </summary>
/// <remarks>
/// This is the base class for semantic context "operators", which operate on
/// a collection of semantic context "operands".
/// </remarks>
/// <since>4.3</since>
public abstract class Operator : SemanticContext public abstract class Operator : SemanticContext
{ {
/// <summary>Gets the operands for the semantic context operator.</summary>
/// <remarks>Gets the operands for the semantic context operator.</remarks>
/// <returns>
/// a collection of
/// <see cref="SemanticContext"/>
/// operands for the
/// operator.
/// </returns>
/// <since>4.3</since>
[NotNull] [NotNull]
public abstract ICollection<SemanticContext> Operands public abstract ICollection<SemanticContext> Operands
{ {
@ -278,14 +180,6 @@ namespace Antlr4.Runtime.Atn
} }
} }
/// <summary>
/// A semantic context which is true whenever none of the contained contexts
/// is false.
/// </summary>
/// <remarks>
/// A semantic context which is true whenever none of the contained contexts
/// is false.
/// </remarks>
public class AND : SemanticContext.Operator public class AND : SemanticContext.Operator
{ {
[NotNull] [NotNull]
@ -347,12 +241,6 @@ namespace Antlr4.Runtime.Atn
return MurmurHash.HashCode(opnds, typeof(SemanticContext.AND).GetHashCode()); return MurmurHash.HashCode(opnds, typeof(SemanticContext.AND).GetHashCode());
} }
/// <summary>
/// <inheritDoc/>
/// <p>
/// The evaluation of predicates by this context is short-circuiting, but
/// unordered.</p>
/// </summary>
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack) public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
{ {
foreach (SemanticContext opnd in opnds) foreach (SemanticContext opnd in opnds)
@ -399,7 +287,7 @@ namespace Antlr4.Runtime.Atn
SemanticContext result = operands[0]; SemanticContext result = operands[0];
for (int i = 1; i < operands.Count; i++) for (int i = 1; i < operands.Count; i++)
{ {
result = SemanticContext.And(result, operands[i]); result = SemanticContext.AndOp(result, operands[i]);
} }
return result; return result;
} }
@ -410,14 +298,6 @@ namespace Antlr4.Runtime.Atn
} }
} }
/// <summary>
/// A semantic context which is true whenever at least one of the contained
/// contexts is true.
/// </summary>
/// <remarks>
/// A semantic context which is true whenever at least one of the contained
/// contexts is true.
/// </remarks>
public class OR : SemanticContext.Operator public class OR : SemanticContext.Operator
{ {
[NotNull] [NotNull]
@ -479,12 +359,6 @@ namespace Antlr4.Runtime.Atn
return MurmurHash.HashCode(opnds, typeof(SemanticContext.OR).GetHashCode()); return MurmurHash.HashCode(opnds, typeof(SemanticContext.OR).GetHashCode());
} }
/// <summary>
/// <inheritDoc/>
/// <p>
/// The evaluation of predicates by this context is short-circuiting, but
/// unordered.</p>
/// </summary>
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack) public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
{ {
foreach (SemanticContext opnd in opnds) foreach (SemanticContext opnd in opnds)
@ -531,7 +405,7 @@ namespace Antlr4.Runtime.Atn
SemanticContext result = operands[0]; SemanticContext result = operands[0];
for (int i = 1; i < operands.Count; i++) for (int i = 1; i < operands.Count; i++)
{ {
result = SemanticContext.Or(result, operands[i]); result = SemanticContext.OrOp(result, operands[i]);
} }
return result; return result;
} }
@ -542,7 +416,7 @@ namespace Antlr4.Runtime.Atn
} }
} }
public static SemanticContext And(SemanticContext a, SemanticContext b) public static SemanticContext AndOp(SemanticContext a, SemanticContext b)
{ {
if (a == null || a == NONE) if (a == null || a == NONE)
{ {
@ -560,8 +434,7 @@ namespace Antlr4.Runtime.Atn
return result; return result;
} }
/// <seealso cref="ParserATNSimulator.GetPredsForAmbigAlts(Antlr4.Runtime.Sharpen.BitSet, ATNConfigSet, int)"/> public static SemanticContext OrOp(SemanticContext a, SemanticContext b)
public static SemanticContext Or(SemanticContext a, SemanticContext b)
{ {
if (a == null) if (a == null)
{ {

View File

@ -620,8 +620,7 @@ namespace Antlr4.Runtime
ATNState currentState = recognizer.Interpreter.atn.states[recognizer.State]; ATNState currentState = recognizer.Interpreter.atn.states[recognizer.State];
ATNState next = currentState.Transition(0).target; ATNState next = currentState.Transition(0).target;
ATN atn = recognizer.Interpreter.atn; ATN atn = recognizer.Interpreter.atn;
IntervalSet expectingAtLL2 = atn.NextTokens(next, PredictionContext.FromRuleContext(atn, recognizer.RuleContext)); IntervalSet expectingAtLL2 = atn.NextTokens(next, recognizer.RuleContext);
// System.out.println("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames()));
if (expectingAtLL2.Contains(currentSymbolType)) if (expectingAtLL2.Contains(currentSymbolType))
{ {
ReportMissingToken(recognizer); ReportMissingToken(recognizer);

View File

@ -132,7 +132,7 @@ namespace Antlr4.Runtime.Dfa
protected internal virtual string GetEdgeLabel(int i) protected internal virtual string GetEdgeLabel(int i)
{ {
return vocabulary.GetDisplayName(i); return vocabulary.GetDisplayName(i - 1);
} }
internal virtual string GetStateString(DFAState s) internal virtual string GetStateString(DFAState s)
@ -143,7 +143,7 @@ namespace Antlr4.Runtime.Dfa
} }
int n = s.stateNumber; int n = s.stateNumber;
string baseStateStr = (s.isAcceptState ? ":" : "") + "s" + n ; string baseStateStr = (s.isAcceptState ? ":" : "") + "s" + n + (s.requiresFullContext ? "^" : "");
if ( s.isAcceptState ) { if ( s.isAcceptState ) {
if ( s.predicates!=null ) { if ( s.predicates!=null ) {
return baseStateStr + "=>" + Arrays.ToString(s.predicates); return baseStateStr + "=>" + Arrays.ToString(s.predicates);

View File

@ -1163,9 +1163,9 @@ namespace Antlr4.Runtime
public virtual void DumpDFA() public virtual void DumpDFA()
{ {
bool seenOne = false; bool seenOne = false;
for (int d = 0; d < Interpreter.atn.decisionToDFA.Length; d++) for (int d = 0; d < Interpreter.decisionToDFA.Length; d++)
{ {
DFA dfa = Interpreter.atn.decisionToDFA[d]; DFA dfa = Interpreter.decisionToDFA[d];
if (dfa.states.Count>0) if (dfa.states.Count>0)
{ {
if (seenOne) if (seenOne)