diff --git a/reference/antlr4 b/reference/antlr4 index 5fb64ac91..8083e0b65 160000 --- a/reference/antlr4 +++ b/reference/antlr4 @@ -1 +1 @@ -Subproject commit 5fb64ac91e36209b99e37a6356e66c41f5e50aab +Subproject commit 8083e0b659bb318eb4454591648a01d28e07f03e diff --git a/runtime/CSharp/Antlr4.Runtime/Atn/LexerATNSimulator.cs b/runtime/CSharp/Antlr4.Runtime/Atn/LexerATNSimulator.cs index b6a7a94c0..01d55a1e6 100644 --- a/runtime/CSharp/Antlr4.Runtime/Atn/LexerATNSimulator.cs +++ b/runtime/CSharp/Antlr4.Runtime/Atn/LexerATNSimulator.cs @@ -472,7 +472,7 @@ namespace Antlr4.Runtime.Atn PredictionContext newContext = context.GetParent(i); // "pop" return state ATNState returnState = atn.states[returnStateNumber]; - ATNConfig c = ATNConfig.Create(returnState, config.Alt, newContext); + ATNConfig c = config.Transform(returnState, newContext, false); currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative); } return currentAltReachedAcceptState; diff --git a/runtime/CSharp/Antlr4.Runtime/Atn/ParserATNSimulator.cs b/runtime/CSharp/Antlr4.Runtime/Atn/ParserATNSimulator.cs index 5eaa13b15..71e68ad6f 100644 --- a/runtime/CSharp/Antlr4.Runtime/Atn/ParserATNSimulator.cs +++ b/runtime/CSharp/Antlr4.Runtime/Atn/ParserATNSimulator.cs @@ -1319,7 +1319,8 @@ namespace Antlr4.Runtime.Atn /// . ///
  • Remove all configurations which predict an alternative greater than /// 1, for which another configuration that predicts alternative 1 is in the - /// same ATN state. This transformation is valid for the following reasons: + /// same ATN state with the same prediction context. This transformation is + /// valid for the following reasons: /// ///
  • /// + ///

    + /// The prediction context must be considered by this filter to address + /// situations like the following. + ///

    + /// + ///
    +        /// grammar TA;
    +        /// prog: statement* EOF;
    +        /// statement: letterA | statement letterA 'b' ;
    +        /// letterA: 'a';
    +        /// 
    + ///
    + ///

    + /// If the above grammar, the ATN state immediately before the token + /// reference + /// 'a' + /// in + /// letterA + /// is reachable from the left edge + /// of both the primary and closure blocks of the left-recursive rule + /// statement + /// . The prediction context associated with each of these + /// configurations distinguishes between them, and prevents the alternative + /// which stepped out to + /// prog + /// (and then back in to + /// statement + /// from being eliminated by the filter. + ///

    /// /// /// The configuration set computed by @@ -1349,7 +1379,7 @@ namespace Antlr4.Runtime.Atn [return: NotNull] protected internal virtual ATNConfigSet ApplyPrecedenceFilter(ATNConfigSet configs, ParserRuleContext globalContext, PredictionContextCache contextCache) { - HashSet statesFromAlt1 = new HashSet(); + IDictionary statesFromAlt1 = new Dictionary(); ATNConfigSet configSet = new ATNConfigSet(); foreach (ATNConfig config in configs) { @@ -1364,7 +1394,7 @@ namespace Antlr4.Runtime.Atn // the configuration was eliminated continue; } - statesFromAlt1.Add(config.State.stateNumber); + statesFromAlt1.Put(config.State.stateNumber, config.Context); if (updatedContext != config.SemanticContext) { configSet.Add(config.Transform(config.State, updatedContext, false), contextCache); @@ -1381,7 +1411,8 @@ namespace Antlr4.Runtime.Atn // already handled continue; } - if (statesFromAlt1.Contains(config_1.State.stateNumber)) + PredictionContext context = statesFromAlt1.Get(config_1.State.stateNumber); + if (context != null && context.Equals(config_1.Context)) { // eliminated continue; @@ -1785,9 +1816,9 @@ namespace Antlr4.Runtime.Atn return config.Transform(t.target, newContext, false); } - private sealed class _IComparer_1741 : IComparer + private sealed class _IComparer_1771 : IComparer { - public _IComparer_1741() + public _IComparer_1771() { } @@ -1807,7 +1838,7 @@ namespace Antlr4.Runtime.Atn } } - private static readonly IComparer StateAltSortComparator = new _IComparer_1741(); + private static readonly IComparer StateAltSortComparator = new _IComparer_1771(); private BitSet IsConflicted(ATNConfigSet configset, PredictionContextCache contextCache) { diff --git a/runtime/CSharp/Antlr4.Runtime/ParserInterpreter.cs b/runtime/CSharp/Antlr4.Runtime/ParserInterpreter.cs index ee01d635c..9d27180f8 100644 --- a/runtime/CSharp/Antlr4.Runtime/ParserInterpreter.cs +++ b/runtime/CSharp/Antlr4.Runtime/ParserInterpreter.cs @@ -144,8 +144,18 @@ namespace Antlr4.Runtime // pop; return from rule if (_ctx.IsEmpty()) { - ExitRule(); - return rootContext; + if (startRuleStartState.isPrecedenceRule) + { + ParserRuleContext result = _ctx; + Tuple parentContext = _parentContextStack.Pop(); + UnrollRecursionContexts(parentContext.Item1); + return result; + } + else + { + ExitRule(); + return rootContext; + } } VisitRuleStopState(p); break; diff --git a/runtime/CSharp/Antlr4.Runtime/Recognizer`2.cs b/runtime/CSharp/Antlr4.Runtime/Recognizer`2.cs index adcab8135..13df4c056 100644 --- a/runtime/CSharp/Antlr4.Runtime/Recognizer`2.cs +++ b/runtime/CSharp/Antlr4.Runtime/Recognizer`2.cs @@ -229,6 +229,8 @@ namespace Antlr4.Runtime /// your token objects because you don't have to go modify your lexer /// so that it creates a new Java type. /// + [Obsolete] + [System.ObsoleteAttribute(@"This method is not called by the ANTLR 4 Runtime. Specific implementations of IAntlrErrorStrategy may provide a similar feature when necessary. For example, seeDefaultErrorStrategy.GetTokenErrorDisplay(IToken) .")] public virtual string GetTokenErrorDisplay(IToken t) { if (t == null)