Merge branch 'sharpen'

This commit is contained in:
Sam Harwell 2014-03-25 14:22:53 -05:00
commit 53f2c8f1a6
5 changed files with 54 additions and 11 deletions

@ -1 +1 @@
Subproject commit 5fb64ac91e36209b99e37a6356e66c41f5e50aab Subproject commit 8083e0b659bb318eb4454591648a01d28e07f03e

View File

@ -472,7 +472,7 @@ namespace Antlr4.Runtime.Atn
PredictionContext newContext = context.GetParent(i); PredictionContext newContext = context.GetParent(i);
// "pop" return state // "pop" return state
ATNState returnState = atn.states[returnStateNumber]; 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); currentAltReachedAcceptState = Closure(input, c, configs, currentAltReachedAcceptState, speculative);
} }
return currentAltReachedAcceptState; return currentAltReachedAcceptState;

View File

@ -1319,7 +1319,8 @@ namespace Antlr4.Runtime.Atn
/// .</li> /// .</li>
/// <li>Remove all configurations which predict an alternative greater than /// <li>Remove all configurations which predict an alternative greater than
/// 1, for which another configuration that predicts alternative 1 is in the /// 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:
/// <ul> /// <ul>
/// <li>The closure block cannot contain any epsilon transitions which bypass /// <li>The closure block cannot contain any epsilon transitions which bypass
/// the body of the closure, so all states reachable via alternative 1 are /// the body of the closure, so all states reachable via alternative 1 are
@ -1333,6 +1334,35 @@ namespace Antlr4.Runtime.Atn
/// </ul> /// </ul>
/// </li> /// </li>
/// </ol> /// </ol>
/// <p>
/// The prediction context must be considered by this filter to address
/// situations like the following.
/// </p>
/// <code>
/// <pre>
/// grammar TA;
/// prog: statement* EOF;
/// statement: letterA | statement letterA 'b' ;
/// letterA: 'a';
/// </pre>
/// </code>
/// <p>
/// If the above grammar, the ATN state immediately before the token
/// reference
/// <code>'a'</code>
/// in
/// <code>letterA</code>
/// is reachable from the left edge
/// of both the primary and closure blocks of the left-recursive rule
/// <code>statement</code>
/// . The prediction context associated with each of these
/// configurations distinguishes between them, and prevents the alternative
/// which stepped out to
/// <code>prog</code>
/// (and then back in to
/// <code>statement</code>
/// from being eliminated by the filter.
/// </p>
/// </summary> /// </summary>
/// <param name="configs"> /// <param name="configs">
/// The configuration set computed by /// The configuration set computed by
@ -1349,7 +1379,7 @@ namespace Antlr4.Runtime.Atn
[return: NotNull] [return: NotNull]
protected internal virtual ATNConfigSet ApplyPrecedenceFilter(ATNConfigSet configs, ParserRuleContext globalContext, PredictionContextCache contextCache) protected internal virtual ATNConfigSet ApplyPrecedenceFilter(ATNConfigSet configs, ParserRuleContext globalContext, PredictionContextCache contextCache)
{ {
HashSet<int> statesFromAlt1 = new HashSet<int>(); IDictionary<int, PredictionContext> statesFromAlt1 = new Dictionary<int, PredictionContext>();
ATNConfigSet configSet = new ATNConfigSet(); ATNConfigSet configSet = new ATNConfigSet();
foreach (ATNConfig config in configs) foreach (ATNConfig config in configs)
{ {
@ -1364,7 +1394,7 @@ namespace Antlr4.Runtime.Atn
// the configuration was eliminated // the configuration was eliminated
continue; continue;
} }
statesFromAlt1.Add(config.State.stateNumber); statesFromAlt1.Put(config.State.stateNumber, config.Context);
if (updatedContext != config.SemanticContext) if (updatedContext != config.SemanticContext)
{ {
configSet.Add(config.Transform(config.State, updatedContext, false), contextCache); configSet.Add(config.Transform(config.State, updatedContext, false), contextCache);
@ -1381,7 +1411,8 @@ namespace Antlr4.Runtime.Atn
// already handled // already handled
continue; 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 // eliminated
continue; continue;
@ -1785,9 +1816,9 @@ namespace Antlr4.Runtime.Atn
return config.Transform(t.target, newContext, false); return config.Transform(t.target, newContext, false);
} }
private sealed class _IComparer_1741 : IComparer<ATNConfig> private sealed class _IComparer_1771 : IComparer<ATNConfig>
{ {
public _IComparer_1741() public _IComparer_1771()
{ {
} }
@ -1807,7 +1838,7 @@ namespace Antlr4.Runtime.Atn
} }
} }
private static readonly IComparer<ATNConfig> StateAltSortComparator = new _IComparer_1741(); private static readonly IComparer<ATNConfig> StateAltSortComparator = new _IComparer_1771();
private BitSet IsConflicted(ATNConfigSet configset, PredictionContextCache contextCache) private BitSet IsConflicted(ATNConfigSet configset, PredictionContextCache contextCache)
{ {

View File

@ -143,10 +143,20 @@ namespace Antlr4.Runtime
{ {
// pop; return from rule // pop; return from rule
if (_ctx.IsEmpty()) if (_ctx.IsEmpty())
{
if (startRuleStartState.isPrecedenceRule)
{
ParserRuleContext result = _ctx;
Tuple<ParserRuleContext, int> parentContext = _parentContextStack.Pop();
UnrollRecursionContexts(parentContext.Item1);
return result;
}
else
{ {
ExitRule(); ExitRule();
return rootContext; return rootContext;
} }
}
VisitRuleStopState(p); VisitRuleStopState(p);
break; break;
} }

View File

@ -229,6 +229,8 @@ namespace Antlr4.Runtime
/// your token objects because you don't have to go modify your lexer /// your token objects because you don't have to go modify your lexer
/// so that it creates a new Java type. /// so that it creates a new Java type.
/// </remarks> /// </remarks>
[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) public virtual string GetTokenErrorDisplay(IToken t)
{ {
if (t == null) if (t == null)