This commit is contained in:
Eric Vergnaud 2016-12-11 20:29:05 +08:00
parent f11a380609
commit 10a1580448
72 changed files with 5643 additions and 6729 deletions

View File

@ -25,7 +25,7 @@
<DefineConstants>DEBUG;TRACE;NET35PLUS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>1591</NoWarn>
<NoWarn>1591 0659</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
@ -232,6 +232,9 @@
<Compile Include="Dfa\IEdgeMap.cs" />
<Compile Include="Dfa\SingletonEdgeMap.cs" />
<Compile Include="Dfa\SparseEdgeMap.cs" />
<Compile Include="Misc\Pair.cs" />
<Compile Include="Atn\LexerATNConfig.cs" />
<Compile Include="Atn\MergeCache.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -153,7 +153,7 @@ namespace Antlr4.Runtime
{
if (p >= n)
{
System.Diagnostics.Debug.Assert(La(1) == IntStreamConstants.Eof);
System.Diagnostics.Debug.Assert(LA(1) == IntStreamConstants.EOF);
throw new InvalidOperationException("cannot consume EOF");
}
//System.out.println("prev p="+p+", c="+(char)data[p]);
@ -164,7 +164,7 @@ namespace Antlr4.Runtime
}
//System.out.println("p moves to "+p+" (c='"+(char)data[p]+"')");
public virtual int La(int i)
public virtual int LA(int i)
{
if (i == 0)
{
@ -177,14 +177,14 @@ namespace Antlr4.Runtime
// e.g., translate LA(-1) to use offset i=0; then data[p+0-1]
if ((p + i - 1) < 0)
{
return IntStreamConstants.Eof;
return IntStreamConstants.EOF;
}
}
// invalid; no char before first char
if ((p + i - 1) >= n)
{
//System.out.println("char LA("+i+")=EOF; p="+p);
return IntStreamConstants.Eof;
return IntStreamConstants.EOF;
}
//System.out.println("char LA("+i+")="+(char)data[p+i-1]+"; p="+p);
//System.out.println("LA("+i+"); p="+p+" n="+n+" data.length="+data.length);
@ -193,7 +193,7 @@ namespace Antlr4.Runtime
public virtual int Lt(int i)
{
return La(i);
return LA(i);
}
/// <summary>

View File

@ -40,7 +40,7 @@ namespace Antlr4.Runtime.Atn
{
public class ATN
{
public const int InvalidAltNumber = 0;
public const int INVALID_ALT_NUMBER = 0;
[NotNull]
public readonly IList<ATNState> states = new List<ATNState>();
@ -99,7 +99,7 @@ namespace Antlr4.Runtime.Atn
[NotNull]
public readonly IList<TokensStartState> modeToStartState = new List<TokensStartState>();
private readonly ConcurrentDictionary<PredictionContext, PredictionContext> contextCache = new ConcurrentDictionary<PredictionContext, PredictionContext>();
private readonly PredictionContextCache contextCache = new PredictionContextCache();
[NotNull]
public DFA[] decisionToDFA = new DFA[0];
@ -116,30 +116,7 @@ namespace Antlr4.Runtime.Atn
this.maxTokenType = maxTokenType;
}
public void ClearDFA()
{
decisionToDFA = new DFA[decisionToState.Count];
for (int i = 0; i < decisionToDFA.Length; i++)
{
decisionToDFA[i] = new DFA(decisionToState[i], i);
}
modeToDFA = new DFA[modeToStartState.Count];
for (int i_1 = 0; i_1 < modeToDFA.Length; i_1++)
{
modeToDFA[i_1] = new DFA(modeToStartState[i_1]);
}
contextCache.Clear();
LL1Table.Clear();
}
public virtual int ContextCacheSize
{
get
{
return contextCache.Count;
}
}
public virtual PredictionContext GetCachedContext(PredictionContext context)
{
return PredictionContext.GetCachedContext(context, contextCache, new PredictionContext.IdentityHashMap());
@ -175,7 +152,7 @@ namespace Antlr4.Runtime.Atn
/// <paramref name="s"/>
/// and
/// staying in same rule.
/// <see cref="TokenConstants.Epsilon"/>
/// <see cref="TokenConstants.EPSILON"/>
/// is in set if we reach end of
/// rule.
/// </summary>
@ -186,7 +163,7 @@ namespace Antlr4.Runtime.Atn
{
return s.nextTokenWithinRule;
}
s.nextTokenWithinRule = NextTokens(s, PredictionContext.EmptyLocal);
s.nextTokenWithinRule = NextTokens(s, PredictionContext.EMPTY);
s.nextTokenWithinRule.SetReadonly(true);
return s.nextTokenWithinRule;
}
@ -254,7 +231,7 @@ namespace Antlr4.Runtime.Atn
/// <see cref="RuleStopState"/>
/// of the outermost context without matching any
/// symbols,
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// is added to the returned set.
/// <p>If
/// <paramref name="context"/>
@ -285,25 +262,25 @@ namespace Antlr4.Runtime.Atn
RuleContext ctx = context;
ATNState s = states[stateNumber];
IntervalSet following = NextTokens(s);
if (!following.Contains(TokenConstants.Epsilon))
if (!following.Contains(TokenConstants.EPSILON))
{
return following;
}
IntervalSet expected = new IntervalSet();
expected.AddAll(following);
expected.Remove(TokenConstants.Epsilon);
while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.Epsilon))
expected.Remove(TokenConstants.EPSILON);
while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.EPSILON))
{
ATNState invokingState = states[ctx.invokingState];
RuleTransition rt = (RuleTransition)invokingState.Transition(0);
following = NextTokens(rt.followState);
expected.AddAll(following);
expected.Remove(TokenConstants.Epsilon);
expected.Remove(TokenConstants.EPSILON);
ctx = ctx.Parent;
}
if (following.Contains(TokenConstants.Epsilon))
if (following.Contains(TokenConstants.EPSILON))
{
expected.Add(TokenConstants.Eof);
expected.Add(TokenConstants.EOF);
}
return expected;
}

View File

@ -37,581 +37,235 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>A tuple: (ATN state, predicted alt, syntactic, semantic context).</summary>
/// <remarks>
/// A tuple: (ATN state, predicted alt, syntactic, semantic context).
/// The syntactic context is a graph-structured stack node whose
/// path(s) to the root is the rule invocation(s)
/// chain used to arrive at the state. The semantic context is
/// the tree of semantic predicates encountered before reaching
/// an ATN state.
/// </remarks>
public class ATNConfig
{
/// <summary>
/// This field stores the bit mask for implementing the
/// <see cref="PrecedenceFilterSuppressed()"/>
/// property as a bit within the
/// existing
/// <see cref="altAndOuterContextDepth"/>
/// field.
/// </summary>
private const int SuppressPrecedenceFilter = unchecked((int)(0x80000000));
/** A tuple: (ATN state, predicted alt, syntactic, semantic context).
* The syntactic context is a graph-structured stack node whose
* path(s) to the root is the rule invocation(s)
* chain used to arrive at the state. The semantic context is
* the tree of semantic predicates encountered before reaching
* an ATN state.
*/
public class ATNConfig
{
/**
* This field stores the bit mask for implementing the
* {@link #isPrecedenceFilterSuppressed} property as a bit within the
* existing {@link #reachesIntoOuterContext} field.
*/
private static readonly int SUPPRESS_PRECEDENCE_FILTER = 0x40000000;
/// <summary>The ATN state associated with this configuration</summary>
[NotNull]
private readonly ATNState state;
/** The ATN state associated with this configuration */
public readonly ATNState state;
/// <summary>This is a bit-field currently containing the following values.</summary>
/// <remarks>
/// This is a bit-field currently containing the following values.
/// <ul>
/// <li>0x00FFFFFF: Alternative</li>
/// <li>0x7F000000: Outer context depth</li>
/// <li>0x80000000: Suppress precedence filter</li>
/// </ul>
/// </remarks>
private int altAndOuterContextDepth;
/** What alt (or lexer rule) is predicted by this configuration */
public readonly int alt;
/// <summary>
/// The stack of invoking states leading to the rule/states associated
/// with this config.
/// </summary>
/// <remarks>
/// The stack of invoking states leading to the rule/states associated
/// with this config. We track only those contexts pushed during
/// execution of the ATN simulator.
/// </remarks>
[NotNull]
private PredictionContext context;
/** The stack of invoking states leading to the rule/states associated
* with this config. We track only those contexts pushed during
* execution of the ATN simulator.
*/
public PredictionContext context;
protected internal ATNConfig(ATNState state, int alt, PredictionContext context)
{
System.Diagnostics.Debug.Assert((alt & unchecked((int)(0xFFFFFF))) == alt);
this.state = state;
this.altAndOuterContextDepth = alt;
this.context = context;
}
/**
* We cannot execute predicates dependent upon local context unless
* we know for sure we are in the correct context. Because there is
* no way to do this efficiently, we simply cannot evaluate
* dependent predicates unless we are in the rule that initially
* invokes the ATN simulator.
*
* <p>
* closure() tracks the depth of how far we dip into the outer context:
* depth &gt; 0. Note that it may not be totally accurate depth since I
* don't ever decrement. TODO: make it a boolean then</p>
*
* <p>
* For memory efficiency, the {@link #isPrecedenceFilterSuppressed} method
* is also backed by this field. Since the field is publicly accessible, the
* highest bit which would not cause the value to become negative is used to
* store this field. This choice minimizes the risk that code which only
* compares this value to 0 would be affected by the new purpose of the
* flag. It also ensures the performance of the existing {@link ATNConfig}
* constructors as well as certain operations like
* {@link ATNConfigSet#add(ATNConfig, DoubleKeyMap)} method are
* <em>completely</em> unaffected by the change.</p>
*/
public int reachesIntoOuterContext;
protected internal ATNConfig(Antlr4.Runtime.Atn.ATNConfig c, ATNState state, PredictionContext context)
{
this.state = state;
this.altAndOuterContextDepth = c.altAndOuterContextDepth;
this.context = context;
}
public static Antlr4.Runtime.Atn.ATNConfig Create(ATNState state, int alt, PredictionContext context)
{
return Create(state, alt, context, Antlr4.Runtime.Atn.SemanticContext.None, null);
}
public readonly SemanticContext semanticContext;
public static Antlr4.Runtime.Atn.ATNConfig Create(ATNState state, int alt, PredictionContext context, Antlr4.Runtime.Atn.SemanticContext semanticContext)
{
return Create(state, alt, context, semanticContext, null);
}
public ATNConfig(ATNConfig old)
{ // dup
this.state = old.state;
this.alt = old.alt;
this.context = old.context;
this.semanticContext = old.semanticContext;
this.reachesIntoOuterContext = old.reachesIntoOuterContext;
}
public static Antlr4.Runtime.Atn.ATNConfig Create(ATNState state, int alt, PredictionContext context, Antlr4.Runtime.Atn.SemanticContext semanticContext, LexerActionExecutor lexerActionExecutor)
{
if (semanticContext != Antlr4.Runtime.Atn.SemanticContext.None)
{
if (lexerActionExecutor != null)
{
return new ATNConfig.ActionSemanticContextATNConfig(lexerActionExecutor, semanticContext, state, alt, context, false);
}
else
{
return new ATNConfig.SemanticContextATNConfig(semanticContext, state, alt, context);
}
}
else
{
if (lexerActionExecutor != null)
{
return new ATNConfig.ActionATNConfig(lexerActionExecutor, state, alt, context, false);
}
else
{
return new Antlr4.Runtime.Atn.ATNConfig(state, alt, context);
}
}
}
public ATNConfig(ATNState state,
int alt,
PredictionContext context)
: this(state, alt, context, SemanticContext.NONE)
{
}
/// <summary>Gets the ATN state associated with this configuration.</summary>
/// <remarks>Gets the ATN state associated with this configuration.</remarks>
public ATNState State
{
get
{
return state;
}
}
public ATNConfig(ATNState state,
int alt,
PredictionContext context,
SemanticContext semanticContext)
{
this.state = state;
this.alt = alt;
this.context = context;
this.semanticContext = semanticContext;
}
/// <summary>What alt (or lexer rule) is predicted by this configuration.</summary>
/// <remarks>What alt (or lexer rule) is predicted by this configuration.</remarks>
public int Alt
{
get
{
return altAndOuterContextDepth & unchecked((int)(0x00FFFFFF));
}
}
public ATNConfig(ATNConfig c, ATNState state)
: this(c, state, c.context, c.semanticContext)
{
}
public virtual PredictionContext Context
{
get
{
return context;
}
set
{
PredictionContext context = value;
this.context = context;
}
}
public ATNConfig(ATNConfig c, ATNState state,
SemanticContext semanticContext)
: this(c, state, c.context, semanticContext)
{
}
public bool ReachesIntoOuterContext
{
get
{
return OuterContextDepth != 0;
}
}
public ATNConfig(ATNConfig c,
SemanticContext semanticContext)
: this(c, c.state, c.context, semanticContext)
{
}
/// <summary>
/// We cannot execute predicates dependent upon local context unless
/// we know for sure we are in the correct context.
/// </summary>
/// <remarks>
/// We cannot execute predicates dependent upon local context unless
/// we know for sure we are in the correct context. Because there is
/// no way to do this efficiently, we simply cannot evaluate
/// dependent predicates unless we are in the rule that initially
/// invokes the ATN simulator.
/// <p>
/// closure() tracks the depth of how far we dip into the outer context:
/// depth &gt; 0. Note that it may not be totally accurate depth since I
/// don't ever decrement. TODO: make it a boolean then</p>
/// </remarks>
public virtual int OuterContextDepth
{
get
{
return ((int)(((uint)altAndOuterContextDepth) >> 24)) & unchecked((int)(0x7F));
}
set
{
int outerContextDepth = value;
System.Diagnostics.Debug.Assert(outerContextDepth >= 0);
// saturate at 0x7F - everything but zero/positive is only used for debug information anyway
outerContextDepth = Math.Min(outerContextDepth, unchecked((int)(0x7F)));
this.altAndOuterContextDepth = (outerContextDepth << 24) | (altAndOuterContextDepth & ~unchecked((int)(0x7F000000)));
}
}
public ATNConfig(ATNConfig c, ATNState state,
PredictionContext context)
: this(c, state, context, c.semanticContext)
{
}
public virtual LexerActionExecutor ActionExecutor
{
get
{
return null;
}
}
public ATNConfig(ATNConfig c, ATNState state,
PredictionContext context,
SemanticContext semanticContext)
{
this.state = state;
this.alt = c.alt;
this.context = context;
this.semanticContext = semanticContext;
this.reachesIntoOuterContext = c.reachesIntoOuterContext;
}
public virtual Antlr4.Runtime.Atn.SemanticContext SemanticContext
{
get
{
return Antlr4.Runtime.Atn.SemanticContext.None;
}
}
/**
* This method gets the value of the {@link #reachesIntoOuterContext} field
* as it existed prior to the introduction of the
* {@link #isPrecedenceFilterSuppressed} method.
*/
public int OuterContextDepth
{
get
{
return reachesIntoOuterContext & ~SUPPRESS_PRECEDENCE_FILTER;
}
}
public virtual bool PassedThroughNonGreedyDecision
{
get
{
return false;
}
}
public bool IsPrecedenceFilterSuppressed
{
get
{
return (reachesIntoOuterContext & SUPPRESS_PRECEDENCE_FILTER) != 0;
}
}
public Antlr4.Runtime.Atn.ATNConfig Clone()
{
return Transform(this.State, false);
}
public void SetPrecedenceFilterSuppressed(bool value)
{
if (value)
{
this.reachesIntoOuterContext |= SUPPRESS_PRECEDENCE_FILTER;
}
else {
this.reachesIntoOuterContext &= ~SUPPRESS_PRECEDENCE_FILTER;
}
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, bool checkNonGreedy)
{
return Transform(state, this.context, this.SemanticContext, checkNonGreedy, this.ActionExecutor);
}
/** 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.
*/
public override bool Equals(Object o)
{
if (!(o is ATNConfig)) {
return false;
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, Antlr4.Runtime.Atn.SemanticContext semanticContext, bool checkNonGreedy)
{
return Transform(state, this.context, semanticContext, checkNonGreedy, this.ActionExecutor);
}
return this.Equals((ATNConfig)o);
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, PredictionContext context, bool checkNonGreedy)
{
return Transform(state, context, this.SemanticContext, checkNonGreedy, this.ActionExecutor);
}
public virtual bool Equals(ATNConfig other)
{
if (this == other)
{
return true;
}
else if (other == null)
{
return false;
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, LexerActionExecutor lexerActionExecutor, bool checkNonGreedy)
{
return Transform(state, context, this.SemanticContext, checkNonGreedy, lexerActionExecutor);
}
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)
&& this.IsPrecedenceFilterSuppressed == other.IsPrecedenceFilterSuppressed;
}
private Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, PredictionContext context, Antlr4.Runtime.Atn.SemanticContext semanticContext, bool checkNonGreedy, LexerActionExecutor lexerActionExecutor)
{
bool passedThroughNonGreedy = checkNonGreedy && CheckNonGreedyDecision(this, state);
if (semanticContext != Antlr4.Runtime.Atn.SemanticContext.None)
{
if (lexerActionExecutor != null || passedThroughNonGreedy)
{
return new ATNConfig.ActionSemanticContextATNConfig(lexerActionExecutor, semanticContext, this, state, context, passedThroughNonGreedy);
}
else
{
return new ATNConfig.SemanticContextATNConfig(semanticContext, this, state, context);
}
}
else
{
if (lexerActionExecutor != null || passedThroughNonGreedy)
{
return new ATNConfig.ActionATNConfig(lexerActionExecutor, this, state, context, passedThroughNonGreedy);
}
else
{
return new Antlr4.Runtime.Atn.ATNConfig(this, state, context);
}
}
}
public override int GetHashCode()
{
int hashCode = MurmurHash.Initialize(7);
hashCode = MurmurHash.Update(hashCode, state.stateNumber);
hashCode = MurmurHash.Update(hashCode, alt);
hashCode = MurmurHash.Update(hashCode, context);
hashCode = MurmurHash.Update(hashCode, semanticContext);
hashCode = MurmurHash.Finish(hashCode, 4);
return hashCode;
}
private static bool CheckNonGreedyDecision(Antlr4.Runtime.Atn.ATNConfig source, ATNState target)
{
return source.PassedThroughNonGreedyDecision || target is DecisionState && ((DecisionState)target).nonGreedy;
}
public override String ToString()
{
return ToString(null, true);
}
public virtual Antlr4.Runtime.Atn.ATNConfig AppendContext(int context, PredictionContextCache contextCache)
{
PredictionContext appendedContext = Context.AppendContext(context, contextCache);
Antlr4.Runtime.Atn.ATNConfig result = Transform(State, appendedContext, false);
return result;
}
public String ToString(IRecognizer recog, bool showAlt)
{
StringBuilder buf = new StringBuilder();
// if ( state.ruleIndex>=0 ) {
// if ( recog!=null ) buf.append(recog.getRuleNames()[state.ruleIndex]+":");
// else buf.append(state.ruleIndex+":");
// }
buf.Append('(');
buf.Append(state);
if (showAlt)
{
buf.Append(",");
buf.Append(alt);
}
if (context != null)
{
buf.Append(",[");
buf.Append(context.ToString());
buf.Append("]");
}
if (semanticContext != null && semanticContext != SemanticContext.NONE)
{
buf.Append(",");
buf.Append(semanticContext);
}
if (OuterContextDepth > 0)
{
buf.Append(",up=").Append(OuterContextDepth);
}
buf.Append(')');
return buf.ToString();
}
}
public virtual Antlr4.Runtime.Atn.ATNConfig AppendContext(PredictionContext context, PredictionContextCache contextCache)
{
PredictionContext appendedContext = Context.AppendContext(context, contextCache);
Antlr4.Runtime.Atn.ATNConfig result = Transform(State, appendedContext, false);
return result;
}
public virtual bool Contains(Antlr4.Runtime.Atn.ATNConfig subconfig)
{
if (this.state.stateNumber != subconfig.State.stateNumber || this.Alt != subconfig.Alt || !this.SemanticContext.Equals(subconfig.SemanticContext))
{
return false;
}
Stack<PredictionContext> leftWorkList = new Stack<PredictionContext>();
Stack<PredictionContext> rightWorkList = new Stack<PredictionContext>();
leftWorkList.Push(Context);
rightWorkList.Push(subconfig.Context);
while (leftWorkList.Count > 0)
{
PredictionContext left = leftWorkList.Pop();
PredictionContext right = rightWorkList.Pop();
if (left == right)
{
return true;
}
if (left.Size < right.Size)
{
return false;
}
if (right.IsEmpty)
{
return left.HasEmpty;
}
else
{
for (int i = 0; i < right.Size; i++)
{
int index = left.FindReturnState(right.GetReturnState(i));
if (index < 0)
{
// assumes invokingStates has no duplicate entries
return false;
}
leftWorkList.Push(left.GetParent(index));
rightWorkList.Push(right.GetParent(i));
}
}
}
return false;
}
public bool PrecedenceFilterSuppressed
{
get
{
return (altAndOuterContextDepth & SuppressPrecedenceFilter) != 0;
}
set
{
if (value)
{
this.altAndOuterContextDepth |= SuppressPrecedenceFilter;
}
else
{
this.altAndOuterContextDepth &= ~SuppressPrecedenceFilter;
}
}
}
/// <summary>
/// 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.
/// </summary>
/// <remarks>
/// 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.
/// </remarks>
public override bool Equals(object o)
{
if (!(o is Antlr4.Runtime.Atn.ATNConfig))
{
return false;
}
return this.Equals((Antlr4.Runtime.Atn.ATNConfig)o);
}
public virtual bool Equals(Antlr4.Runtime.Atn.ATNConfig other)
{
if (this == other)
{
return true;
}
else
{
if (other == null)
{
return false;
}
}
return this.State.stateNumber == other.State.stateNumber && this.Alt == other.Alt && this.ReachesIntoOuterContext == other.ReachesIntoOuterContext && this.Context.Equals(other.Context) && this.SemanticContext.Equals(other.SemanticContext) && this.PrecedenceFilterSuppressed == other.PrecedenceFilterSuppressed && this.PassedThroughNonGreedyDecision == other.PassedThroughNonGreedyDecision && EqualityComparer<LexerActionExecutor>.Default.Equals(this.ActionExecutor, other.ActionExecutor);
}
public override int GetHashCode()
{
int hashCode = MurmurHash.Initialize(7);
hashCode = MurmurHash.Update(hashCode, State.stateNumber);
hashCode = MurmurHash.Update(hashCode, Alt);
hashCode = MurmurHash.Update(hashCode, ReachesIntoOuterContext ? 1 : 0);
hashCode = MurmurHash.Update(hashCode, Context);
hashCode = MurmurHash.Update(hashCode, SemanticContext);
hashCode = MurmurHash.Update(hashCode, PassedThroughNonGreedyDecision ? 1 : 0);
hashCode = MurmurHash.Update(hashCode, ActionExecutor);
hashCode = MurmurHash.Finish(hashCode, 7);
return hashCode;
}
public virtual string ToDotString()
{
#if COMPACT
throw new NotImplementedException("The current platform does not provide RuntimeHelpers.GetHashCode(object).");
#else
StringBuilder builder = new StringBuilder();
builder.Append("digraph G {\n");
builder.Append("rankdir=LR;\n");
HashSet<PredictionContext> visited = new HashSet<PredictionContext>();
Stack<PredictionContext> workList = new Stack<PredictionContext>();
workList.Push(Context);
visited.Add(Context);
while (workList.Count > 0)
{
PredictionContext current = workList.Pop();
for (int i = 0; i < current.Size; i++)
{
builder.Append(" s").Append(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(current));
builder.Append("->");
builder.Append("s").Append(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(current.GetParent(i)));
builder.Append("[label=\"").Append(current.GetReturnState(i)).Append("\"];\n");
if (visited.Add(current.GetParent(i)))
{
workList.Push(current.GetParent(i));
}
}
}
builder.Append("}\n");
return builder.ToString();
#endif
}
public override string ToString()
{
return ToString(null, true, false);
}
public virtual string ToString(IRecognizer recog, bool showAlt)
{
return ToString(recog, showAlt, true);
}
public virtual string ToString(IRecognizer recog, bool showAlt, bool showContext)
{
StringBuilder buf = new StringBuilder();
// if ( state.ruleIndex>=0 ) {
// if ( recog!=null ) buf.append(recog.getRuleNames()[state.ruleIndex]+":");
// else buf.append(state.ruleIndex+":");
// }
string[] contexts;
if (showContext)
{
contexts = Context.ToStrings(recog, this.State.stateNumber);
}
else
{
contexts = new string[] { "?" };
}
bool first = true;
foreach (string contextDesc in contexts)
{
if (first)
{
first = false;
}
else
{
buf.Append(", ");
}
buf.Append('(');
buf.Append(State);
if (showAlt)
{
buf.Append(",");
buf.Append(Alt);
}
if (Context != null)
{
buf.Append(",");
buf.Append(contextDesc);
}
if (SemanticContext != null && SemanticContext != Antlr4.Runtime.Atn.SemanticContext.None)
{
buf.Append(",");
buf.Append(SemanticContext);
}
if (ReachesIntoOuterContext)
{
buf.Append(",up=").Append(OuterContextDepth);
}
buf.Append(')');
}
return buf.ToString();
}
private class SemanticContextATNConfig : ATNConfig
{
[NotNull]
private readonly Antlr4.Runtime.Atn.SemanticContext semanticContext;
public SemanticContextATNConfig(Antlr4.Runtime.Atn.SemanticContext semanticContext, ATNState state, int alt, PredictionContext context)
: base(state, alt, context)
{
this.semanticContext = semanticContext;
}
public SemanticContextATNConfig(Antlr4.Runtime.Atn.SemanticContext semanticContext, ATNConfig c, ATNState state, PredictionContext context)
: base(c, state, context)
{
this.semanticContext = semanticContext;
}
public override Antlr4.Runtime.Atn.SemanticContext SemanticContext
{
get
{
return semanticContext;
}
}
}
private class ActionATNConfig : ATNConfig
{
private readonly LexerActionExecutor lexerActionExecutor;
private readonly bool passedThroughNonGreedyDecision;
public ActionATNConfig(LexerActionExecutor lexerActionExecutor, ATNState state, int alt, PredictionContext context, bool passedThroughNonGreedyDecision)
: base(state, alt, context)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
}
protected internal ActionATNConfig(LexerActionExecutor lexerActionExecutor, ATNConfig c, ATNState state, PredictionContext context, bool passedThroughNonGreedyDecision)
: base(c, state, context)
{
if (c.SemanticContext != SemanticContext.None)
{
throw new NotSupportedException();
}
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
}
public override LexerActionExecutor ActionExecutor
{
get
{
return lexerActionExecutor;
}
}
public override bool PassedThroughNonGreedyDecision
{
get
{
return passedThroughNonGreedyDecision;
}
}
}
private class ActionSemanticContextATNConfig : ATNConfig.SemanticContextATNConfig
{
private readonly LexerActionExecutor lexerActionExecutor;
private readonly bool passedThroughNonGreedyDecision;
public ActionSemanticContextATNConfig(LexerActionExecutor lexerActionExecutor, SemanticContext semanticContext, ATNState state, int alt, PredictionContext context, bool passedThroughNonGreedyDecision)
: base(semanticContext, state, alt, context)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
}
public ActionSemanticContextATNConfig(LexerActionExecutor lexerActionExecutor, SemanticContext semanticContext, ATNConfig c, ATNState state, PredictionContext context, bool passedThroughNonGreedyDecision)
: base(semanticContext, c, state, context)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
}
public override LexerActionExecutor ActionExecutor
{
get
{
return lexerActionExecutor;
}
}
public override bool PassedThroughNonGreedyDecision
{
get
{
return passedThroughNonGreedyDecision;
}
}
}
}
}

View File

@ -39,643 +39,371 @@ using IEnumerator = System.Collections.IEnumerator;
namespace Antlr4.Runtime.Atn
{
/// <author>Sam Harwell</author>
public class ATNConfigSet : IEnumerable<ATNConfig>
{
/// <summary>
/// This maps (state, alt) -&gt; merged
/// <see cref="ATNConfig"/>
/// . The key does not account for
/// the
/// <see cref="ATNConfig.SemanticContext()"/>
/// of the value, which is only a problem if a single
/// <c>ATNConfigSet</c>
/// contains two configs with the same state and alternative
/// but different semantic contexts. When this case arises, the first config
/// added to this map stays, and the remaining configs are placed in
/// <see cref="unmerged"/>
/// .
/// <p/>
/// This map is only used for optimizing the process of adding configs to the set,
/// and is
/// <see langword="null"/>
/// for read-only sets stored in the DFA.
/// </summary>
private readonly Dictionary<long, ATNConfig> mergedConfigs;
public class ATNConfigSet
{
/// <summary>
/// This is an "overflow" list holding configs which cannot be merged with one
/// of the configs in
/// <see cref="mergedConfigs"/>
/// but have a colliding key. This
/// occurs when two configs in the set have the same state and alternative but
/// different semantic contexts.
/// <p/>
/// This list is only used for optimizing the process of adding configs to the set,
/// and is
/// <see langword="null"/>
/// for read-only sets stored in the DFA.
/// </summary>
private readonly List<ATNConfig> unmerged;
/// <summary>This is a list of all configs in this set.</summary>
/// <remarks>This is a list of all configs in this set.</remarks>
private readonly List<ATNConfig> configs;
/** Indicates that the set of configurations is read-only. Do not
* allow any code to manipulate the set; DFA states will point at
* the sets and they must not change. This does not protect the other
* fields; in particular, conflictingAlts is set after
* we've made this readonly.
*/
protected bool readOnly = false;
private int uniqueAlt;
/**
* All configs but hashed by (s, i, _, pi) not including context. Wiped out
* when we go readonly as this set becomes a DFA state.
*/
public ConfigHashSet configLookup;
private ConflictInfo conflictInfo;
/** Track the elements as they are added to the set; supports get(i) */
public List<ATNConfig> configs = new List<ATNConfig>(7);
private bool hasSemanticContext;
// TODO: these fields make me pretty uncomfortable but nice to pack up info together, saves recomputation
// TODO: can we track conflicts as they are added to save scanning configs later?
public int uniqueAlt;
/** Currently this is only used when we detect SLL conflict; this does
* not necessarily represent the ambiguous alternatives. In fact,
* I should also point out that this seems to include predicated alternatives
* that have predicates that evaluate to false. Computed in computeTargetState().
*/
public BitSet conflictingAlts;
private bool dipsIntoOuterContext;
// Used in parser and lexer. In lexer, it indicates we hit a pred
// while computing a closure operation. Don't make a DFA state from this.
public bool hasSemanticContext;
public bool dipsIntoOuterContext;
/// <summary>
/// When
/// <see langword="true"/>
/// , this config set represents configurations where the entire
/// outer context has been consumed by the ATN interpreter. This prevents the
/// <see cref="ParserATNSimulator.Closure(ATNConfigSet, ATNConfigSet, bool, bool, PredictionContextCache, bool)"/>
/// from pursuing the global FOLLOW when a
/// rule stop state is reached with an empty prediction context.
/// <p/>
/// Note:
/// <c>outermostConfigSet</c>
/// and
/// <see cref="dipsIntoOuterContext"/>
/// should never
/// be true at the same time.
/// </summary>
private bool outermostConfigSet;
/** Indicates that this configuration set is part of a full context
* LL prediction. It will be used to determine how to merge $. With SLL
* it's a wildcard whereas it is not for LL context merge.
*/
public readonly bool fullCtx;
private int cachedHashCode = -1;
private int cachedHashCode = -1;
public ATNConfigSet()
{
// Used in parser and lexer. In lexer, it indicates we hit a pred
// while computing a closure operation. Don't make a DFA state from this.
this.mergedConfigs = new Dictionary<long, ATNConfig>();
this.unmerged = new List<ATNConfig>();
this.configs = new List<ATNConfig>();
this.uniqueAlt = ATN.InvalidAltNumber;
}
public ATNConfigSet(bool fullCtx)
{
configLookup = new ConfigHashSet();
this.fullCtx = fullCtx;
}
protected internal ATNConfigSet(Antlr4.Runtime.Atn.ATNConfigSet set, bool @readonly)
{
if (@readonly)
{
this.mergedConfigs = null;
this.unmerged = null;
}
else
{
if (!set.IsReadOnly)
{
this.mergedConfigs = new Dictionary<long, ATNConfig>(set.mergedConfigs);
this.unmerged = new List<ATNConfig>(set.unmerged);
}
else
{
this.mergedConfigs = new Dictionary<long, ATNConfig>(set.configs.Count);
this.unmerged = new List<ATNConfig>();
}
}
this.configs = new List<ATNConfig>(set.configs);
this.dipsIntoOuterContext = set.dipsIntoOuterContext;
this.hasSemanticContext = set.hasSemanticContext;
this.outermostConfigSet = set.outermostConfigSet;
if (@readonly || !set.IsReadOnly)
{
this.uniqueAlt = set.uniqueAlt;
this.conflictInfo = set.conflictInfo;
}
}
public ATNConfigSet()
: this(true)
{
}
/// <summary>
/// Get the set of all alternatives represented by configurations in this
/// set.
/// </summary>
/// <remarks>
/// Get the set of all alternatives represented by configurations in this
/// set.
/// </remarks>
[NotNull]
public virtual BitSet RepresentedAlternatives
{
get
{
// if (!readonly && set.isReadOnly()) -> addAll is called from clone()
if (conflictInfo != null)
{
return (BitSet)conflictInfo.ConflictedAlts.Clone();
}
BitSet alts = new BitSet();
foreach (ATNConfig config in this)
{
alts.Set(config.Alt);
}
return alts;
}
}
public ATNConfigSet(ATNConfigSet old)
: this(old.fullCtx)
{
AddAll(old.configs);
this.uniqueAlt = old.uniqueAlt;
this.conflictingAlts = old.conflictingAlts;
this.hasSemanticContext = old.hasSemanticContext;
this.dipsIntoOuterContext = old.dipsIntoOuterContext;
}
public bool IsReadOnly
{
get
{
return mergedConfigs == null;
}
}
public bool Add(ATNConfig config)
{
return Add(config, null);
}
public virtual bool IsOutermostConfigSet
{
get
{
return outermostConfigSet;
}
set
{
bool outermostConfigSet = value;
if (this.outermostConfigSet && !outermostConfigSet)
{
throw new InvalidOperationException();
}
System.Diagnostics.Debug.Assert(!outermostConfigSet || !dipsIntoOuterContext);
this.outermostConfigSet = outermostConfigSet;
}
}
/**
* Adding a new config means merging contexts with existing configs for
* {@code (s, i, pi, _)}, where {@code s} is the
* {@link ATNConfig#state}, {@code i} is the {@link ATNConfig#alt}, and
* {@code pi} is the {@link ATNConfig#semanticContext}. We use
* {@code (s,i,pi)} as key.
*
* <p>This method updates {@link #dipsIntoOuterContext} and
* {@link #hasSemanticContext} when necessary.</p>
*/
public bool Add(ATNConfig config, MergeCache mergeCache)
{
if (readOnly)
throw new Exception("This set is readonly");
if (config.semanticContext != SemanticContext.NONE)
{
hasSemanticContext = true;
}
if (config.OuterContextDepth > 0)
{
dipsIntoOuterContext = true;
}
ATNConfig existing = configLookup.GetOrAdd(config);
if (existing == config)
{ // we added this new one
cachedHashCode = -1;
configs.Add(config); // track order here
return true;
}
// a previous (s,i,pi,_), merge with it and save result
bool rootIsWildcard = !fullCtx;
PredictionContext merged = PredictionContext.Merge(existing.context, config.context, rootIsWildcard, mergeCache);
// no need to check for existing.context, config.context in cache
// since only way to create new graphs is "call rule" and here. We
// cache at both places.
existing.reachesIntoOuterContext = Math.Max(existing.reachesIntoOuterContext, config.reachesIntoOuterContext);
public virtual HashSet<ATNState> States
{
get
{
HashSet<ATNState> states = new HashSet<ATNState>();
foreach (ATNConfig c in this.configs)
{
states.Add(c.State);
}
return states;
}
}
// make sure to preserve the precedence filter suppression during the merge
if (config.IsPrecedenceFilterSuppressed)
{
existing.SetPrecedenceFilterSuppressed(true);
}
public virtual void OptimizeConfigs(ATNSimulator interpreter)
{
if (configs.Count == 0)
{
return;
}
for (int i = 0; i < configs.Count; i++)
{
ATNConfig config = configs[i];
config.Context = interpreter.atn.GetCachedContext(config.Context);
}
}
existing.context = merged; // replace context; no need to alt mapping
return true;
}
public virtual Antlr4.Runtime.Atn.ATNConfigSet Clone(bool @readonly)
{
Antlr4.Runtime.Atn.ATNConfigSet copy = new Antlr4.Runtime.Atn.ATNConfigSet(this, @readonly);
if (!@readonly && this.IsReadOnly)
{
copy.AddAll(configs);
}
return copy;
}
/** Return a List holding list of configs */
public List<ATNConfig> elements() { return configs; }
public virtual int Count
{
get
{
return configs.Count;
}
}
public HashSet<ATNState> getStates()
{
HashSet<ATNState> states = new HashSet<ATNState>();
foreach (ATNConfig c in configs)
{
states.Add(c.state);
}
return states;
}
public virtual bool IsEmpty()
{
return configs.Count == 0;
}
/**
* Gets the complete set of represented alternatives for the configuration
* set.
*
* @return the set of represented alternatives in this configuration set
*
* @since 4.3
*/
public virtual bool Contains(object o)
{
if (!(o is ATNConfig))
{
return false;
}
ATNConfig config = (ATNConfig)o;
long configKey = GetKey(config);
ATNConfig mergedConfig;
if (mergedConfigs.TryGetValue(configKey, out mergedConfig) && CanMerge(config, configKey, mergedConfig))
{
return mergedConfig.Contains(config);
}
foreach (ATNConfig c in unmerged)
{
if (c.Contains(config))
{
return true;
}
}
return false;
}
public BitSet getAlts()
{
BitSet alts = new BitSet();
foreach (ATNConfig config in configs)
{
alts.Set(config.alt);
}
return alts;
}
public virtual IEnumerator<ATNConfig> GetEnumerator()
{
return configs.GetEnumerator();
}
public List<SemanticContext> getPredicates()
{
List<SemanticContext> preds = new List<SemanticContext>();
foreach (ATNConfig c in configs)
{
if (c.semanticContext != SemanticContext.NONE)
{
preds.Add(c.semanticContext);
}
}
return preds;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public ATNConfig get(int i) { return configs[i]; }
public virtual object[] ToArray()
{
return configs.ToArray();
}
public void OptimizeConfigs(ATNSimulator interpreter)
{
if (readOnly)
throw new Exception("This set is readonly");
if (configLookup.Count == 0)
return;
public virtual bool Add(ATNConfig e)
{
return Add(e, null);
}
foreach (ATNConfig config in configs)
{
// int before = PredictionContext.getAllContextNodes(config.context).size();
config.context = interpreter.getCachedContext(config.context);
// int after = PredictionContext.getAllContextNodes(config.context).size();
// System.out.println("configs "+before+"->"+after);
}
}
public virtual bool Add(ATNConfig e, PredictionContextCache contextCache)
{
EnsureWritable();
System.Diagnostics.Debug.Assert(!outermostConfigSet || !e.ReachesIntoOuterContext);
if (contextCache == null)
{
contextCache = PredictionContextCache.Uncached;
}
bool addKey;
long key = GetKey(e);
ATNConfig mergedConfig;
addKey = !mergedConfigs.TryGetValue(key, out mergedConfig);
if (mergedConfig != null && CanMerge(e, key, mergedConfig))
{
mergedConfig.OuterContextDepth = Math.Max(mergedConfig.OuterContextDepth, e.OuterContextDepth);
if (e.PrecedenceFilterSuppressed)
{
mergedConfig.PrecedenceFilterSuppressed = true;
}
PredictionContext joined = PredictionContext.Join(mergedConfig.Context, e.Context, contextCache);
UpdatePropertiesForMergedConfig(e);
if (mergedConfig.Context == joined)
{
return false;
}
mergedConfig.Context = joined;
return true;
}
for (int i = 0; i < unmerged.Count; i++)
{
ATNConfig unmergedConfig = unmerged[i];
if (CanMerge(e, key, unmergedConfig))
{
unmergedConfig.OuterContextDepth = Math.Max(unmergedConfig.OuterContextDepth, e.OuterContextDepth);
if (e.PrecedenceFilterSuppressed)
{
unmergedConfig.PrecedenceFilterSuppressed = true;
}
PredictionContext joined = PredictionContext.Join(unmergedConfig.Context, e.Context, contextCache);
UpdatePropertiesForMergedConfig(e);
if (unmergedConfig.Context == joined)
{
return false;
}
unmergedConfig.Context = joined;
if (addKey)
{
mergedConfigs[key] = unmergedConfig;
unmerged.RemoveAt(i);
}
return true;
}
}
configs.Add(e);
if (addKey)
{
mergedConfigs[key] = e;
}
else
{
unmerged.Add(e);
}
UpdatePropertiesForAddedConfig(e);
return true;
}
public bool AddAll(ICollection<ATNConfig> coll)
{
foreach (ATNConfig c in coll) Add(c);
return false;
}
private void UpdatePropertiesForMergedConfig(ATNConfig config)
{
// merged configs can't change the alt or semantic context
dipsIntoOuterContext |= config.ReachesIntoOuterContext;
System.Diagnostics.Debug.Assert(!outermostConfigSet || !dipsIntoOuterContext);
}
public override bool Equals(Object o)
{
if (o == this)
{
return true;
}
else if (!(o is ATNConfigSet))
{
return false;
}
private void UpdatePropertiesForAddedConfig(ATNConfig config)
{
if (configs.Count == 1)
{
uniqueAlt = config.Alt;
}
else
{
if (uniqueAlt != config.Alt)
{
uniqueAlt = ATN.InvalidAltNumber;
}
}
hasSemanticContext |= !SemanticContext.None.Equals(config.SemanticContext);
dipsIntoOuterContext |= config.ReachesIntoOuterContext;
System.Diagnostics.Debug.Assert(!outermostConfigSet || !dipsIntoOuterContext);
}
// System.out.print("equals " + this + ", " + o+" = ");
ATNConfigSet other = (ATNConfigSet)o;
bool same = configs != null &&
configs.Equals(other.configs) && // includes stack context
this.fullCtx == other.fullCtx &&
this.uniqueAlt == other.uniqueAlt &&
this.conflictingAlts == other.conflictingAlts &&
this.hasSemanticContext == other.hasSemanticContext &&
this.dipsIntoOuterContext == other.dipsIntoOuterContext;
protected internal virtual bool CanMerge(ATNConfig left, long leftKey, ATNConfig right)
{
if (left.State.stateNumber != right.State.stateNumber)
{
return false;
}
if (leftKey != GetKey(right))
{
return false;
}
return left.SemanticContext.Equals(right.SemanticContext);
}
// System.out.println(same);
return same;
}
protected internal virtual long GetKey(ATNConfig e)
{
long key = e.State.stateNumber;
key = (key << 12) | (e.Alt & 0xFFFL);
return key;
}
public virtual bool Remove(object o)
{
EnsureWritable();
throw new NotSupportedException("Not supported yet.");
}
public override int GetHashCode()
{
if (IsReadOnly)
{
if (cachedHashCode == -1)
{
cachedHashCode = configs.GetHashCode();
}
public virtual bool ContainsAll(IEnumerable<ATNConfig> c)
{
foreach (ATNConfig o in c)
{
if (!Contains(o))
{
return false;
}
}
return true;
}
return cachedHashCode;
}
public virtual bool AddAll(IEnumerable<ATNConfig> c)
{
return AddAll(c, null);
}
return configs.GetHashCode();
}
public virtual bool AddAll(IEnumerable<ATNConfig> c, PredictionContextCache contextCache)
{
EnsureWritable();
bool changed = false;
foreach (ATNConfig group in c)
{
changed |= Add(group, contextCache);
}
return changed;
}
public int Count
{
get
{
return configs.Count;
}
}
public virtual bool RetainAll<_T0>(ICollection<_T0> c)
{
EnsureWritable();
throw new NotSupportedException("Not supported yet.");
}
public bool Empty
{
get
{
public virtual bool RemoveAll<_T0>(ICollection<_T0> c)
{
EnsureWritable();
throw new NotSupportedException("Not supported yet.");
}
return configs.Count == 0;
}
}
public virtual void Clear()
{
EnsureWritable();
mergedConfigs.Clear();
unmerged.Clear();
configs.Clear();
dipsIntoOuterContext = false;
hasSemanticContext = false;
uniqueAlt = ATN.InvalidAltNumber;
conflictInfo = null;
}
public bool Contains(Object o)
{
if (configLookup == null)
{
throw new Exception("This method is not implemented for readonly sets.");
}
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
if (!(obj is Antlr4.Runtime.Atn.ATNConfigSet))
{
return false;
}
Antlr4.Runtime.Atn.ATNConfigSet other = (Antlr4.Runtime.Atn.ATNConfigSet)obj;
return this.outermostConfigSet == other.outermostConfigSet && Utils.Equals(conflictInfo, other.conflictInfo) && configs.SequenceEqual(other.configs);
}
return configLookup.Contains((ATNConfig)o);
}
public override int GetHashCode()
{
if (IsReadOnly && cachedHashCode != -1)
{
return cachedHashCode;
}
int hashCode = 1;
hashCode = 5 * hashCode ^ (outermostConfigSet ? 1 : 0);
hashCode = 5 * hashCode ^ SequenceEqualityComparer<ATNConfig>.Default.GetHashCode(configs);
if (IsReadOnly)
{
cachedHashCode = hashCode;
}
return hashCode;
}
public override string ToString()
{
return ToString(false);
}
public void Clear()
{
if (readOnly)
throw new Exception("This set is readonly");
configs.Clear();
cachedHashCode = -1;
configLookup.Clear();
}
public virtual string ToString(bool showContext)
{
StringBuilder buf = new StringBuilder();
List<ATNConfig> sortedConfigs = new List<ATNConfig>(configs);
sortedConfigs.Sort(new _IComparer_475());
buf.Append("[");
for (int i = 0; i < sortedConfigs.Count; i++)
{
if (i > 0)
{
buf.Append(", ");
}
buf.Append(sortedConfigs[i].ToString(null, true, showContext));
}
buf.Append("]");
if (hasSemanticContext)
{
buf.Append(",hasSemanticContext=").Append(hasSemanticContext);
}
if (uniqueAlt != ATN.InvalidAltNumber)
{
buf.Append(",uniqueAlt=").Append(uniqueAlt);
}
if (conflictInfo != null)
{
buf.Append(",conflictingAlts=").Append(conflictInfo.ConflictedAlts);
if (!conflictInfo.IsExact)
{
buf.Append("*");
}
}
if (dipsIntoOuterContext)
{
buf.Append(",dipsIntoOuterContext");
}
return buf.ToString();
}
public bool IsReadOnly
{
get
{
return readOnly;
}
set
{
this.readOnly = value;
configLookup = null; // can't mod, no need for lookup cache
}
}
private sealed class _IComparer_475 : IComparer<ATNConfig>
{
public _IComparer_475()
{
}
public override String ToString()
{
StringBuilder buf = new StringBuilder();
buf.Append(elements().ToString());
if (hasSemanticContext)
buf.Append(",hasSemanticContext=")
.Append(hasSemanticContext);
if (uniqueAlt != ATN.INVALID_ALT_NUMBER)
buf.Append(",uniqueAlt=")
.Append(uniqueAlt);
if (conflictingAlts != null)
buf.Append(",conflictingAlts=")
.Append(conflictingAlts);
if (dipsIntoOuterContext)
buf.Append(",dipsIntoOuterContext");
return buf.ToString();
}
public int Compare(ATNConfig o1, ATNConfig o2)
{
if (o1.Alt != o2.Alt)
{
return o1.Alt - o2.Alt;
}
else
{
if (o1.State.stateNumber != o2.State.stateNumber)
{
return o1.State.stateNumber - o2.State.stateNumber;
}
else
{
return string.CompareOrdinal(o1.SemanticContext.ToString(), o2.SemanticContext.ToString());
}
}
}
}
public virtual int UniqueAlt
{
get
{
return uniqueAlt;
}
}
}
public virtual bool HasSemanticContext
{
get
{
return hasSemanticContext;
}
}
public class OrderedATNConfigSet : ATNConfigSet
{
public virtual void ClearExplicitSemanticContext()
{
EnsureWritable();
hasSemanticContext = false;
}
public OrderedATNConfigSet()
{
this.configLookup = new LexerConfigHashSet();
}
public virtual void MarkExplicitSemanticContext()
{
EnsureWritable();
hasSemanticContext = true;
}
public class LexerConfigHashSet : ConfigHashSet
{
public LexerConfigHashSet()
public virtual ConflictInfo ConflictInformation
{
get
{
return conflictInfo;
}
set
{
ConflictInfo conflictInfo = value;
EnsureWritable();
this.conflictInfo = conflictInfo;
}
}
{
}
}
}
public virtual BitSet ConflictingAlts
{
get
{
if (conflictInfo == null)
{
return null;
}
return conflictInfo.ConflictedAlts;
}
}
public virtual bool IsExactConflict
{
get
{
if (conflictInfo == null)
{
return false;
}
return conflictInfo.IsExact;
}
}
/**
* The reason that we need this is because we don't want the hash map to use
* the standard hash code and equals. We need all configurations with the same
* {@code (s,i,_,semctx)} to be equal. Unfortunately, this key effectively doubles
* the number of objects associated with ATNConfigs. The other solution is to
* use a hash table that lets us specify the equals/hashcode operation.
*/
public class ConfigHashSet : HashSet<ATNConfig>
{
public virtual bool DipsIntoOuterContext
{
get
{
return dipsIntoOuterContext;
}
}
public ConfigHashSet()
: base(new ConfigEqualityComparator())
{
}
public virtual ATNConfig this[int index]
{
get
{
return configs[index];
}
}
public ATNConfig GetOrAdd(ATNConfig config)
{
if (this.Contains(config))
return null; // TODO
else
{
this.Add(config);
return config;
}
}
public virtual void Remove(int index)
{
EnsureWritable();
ATNConfig config = configs[index];
configs.Remove(config);
long key = GetKey(config);
ATNConfig existing;
if (mergedConfigs.TryGetValue(key, out existing) && existing == config)
{
mergedConfigs.Remove(key);
}
else
{
for (int i = 0; i < unmerged.Count; i++)
{
if (unmerged[i] == config)
{
unmerged.RemoveAt(i);
return;
}
}
}
}
}
public class ConfigEqualityComparator : IEqualityComparer<ATNConfig>
{
public int GetHashCode(ATNConfig o)
{
int hashCode = 7;
hashCode = 31 * hashCode + o.state.stateNumber;
hashCode = 31 * hashCode + o.alt;
hashCode = 31 * hashCode + o.semanticContext.GetHashCode();
return hashCode;
}
public bool Equals(ATNConfig a, ATNConfig b)
{
if (a == b) return true;
if (a == null || b == null) return false;
return a.state.stateNumber == b.state.stateNumber
&& a.alt == b.alt
&& a.semanticContext.Equals(b.semanticContext);
}
}
protected internal void EnsureWritable()
{
if (IsReadOnly)
{
throw new InvalidOperationException("This ATNConfigSet is read only.");
}
}
}
}

View File

@ -466,7 +466,7 @@ namespace Antlr4.Runtime.Atn
if (atn.grammarType == ATNType.Lexer) {
int tokenType = ReadInt ();
if (tokenType == unchecked((int)(0xFFFF))) {
tokenType = TokenConstants.Eof;
tokenType = TokenConstants.EOF;
}
atn.ruleToTokenType [i_5] = tokenType;
}
@ -708,7 +708,7 @@ namespace Antlr4.Runtime.Atn
{
RuleStartState startState = atn.ruleToStartState[i];
ATNState middleState = startState;
while (middleState.OnlyHasEpsilonTransitions && middleState.NumberOfOptimizedTransitions == 1 && middleState.GetOptimizedTransition(0).TransitionType == TransitionType.Epsilon)
while (middleState.OnlyHasEpsilonTransitions && middleState.NumberOfOptimizedTransitions == 1 && middleState.GetOptimizedTransition(0).TransitionType == TransitionType.EPSILON)
{
middleState = middleState.GetOptimizedTransition(0).target;
}
@ -724,16 +724,16 @@ namespace Antlr4.Runtime.Atn
}
switch (matchTransition.TransitionType)
{
case TransitionType.Atom:
case TransitionType.Range:
case TransitionType.Set:
case TransitionType.ATOM:
case TransitionType.RANGE:
case TransitionType.SET:
{
ruleToInlineTransition[i] = matchTransition;
break;
}
case TransitionType.NotSet:
case TransitionType.Wildcard:
case TransitionType.NOT_SET:
case TransitionType.WILDCARD:
{
// not implemented yet
continue;
@ -790,19 +790,19 @@ namespace Antlr4.Runtime.Atn
optimizedTransitions.Add(new EpsilonTransition(intermediateState));
switch (effective.TransitionType)
{
case TransitionType.Atom:
case TransitionType.ATOM:
{
intermediateState.AddTransition(new AtomTransition(target, ((AtomTransition)effective).token));
break;
}
case TransitionType.Range:
case TransitionType.RANGE:
{
intermediateState.AddTransition(new RangeTransition(target, ((RangeTransition)effective).from, ((RangeTransition)effective).to));
break;
}
case TransitionType.Set:
case TransitionType.SET:
{
intermediateState.AddTransition(new SetTransition(target, effective.Label));
break;
@ -846,7 +846,7 @@ namespace Antlr4.Runtime.Atn
{
Transition transition = state.GetOptimizedTransition(i);
ATNState intermediate = transition.target;
if (transition.TransitionType != TransitionType.Epsilon || ((EpsilonTransition)transition).OutermostPrecedenceReturn != -1 || intermediate.StateType != StateType.Basic || !intermediate.OnlyHasEpsilonTransitions)
if (transition.TransitionType != TransitionType.EPSILON || ((EpsilonTransition)transition).OutermostPrecedenceReturn != -1 || intermediate.StateType != StateType.Basic || !intermediate.OnlyHasEpsilonTransitions)
{
if (optimizedTransitions != null)
{
@ -856,7 +856,7 @@ namespace Antlr4.Runtime.Atn
}
for (int j = 0; j < intermediate.NumberOfOptimizedTransitions; j++)
{
if (intermediate.GetOptimizedTransition(j).TransitionType != TransitionType.Epsilon || ((EpsilonTransition)intermediate.GetOptimizedTransition(j)).OutermostPrecedenceReturn != -1)
if (intermediate.GetOptimizedTransition(j).TransitionType != TransitionType.EPSILON || ((EpsilonTransition)intermediate.GetOptimizedTransition(j)).OutermostPrecedenceReturn != -1)
{
if (optimizedTransitions != null)
{
@ -1069,7 +1069,7 @@ nextTransition_continue: ;
IList<Transition> transitions = optimizedPath ? state.optimizedTransitions : state.transitions;
foreach (Transition t in transitions)
{
if (t.TransitionType != TransitionType.Epsilon)
if (t.TransitionType != TransitionType.EPSILON)
{
return false;
}
@ -1112,16 +1112,16 @@ nextTransition_continue: ;
ATNState target = atn.states[trg];
switch (type)
{
case TransitionType.Epsilon:
case TransitionType.EPSILON:
{
return new EpsilonTransition(target);
}
case TransitionType.Range:
case TransitionType.RANGE:
{
if (arg3 != 0)
{
return new RangeTransition(target, TokenConstants.Eof, arg2);
return new RangeTransition(target, TokenConstants.EOF, arg2);
}
else
{
@ -1129,28 +1129,28 @@ nextTransition_continue: ;
}
}
case TransitionType.Rule:
case TransitionType.RULE:
{
RuleTransition rt = new RuleTransition((RuleStartState)atn.states[arg1], arg2, arg3, target);
return rt;
}
case TransitionType.Predicate:
case TransitionType.PREDICATE:
{
PredicateTransition pt = new PredicateTransition(target, arg1, arg2, arg3 != 0);
return pt;
}
case TransitionType.Precedence:
case TransitionType.PRECEDENCE:
{
return new PrecedencePredicateTransition(target, arg1);
}
case TransitionType.Atom:
case TransitionType.ATOM:
{
if (arg3 != 0)
{
return new AtomTransition(target, TokenConstants.Eof);
return new AtomTransition(target, TokenConstants.EOF);
}
else
{
@ -1158,23 +1158,23 @@ nextTransition_continue: ;
}
}
case TransitionType.Action:
case TransitionType.ACTION:
{
ActionTransition a = new ActionTransition(target, arg1, arg2, arg3 != 0);
return a;
}
case TransitionType.Set:
case TransitionType.SET:
{
return new SetTransition(target, sets[arg1]);
}
case TransitionType.NotSet:
case TransitionType.NOT_SET:
{
return new NotSetTransition(target, sets[arg1]);
}
case TransitionType.Wildcard:
case TransitionType.WILDCARD:
{
return new WildcardTransition(target);
}

View File

@ -36,74 +36,88 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
public abstract class ATNSimulator
{
[Obsolete(@"Use ATNDeserializer.SerializedVersion instead.")]
public static readonly int SerializedVersion = ATNDeserializer.SerializedVersion;
public abstract class ATNSimulator
{
/// <summary>This is the current serialized UUID.</summary>
/// <remarks>This is the current serialized UUID.</remarks>
[Obsolete(@"Use ATNDeserializer.CheckCondition(bool) instead.")]
public static readonly Guid SerializedUuid = ATNDeserializer.SerializedUuid;
public const char RuleVariantDelimiter = '$';
/** Must distinguish between missing edge and edge we know leads nowhere */
public const string RuleLfVariantMarker = "$lf$";
public static readonly DFAState ERROR = InitERROR();
public const string RuleNolfVariantMarker = "$nolf$";
static DFAState InitERROR()
{
DFAState state = new DFAState(new ATNConfigSet());
state.stateNumber = Int32.MaxValue;
return state;
}
/// <summary>Must distinguish between missing edge and edge we know leads nowhere</summary>
[NotNull]
public static readonly DFAState Error =
new DFAState(new EmptyEdgeMap<DFAState>(0, -1), new EmptyEdgeMap<DFAState>(0, -1), new ATNConfigSet())
{
stateNumber = int.MaxValue
};
public readonly ATN atn;
[NotNull]
public readonly ATN atn;
/** The context cache maps all PredictionContext objects that are equals()
* to a single cached copy. This cache is shared across all contexts
* in all ATNConfigs in all DFA states. We rebuild each ATNConfigSet
* to use only cached nodes/graphs in addDFAState(). We don't want to
* fill this during closure() since there are lots of contexts that
* pop up but are not used ever again. It also greatly slows down closure().
*
* <p>This cache makes a huge difference in memory and a little bit in speed.
* For the Java grammar on java.*, it dropped the memory requirements
* at the end from 25M to 16M. We don't store any of the full context
* graphs in the DFA because they are limited to local context only,
* but apparently there's a lot of repetition there as well. We optimize
* the config contexts before storing the config set in the DFA states
* by literally rebuilding them with cached subgraphs only.</p>
*
* <p>I tried a cache for use during closure operations, that was
* whacked after each adaptivePredict(). It cost a little bit
* more time I think and doesn't save on the overall footprint
* so it's not worth the complexity.</p>
*/
protected readonly PredictionContextCache sharedContextCache;
public ATNSimulator(ATN atn)
{
this.atn = atn;
}
public abstract void Reset();
public ATNSimulator(ATN atn, PredictionContextCache sharedContextCache)
{
this.atn = atn;
this.sharedContextCache = sharedContextCache;
}
/// <summary>Clear the DFA cache used by the current instance.</summary>
/// <remarks>
/// Clear the DFA cache used by the current instance. Since the DFA cache may
/// be shared by multiple ATN simulators, this method may affect the
/// performance (but not accuracy) of other parsers which are being used
/// concurrently.
/// </remarks>
/// <exception cref="System.NotSupportedException">
/// if the current instance does not
/// support clearing the DFA.
/// </exception>
/// <since>4.3</since>
public virtual void ClearDFA()
{
atn.ClearDFA();
}
public abstract void Reset();
[Obsolete(@"Use ATNDeserializer.Deserialize(char[]) instead.")]
public static ATN Deserialize(char[] data)
{
return new ATNDeserializer().Deserialize(data);
}
/**
* Clear the DFA cache used by the current instance. Since the DFA cache may
* be shared by multiple ATN simulators, this method may affect the
* performance (but not accuracy) of other parsers which are being used
* concurrently.
*
* @throws UnsupportedOperationException if the current instance does not
* support clearing the DFA.
*
* @since 4.3
*/
public virtual void ClearDFA()
{
throw new Exception("This ATN simulator does not support clearing the DFA.");
}
[return: NotNull]
[Obsolete(@"Use ATNDeserializer.EdgeFactory(ATN, TransitionType, int, int, int, int, int, System.Collections.Generic.IList{E}) instead.")]
public static Transition EdgeFactory(ATN atn, TransitionType type, int src, int trg, int arg1, int arg2, int arg3, IList<IntervalSet> sets)
{
return new ATNDeserializer().EdgeFactory(atn, type, src, trg, arg1, arg2, arg3, sets);
}
public PredictionContextCache getSharedContextCache()
{
return sharedContextCache;
}
[Obsolete(@"Use ATNDeserializer.StateFactory(StateType, int) instead.")]
public static ATNState StateFactory(StateType type, int ruleIndex)
{
return new ATNDeserializer().StateFactory(type, ruleIndex);
}
}
public PredictionContext getCachedContext(PredictionContext context)
{
if (sharedContextCache == null) return context;
lock (sharedContextCache)
{
PredictionContext.IdentityHashMap visited =
new PredictionContext.IdentityHashMap();
return PredictionContext.GetCachedContext(context,
sharedContextCache,
visited);
}
}
}
}

View File

@ -58,7 +58,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Action;
return Antlr4.Runtime.Atn.TransitionType.ACTION;
}
}

View File

@ -56,7 +56,7 @@ namespace Antlr4.Runtime.Atn
/// configuration set is not equal to the minimum represented alternative in the
/// conflicting SLL configuration set. Grammars and inputs which result in this
/// scenario are unable to use
/// <see cref="PredictionMode.Sll"/>
/// <see cref="PredictionMode.SLL"/>
/// , which in turn means
/// they cannot use the two-stage parsing strategy to improve parsing performance
/// for that input.</p>

View File

@ -29,244 +29,123 @@
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
#pragma warning disable 0659 // 'class' overrides Object.Equals(object o) but does not override Object.GetHashCode()
public class ArrayPredictionContext : PredictionContext
{
[NotNull]
public readonly PredictionContext[] parents;
[NotNull]
public readonly int[] returnStates;
internal ArrayPredictionContext(PredictionContext[] parents, int[] returnStates)
: base(CalculateHashCode(parents, returnStates))
{
System.Diagnostics.Debug.Assert(parents.Length == returnStates.Length);
System.Diagnostics.Debug.Assert(returnStates.Length > 1 || returnStates[0] != EmptyFullStateKey, "Should be using PredictionContext.EMPTY instead.");
this.parents = parents;
this.returnStates = returnStates;
}
public class ArrayPredictionContext : PredictionContext
{
/** Parent can be null only if full ctx mode and we make an array
* from {@link #EMPTY} and non-empty. We merge {@link #EMPTY} by using null parent and
* returnState == {@link #EMPTY_RETURN_STATE}.
*/
public readonly PredictionContext[] parents;
internal ArrayPredictionContext(PredictionContext[] parents, int[] returnStates, int hashCode)
: base(hashCode)
{
System.Diagnostics.Debug.Assert(parents.Length == returnStates.Length);
System.Diagnostics.Debug.Assert(returnStates.Length > 1 || returnStates[0] != EmptyFullStateKey, "Should be using PredictionContext.EMPTY instead.");
this.parents = parents;
this.returnStates = returnStates;
}
/** Sorted for merge, no duplicates; if present,
* {@link #EMPTY_RETURN_STATE} is always last.
*/
public readonly int[] returnStates;
public override PredictionContext GetParent(int index)
{
return parents[index];
}
public ArrayPredictionContext(SingletonPredictionContext a)
: this(new PredictionContext[] { a.parent }, new int[] { a.returnState })
{
}
public override int GetReturnState(int index)
{
return returnStates[index];
}
public ArrayPredictionContext(PredictionContext[] parents, int[] returnStates)
: base(CalculateHashCode(parents, returnStates))
{
// System.err.println("CREATE ARRAY: "+Arrays.toString(parents)+", "+Arrays.toString(returnStates));
this.parents = parents;
this.returnStates = returnStates;
}
public override int FindReturnState(int returnState)
{
return System.Array.BinarySearch(returnStates, returnState);
}
public override bool IsEmpty
{
get
{
// since EMPTY_RETURN_STATE can only appear in the last position, we
// don't need to verify that size==1
return returnStates[0] == EMPTY_RETURN_STATE;
}
}
public override int Size
{
get
{
return returnStates.Length;
}
}
public override int Size
{
get
{
return returnStates.Length;
}
}
public override bool IsEmpty
{
get
{
return false;
}
}
public override PredictionContext GetParent(int index)
{
return parents[index];
}
public override bool HasEmpty
{
get
{
return returnStates[returnStates.Length - 1] == EmptyFullStateKey;
}
}
public override int GetReturnState(int index)
{
return returnStates[index];
}
protected internal override PredictionContext AddEmptyContext()
{
if (HasEmpty)
{
return this;
}
PredictionContext[] parents2 = Arrays.CopyOf(parents, parents.Length + 1);
int[] returnStates2 = Arrays.CopyOf(returnStates, returnStates.Length + 1);
parents2[parents2.Length - 1] = PredictionContext.EmptyFull;
returnStates2[returnStates2.Length - 1] = PredictionContext.EmptyFullStateKey;
return new Antlr4.Runtime.Atn.ArrayPredictionContext(parents2, returnStates2);
}
// @Override
// public int findReturnState(int returnState) {
// return Arrays.binarySearch(returnStates, returnState);
// }
protected internal override PredictionContext RemoveEmptyContext()
{
if (!HasEmpty)
{
return this;
}
if (returnStates.Length == 2)
{
return new SingletonPredictionContext(parents[0], returnStates[0]);
}
else
{
PredictionContext[] parents2 = Arrays.CopyOf(parents, parents.Length - 1);
int[] returnStates2 = Arrays.CopyOf(returnStates, returnStates.Length - 1);
return new Antlr4.Runtime.Atn.ArrayPredictionContext(parents2, returnStates2);
}
}
public override bool Equals(Object o)
{
if (this == o)
{
return true;
}
else if (!(o is ArrayPredictionContext))
{
return false;
}
public override PredictionContext AppendContext(PredictionContext suffix, PredictionContextCache contextCache)
{
return AppendContext(this, suffix, new PredictionContext.IdentityHashMap());
}
if (this.GetHashCode() != o.GetHashCode())
{
return false; // can't be same if hash is different
}
private static PredictionContext AppendContext(PredictionContext context, PredictionContext suffix, PredictionContext.IdentityHashMap visited)
{
if (suffix.IsEmpty)
{
if (IsEmptyLocal(suffix))
{
if (context.HasEmpty)
{
return EmptyLocal;
}
throw new NotSupportedException("what to do here?");
}
return context;
}
if (suffix.Size != 1)
{
throw new NotSupportedException("Appending a tree suffix is not yet supported.");
}
PredictionContext result;
if (!visited.TryGetValue(context, out result))
{
if (context.IsEmpty)
{
result = suffix;
}
else
{
int parentCount = context.Size;
if (context.HasEmpty)
{
parentCount--;
}
PredictionContext[] updatedParents = new PredictionContext[parentCount];
int[] updatedReturnStates = new int[parentCount];
for (int i = 0; i < parentCount; i++)
{
updatedReturnStates[i] = context.GetReturnState(i);
}
for (int i_1 = 0; i_1 < parentCount; i_1++)
{
updatedParents[i_1] = AppendContext(context.GetParent(i_1), suffix, visited);
}
if (updatedParents.Length == 1)
{
result = new SingletonPredictionContext(updatedParents[0], updatedReturnStates[0]);
}
else
{
System.Diagnostics.Debug.Assert(updatedParents.Length > 1);
result = new Antlr4.Runtime.Atn.ArrayPredictionContext(updatedParents, updatedReturnStates);
}
if (context.HasEmpty)
{
result = PredictionContext.Join(result, suffix);
}
}
visited[context] = result;
}
return result;
}
ArrayPredictionContext a = (ArrayPredictionContext)o;
return Arrays.Equals(returnStates, a.returnStates) &&
Arrays.Equals(parents, a.parents);
}
public override bool Equals(object o)
{
if (this == o)
{
return true;
}
else
{
if (!(o is Antlr4.Runtime.Atn.ArrayPredictionContext))
{
return false;
}
}
if (this.GetHashCode() != o.GetHashCode())
{
return false;
}
// can't be same if hash is different
Antlr4.Runtime.Atn.ArrayPredictionContext other = (Antlr4.Runtime.Atn.ArrayPredictionContext)o;
return Equals(other, new HashSet<PredictionContextCache.IdentityCommutativePredictionContextOperands>());
}
private bool Equals(Antlr4.Runtime.Atn.ArrayPredictionContext other, HashSet<PredictionContextCache.IdentityCommutativePredictionContextOperands> visited)
{
Stack<PredictionContext> selfWorkList = new Stack<PredictionContext>();
Stack<PredictionContext> otherWorkList = new Stack<PredictionContext>();
selfWorkList.Push(this);
otherWorkList.Push(other);
while (selfWorkList.Count > 0)
{
PredictionContextCache.IdentityCommutativePredictionContextOperands operands = new PredictionContextCache.IdentityCommutativePredictionContextOperands(selfWorkList.Pop(), otherWorkList.Pop());
if (!visited.Add(operands))
{
continue;
}
int selfSize = operands.X.Size;
if (selfSize == 0)
{
if (!operands.X.Equals(operands.Y))
{
return false;
}
continue;
}
int otherSize = operands.Y.Size;
if (selfSize != otherSize)
{
return false;
}
for (int i = 0; i < selfSize; i++)
{
if (operands.X.GetReturnState(i) != operands.Y.GetReturnState(i))
{
return false;
}
PredictionContext selfParent = operands.X.GetParent(i);
PredictionContext otherParent = operands.Y.GetParent(i);
if (selfParent.GetHashCode() != otherParent.GetHashCode())
{
return false;
}
if (selfParent != otherParent)
{
selfWorkList.Push(selfParent);
otherWorkList.Push(otherParent);
}
}
}
return true;
}
}
public override String ToString()
{
if (IsEmpty)
return "[]";
StringBuilder buf = new StringBuilder();
buf.Append("[");
for (int i = 0; i < returnStates.Length; i++)
{
if (i > 0) buf.Append(", ");
if (returnStates[i] == EMPTY_RETURN_STATE)
{
buf.Append("$");
continue;
}
buf.Append(returnStates[i]);
if (parents[i] != null)
{
buf.Append(' ');
buf.Append(parents[i].ToString());
}
else {
buf.Append("null");
}
}
buf.Append("]");
return buf.ToString();
}
}
}

View File

@ -50,7 +50,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Atom;
return Antlr4.Runtime.Atn.TransitionType.ATOM;
}
}

View File

@ -33,7 +33,6 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>This class stores information about a configuration conflict.</summary>
/// <remarks>This class stores information about a configuration conflict.</remarks>
/// <author>Sam Harwell</author>
public class ConflictInfo
{
@ -68,7 +67,7 @@ namespace Antlr4.Runtime.Atn
/// conflict indicates a true ambiguity in the input.
/// <p>
/// For the
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
/// <see cref="PredictionMode.LL_EXACT_AMBIG_DETECTION"/>
/// prediction mode,
/// accept states are conflicting but not exact are treated as non-accept
/// states.</p>

View File

@ -43,7 +43,7 @@ namespace Antlr4.Runtime.Atn
/// equal to the minimum represented alternative in the conflicting SLL
/// configuration set. Grammars and inputs which result in this scenario are
/// unable to use
/// <see cref="PredictionMode.Sll"/>
/// <see cref="PredictionMode.SLL"/>
/// , which in turn means they cannot use
/// the two-stage parsing strategy to improve parsing performance for that
/// input.</p>

View File

@ -35,271 +35,239 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>This class contains profiling gathered for a particular decision.</summary>
/// <remarks>
/// This class contains profiling gathered for a particular decision.
/// <p>
/// Parsing performance in ANTLR 4 is heavily influenced by both static factors
/// (e.g. the form of the rules in the grammar) and dynamic factors (e.g. the
/// choice of input and the state of the DFA cache at the time profiling
/// operations are started). For best results, gather and use aggregate
/// statistics from a large sample of inputs representing the inputs expected in
/// production before using the results to make changes in the grammar.</p>
/// </remarks>
/// <since>4.3</since>
public class DecisionInfo
{
/// <summary>
/// The decision number, which is an index into
/// <see cref="ATN.decisionToState"/>
/// .
/// </summary>
public readonly int decision;
/// <summary>This class contains profiling gathered for a particular decision.</summary>
/// <remarks>
/// This class contains profiling gathered for a particular decision.
/// <p>
/// Parsing performance in ANTLR 4 is heavily influenced by both static factors
/// (e.g. the form of the rules in the grammar) and dynamic factors (e.g. the
/// choice of input and the state of the DFA cache at the time profiling
/// operations are started). For best results, gather and use aggregate
/// statistics from a large sample of inputs representing the inputs expected in
/// production before using the results to make changes in the grammar.</p>
/// </remarks>
/// <since>4.3</since>
public class DecisionInfo
{
/// <summary>
/// The total number of times
/// <see cref="ParserATNSimulator.AdaptivePredict(ITokenStream, int, ParserRuleContext)"/>
/// was
/// invoked for this decision.
/// </summary>
public long invocations;
/**
* The decision number, which is an index into {@link ATN#decisionToState}.
*/
public readonly int decision;
/// <summary>The sum of the lookahead required for SLL prediction for this decision.</summary>
/// <remarks>
/// The sum of the lookahead required for SLL prediction for this decision.
/// Note that SLL prediction is used before LL prediction for performance
/// reasons even when
/// <see cref="PredictionMode.Ll"/>
/// or
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
/// is used.
/// </remarks>
public long SLL_TotalLook;
/**
* The total number of times {@link ParserATNSimulator#adaptivePredict} was
* invoked for this decision.
*/
public long invocations;
/// <summary>
/// Gets the minimum lookahead required for any single SLL prediction to
/// complete for this decision, by reaching a unique prediction, reaching an
/// SLL conflict state, or encountering a syntax error.
/// </summary>
/// <remarks>
/// Gets the minimum lookahead required for any single SLL prediction to
/// complete for this decision, by reaching a unique prediction, reaching an
/// SLL conflict state, or encountering a syntax error.
/// </remarks>
public long SLL_MinLook;
/**
* The total time spent in {@link ParserATNSimulator#adaptivePredict} for
* this decision, in nanoseconds.
*
* <p>
* The value of this field contains the sum of differential results obtained
* by {@link System#nanoTime()}, and is not adjusted to compensate for JIT
* and/or garbage collection overhead. For best accuracy, use a modern JVM
* implementation that provides precise results from
* {@link System#nanoTime()}, and perform profiling in a separate process
* which is warmed up by parsing the input prior to profiling. If desired,
* call {@link ATNSimulator#clearDFA} to reset the DFA cache to its initial
* state before starting the profiling measurement pass.</p>
*/
public long timeInPrediction;
/// <summary>
/// Gets the maximum lookahead required for any single SLL prediction to
/// complete for this decision, by reaching a unique prediction, reaching an
/// SLL conflict state, or encountering a syntax error.
/// </summary>
/// <remarks>
/// Gets the maximum lookahead required for any single SLL prediction to
/// complete for this decision, by reaching a unique prediction, reaching an
/// SLL conflict state, or encountering a syntax error.
/// </remarks>
public long SLL_MaxLook;
/**
* The sum of the lookahead required for SLL prediction for this decision.
* Note that SLL prediction is used before LL prediction for performance
* reasons even when {@link PredictionMode#LL} or
* {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} is used.
*/
public long SLL_TotalLook;
/// <summary>
/// Gets the
/// <see cref="LookaheadEventInfo"/>
/// associated with the event where the
/// <see cref="SLL_MaxLook"/>
/// value was set.
/// </summary>
public LookaheadEventInfo SLL_MaxLookEvent;
/**
* Gets the minimum lookahead required for any single SLL prediction to
* complete for this decision, by reaching a unique prediction, reaching an
* SLL conflict state, or encountering a syntax error.
*/
public long SLL_MinLook;
/// <summary>The sum of the lookahead required for LL prediction for this decision.</summary>
/// <remarks>
/// The sum of the lookahead required for LL prediction for this decision.
/// Note that LL prediction is only used when SLL prediction reaches a
/// conflict state.
/// </remarks>
public long LL_TotalLook;
/**
* Gets the maximum lookahead required for any single SLL prediction to
* complete for this decision, by reaching a unique prediction, reaching an
* SLL conflict state, or encountering a syntax error.
*/
public long SLL_MaxLook;
/// <summary>
/// Gets the minimum lookahead required for any single LL prediction to
/// complete for this decision.
/// </summary>
/// <remarks>
/// Gets the minimum lookahead required for any single LL prediction to
/// complete for this decision. An LL prediction completes when the algorithm
/// reaches a unique prediction, a conflict state (for
/// <see cref="PredictionMode.Ll"/>
/// , an ambiguity state (for
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
/// , or a syntax error.
/// </remarks>
public long LL_MinLook;
/**
* Gets the {@link LookaheadEventInfo} associated with the event where the
* {@link #SLL_MaxLook} value was set.
*/
public LookaheadEventInfo SLL_MaxLookEvent;
/// <summary>
/// Gets the maximum lookahead required for any single LL prediction to
/// complete for this decision.
/// </summary>
/// <remarks>
/// Gets the maximum lookahead required for any single LL prediction to
/// complete for this decision. An LL prediction completes when the algorithm
/// reaches a unique prediction, a conflict state (for
/// <see cref="PredictionMode.Ll"/>
/// , an ambiguity state (for
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
/// , or a syntax error.
/// </remarks>
public long LL_MaxLook;
/**
* The sum of the lookahead required for LL prediction for this decision.
* Note that LL prediction is only used when SLL prediction reaches a
* conflict state.
*/
public long LL_TotalLook;
/// <summary>
/// Gets the
/// <see cref="LookaheadEventInfo"/>
/// associated with the event where the
/// <see cref="LL_MaxLook"/>
/// value was set.
/// </summary>
public LookaheadEventInfo LL_MaxLookEvent;
/**
* Gets the minimum lookahead required for any single LL prediction to
* complete for this decision. An LL prediction completes when the algorithm
* reaches a unique prediction, a conflict state (for
* {@link PredictionMode#LL}, an ambiguity state (for
* {@link PredictionMode#LL_EXACT_AMBIG_DETECTION}, or a syntax error.
*/
public long LL_MinLook;
/// <summary>
/// A collection of
/// <see cref="ContextSensitivityInfo"/>
/// instances describing the
/// context sensitivities encountered during LL prediction for this decision.
/// </summary>
/// <seealso cref="ContextSensitivityInfo"/>
public readonly IList<ContextSensitivityInfo> contextSensitivities = new List<ContextSensitivityInfo>();
/**
* Gets the maximum lookahead required for any single LL prediction to
* complete for this decision. An LL prediction completes when the algorithm
* reaches a unique prediction, a conflict state (for
* {@link PredictionMode#LL}, an ambiguity state (for
* {@link PredictionMode#LL_EXACT_AMBIG_DETECTION}, or a syntax error.
*/
public long LL_MaxLook;
/// <summary>
/// A collection of
/// <see cref="ErrorInfo"/>
/// instances describing the parse errors
/// identified during calls to
/// <see cref="ParserATNSimulator.AdaptivePredict(ITokenStream, int, ParserRuleContext)"/>
/// for
/// this decision.
/// </summary>
/// <seealso cref="ErrorInfo"/>
public readonly IList<ErrorInfo> errors = new List<ErrorInfo>();
/**
* Gets the {@link LookaheadEventInfo} associated with the event where the
* {@link #LL_MaxLook} value was set.
*/
public LookaheadEventInfo LL_MaxLookEvent;
/// <summary>
/// A collection of
/// <see cref="AmbiguityInfo"/>
/// instances describing the
/// ambiguities encountered during LL prediction for this decision.
/// </summary>
/// <seealso cref="AmbiguityInfo"/>
public readonly IList<AmbiguityInfo> ambiguities = new List<AmbiguityInfo>();
/**
* A collection of {@link ContextSensitivityInfo} instances describing the
* context sensitivities encountered during LL prediction for this decision.
*
* @see ContextSensitivityInfo
*/
public readonly List<ContextSensitivityInfo> contextSensitivities = new List<ContextSensitivityInfo>();
/// <summary>
/// A collection of
/// <see cref="PredicateEvalInfo"/>
/// instances describing the
/// results of evaluating individual predicates during prediction for this
/// decision.
/// </summary>
/// <seealso cref="PredicateEvalInfo"/>
public readonly IList<PredicateEvalInfo> predicateEvals = new List<PredicateEvalInfo>();
/**
* A collection of {@link ErrorInfo} instances describing the parse errors
* identified during calls to {@link ParserATNSimulator#adaptivePredict} for
* this decision.
*
* @see ErrorInfo
*/
public readonly List<ErrorInfo> errors = new List<ErrorInfo>();
/// <summary>
/// The total number of ATN transitions required during SLL prediction for
/// this decision.
/// </summary>
/// <remarks>
/// The total number of ATN transitions required during SLL prediction for
/// this decision. An ATN transition is determined by the number of times the
/// DFA does not contain an edge that is required for prediction, resulting
/// in on-the-fly computation of that edge.
/// <p>
/// If DFA caching of SLL transitions is employed by the implementation, ATN
/// computation may cache the computed edge for efficient lookup during
/// future parsing of this decision. Otherwise, the SLL parsing algorithm
/// will use ATN transitions exclusively.</p>
/// </remarks>
/// <seealso cref="SLL_ATNTransitions"/>
/// <seealso cref="ParserATNSimulator.ComputeTargetState"/>
/// <seealso cref="LexerATNSimulator.ComputeTargetState"/>
public long SLL_ATNTransitions;
/**
* A collection of {@link AmbiguityInfo} instances describing the
* ambiguities encountered during LL prediction for this decision.
*
* @see AmbiguityInfo
*/
public readonly List<AmbiguityInfo> ambiguities = new List<AmbiguityInfo>();
/// <summary>
/// The total number of DFA transitions required during SLL prediction for
/// this decision.
/// </summary>
/// <remarks>
/// The total number of DFA transitions required during SLL prediction for
/// this decision.
/// <p>If the ATN simulator implementation does not use DFA caching for SLL
/// transitions, this value will be 0.</p>
/// </remarks>
/// <seealso cref="ParserATNSimulator.GetExistingTargetState"/>
/// <seealso cref="LexerATNSimulator.GetExistingTargetState"/>
public long SLL_DFATransitions;
/**
* A collection of {@link PredicateEvalInfo} instances describing the
* results of evaluating individual predicates during prediction for this
* decision.
*
* @see PredicateEvalInfo
*/
public readonly List<PredicateEvalInfo> predicateEvals = new List<PredicateEvalInfo>();
/// <summary>
/// Gets the total number of times SLL prediction completed in a conflict
/// state, resulting in fallback to LL prediction.
/// </summary>
/// <remarks>
/// Gets the total number of times SLL prediction completed in a conflict
/// state, resulting in fallback to LL prediction.
/// <p>Note that this value is not related to whether or not
/// <see cref="PredictionMode.Sll"/>
/// may be used successfully with a particular
/// grammar. If the ambiguity resolution algorithm applied to the SLL
/// conflicts for this decision produce the same result as LL prediction for
/// this decision,
/// <see cref="PredictionMode.Sll"/>
/// would produce the same overall
/// parsing result as
/// <see cref="PredictionMode.Ll"/>
/// .</p>
/// </remarks>
public long LL_Fallback;
/**
* The total number of ATN transitions required during SLL prediction for
* this decision. An ATN transition is determined by the number of times the
* DFA does not contain an edge that is required for prediction, resulting
* in on-the-fly computation of that edge.
*
* <p>
* If DFA caching of SLL transitions is employed by the implementation, ATN
* computation may cache the computed edge for efficient lookup during
* future parsing of this decision. Otherwise, the SLL parsing algorithm
* will use ATN transitions exclusively.</p>
*
* @see #SLL_ATNTransitions
* @see ParserATNSimulator#computeTargetState
* @see LexerATNSimulator#computeTargetState
*/
public long SLL_ATNTransitions;
/// <summary>
/// The total number of ATN transitions required during LL prediction for
/// this decision.
/// </summary>
/// <remarks>
/// The total number of ATN transitions required during LL prediction for
/// this decision. An ATN transition is determined by the number of times the
/// DFA does not contain an edge that is required for prediction, resulting
/// in on-the-fly computation of that edge.
/// <p>
/// If DFA caching of LL transitions is employed by the implementation, ATN
/// computation may cache the computed edge for efficient lookup during
/// future parsing of this decision. Otherwise, the LL parsing algorithm will
/// use ATN transitions exclusively.</p>
/// </remarks>
/// <seealso cref="LL_DFATransitions"/>
/// <seealso cref="ParserATNSimulator.ComputeTargetState"/>
/// <seealso cref="LexerATNSimulator.ComputeTargetState"/>
public long LL_ATNTransitions;
/**
* The total number of DFA transitions required during SLL prediction for
* this decision.
*
* <p>If the ATN simulator implementation does not use DFA caching for SLL
* transitions, this value will be 0.</p>
*
* @see ParserATNSimulator#getExistingTargetState
* @see LexerATNSimulator#getExistingTargetState
*/
public long SLL_DFATransitions;
/// <summary>
/// The total number of DFA transitions required during LL prediction for
/// this decision.
/// </summary>
/// <remarks>
/// The total number of DFA transitions required during LL prediction for
/// this decision.
/// <p>If the ATN simulator implementation does not use DFA caching for LL
/// transitions, this value will be 0.</p>
/// </remarks>
/// <seealso cref="ParserATNSimulator.GetExistingTargetState"/>
/// <seealso cref="LexerATNSimulator.GetExistingTargetState"/>
public long LL_DFATransitions;
/**
* Gets the total number of times SLL prediction completed in a conflict
* state, resulting in fallback to LL prediction.
*
* <p>Note that this value is not related to whether or not
* {@link PredictionMode#SLL} may be used successfully with a particular
* grammar. If the ambiguity resolution algorithm applied to the SLL
* conflicts for this decision produce the same result as LL prediction for
* this decision, {@link PredictionMode#SLL} would produce the same overall
* parsing result as {@link PredictionMode#LL}.</p>
*/
public long LL_Fallback;
/// <summary>
/// Constructs a new instance of the
/// <see cref="DecisionInfo"/>
/// class to contain
/// statistics for a particular decision.
/// </summary>
/// <param name="decision">The decision number</param>
public DecisionInfo(int decision)
{
this.decision = decision;
}
/**
* The total number of ATN transitions required during LL prediction for
* this decision. An ATN transition is determined by the number of times the
* DFA does not contain an edge that is required for prediction, resulting
* in on-the-fly computation of that edge.
*
* <p>
* If DFA caching of LL transitions is employed by the implementation, ATN
* computation may cache the computed edge for efficient lookup during
* future parsing of this decision. Otherwise, the LL parsing algorithm will
* use ATN transitions exclusively.</p>
*
* @see #LL_DFATransitions
* @see ParserATNSimulator#computeTargetState
* @see LexerATNSimulator#computeTargetState
*/
public long LL_ATNTransitions;
public override string ToString()
{
return "{" + "decision=" + decision + ", contextSensitivities=" + contextSensitivities.Count + ", errors=" + errors.Count + ", ambiguities=" + ambiguities.Count + ", SLL_lookahead=" + SLL_TotalLook + ", SLL_ATNTransitions=" + SLL_ATNTransitions + ", SLL_DFATransitions=" + SLL_DFATransitions + ", LL_Fallback=" + LL_Fallback + ", LL_lookahead=" + LL_TotalLook + ", LL_ATNTransitions=" + LL_ATNTransitions + '}';
}
}
/**
* The total number of DFA transitions required during LL prediction for
* this decision.
*
* <p>If the ATN simulator implementation does not use DFA caching for LL
* transitions, this value will be 0.</p>
*
* @see ParserATNSimulator#getExistingTargetState
* @see LexerATNSimulator#getExistingTargetState
*/
public long LL_DFATransitions;
/**
* Constructs a new instance of the {@link DecisionInfo} class to contain
* statistics for a particular decision.
*
* @param decision The decision number
*/
public DecisionInfo(int decision)
{
this.decision = decision;
}
public override string ToString()
{
return "{" +
"decision=" + decision +
", contextSensitivities=" + contextSensitivities.Count +
", errors=" + errors.Count +
", ambiguities=" + ambiguities.Count +
", SLL_lookahead=" + SLL_TotalLook +
", SLL_ATNTransitions=" + SLL_ATNTransitions +
", SLL_DFATransitions=" + SLL_DFATransitions +
", LL_Fallback=" + LL_Fallback +
", LL_lookahead=" + LL_TotalLook +
", LL_ATNTransitions=" + LL_ATNTransitions +
'}';
}
}
}

View File

@ -35,37 +35,15 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
#pragma warning disable 0659 // 'class' overrides Object.Equals(object o) but does not override Object.GetHashCode()
public sealed class EmptyPredictionContext : PredictionContext
public sealed class EmptyPredictionContext : SingletonPredictionContext
{
public static readonly Antlr4.Runtime.Atn.EmptyPredictionContext LocalContext = new Antlr4.Runtime.Atn.EmptyPredictionContext(false);
public static readonly Antlr4.Runtime.Atn.EmptyPredictionContext FullContext = new Antlr4.Runtime.Atn.EmptyPredictionContext(true);
private readonly bool fullContext;
private EmptyPredictionContext(bool fullContext)
: base(CalculateEmptyHashCode())
internal EmptyPredictionContext()
: base(null, EMPTY_RETURN_STATE)
{
this.fullContext = fullContext;
}
public bool IsFullContext
{
get
{
return fullContext;
}
}
protected internal override PredictionContext AddEmptyContext()
{
return this;
}
protected internal override PredictionContext RemoveEmptyContext()
{
throw new NotSupportedException("Cannot remove the empty context from itself.");
}
public override PredictionContext GetParent(int index)
{
@ -77,11 +55,7 @@ namespace Antlr4.Runtime.Atn
throw new ArgumentOutOfRangeException();
}
public override int FindReturnState(int returnState)
{
return -1;
}
public override int Size
{
get
@ -90,16 +64,6 @@ namespace Antlr4.Runtime.Atn
}
}
public override PredictionContext AppendContext(int returnContext, PredictionContextCache contextCache)
{
return contextCache.GetChild(this, returnContext);
}
public override PredictionContext AppendContext(PredictionContext suffix, PredictionContextCache contextCache)
{
return suffix;
}
public override bool IsEmpty
{
get
@ -108,7 +72,7 @@ namespace Antlr4.Runtime.Atn
}
}
public override bool HasEmpty
public override bool HasEmptyPath
{
get
{

View File

@ -67,7 +67,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Epsilon;
return Antlr4.Runtime.Atn.TransitionType.EPSILON;
}
}

View File

@ -86,7 +86,7 @@ namespace Antlr4.Runtime.Atn
HashSet<ATNConfig> lookBusy = new HashSet<ATNConfig>();
bool seeThruPreds = false;
// fail to get lookahead upon pred
Look(s.Transition(alt).target, null, PredictionContext.EmptyLocal, look[alt], lookBusy, new BitSet(), seeThruPreds, false);
Look(s.Transition(alt).target, null, PredictionContext.EMPTY, look[alt], lookBusy, new BitSet(), seeThruPreds, false);
// Wipe out lookahead for this alternative if we found nothing
// or we had a predicate when we !seeThruPreds
if (look[alt].Count == 0 || look[alt].Contains(HitPred))
@ -111,7 +111,7 @@ namespace Antlr4.Runtime.Atn
/// and the end of the rule containing
/// <paramref name="s"/>
/// is reached,
/// <see cref="TokenConstants.Epsilon"/>
/// <see cref="TokenConstants.EPSILON"/>
/// is added to the result set.
/// If
/// <paramref name="ctx"/>
@ -119,7 +119,7 @@ namespace Antlr4.Runtime.Atn
/// <see langword="null"/>
/// and the end of the outermost rule is
/// reached,
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// is added to the result set.</p>
/// </summary>
/// <param name="s">the ATN state</param>
@ -157,7 +157,7 @@ namespace Antlr4.Runtime.Atn
/// and the end of the rule containing
/// <paramref name="s"/>
/// is reached,
/// <see cref="TokenConstants.Epsilon"/>
/// <see cref="TokenConstants.EPSILON"/>
/// is added to the result set.
/// If
/// <paramref name="ctx"/>
@ -165,7 +165,7 @@ namespace Antlr4.Runtime.Atn
/// <c>PredictionContext#EMPTY_LOCAL</c>
/// and the end of the outermost rule is
/// reached,
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// is added to the result set.</p>
/// </summary>
/// <param name="s">the ATN state</param>
@ -216,7 +216,7 @@ namespace Antlr4.Runtime.Atn
/// or the end of the rule containing
/// <paramref name="s"/>
/// is reached,
/// <see cref="TokenConstants.Epsilon"/>
/// <see cref="TokenConstants.EPSILON"/>
/// is added to the result set. If
/// <paramref name="ctx"/>
/// is not
@ -228,7 +228,7 @@ namespace Antlr4.Runtime.Atn
/// and
/// <paramref name="stopState"/>
/// or the end of the outermost rule is reached,
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// is added to the result set.
/// </summary>
/// <param name="s">the ATN state.</param>
@ -271,7 +271,7 @@ namespace Antlr4.Runtime.Atn
/// </param>
/// <param name="addEOF">
/// Add
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// to the result if the end of the
/// outermost context is reached. This parameter has no effect if
/// <paramref name="ctx"/>
@ -282,37 +282,30 @@ namespace Antlr4.Runtime.Atn
protected internal virtual void Look(ATNState s, ATNState stopState, PredictionContext ctx, IntervalSet look, HashSet<ATNConfig> lookBusy, BitSet calledRuleStack, bool seeThruPreds, bool addEOF)
{
// System.out.println("_LOOK("+s.stateNumber+", ctx="+ctx);
ATNConfig c = ATNConfig.Create(s, 0, ctx);
ATNConfig c = new ATNConfig(s, 0, ctx);
if (!lookBusy.Add(c))
{
return;
}
if (s == stopState)
{
if (PredictionContext.IsEmptyLocal(ctx))
if (ctx == null)
{
look.Add(TokenConstants.Epsilon);
look.Add(TokenConstants.EPSILON);
return;
}
else
{
if (ctx.IsEmpty)
{
if (addEOF)
{
look.Add(TokenConstants.Eof);
}
return;
}
else if (ctx.IsEmpty && addEOF) {
look.Add(TokenConstants.EOF);
return;
}
}
if (s is RuleStopState)
{
if (ctx.IsEmpty && !PredictionContext.IsEmptyLocal(ctx))
if (ctx.IsEmpty && !ctx.IsEmpty)
{
if (addEOF)
{
look.Add(TokenConstants.Eof);
look.Add(TokenConstants.EOF);
}
return;
}
@ -322,7 +315,7 @@ namespace Antlr4.Runtime.Atn
calledRuleStack.Clear(s.ruleIndex);
for (int i = 0; i < ctx.Size; i++)
{
if (ctx.GetReturnState(i) == PredictionContext.EmptyFullStateKey)
if (ctx.GetReturnState(i) == PredictionContext.EMPTY_RETURN_STATE)
{
continue;
}

View File

@ -0,0 +1,116 @@
using System;
using Antlr4.Runtime.Misc;
namespace Antlr4.Runtime.Atn
{
public class LexerATNConfig : ATNConfig
{
/**
* This is the backing field for {@link #getLexerActionExecutor}.
*/
private readonly LexerActionExecutor lexerActionExecutor;
private readonly bool passedThroughNonGreedyDecision;
public LexerATNConfig(ATNState state,
int alt,
PredictionContext context)
: base(state, alt, context/*, SemanticContext.NONE*/) // TODO
{
this.passedThroughNonGreedyDecision = false;
this.lexerActionExecutor = null;
}
public LexerATNConfig(ATNState state,
int alt,
PredictionContext context,
LexerActionExecutor lexerActionExecutor)
: base(state, alt, context, SemanticContext.NONE)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = false;
}
public LexerATNConfig(LexerATNConfig c, ATNState state)
: base(c, state, c.context, c.semanticContext)
{
this.lexerActionExecutor = c.lexerActionExecutor;
this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
}
public LexerATNConfig(LexerATNConfig c, ATNState state,
LexerActionExecutor lexerActionExecutor)
: base(c, state, c.context, c.semanticContext)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
}
public LexerATNConfig(LexerATNConfig c, ATNState state,
PredictionContext context)
: base(c, state, context, c.semanticContext)
{
this.lexerActionExecutor = c.lexerActionExecutor;
this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
}
/**
* Gets the {@link LexerActionExecutor} capable of executing the embedded
* action(s) for the current configuration.
*/
public LexerActionExecutor getLexerActionExecutor()
{
return lexerActionExecutor;
}
public bool hasPassedThroughNonGreedyDecision()
{
return passedThroughNonGreedyDecision;
}
public override int GetHashCode()
{
int hashCode = MurmurHash.Initialize(7);
hashCode = MurmurHash.Update(hashCode, state.stateNumber);
hashCode = MurmurHash.Update(hashCode, alt);
hashCode = MurmurHash.Update(hashCode, context);
hashCode = MurmurHash.Update(hashCode, semanticContext);
hashCode = MurmurHash.Update(hashCode, passedThroughNonGreedyDecision ? 1 : 0);
hashCode = MurmurHash.Update(hashCode, lexerActionExecutor);
hashCode = MurmurHash.Finish(hashCode, 6);
return hashCode;
}
public override bool Equals(ATNConfig other)
{
if (this == other)
{
return true;
}
else if (!(other is LexerATNConfig))
{
return false;
}
LexerATNConfig lexerOther = (LexerATNConfig)other;
if (passedThroughNonGreedyDecision != lexerOther.passedThroughNonGreedyDecision)
{
return false;
}
if (!(lexerActionExecutor==null ? lexerOther.lexerActionExecutor==null : lexerActionExecutor.Equals(lexerOther.lexerActionExecutor)))
{
return false;
}
return base.Equals(other);
}
private static bool checkNonGreedyDecision(LexerATNConfig source, ATNState target)
{
return source.passedThroughNonGreedyDecision
|| target is DecisionState && ((DecisionState)target).nonGreedy;
}
}
}

View File

@ -0,0 +1,16 @@
using System;
namespace Antlr4.Runtime.Atn
{
public class MergeCache
{
public PredictionContext Get(PredictionContext a, PredictionContext b)
{
throw new NotImplementedException();
}
public void Put(PredictionContext a, PredictionContext b, PredictionContext value)
{
throw new NotImplementedException();
}
}
}

View File

@ -44,7 +44,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.NotSet;
return Antlr4.Runtime.Atn.TransitionType.NOT_SET;
}
}

View File

@ -32,6 +32,7 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/*
/// <author>Sam Harwell</author>
public class OrderedATNConfigSet : ATNConfigSet
{
@ -64,4 +65,5 @@ namespace Antlr4.Runtime.Atn
return left.Equals(right);
}
}
*/
}

View File

@ -35,212 +35,176 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// This class provides access to specific and aggregate statistics gathered
/// during profiling of a parser.
/// </summary>
/// <remarks>
/// This class provides access to specific and aggregate statistics gathered
/// during profiling of a parser.
/// </remarks>
/// <since>4.3</since>
public class ParseInfo
{
protected internal readonly ProfilingATNSimulator atnSimulator;
/**
* This class provides access to specific and aggregate statistics gathered
* during profiling of a parser.
*
* @since 4.3
*/
public class ParseInfo
{
protected readonly ProfilingATNSimulator atnSimulator;
public ParseInfo(ProfilingATNSimulator atnSimulator)
{
this.atnSimulator = atnSimulator;
}
public ParseInfo(ProfilingATNSimulator atnSimulator)
{
this.atnSimulator = atnSimulator;
}
/// <summary>
/// Gets an array of
/// <see cref="DecisionInfo"/>
/// instances containing the profiling
/// information gathered for each decision in the ATN.
/// </summary>
/// <returns>
/// An array of
/// <see cref="DecisionInfo"/>
/// instances, indexed by decision
/// number.
/// </returns>
[NotNull]
public virtual Antlr4.Runtime.Atn.DecisionInfo[] DecisionInfo
{
get
{
return atnSimulator.DecisionInfo;
}
}
/**
* Gets an array of {@link DecisionInfo} instances containing the profiling
* information gathered for each decision in the ATN.
*
* @return An array of {@link DecisionInfo} instances, indexed by decision
* number.
*/
public DecisionInfo[] getDecisionInfo()
{
return atnSimulator.getDecisionInfo();
}
/// <summary>
/// Gets the decision numbers for decisions that required one or more
/// full-context predictions during parsing.
/// </summary>
/// <remarks>
/// Gets the decision numbers for decisions that required one or more
/// full-context predictions during parsing. These are decisions for which
/// <see cref="Antlr4.Runtime.Atn.DecisionInfo.LL_Fallback"/>
/// is non-zero.
/// </remarks>
/// <returns>
/// A list of decision numbers which required one or more
/// full-context predictions during parsing.
/// </returns>
[return: NotNull]
public virtual IList<int> GetLLDecisions()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
IList<int> Ll = new List<int>();
for (int i = 0; i < decisions.Length; i++)
{
long fallBack = decisions[i].LL_Fallback;
if (fallBack > 0)
{
Ll.Add(i);
}
}
return Ll;
}
/**
* Gets the decision numbers for decisions that required one or more
* full-context predictions during parsing. These are decisions for which
* {@link DecisionInfo#LL_Fallback} is non-zero.
*
* @return A list of decision numbers which required one or more
* full-context predictions during parsing.
*/
public List<int> getLLDecisions()
{
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
List<int> LL = new List<int>();
for (int i = 0; i < decisions.Length; i++)
{
long fallBack = decisions[i].LL_Fallback;
if (fallBack > 0) LL.Add(i);
}
return LL;
}
/// <summary>
/// Gets the total number of SLL lookahead operations across all decisions
/// made during parsing.
/// </summary>
/// <remarks>
/// Gets the total number of SLL lookahead operations across all decisions
/// made during parsing. This value is the sum of
/// <see cref="Antlr4.Runtime.Atn.DecisionInfo.SLL_TotalLook"/>
/// for all decisions.
/// </remarks>
public virtual long GetTotalSLLLookaheadOps()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].SLL_TotalLook;
}
return k;
}
/**
* Gets the total time spent during prediction across all decisions made
* during parsing. This value is the sum of
* {@link DecisionInfo#timeInPrediction} for all decisions.
*/
public long getTotalTimeInPrediction()
{
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long t = 0;
for (int i = 0; i < decisions.Length; i++)
{
t += decisions[i].timeInPrediction;
}
return t;
}
/// <summary>
/// Gets the total number of LL lookahead operations across all decisions
/// made during parsing.
/// </summary>
/// <remarks>
/// Gets the total number of LL lookahead operations across all decisions
/// made during parsing. This value is the sum of
/// <see cref="Antlr4.Runtime.Atn.DecisionInfo.LL_TotalLook"/>
/// for all decisions.
/// </remarks>
public virtual long GetTotalLLLookaheadOps()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].LL_TotalLook;
}
return k;
}
/**
* Gets the total number of SLL lookahead operations across all decisions
* made during parsing. This value is the sum of
* {@link DecisionInfo#SLL_TotalLook} for all decisions.
*/
public long getTotalSLLLookaheadOps()
{
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].SLL_TotalLook;
}
return k;
}
/// <summary>
/// Gets the total number of ATN lookahead operations for SLL prediction
/// across all decisions made during parsing.
/// </summary>
/// <remarks>
/// Gets the total number of ATN lookahead operations for SLL prediction
/// across all decisions made during parsing.
/// </remarks>
public virtual long GetTotalSLLATNLookaheadOps()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].SLL_ATNTransitions;
}
return k;
}
/**
* Gets the total number of LL lookahead operations across all decisions
* made during parsing. This value is the sum of
* {@link DecisionInfo#LL_TotalLook} for all decisions.
*/
public long getTotalLLLookaheadOps()
{
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].LL_TotalLook;
}
return k;
}
/// <summary>
/// Gets the total number of ATN lookahead operations for LL prediction
/// across all decisions made during parsing.
/// </summary>
/// <remarks>
/// Gets the total number of ATN lookahead operations for LL prediction
/// across all decisions made during parsing.
/// </remarks>
public virtual long GetTotalLLATNLookaheadOps()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].LL_ATNTransitions;
}
return k;
}
/**
* Gets the total number of ATN lookahead operations for SLL prediction
* across all decisions made during parsing.
*/
public long getTotalSLLATNLookaheadOps()
{
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].SLL_ATNTransitions;
}
return k;
}
/// <summary>
/// Gets the total number of ATN lookahead operations for SLL and LL
/// prediction across all decisions made during parsing.
/// </summary>
/// <remarks>
/// Gets the total number of ATN lookahead operations for SLL and LL
/// prediction across all decisions made during parsing.
/// <p>
/// This value is the sum of
/// <see cref="GetTotalSLLATNLookaheadOps()"/>
/// and
/// <see cref="GetTotalLLATNLookaheadOps()"/>
/// .</p>
/// </remarks>
public virtual long GetTotalATNLookaheadOps()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].SLL_ATNTransitions;
k += decisions[i].LL_ATNTransitions;
}
return k;
}
/**
* Gets the total number of ATN lookahead operations for LL prediction
* across all decisions made during parsing.
*/
public long getTotalLLATNLookaheadOps()
{
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].LL_ATNTransitions;
}
return k;
}
/// <summary>
/// Gets the total number of DFA states stored in the DFA cache for all
/// decisions in the ATN.
/// </summary>
/// <remarks>
/// Gets the total number of DFA states stored in the DFA cache for all
/// decisions in the ATN.
/// </remarks>
public virtual int GetDFASize()
{
int n = 0;
DFA[] decisionToDFA = atnSimulator.atn.decisionToDFA;
for (int i = 0; i < decisionToDFA.Length; i++)
{
n += GetDFASize(i);
}
return n;
}
/**
* Gets the total number of ATN lookahead operations for SLL and LL
* prediction across all decisions made during parsing.
*
* <p>
* This value is the sum of {@link #getTotalSLLATNLookaheadOps} and
* {@link #getTotalLLATNLookaheadOps}.</p>
*/
public long getTotalATNLookaheadOps()
{
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
k += decisions[i].SLL_ATNTransitions;
k += decisions[i].LL_ATNTransitions;
}
return k;
}
/**
* Gets the total number of DFA states stored in the DFA cache for all
* decisions in the ATN.
*/
public int getDFASize()
{
int n = 0;
DFA[] decisionToDFA = atnSimulator.decisionToDFA;
for (int i = 0; i < decisionToDFA.Length; i++)
{
n += getDFASize(i);
}
return n;
}
/**
* Gets the total number of DFA states stored in the DFA cache for a
* particular decision.
*/
public int getDFASize(int decision)
{
DFA decisionToDFA = atnSimulator.decisionToDFA[decision];
return decisionToDFA.states.Count;
}
}
/// <summary>
/// Gets the total number of DFA states stored in the DFA cache for a
/// particular decision.
/// </summary>
/// <remarks>
/// Gets the total number of DFA states stored in the DFA cache for a
/// particular decision.
/// </remarks>
public virtual int GetDFASize(int decision)
{
DFA decisionToDFA = atnSimulator.atn.decisionToDFA[decision];
return decisionToDFA.states.Count;
}
}
}

View File

@ -47,7 +47,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Precedence;
return Antlr4.Runtime.Atn.TransitionType.PRECEDENCE;
}
}

View File

@ -56,7 +56,7 @@ namespace Antlr4.Runtime.Atn
/// . Note that other ATN
/// configurations may predict the same alternative which are guarded by
/// other semantic contexts and/or
/// <see cref="SemanticContext.None"/>
/// <see cref="SemanticContext.NONE"/>
/// .
/// </summary>
public readonly int predictedAlt;

View File

@ -65,7 +65,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Predicate;
return Antlr4.Runtime.Atn.TransitionType.PREDICATE;
}
}

View File

@ -27,179 +27,46 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// Used to cache
/// <see cref="PredictionContext"/>
/// objects. Its used for the shared
/// context cash associated with contexts in DFA states. This cache
/// can be used for both lexers and parsers.
/// </summary>
/// <author>Sam Harwell</author>
public class PredictionContextCache
{
public static readonly Antlr4.Runtime.Atn.PredictionContextCache Uncached = new Antlr4.Runtime.Atn.PredictionContextCache(false);
public class PredictionContextCache
{
protected readonly Dictionary<PredictionContext, PredictionContext> cache =
new Dictionary<PredictionContext, PredictionContext>();
private readonly IDictionary<PredictionContext, PredictionContext> contexts = new Dictionary<PredictionContext, PredictionContext>();
/** Add a context to the cache and return it. If the context already exists,
* return that one instead and do not add a new context to the cache.
* Protect shared cache from unsafe thread access.
*/
public PredictionContext Add(PredictionContext ctx)
{
if (ctx == PredictionContext.EMPTY)
return PredictionContext.EMPTY;
PredictionContext existing = cache.Get(ctx);
if (existing != null)
{
return existing;
}
cache.Put(ctx, ctx);
return ctx;
}
private readonly IDictionary<PredictionContextCache.PredictionContextAndInt, PredictionContext> childContexts = new Dictionary<PredictionContextCache.PredictionContextAndInt, PredictionContext>();
public PredictionContext Get(PredictionContext ctx)
{
return cache.Get(ctx);
}
private readonly IDictionary<PredictionContextCache.IdentityCommutativePredictionContextOperands, PredictionContext> joinContexts = new Dictionary<PredictionContextCache.IdentityCommutativePredictionContextOperands, PredictionContext>();
public int Count
{
get
{
return cache.Count;
}
}
private readonly bool enableCache;
public PredictionContextCache()
: this(true)
{
}
private PredictionContextCache(bool enableCache)
{
this.enableCache = enableCache;
}
public virtual PredictionContext GetAsCached(PredictionContext context)
{
if (!enableCache)
{
return context;
}
PredictionContext result;
if (!contexts.TryGetValue(context, out result))
{
result = context;
contexts[context] = context;
}
return result;
}
public virtual PredictionContext GetChild(PredictionContext context, int invokingState)
{
if (!enableCache)
{
return context.GetChild(invokingState);
}
PredictionContextCache.PredictionContextAndInt operands = new PredictionContextCache.PredictionContextAndInt(context, invokingState);
PredictionContext result;
if (!childContexts.TryGetValue(operands, out result))
{
result = context.GetChild(invokingState);
result = GetAsCached(result);
childContexts[operands] = result;
}
return result;
}
public virtual PredictionContext Join(PredictionContext x, PredictionContext y)
{
if (!enableCache)
{
return PredictionContext.Join(x, y, this);
}
PredictionContextCache.IdentityCommutativePredictionContextOperands operands = new PredictionContextCache.IdentityCommutativePredictionContextOperands(x, y);
PredictionContext result;
if (joinContexts.TryGetValue(operands, out result))
{
return result;
}
result = PredictionContext.Join(x, y, this);
result = GetAsCached(result);
joinContexts[operands] = result;
return result;
}
protected internal sealed class PredictionContextAndInt
{
private readonly PredictionContext obj;
private readonly int value;
public PredictionContextAndInt(PredictionContext obj, int value)
{
this.obj = obj;
this.value = value;
}
public override bool Equals(object obj)
{
if (!(obj is PredictionContextCache.PredictionContextAndInt))
{
return false;
}
else
{
if (obj == this)
{
return true;
}
}
PredictionContextCache.PredictionContextAndInt other = (PredictionContextCache.PredictionContextAndInt)obj;
return this.value == other.value && (this.obj == other.obj || (this.obj != null && this.obj.Equals(other.obj)));
}
public override int GetHashCode()
{
int hashCode = 5;
hashCode = 7 * hashCode + (obj != null ? obj.GetHashCode() : 0);
hashCode = 7 * hashCode + value;
return hashCode;
}
}
protected internal sealed class IdentityCommutativePredictionContextOperands
{
private readonly PredictionContext x;
private readonly PredictionContext y;
public IdentityCommutativePredictionContextOperands(PredictionContext x, PredictionContext y)
{
this.x = x;
this.y = y;
}
public PredictionContext X
{
get
{
return x;
}
}
public PredictionContext Y
{
get
{
return y;
}
}
public override bool Equals(object obj)
{
if (!(obj is PredictionContextCache.IdentityCommutativePredictionContextOperands))
{
return false;
}
else
{
if (this == obj)
{
return true;
}
}
PredictionContextCache.IdentityCommutativePredictionContextOperands other = (PredictionContextCache.IdentityCommutativePredictionContextOperands)obj;
return (this.x == other.x && this.y == other.y) || (this.x == other.y && this.y == other.x);
}
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode();
}
}
}
}
}

View File

@ -58,21 +58,21 @@ namespace Antlr4.Runtime.Atn
/// <p>
/// When using this prediction mode, the parser will either return a correct
/// parse tree (i.e. the same parse tree that would be returned with the
/// <see cref="Ll"/>
/// <see cref="LL"/>
/// prediction mode), or it will report a syntax error. If a
/// syntax error is encountered when using the
/// <see cref="Sll"/>
/// <see cref="SLL"/>
/// prediction mode,
/// it may be due to either an actual syntax error in the input or indicate
/// that the particular combination of grammar and input requires the more
/// powerful
/// <see cref="Ll"/>
/// <see cref="LL"/>
/// prediction abilities to complete successfully.</p>
/// <p>
/// This prediction mode does not provide any guarantees for prediction
/// behavior for syntactically-incorrect inputs.</p>
/// </remarks>
public static readonly PredictionMode Sll = new PredictionMode();
public static readonly PredictionMode SLL = new PredictionMode();
/// <summary>The LL(*) prediction mode.</summary>
/// <remarks>
@ -91,13 +91,13 @@ namespace Antlr4.Runtime.Atn
/// This prediction mode does not provide any guarantees for prediction
/// behavior for syntactically-incorrect inputs.</p>
/// </remarks>
public static readonly PredictionMode Ll = new PredictionMode();
public static readonly PredictionMode LL = new PredictionMode();
/// <summary>The LL(*) prediction mode with exact ambiguity detection.</summary>
/// <remarks>
/// The LL(*) prediction mode with exact ambiguity detection. In addition to
/// the correctness guarantees provided by the
/// <see cref="Ll"/>
/// <see cref="LL"/>
/// prediction mode,
/// this prediction mode instructs the prediction algorithm to determine the
/// complete and exact set of ambiguous alternatives for every ambiguous
@ -111,7 +111,7 @@ namespace Antlr4.Runtime.Atn
/// This prediction mode does not provide any guarantees for prediction
/// behavior for syntactically-incorrect inputs.</p>
/// </remarks>
public static readonly PredictionMode LlExactAmbigDetection = new PredictionMode();
public static readonly PredictionMode LL_EXACT_AMBIG_DETECTION = new PredictionMode();
/// <summary>A Map that uses just the state and the stack context as the key.</summary>
/// <remarks>A Map that uses just the state and the stack context as the key.</remarks>
@ -141,8 +141,8 @@ namespace Antlr4.Runtime.Atn
public override int GetHashCode(ATNConfig o)
{
int hashCode = MurmurHash.Initialize(7);
hashCode = MurmurHash.Update(hashCode, o.State.stateNumber);
hashCode = MurmurHash.Update(hashCode, o.Context);
hashCode = MurmurHash.Update(hashCode, o.state.stateNumber);
hashCode = MurmurHash.Update(hashCode, o.context);
hashCode = MurmurHash.Finish(hashCode, 2);
return hashCode;
}
@ -157,7 +157,7 @@ namespace Antlr4.Runtime.Atn
{
return false;
}
return a.State.stateNumber == b.State.stateNumber && a.Context.Equals(b.Context);
return a.state.stateNumber == b.state.stateNumber && a.context.Equals(b.context);
}
}
@ -265,34 +265,33 @@ namespace Antlr4.Runtime.Atn
/// <see cref="ATNConfigSet"/>
/// will merge everything ignoring predicates.</p>
/// </remarks>
public static bool HasSLLConflictTerminatingPrediction(PredictionMode mode, ATNConfigSet configs)
public static bool HasSLLConflictTerminatingPrediction(PredictionMode mode, ATNConfigSet configSet)
{
if (AllConfigsInRuleStopStates(configs))
if (AllConfigsInRuleStopStates(configSet.configs))
{
return true;
}
// pure SLL mode parsing
if (mode == PredictionMode.Sll)
if (mode == PredictionMode.SLL)
{
// Don't bother with combining configs from different semantic
// contexts if we can fail over to full LL; costs more time
// since we'll often fail over anyway.
if (configs.HasSemanticContext)
if (configSet.hasSemanticContext)
{
// dup configs, tossing out semantic predicates
ATNConfigSet dup = new ATNConfigSet();
foreach (ATNConfig c in configs)
foreach (ATNConfig c in configSet.configs)
{
c.Transform(c.State, SemanticContext.None, false);
dup.Add(c);
dup.Add(new ATNConfig(c, SemanticContext.NONE));
}
configs = dup;
configSet = dup;
}
}
// now we have combined contexts for configs with dissimilar preds
// pure SLL or combined SLL+LL mode parsing
ICollection<BitSet> altsets = GetConflictingAltSubsets(configs);
bool heuristic = HasConflictingAltSet(altsets) && !HasStateAssociatedWithOneAlt(configs);
ICollection<BitSet> altsets = GetConflictingAltSubsets(configSet.configs);
bool heuristic = HasConflictingAltSet(altsets) && !HasStateAssociatedWithOneAlt(configSet.configs);
return heuristic;
}
@ -320,7 +319,7 @@ namespace Antlr4.Runtime.Atn
{
foreach (ATNConfig c in configs)
{
if (c.State is RuleStopState)
if (c.state is RuleStopState)
{
return true;
}
@ -352,7 +351,7 @@ namespace Antlr4.Runtime.Atn
{
foreach (ATNConfig config in configs)
{
if (!(config.State is RuleStopState))
if (!(config.state is RuleStopState))
{
return false;
}
@ -776,7 +775,7 @@ namespace Antlr4.Runtime.Atn
/// Returns the unique alternative predicted by all alternative subsets in
/// <paramref name="altsets"/>
/// . If no such alternative exists, this method returns
/// <see cref="ATN.InvalidAltNumber"/>
/// <see cref="ATN.INVALID_ALT_NUMBER"/>
/// .
/// </summary>
/// <param name="altsets">a collection of alternative subsets</param>
@ -787,7 +786,7 @@ namespace Antlr4.Runtime.Atn
{
return all.NextSetBit(0);
}
return ATN.InvalidAltNumber;
return ATN.INVALID_ALT_NUMBER;
}
/// <summary>
@ -844,7 +843,7 @@ namespace Antlr4.Runtime.Atn
alts = new BitSet();
configToAlts[c] = alts;
}
alts.Set(c.Alt);
alts.Set(c.alt);
}
return configToAlts.Values;
}
@ -871,12 +870,12 @@ namespace Antlr4.Runtime.Atn
foreach (ATNConfig c in configs)
{
BitSet alts;
if (!m.TryGetValue(c.State, out alts))
if (!m.TryGetValue(c.state, out alts))
{
alts = new BitSet();
m[c.State] = alts;
m[c.state] = alts;
}
alts.Set(c.Alt);
alts.Set(c.alt);
}
return m;
}
@ -904,7 +903,7 @@ namespace Antlr4.Runtime.Atn
if (viableAlts.Cardinality() > 1)
{
// more than 1 viable alt
return ATN.InvalidAltNumber;
return ATN.INVALID_ALT_NUMBER;
}
}
return viableAlts.NextSetBit(0);

View File

@ -2,6 +2,7 @@
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* Copyright (c) 2016 Eric Vergnaud
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -35,240 +36,237 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <since>4.3</since>
public class ProfilingATNSimulator : ParserATNSimulator
{
protected internal readonly Antlr4.Runtime.Atn.DecisionInfo[] decisions;
/**
* @since 4.3
*/
public class ProfilingATNSimulator : ParserATNSimulator
{
protected readonly DecisionInfo[] decisions;
protected int numDecisions;
protected internal int numDecisions;
protected int sllStopIndex;
protected int llStopIndex;
private ITokenStream _input;
protected int currentDecision;
protected DFAState currentState;
private int _startIndex;
/** At the point of LL failover, we record how SLL would resolve the conflict so that
* we can determine whether or not a decision / input pair is context-sensitive.
* If LL gives a different result than SLL's predicted alternative, we have a
* context sensitivity for sure. The converse is not necessarily true, however.
* It's possible that after conflict resolution chooses minimum alternatives,
* SLL could get the same answer as LL. Regardless of whether or not the result indicates
* an ambiguity, it is not treated as a context sensitivity because LL prediction
* was not required in order to produce a correct prediction for this decision and input sequence.
* It may in fact still be a context sensitivity but we don't know by looking at the
* minimum alternatives for the current input.
*/
protected int conflictingAltResolvedBySLL;
private int _sllStopIndex;
public ProfilingATNSimulator(Parser parser)
: base(parser,
parser.Interpreter.atn,
parser.Interpreter.decisionToDFA,
parser.Interpreter.getSharedContextCache())
{
numDecisions = atn.decisionToState.Count;
decisions = new DecisionInfo[numDecisions];
for (int i = 0; i < numDecisions; i++)
{
decisions[i] = new DecisionInfo(i);
}
}
private int _llStopIndex;
public override int AdaptivePredict(ITokenStream input, int decision, ParserRuleContext outerContext)
{
try
{
this.sllStopIndex = -1;
this.llStopIndex = -1;
this.currentDecision = decision;
long start = DateTime.Now.ToFileTime(); // expensive but useful info
int alt = base.AdaptivePredict(input, decision, outerContext);
long stop = DateTime.Now.ToFileTime();
decisions[decision].timeInPrediction += (stop - start);
decisions[decision].invocations++;
protected internal int currentDecision;
int SLL_k = sllStopIndex - startIndex + 1;
decisions[decision].SLL_TotalLook += SLL_k;
decisions[decision].SLL_MinLook = decisions[decision].SLL_MinLook == 0 ? SLL_k : Math.Min(decisions[decision].SLL_MinLook, SLL_k);
if (SLL_k > decisions[decision].SLL_MaxLook)
{
decisions[decision].SLL_MaxLook = SLL_k;
decisions[decision].SLL_MaxLookEvent =
new LookaheadEventInfo(decision, null/*, alt*/, input, startIndex, sllStopIndex, false);
}
protected internal SimulatorState currentState;
if (llStopIndex >= 0)
{
int LL_k = llStopIndex - startIndex + 1;
decisions[decision].LL_TotalLook += LL_k;
decisions[decision].LL_MinLook = decisions[decision].LL_MinLook == 0 ? LL_k : Math.Min(decisions[decision].LL_MinLook, LL_k);
if (LL_k > decisions[decision].LL_MaxLook)
{
decisions[decision].LL_MaxLook = LL_k;
decisions[decision].LL_MaxLookEvent =
new LookaheadEventInfo(decision, null/*, alt*/, input, startIndex, llStopIndex, true);
}
}
/// <summary>
/// At the point of LL failover, we record how SLL would resolve the conflict so that
/// we can determine whether or not a decision / input pair is context-sensitive.
/// </summary>
/// <remarks>
/// At the point of LL failover, we record how SLL would resolve the conflict so that
/// we can determine whether or not a decision / input pair is context-sensitive.
/// If LL gives a different result than SLL's predicted alternative, we have a
/// context sensitivity for sure. The converse is not necessarily true, however.
/// It's possible that after conflict resolution chooses minimum alternatives,
/// SLL could get the same answer as LL. Regardless of whether or not the result indicates
/// an ambiguity, it is not treated as a context sensitivity because LL prediction
/// was not required in order to produce a correct prediction for this decision and input sequence.
/// It may in fact still be a context sensitivity but we don't know by looking at the
/// minimum alternatives for the current input.
/// </remarks>
protected internal int conflictingAltResolvedBySLL;
return alt;
}
finally
{
this.currentDecision = -1;
}
}
public ProfilingATNSimulator(Parser parser)
: base(parser, parser.Interpreter.atn)
{
optimize_ll1 = false;
reportAmbiguities = true;
numDecisions = atn.decisionToState.Count;
decisions = new Antlr4.Runtime.Atn.DecisionInfo[numDecisions];
for (int i = 0; i < numDecisions; i++)
{
decisions[i] = new Antlr4.Runtime.Atn.DecisionInfo(i);
}
}
protected override DFAState GetExistingTargetState(DFAState previousD, int t)
{
// this method is called after each time the input position advances
// during SLL prediction
sllStopIndex = input.Index;
public override int AdaptivePredict(ITokenStream input, int decision, ParserRuleContext outerContext)
{
try
{
this._input = input;
this._startIndex = input.Index;
// it's possible for SLL to reach a conflict state without consuming any input
this._sllStopIndex = _startIndex - 1;
this._llStopIndex = -1;
this.currentDecision = decision;
this.currentState = null;
this.conflictingAltResolvedBySLL = ATN.InvalidAltNumber;
// expensive but useful info
int alt = base.AdaptivePredict(input, decision, outerContext);
decisions[decision].invocations++;
int SLL_k = _sllStopIndex - _startIndex + 1;
decisions[decision].SLL_TotalLook += SLL_k;
decisions[decision].SLL_MinLook = decisions[decision].SLL_MinLook == 0 ? SLL_k : Math.Min(decisions[decision].SLL_MinLook, SLL_k);
if (SLL_k > decisions[decision].SLL_MaxLook)
{
decisions[decision].SLL_MaxLook = SLL_k;
decisions[decision].SLL_MaxLookEvent = new LookaheadEventInfo(decision, null, input, _startIndex, _sllStopIndex, false);
}
if (_llStopIndex >= 0)
{
int LL_k = _llStopIndex - _startIndex + 1;
decisions[decision].LL_TotalLook += LL_k;
decisions[decision].LL_MinLook = decisions[decision].LL_MinLook == 0 ? LL_k : Math.Min(decisions[decision].LL_MinLook, LL_k);
if (LL_k > decisions[decision].LL_MaxLook)
{
decisions[decision].LL_MaxLook = LL_k;
decisions[decision].LL_MaxLookEvent = new LookaheadEventInfo(decision, null, input, _startIndex, _llStopIndex, true);
}
}
return alt;
}
finally
{
this._input = null;
this.currentDecision = -1;
}
}
DFAState existingTargetState = base.GetExistingTargetState(previousD, t);
if (existingTargetState != null)
{
decisions[currentDecision].SLL_DFATransitions++; // count only if we transition over a DFA state
if (existingTargetState == ERROR)
{
decisions[currentDecision].errors.Add(
new ErrorInfo(currentDecision, null /*previousD.configs*/, input, startIndex, sllStopIndex)
);
}
}
protected internal override SimulatorState GetStartState(DFA dfa, ITokenStream input, ParserRuleContext outerContext, bool useContext)
{
SimulatorState state = base.GetStartState(dfa, input, outerContext, useContext);
currentState = state;
return state;
}
currentState = existingTargetState;
return existingTargetState;
}
protected internal override SimulatorState ComputeStartState(DFA dfa, ParserRuleContext globalContext, bool useContext)
{
SimulatorState state = base.ComputeStartState(dfa, globalContext, useContext);
currentState = state;
return state;
}
protected override DFAState ComputeTargetState(DFA dfa, DFAState previousD, int t)
{
DFAState state = base.ComputeTargetState(dfa, previousD, t);
currentState = state;
return state;
}
protected internal override SimulatorState ComputeReachSet(DFA dfa, SimulatorState previous, int t, PredictionContextCache contextCache)
{
SimulatorState reachState = base.ComputeReachSet(dfa, previous, t, contextCache);
if (reachState == null)
{
// no reach on current lookahead symbol. ERROR.
decisions[currentDecision].errors.Add(new ErrorInfo(currentDecision, previous, _input, _startIndex, _input.Index));
}
currentState = reachState;
return reachState;
}
protected override ATNConfigSet ComputeReachSet(ATNConfigSet closure, int t, bool fullCtx)
{
if (fullCtx)
{
// this method is called after each time the input position advances
// during full context prediction
llStopIndex = input.Index;
}
protected internal override DFAState GetExistingTargetState(DFAState previousD, int t)
{
// this method is called after each time the input position advances
if (currentState.useContext)
{
_llStopIndex = _input.Index;
}
else
{
_sllStopIndex = _input.Index;
}
DFAState existingTargetState = base.GetExistingTargetState(previousD, t);
if (existingTargetState != null)
{
// this method is directly called by execDFA; must construct a SimulatorState
// to represent the current state for this case
currentState = new SimulatorState(currentState.outerContext, existingTargetState, currentState.useContext, currentState.remainingOuterContext);
if (currentState.useContext)
{
decisions[currentDecision].LL_DFATransitions++;
}
else
{
decisions[currentDecision].SLL_DFATransitions++;
}
// count only if we transition over a DFA state
if (existingTargetState == Error)
{
SimulatorState state = new SimulatorState(currentState.outerContext, previousD, currentState.useContext, currentState.remainingOuterContext);
decisions[currentDecision].errors.Add(new ErrorInfo(currentDecision, state, _input, _startIndex, _input.Index));
}
}
return existingTargetState;
}
ATNConfigSet reachConfigs = base.ComputeReachSet(closure, t, fullCtx);
if (fullCtx)
{
decisions[currentDecision].LL_ATNTransitions++; // count computation even if error
if (reachConfigs != null)
{
}
else { // no reach on current lookahead symbol. ERROR.
// TODO: does not handle delayed errors per getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule()
decisions[currentDecision].errors.Add(
new ErrorInfo(currentDecision, null /*closure*/, input, startIndex, llStopIndex)
);
}
}
else {
decisions[currentDecision].SLL_ATNTransitions++;
if (reachConfigs != null)
{
}
else { // no reach on current lookahead symbol. ERROR.
decisions[currentDecision].errors.Add(
new ErrorInfo(currentDecision, null /*closure*/, input, startIndex, sllStopIndex)
);
}
}
return reachConfigs;
}
protected internal override Tuple<DFAState, ParserRuleContext> ComputeTargetState(DFA dfa, DFAState s, ParserRuleContext remainingGlobalContext, int t, bool useContext, PredictionContextCache contextCache)
{
Tuple<DFAState, ParserRuleContext> targetState = base.ComputeTargetState(dfa, s, remainingGlobalContext, t, useContext, contextCache);
if (useContext)
{
decisions[currentDecision].LL_ATNTransitions++;
}
else
{
decisions[currentDecision].SLL_ATNTransitions++;
}
return targetState;
}
protected override bool EvalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt, bool fullCtx)
{
bool result = base.EvalSemanticContext(pred, parserCallStack, alt, fullCtx);
if (!(pred is SemanticContext.PrecedencePredicate)) {
bool fullContext = llStopIndex >= 0;
int stopIndex = fullContext ? llStopIndex : sllStopIndex;
decisions[currentDecision].predicateEvals.Add(
new PredicateEvalInfo(null , currentDecision, input, startIndex, stopIndex, pred, result, alt/*, fullCtx*/)
);
}
protected internal override bool EvalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt)
{
bool result = base.EvalSemanticContext(pred, parserCallStack, alt);
if (!(pred is SemanticContext.PrecedencePredicate))
{
bool fullContext = _llStopIndex >= 0;
int stopIndex = fullContext ? _llStopIndex : _sllStopIndex;
decisions[currentDecision].predicateEvals.Add(new PredicateEvalInfo(currentState, currentDecision, _input, _startIndex, stopIndex, pred, result, alt));
}
return result;
}
return result;
}
protected internal override void ReportContextSensitivity(DFA dfa, int prediction, SimulatorState acceptState, int startIndex, int stopIndex)
{
if (prediction != conflictingAltResolvedBySLL)
{
decisions[currentDecision].contextSensitivities.Add(new ContextSensitivityInfo(currentDecision, acceptState, _input, startIndex, stopIndex));
}
base.ReportContextSensitivity(dfa, prediction, acceptState, startIndex, stopIndex);
}
protected override void ReportAttemptingFullContext(DFA dfa, BitSet conflictingAlts, ATNConfigSet configs, int startIndex, int stopIndex)
{
if (conflictingAlts != null)
{
conflictingAltResolvedBySLL = conflictingAlts.NextSetBit(0);
}
else {
conflictingAltResolvedBySLL = configs.getAlts().NextSetBit(0);
}
decisions[currentDecision].LL_Fallback++;
base.ReportAttemptingFullContext(dfa, conflictingAlts, configs, startIndex, stopIndex);
}
protected internal override void ReportAttemptingFullContext(DFA dfa, BitSet conflictingAlts, SimulatorState conflictState, int startIndex, int stopIndex)
{
if (conflictingAlts != null)
{
conflictingAltResolvedBySLL = conflictingAlts.NextSetBit(0);
}
else
{
conflictingAltResolvedBySLL = conflictState.s0.configs.RepresentedAlternatives.NextSetBit(0);
}
decisions[currentDecision].LL_Fallback++;
base.ReportAttemptingFullContext(dfa, conflictingAlts, conflictState, startIndex, stopIndex);
}
protected override void ReportContextSensitivity(DFA dfa, int prediction, ATNConfigSet configs, int startIndex, int stopIndex)
{
if (prediction != conflictingAltResolvedBySLL)
{
decisions[currentDecision].contextSensitivities.Add(
new ContextSensitivityInfo(currentDecision, null /*configs*/, input, startIndex, stopIndex)
);
}
base.ReportContextSensitivity(dfa, prediction, configs, startIndex, stopIndex);
}
protected internal override void ReportAmbiguity(DFA dfa, DFAState D, int startIndex, int stopIndex, bool exact, BitSet ambigAlts, ATNConfigSet configs)
{
int prediction;
if (ambigAlts != null)
{
prediction = ambigAlts.NextSetBit(0);
}
else
{
prediction = configs.RepresentedAlternatives.NextSetBit(0);
}
if (conflictingAltResolvedBySLL != ATN.InvalidAltNumber && prediction != conflictingAltResolvedBySLL)
{
// Even though this is an ambiguity we are reporting, we can
// still detect some context sensitivities. Both SLL and LL
// are showing a conflict, hence an ambiguity, but if they resolve
// to different minimum alternatives we have also identified a
// context sensitivity.
decisions[currentDecision].contextSensitivities.Add(new ContextSensitivityInfo(currentDecision, currentState, _input, startIndex, stopIndex));
}
decisions[currentDecision].ambiguities.Add(new AmbiguityInfo(currentDecision, currentState, _input, startIndex, stopIndex));
base.ReportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configs);
}
protected override void ReportAmbiguity(DFA dfa, DFAState D, int startIndex, int stopIndex, bool exact,
BitSet ambigAlts, ATNConfigSet configSet)
{
int prediction;
if (ambigAlts != null)
{
prediction = ambigAlts.NextSetBit(0);
}
else {
prediction = configSet.getAlts().NextSetBit(0);
}
if (configSet.fullCtx && prediction != conflictingAltResolvedBySLL)
{
// Even though this is an ambiguity we are reporting, we can
// still detect some context sensitivities. Both SLL and LL
// are showing a conflict, hence an ambiguity, but if they resolve
// to different minimum alternatives we have also identified a
// context sensitivity.
decisions[currentDecision].contextSensitivities.Add(
new ContextSensitivityInfo(currentDecision, null /*configs*/, input, startIndex, stopIndex)
);
}
decisions[currentDecision].ambiguities.Add(
new AmbiguityInfo(currentDecision, null /*configs, ambigAlts*/,
input, startIndex, stopIndex/*, configs.IsFullContext*/)
);
base.ReportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configSet);
}
// ---------------------------------------------------------------------
public DecisionInfo[] getDecisionInfo()
{
return decisions;
}
public DFAState getCurrentState()
{
return currentState;
}
}
public virtual Antlr4.Runtime.Atn.DecisionInfo[] DecisionInfo
{
get
{
// ---------------------------------------------------------------------
return decisions;
}
}
}
}

View File

@ -50,7 +50,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Range;
return Antlr4.Runtime.Atn.TransitionType.RANGE;
}
}

View File

@ -68,7 +68,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Rule;
return Antlr4.Runtime.Atn.TransitionType.RULE;
}
}

View File

@ -70,7 +70,7 @@ namespace Antlr4.Runtime.Atn
///
/// 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
@ -99,7 +99,7 @@ namespace Antlr4.Runtime.Atn
/// evaluated, which will be one of the following values.
/// <ul>
/// <li>
/// <see cref="None"/>
/// <see cref="NONE"/>
/// : if the predicate simplifies to
/// <see langword="true"/>
/// after
@ -210,7 +210,7 @@ namespace Antlr4.Runtime.Atn
{
if (parser.Precpred(parserCallStack, precedence))
{
return SemanticContext.None;
return SemanticContext.NONE;
}
else
{
@ -380,7 +380,7 @@ namespace Antlr4.Runtime.Atn
}
else
{
if (evaluated != None)
if (evaluated != NONE)
{
// Reduce the result by skipping true elements
operands.Add(evaluated);
@ -394,7 +394,7 @@ namespace Antlr4.Runtime.Atn
if (operands.Count == 0)
{
// all elements were true, so the AND context is true
return None;
return NONE;
}
SemanticContext result = operands[0];
for (int i = 1; i < operands.Count; i++)
@ -505,10 +505,10 @@ namespace Antlr4.Runtime.Atn
{
SemanticContext evaluated = context.EvalPrecedence(parser, parserCallStack);
differs |= (evaluated != context);
if (evaluated == None)
if (evaluated == NONE)
{
// The OR context is true if any element is true
return None;
return NONE;
}
else
{
@ -544,11 +544,11 @@ namespace Antlr4.Runtime.Atn
public static SemanticContext AndOp(SemanticContext a, SemanticContext b)
{
if (a == null || a == None)
if (a == null || a == NONE)
{
return b;
}
if (b == null || b == None)
if (b == null || b == NONE)
{
return a;
}
@ -571,9 +571,9 @@ namespace Antlr4.Runtime.Atn
{
return a;
}
if (a == None || b == None)
if (a == NONE || b == NONE)
{
return None;
return NONE;
}
SemanticContext.OR result = new SemanticContext.OR(a, b);
if (result.opnds.Length == 1)

View File

@ -55,7 +55,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Set;
return Antlr4.Runtime.Atn.TransitionType.SET;
}
}

View File

@ -34,8 +34,19 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
#pragma warning disable 0659 // 'class' overrides Object.Equals(object o) but does not override Object.GetHashCode()
public class SingletonPredictionContext : PredictionContext
public class SingletonPredictionContext : PredictionContext
{
public static PredictionContext Create(PredictionContext parent, int returnState)
{
if (returnState == EMPTY_RETURN_STATE && parent == null)
{
// someone can pass in the bits of an array ctx that mean $
return PredictionContext.EMPTY;
}
return new SingletonPredictionContext(parent, returnState);
}
[NotNull]
public readonly PredictionContext parent;
@ -44,7 +55,6 @@ namespace Antlr4.Runtime.Atn
internal SingletonPredictionContext(PredictionContext parent, int returnState)
: base(CalculateHashCode(parent, returnState))
{
System.Diagnostics.Debug.Assert(returnState != EmptyFullStateKey && returnState != EmptyLocalStateKey);
this.parent = parent;
this.returnState = returnState;
}
@ -61,11 +71,7 @@ namespace Antlr4.Runtime.Atn
return returnState;
}
public override int FindReturnState(int returnState)
{
return this.returnState == returnState ? 0 : -1;
}
public override int Size
{
get
@ -82,7 +88,7 @@ namespace Antlr4.Runtime.Atn
}
}
public override bool HasEmpty
public override bool HasEmptyPath
{
get
{
@ -90,23 +96,6 @@ namespace Antlr4.Runtime.Atn
}
}
public override PredictionContext AppendContext(PredictionContext suffix, PredictionContextCache contextCache)
{
return contextCache.GetChild(parent.AppendContext(suffix, contextCache), returnState);
}
protected internal override PredictionContext AddEmptyContext()
{
PredictionContext[] parents = new PredictionContext[] { parent, EmptyFull };
int[] returnStates = new int[] { returnState, EmptyFullStateKey };
return new ArrayPredictionContext(parents, returnStates);
}
protected internal override PredictionContext RemoveEmptyContext()
{
return this;
}
public override bool Equals(object o)
{
if (o == this)

View File

@ -34,16 +34,16 @@ namespace Antlr4.Runtime.Atn
{
public enum TransitionType
{
Invalid,
Epsilon,
Range,
Rule,
Predicate,
Atom,
Action,
Set,
NotSet,
Wildcard,
Precedence
INVALID,
EPSILON,
RANGE,
RULE,
PREDICATE,
ATOM,
ACTION,
SET,
NOT_SET,
WILDCARD,
PRECEDENCE
}
}

View File

@ -44,7 +44,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Wildcard;
return Antlr4.Runtime.Atn.TransitionType.WILDCARD;
}
}

View File

@ -89,7 +89,7 @@ namespace Antlr4.Runtime
/// <see cref="p"/>
/// <c>]</c>
/// should be
/// <see cref="Lt(int)">LT(1)</see>
/// <see cref="LT(int)">LT(1)</see>
/// .
/// <p>This field is set to -1 when the stream is first constructed or when
/// <see cref="SetTokenSource(ITokenSource)"/>
@ -104,7 +104,7 @@ namespace Antlr4.Runtime
/// <summary>
/// Indicates whether the
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// token has been fetched from
/// <see cref="_tokenSource"/>
/// and added to
@ -122,7 +122,7 @@ namespace Antlr4.Runtime
/// and
/// <see cref="p"/>
/// instead of calling
/// <see cref="La(int)"/>
/// <see cref="LA(int)"/>
/// .</li>
/// <li>
/// <see cref="Fetch(int)"/>
@ -209,7 +209,7 @@ namespace Antlr4.Runtime
// not yet initialized
skipEofCheck = false;
}
if (!skipEofCheck && La(1) == IntStreamConstants.Eof)
if (!skipEofCheck && LA(1) == IntStreamConstants.EOF)
{
throw new InvalidOperationException("cannot consume EOF");
}
@ -268,7 +268,7 @@ namespace Antlr4.Runtime
((IWritableToken)t).TokenIndex = tokens.Count;
}
tokens.Add(t);
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
fetchedEOF = true;
return i + 1;
@ -303,7 +303,7 @@ namespace Antlr4.Runtime
for (int i = start; i <= stop; i++)
{
IToken t = tokens[i];
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
break;
}
@ -312,9 +312,9 @@ namespace Antlr4.Runtime
return subset;
}
public virtual int La(int i)
public virtual int LA(int i)
{
return Lt(i).Type;
return LT(i).Type;
}
protected internal virtual IToken Lb(int k)
@ -327,7 +327,7 @@ namespace Antlr4.Runtime
}
[return: NotNull]
public virtual IToken Lt(int k)
public virtual IToken LT(int k)
{
LazyInit();
if (k == 0)
@ -477,7 +477,7 @@ namespace Antlr4.Runtime
IToken token = tokens[i];
while (token.Channel != channel)
{
if (token.Type == TokenConstants.Eof)
if (token.Type == TokenConstants.EOF)
{
return i;
}
@ -520,7 +520,7 @@ namespace Antlr4.Runtime
while (i >= 0)
{
IToken token = tokens[i];
if (token.Type == TokenConstants.Eof || token.Channel == channel)
if (token.Type == TokenConstants.EOF || token.Channel == channel)
{
return i;
}
@ -681,7 +681,7 @@ namespace Antlr4.Runtime
for (int i = start; i <= stop; i++)
{
IToken t = tokens[i];
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
break;
}

View File

@ -45,9 +45,9 @@ namespace Antlr4.Runtime
/// <see cref="BufferedTokenStream.GetText()"/>
/// . The channel filtering is only used for code
/// accessing tokens via the lookahead methods
/// <see cref="BufferedTokenStream.La(int)"/>
/// <see cref="BufferedTokenStream.LA(int)"/>
/// ,
/// <see cref="Lt(int)"/>
/// <see cref="LT(int)"/>
/// , and
/// <see cref="Lb(int)"/>
/// .</p>
@ -109,7 +109,7 @@ namespace Antlr4.Runtime
/// or have the
/// <see cref="IToken.Type()"/>
/// equal to
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// will be returned by the
/// token stream lookahead methods.
/// </summary>
@ -148,7 +148,7 @@ namespace Antlr4.Runtime
return tokens[i];
}
public override IToken Lt(int k)
public override IToken LT(int k)
{
//System.out.println("enter LT("+k+")");
LazyInit();
@ -190,7 +190,7 @@ namespace Antlr4.Runtime
{
n++;
}
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
break;
}

View File

@ -288,9 +288,9 @@ namespace Antlr4.Runtime
return;
}
ITokenStream tokens = ((ITokenStream)recognizer.InputStream);
int la = tokens.La(1);
int la = tokens.LA(1);
// try cheaper subset first; might get lucky. seems to shave a wee bit off
if (recognizer.Atn.NextTokens(s).Contains(la) || la == TokenConstants.Eof)
if (recognizer.Atn.NextTokens(s).Contains(la) || la == TokenConstants.EOF)
{
return;
}
@ -349,7 +349,7 @@ namespace Antlr4.Runtime
string input;
if (tokens != null)
{
if (e.StartToken.Type == TokenConstants.Eof)
if (e.StartToken.Type == TokenConstants.EOF)
{
input = "<EOF>";
}
@ -613,7 +613,7 @@ namespace Antlr4.Runtime
/// </returns>
protected internal virtual bool SingleTokenInsertion(Parser recognizer)
{
int currentSymbolType = ((ITokenStream)recognizer.InputStream).La(1);
int currentSymbolType = ((ITokenStream)recognizer.InputStream).LA(1);
// if current token is consistent with what could come after current
// ATN state, then we know we're missing a token; error recovery
// is free to conjure up and insert the missing token
@ -665,7 +665,7 @@ namespace Antlr4.Runtime
[return: Nullable]
protected internal virtual IToken SingleTokenDeletion(Parser recognizer)
{
int nextTokenType = ((ITokenStream)recognizer.InputStream).La(2);
int nextTokenType = ((ITokenStream)recognizer.InputStream).LA(2);
IntervalSet expecting = GetExpectedTokens(recognizer);
if (expecting.Contains(nextTokenType))
{
@ -709,7 +709,7 @@ namespace Antlr4.Runtime
int expectedTokenType = expecting.MinElement;
// get any element
string tokenText;
if (expectedTokenType == TokenConstants.Eof)
if (expectedTokenType == TokenConstants.EOF)
{
tokenText = "<missing EOF>";
}
@ -718,8 +718,8 @@ namespace Antlr4.Runtime
tokenText = "<missing " + recognizer.Vocabulary.GetDisplayName(expectedTokenType) + ">";
}
IToken current = currentSymbol;
IToken lookback = ((ITokenStream)recognizer.InputStream).Lt(-1);
if (current.Type == TokenConstants.Eof && lookback != null)
IToken lookback = ((ITokenStream)recognizer.InputStream).LT(-1);
if (current.Type == TokenConstants.EOF && lookback != null)
{
current = lookback;
}
@ -761,7 +761,7 @@ namespace Antlr4.Runtime
string s = GetSymbolText(t);
if (s == null)
{
if (GetSymbolType(t) == TokenConstants.Eof)
if (GetSymbolType(t) == TokenConstants.EOF)
{
s = "<EOF>";
}
@ -808,7 +808,7 @@ namespace Antlr4.Runtime
recoverSet.AddAll(follow);
ctx = ctx.Parent;
}
recoverSet.Remove(TokenConstants.Epsilon);
recoverSet.Remove(TokenConstants.EPSILON);
// System.out.println("recover set "+recoverSet.toString(recognizer.getTokenNames()));
return recoverSet;
}
@ -818,13 +818,13 @@ namespace Antlr4.Runtime
protected internal virtual void ConsumeUntil(Parser recognizer, IntervalSet set)
{
// System.err.println("consumeUntil("+set.toString(recognizer.getTokenNames())+")");
int ttype = ((ITokenStream)recognizer.InputStream).La(1);
while (ttype != TokenConstants.Eof && !set.Contains(ttype))
int ttype = ((ITokenStream)recognizer.InputStream).LA(1);
while (ttype != TokenConstants.EOF && !set.Contains(ttype))
{
//System.out.println("consume during recover LA(1)="+getTokenNames()[input.LA(1)]);
// recognizer.getInputStream().consume();
recognizer.Consume();
ttype = ((ITokenStream)recognizer.InputStream).La(1);
ttype = ((ITokenStream)recognizer.InputStream).LA(1);
}
}
}

View File

@ -56,9 +56,6 @@ namespace Antlr4.Runtime.Dfa
[NotNull]
public readonly AtomicReference<DFAState> s0 = new AtomicReference<DFAState>();
[NotNull]
public readonly AtomicReference<DFAState> s0full = new AtomicReference<DFAState>();
public readonly int decision;
/// <summary>From which ATN state did we create this DFA?</summary>
@ -71,9 +68,6 @@ namespace Antlr4.Runtime.Dfa
private readonly int maxDfaEdge;
[NotNull]
private static readonly Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> emptyPrecedenceEdges = new Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState>(0, 200);
[NotNull]
private readonly Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> emptyEdgeMap;
@ -99,12 +93,12 @@ namespace Antlr4.Runtime.Dfa
this.decision = decision;
if (this.atnStartState.atn.grammarType == ATNType.Lexer)
{
minDfaEdge = LexerATNSimulator.MinDfaEdge;
maxDfaEdge = LexerATNSimulator.MaxDfaEdge;
minDfaEdge = LexerATNSimulator.MIN_DFA_EDGE;
maxDfaEdge = LexerATNSimulator.MAX_DFA_EDGE;
}
else
{
minDfaEdge = TokenConstants.Eof;
minDfaEdge = TokenConstants.EOF;
maxDfaEdge = atnStartState.atn.maxTokenType;
}
this.emptyEdgeMap = new Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState>(minDfaEdge, maxDfaEdge);
@ -206,26 +200,23 @@ namespace Antlr4.Runtime.Dfa
}
set
{
bool precedenceDfa = value;
// s0.get() and s0full.get() are never null for a precedence DFA
// s0full.get() is never null for a precedence DFA
// s0.get() is never null for a precedence DFA
lock (this)
{
if (this.precedenceDfa != precedenceDfa)
if (this.precedenceDfa != value)
{
this.states.Clear();
if (precedenceDfa)
if (value)
{
this.s0.Set(new DFAState(emptyPrecedenceEdges, EmptyContextEdgeMap, new ATNConfigSet()));
this.s0full.Set(new DFAState(emptyPrecedenceEdges, EmptyContextEdgeMap, new ATNConfigSet()));
this.s0.Set(new DFAState(new ATNConfigSet()));
}
else
{
this.s0.Set(null);
this.s0full.Set(null);
}
this.precedenceDfa = precedenceDfa;
this.precedenceDfa = value;
}
}
}
@ -248,14 +239,8 @@ namespace Antlr4.Runtime.Dfa
{
throw new InvalidOperationException("Only precedence DFAs may contain a precedence start state.");
}
if (fullContext)
{
return s0full.Get().GetTarget(precedence);
}
else
{
return s0.Get().GetTarget(precedence);
}
return s0.Get().edges[precedence];
}
/// <summary>Set the start state for a specific precedence value.</summary>
@ -268,7 +253,7 @@ namespace Antlr4.Runtime.Dfa
/// </param>
/// <exception cref="System.InvalidOperationException">if this is not a precedence DFA.</exception>
/// <seealso cref="IsPrecedenceDfa()"/>
public void SetPrecedenceStartState(int precedence, bool fullContext, DFAState startState)
public void SetPrecedenceStartState(int precedence, DFAState startState)
{
if (!IsPrecedenceDfa)
{
@ -278,19 +263,9 @@ namespace Antlr4.Runtime.Dfa
{
return;
}
if (fullContext)
lock (s0)
{
lock (s0full)
{
s0full.Get().SetTarget(precedence, startState);
}
}
else
{
lock (s0)
{
s0.Get().SetTarget(precedence, startState);
}
s0.Get().edges[precedence] = startState;
}
}
@ -299,25 +274,13 @@ namespace Antlr4.Runtime.Dfa
get
{
if (IsPrecedenceDfa)
{
return s0.Get().EdgeMap.Count == 0 && s0full.Get().EdgeMap.Count == 0;
}
return s0.Get() == null && s0full.Get() == null;
}
}
public virtual bool IsContextSensitive
{
get
{
if (IsPrecedenceDfa)
{
return s0full.Get().EdgeMap.Count != 0;
}
return s0full.Get() != null;
return s0.Get().edges.Length == 0 ;
else
return s0.Get() == null;
}
}
public virtual DFAState AddState(DFAState state)
{
state.stateNumber = Interlocked.Increment(ref nextStateNumber) - 1;

View File

@ -85,40 +85,9 @@ namespace Antlr4.Runtime.Dfa
states.Sort(new _IComparer_103());
foreach (DFAState s in states)
{
IEnumerable<KeyValuePair<int, DFAState>> edges = s.EdgeMap;
IEnumerable<KeyValuePair<int, DFAState>> contextEdges = s.ContextEdgeMap;
foreach (KeyValuePair<int, DFAState> entry in edges)
foreach (DFAState edge in s.edges)
{
if ((entry.Value == null || entry.Value == ATNSimulator.Error) && !s.IsContextSymbol(entry.Key))
{
continue;
}
bool contextSymbol = false;
buf.Append(GetStateString(s)).Append("-").Append(GetEdgeLabel(entry.Key)).Append("->");
if (s.IsContextSymbol(entry.Key))
{
buf.Append("!");
contextSymbol = true;
}
DFAState t = entry.Value;
if (t != null && t.stateNumber != int.MaxValue)
{
buf.Append(GetStateString(t)).Append('\n');
}
else
{
if (contextSymbol)
{
buf.Append("ctx\n");
}
}
}
if (s.IsContextSensitive)
{
foreach (KeyValuePair<int, DFAState> entry_1 in contextEdges)
{
buf.Append(GetStateString(s)).Append("-").Append(GetContextLabel(entry_1.Key)).Append("->").Append(GetStateString(entry_1.Value)).Append("\n");
}
buf.Append(GetStateString(s));
}
}
}
@ -145,16 +114,9 @@ namespace Antlr4.Runtime.Dfa
protected internal virtual string GetContextLabel(int i)
{
if (i == PredictionContext.EmptyFullStateKey)
if (i == PredictionContext.EMPTY_RETURN_STATE)
{
return "ctx:EMPTY_FULL";
}
else
{
if (i == PredictionContext.EmptyLocalStateKey)
{
return "ctx:EMPTY_LOCAL";
}
return "ctx:EMPTY";
}
if (atn != null && i > 0 && i <= atn.states.Count)
{
@ -175,19 +137,19 @@ namespace Antlr4.Runtime.Dfa
internal virtual string GetStateString(DFAState s)
{
if (s == ATNSimulator.Error)
if (s == ATNSimulator.ERROR)
{
return "ERROR";
}
int n = s.stateNumber;
string baseStateStr = (s.IsAcceptState ? ":" : "") + "s" + n + (s.IsContextSensitive ? "^" : "");
if ( s.IsAcceptState ) {
string baseStateStr = (s.isAcceptState ? ":" : "") + "s" + n ;
if ( s.isAcceptState ) {
if ( s.predicates!=null ) {
return baseStateStr + "=>" + Arrays.ToString(s.predicates);
}
else {
return baseStateStr + "=>" + s.Prediction;
return baseStateStr + "=>" + s.prediction;
}
}
else {

View File

@ -39,332 +39,174 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Dfa
{
/// <summary>A DFA state represents a set of possible ATN configurations.</summary>
/// <remarks>
/// A DFA state represents a set of possible ATN configurations.
/// As Aho, Sethi, Ullman p. 117 says "The DFA uses its state
/// to keep track of all possible states the ATN can be in after
/// reading each input symbol. That is to say, after reading
/// input a1a2..an, the DFA is in a state that represents the
/// subset T of the states of the ATN that are reachable from the
/// ATN's start state along some path labeled a1a2..an."
/// In conventional NFA&#x2192;DFA conversion, therefore, the subset T
/// would be a bitset representing the set of states the
/// ATN could be in. We need to track the alt predicted by each
/// state as well, however. More importantly, we need to maintain
/// a stack of states, tracking the closure operations as they
/// jump from rule to rule, emulating rule invocations (method calls).
/// I have to add a stack to simulate the proper lookahead sequences for
/// the underlying LL grammar from which the ATN was derived.
/// <p>I use a set of ATNConfig objects not simple states. An ATNConfig
/// is both a state (ala normal conversion) and a RuleContext describing
/// the chain of rules (if any) followed to arrive at that state.</p>
/// <p>A DFA state may have multiple references to a particular state,
/// but with different ATN contexts (with same or different alts)
/// meaning that state was reached via a different set of rule invocations.</p>
/// </remarks>
public class DFAState
{
public int stateNumber = -1;
/// <summary>A DFA state represents a set of possible ATN configurations.</summary>
/// <remarks>
/// A DFA state represents a set of possible ATN configurations.
/// As Aho, Sethi, Ullman p. 117 says "The DFA uses its state
/// to keep track of all possible states the ATN can be in after
/// reading each input symbol. That is to say, after reading
/// input a1a2..an, the DFA is in a state that represents the
/// subset T of the states of the ATN that are reachable from the
/// ATN's start state along some path labeled a1a2..an."
/// In conventional NFA&#x2192;DFA conversion, therefore, the subset T
/// would be a bitset representing the set of states the
/// ATN could be in. We need to track the alt predicted by each
/// state as well, however. More importantly, we need to maintain
/// a stack of states, tracking the closure operations as they
/// jump from rule to rule, emulating rule invocations (method calls).
/// I have to add a stack to simulate the proper lookahead sequences for
/// the underlying LL grammar from which the ATN was derived.
/// <p>I use a set of ATNConfig objects not simple states. An ATNConfig
/// is both a state (ala normal conversion) and a RuleContext describing
/// the chain of rules (if any) followed to arrive at that state.</p>
/// <p>A DFA state may have multiple references to a particular state,
/// but with different ATN contexts (with same or different alts)
/// meaning that state was reached via a different set of rule invocations.</p>
/// </remarks>
public class DFAState
{
public int stateNumber = -1;
[NotNull]
public readonly ATNConfigSet configs;
/// <summary>
/// <c>edges.get(symbol)</c>
/// points to target of symbol.
/// </summary>
[NotNull]
private volatile AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> edges;
public ATNConfigSet configSet = new ATNConfigSet();
private Antlr4.Runtime.Dfa.AcceptStateInfo acceptStateInfo;
/** {@code edges[symbol]} points to target of symbol. Shift up by 1 so (-1)
* {@link Token#EOF} maps to {@code edges[0]}.
*/
/// <summary>These keys for these edges are the top level element of the global context.</summary>
/// <remarks>These keys for these edges are the top level element of the global context.</remarks>
[NotNull]
private volatile AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> contextEdges;
public DFAState[] edges;
/// <summary>Symbols in this set require a global context transition before matching an input symbol.</summary>
/// <remarks>Symbols in this set require a global context transition before matching an input symbol.</remarks>
[Nullable]
private BitSet contextSymbols;
public bool isAcceptState = false;
/// <summary>
/// This list is computed by
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator.PredicateDFAState(DFAState, Antlr4.Runtime.Atn.ATNConfigSet, int)"/>
/// .
/// </summary>
[Nullable]
public DFAState.PredPrediction[] predicates;
/** if accept state, what ttype do we match or alt do we predict?
* This is set to {@link ATN#INVALID_ALT_NUMBER} when {@link #predicates}{@code !=null} or
* {@link #requiresFullContext}.
*/
public int prediction;
/// <summary>Map a predicate to a predicted alternative.</summary>
/// <remarks>Map a predicate to a predicted alternative.</remarks>
public class PredPrediction
{
[NotNull]
public SemanticContext pred;
public LexerActionExecutor lexerActionExecutor;
public int alt;
/**
* Indicates that this state was created during SLL prediction that
* discovered a conflict between the configurations in the state. Future
* {@link ParserATNSimulator#execATN} invocations immediately jumped doing
* full context prediction if this field is true.
*/
public bool requiresFullContext;
public PredPrediction(SemanticContext pred, int alt)
{
// never null; at least SemanticContext.NONE
this.alt = alt;
this.pred = pred;
}
/** During SLL parsing, this is a list of predicates associated with the
* ATN configurations of the DFA state. When we have predicates,
* {@link #requiresFullContext} is {@code false} since full context prediction evaluates predicates
* on-the-fly. If this is not null, then {@link #prediction} is
* {@link ATN#INVALID_ALT_NUMBER}.
*
* <p>We only use these for non-{@link #requiresFullContext} but conflicting states. That
* means we know from the context (it's $ or we don't dip into outer
* context) that it's an ambiguity not a conflict.</p>
*
* <p>This list is computed by {@link ParserATNSimulator#predicateDFAState}.</p>
*/
public override string ToString()
{
return "(" + pred + ", " + alt + ")";
}
}
public PredPrediction[] predicates;
public DFAState(DFA dfa, ATNConfigSet configs)
: this(dfa.EmptyEdgeMap, dfa.EmptyContextEdgeMap, configs)
{
}
public DFAState(EmptyEdgeMap<DFAState> emptyEdges, EmptyEdgeMap<DFAState> emptyContextEdges, ATNConfigSet configs)
{
this.configs = configs;
this.edges = emptyEdges;
this.contextEdges = emptyContextEdges;
}
public bool IsContextSensitive
{
get
{
return contextSymbols != null;
}
}
public DFAState() { }
public bool IsContextSymbol(int symbol)
{
if (!IsContextSensitive || symbol < edges.minIndex)
{
return false;
}
return contextSymbols.Get(symbol - edges.minIndex);
}
public DFAState(int stateNumber) { this.stateNumber = stateNumber; }
public void SetContextSymbol(int symbol)
{
System.Diagnostics.Debug.Assert(IsContextSensitive);
if (symbol < edges.minIndex)
{
return;
}
contextSymbols.Set(symbol - edges.minIndex);
}
public DFAState(ATNConfigSet configs) { this.configSet = configs; }
public virtual void SetContextSensitive(ATN atn)
{
System.Diagnostics.Debug.Assert(!configs.IsOutermostConfigSet);
if (IsContextSensitive)
{
return;
}
lock (this)
{
if (contextSymbols == null)
{
contextSymbols = new BitSet();
}
}
}
/** Get the set of all alts mentioned by all ATN configurations in this
* DFA state.
*/
public HashSet<int> getAltSet()
{
HashSet<int> alts = new HashSet<int>();
if (configSet != null)
{
foreach (ATNConfig c in configSet.configs)
{
alts.Add(c.alt);
}
}
if (alts.Count==0)
return null;
return alts;
}
public AcceptStateInfo AcceptStateInfo
{
get
{
return acceptStateInfo;
}
set
{
AcceptStateInfo acceptStateInfo = value;
this.acceptStateInfo = acceptStateInfo;
}
}
public override int GetHashCode()
{
int hash = MurmurHash.Initialize(7);
hash = MurmurHash.Update(hash, configSet.GetHashCode());
hash = MurmurHash.Finish(hash, 1);
return hash;
}
public bool IsAcceptState
{
get
{
return acceptStateInfo != null;
}
}
/**
* Two {@link DFAState} instances are equal if their ATN configuration sets
* are the same. This method is used to see if a state already exists.
*
* <p>Because the number of alternatives and number of ATN configurations are
* finite, there is a finite number of DFA states that can be processed.
* This is necessary to show that the algorithm terminates.</p>
*
* <p>Cannot test the DFA state numbers here because in
* {@link ParserATNSimulator#addDFAState} we need to know if any other state
* exists that has this exact set of ATN configurations. The
* {@link #stateNumber} is irrelevant.</p>
*/
public override bool Equals(Object o)
{
// compare set of ATN configurations in this set with other
if (this == o) return true;
public int Prediction
{
get
{
if (acceptStateInfo == null)
{
return ATN.InvalidAltNumber;
}
return acceptStateInfo.Prediction;
}
}
if (!(o is DFAState))
{
return false;
}
public LexerActionExecutor LexerActionExecutor
{
get
{
if (acceptStateInfo == null)
{
return null;
}
return acceptStateInfo.LexerActionExecutor;
}
}
DFAState other = (DFAState)o;
// TODO (sam): what to do when configs==null?
bool sameSet = this.configSet.Equals(other.configSet);
// System.out.println("DFAState.equals: "+configs+(sameSet?"==":"!=")+other.configs);
return sameSet;
}
public virtual DFAState GetTarget(int symbol)
{
return edges[symbol];
}
public override String ToString()
{
StringBuilder buf = new StringBuilder();
buf.Append(stateNumber).Append(":").Append(configSet);
if (isAcceptState)
{
buf.Append("=>");
if (predicates != null)
{
buf.Append(Arrays.ToString(predicates));
}
else {
buf.Append(prediction);
}
}
return buf.ToString();
}
}
public virtual void SetTarget(int symbol, DFAState target)
{
edges = edges.Put(symbol, target);
}
/** Map a predicate to a predicted alternative. */
public class PredPrediction
{
#if NET45PLUS
public virtual IReadOnlyDictionary<int, DFAState> EdgeMap
#else
public virtual IDictionary<int, DFAState> EdgeMap
#endif
{
get
{
return edges.ToMap();
}
}
public SemanticContext pred; // never null; at least SemanticContext.NONE
public int alt;
public PredPrediction(SemanticContext pred, int alt)
{
this.alt = alt;
this.pred = pred;
}
public virtual DFAState GetContextTarget(int invokingState)
{
lock (this)
{
if (invokingState == PredictionContext.EmptyFullStateKey)
{
invokingState = -1;
}
return contextEdges[invokingState];
}
}
public virtual void SetContextTarget(int invokingState, DFAState target)
{
lock (this)
{
if (!IsContextSensitive)
{
throw new InvalidOperationException("The state is not context sensitive.");
}
if (invokingState == PredictionContext.EmptyFullStateKey)
{
invokingState = -1;
}
contextEdges = contextEdges.Put(invokingState, target);
}
}
#if NET45PLUS
public virtual IReadOnlyDictionary<int, DFAState> ContextEdgeMap
#else
public virtual IDictionary<int, DFAState> ContextEdgeMap
#endif
{
get
{
var map = contextEdges.ToMap();
if (map.ContainsKey(-1))
{
if (map.Count == 1)
{
return Sharpen.Collections.SingletonMap(PredictionContext.EmptyFullStateKey, map[-1]);
}
else
{
#if NET45PLUS
Dictionary<int, DFAState> result = map.ToDictionary(i => i.Key, i => i.Value);
#else
Dictionary<int, DFAState> result = new Dictionary<int, DFAState>(map);
#endif
result.Add(PredictionContext.EmptyFullStateKey, result[-1]);
result.Remove(-1);
#if NET45PLUS
map = new ReadOnlyDictionary<int, DFAState>(new SortedDictionary<int, DFAState>(result));
#elif COMPACT
map = new SortedList<int, DFAState>(result);
#elif PORTABLE && !NET45PLUS
map = new Dictionary<int, DFAState>(result);
#else
map = new SortedDictionary<int, DFAState>(result);
#endif
}
}
return map;
}
}
public override int GetHashCode()
{
int hash = MurmurHash.Initialize(7);
hash = MurmurHash.Update(hash, configs.GetHashCode());
hash = MurmurHash.Finish(hash, 1);
return hash;
}
/// <summary>
/// Two
/// <see cref="DFAState"/>
/// instances are equal if their ATN configuration sets
/// are the same. This method is used to see if a state already exists.
/// <p>Because the number of alternatives and number of ATN configurations are
/// finite, there is a finite number of DFA states that can be processed.
/// This is necessary to show that the algorithm terminates.</p>
/// <p>Cannot test the DFA state numbers here because in
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator.AddDFAState(DFA, Antlr4.Runtime.Atn.ATNConfigSet, Antlr4.Runtime.Atn.PredictionContextCache)"/>
/// we need to know if any other state
/// exists that has this exact set of ATN configurations. The
/// <see cref="stateNumber"/>
/// is irrelevant.</p>
/// </summary>
public override bool Equals(object o)
{
// compare set of ATN configurations in this set with other
if (this == o)
{
return true;
}
if (!(o is DFAState))
{
return false;
}
DFAState other = (DFAState)o;
bool sameSet = this.configs.Equals(other.configs);
// System.out.println("DFAState.equals: "+configs+(sameSet?"==":"!=")+other.configs);
return sameSet;
}
public override string ToString()
{
StringBuilder buf = new StringBuilder();
buf.Append(stateNumber).Append(":").Append(configs);
if (IsAcceptState)
{
buf.Append("=>");
if (predicates != null)
{
buf.Append(Arrays.ToString(predicates));
}
else
{
buf.Append(Prediction);
}
}
return buf.ToString();
}
}
public override String ToString()
{
return "(" + pred + ", " + alt + ")";
}
}
}

View File

@ -159,7 +159,7 @@ namespace Antlr4.Runtime
/// The set of conflicting or ambiguous alternatives, as
/// reported by the parser.
/// </param>
/// <param name="configs">The conflicting or ambiguous configuration set.</param>
/// <param name="configSet">The conflicting or ambiguous configuration set.</param>
/// <returns>
/// Returns
/// <paramref name="reportedAlts"/>
@ -167,20 +167,20 @@ namespace Antlr4.Runtime
/// <see langword="null"/>
/// , otherwise
/// returns the set of alternatives represented in
/// <paramref name="configs"/>
/// <paramref name="configSet"/>
/// .
/// </returns>
[return: NotNull]
protected internal virtual BitSet GetConflictingAlts(BitSet reportedAlts, ATNConfigSet configs)
protected internal virtual BitSet GetConflictingAlts(BitSet reportedAlts, ATNConfigSet configSet)
{
if (reportedAlts != null)
{
return reportedAlts;
}
BitSet result = new BitSet();
foreach (ATNConfig config in configs)
foreach (ATNConfig config in configSet.configs)
{
result.Set(config.Alt);
result.Set(config.alt);
}
return result;
}

View File

@ -45,7 +45,7 @@ namespace Antlr4.Runtime
/// the stream was constructed. The following is a list of initializing methods:</p>
/// <ul>
/// <li>
/// <see cref="La(int)"/>
/// <see cref="LA(int)"/>
/// </li>
/// <li>
/// <see cref="Consume()"/>
@ -88,7 +88,7 @@ namespace Antlr4.Runtime
/// if an attempt is made to consume the the
/// end of the stream (i.e. if
/// <c>LA(1)==</c>
/// <see cref="IntStreamConstants.Eof">EOF</see>
/// <see cref="IntStreamConstants.EOF">EOF</see>
/// before calling
/// <c>consume</c>
/// ).
@ -140,7 +140,7 @@ namespace Antlr4.Runtime
/// <paramref name="i"/>
/// represents a position at or beyond the end of the stream,
/// this method returns
/// <see cref="IntStreamConstants.Eof"/>
/// <see cref="IntStreamConstants.EOF"/>
/// .</p>
/// <p>The return value is unspecified if
/// <c>i&lt;0</c>
@ -155,7 +155,7 @@ namespace Antlr4.Runtime
/// if the stream does not support
/// retrieving the value of the specified symbol
/// </exception>
int La(int i);
int LA(int i);
/// <summary>
/// A mark provides a guarantee that
@ -286,7 +286,7 @@ namespace Antlr4.Runtime
/// <li>
/// <c>LA(1)</c>
/// returns
/// <see cref="IntStreamConstants.Eof"/>
/// <see cref="IntStreamConstants.EOF"/>
/// </li>
/// </ul>
/// This operation is guaranteed to not throw an exception if
@ -346,11 +346,11 @@ namespace Antlr4.Runtime
{
/// <summary>
/// The value returned by
/// <see cref="IIntStream.La(int)">LA()</see>
/// <see cref="IIntStream.LA(int)">LA()</see>
/// when the end of the stream is
/// reached.
/// </summary>
public const int Eof = -1;
public const int EOF = -1;
/// <summary>
/// The value returned by

View File

@ -79,7 +79,7 @@ namespace Antlr4.Runtime
/// least the <em>minimum</em> potentially viable alternative is truly
/// viable.</p>
/// <p>When the
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection"/>
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LL_EXACT_AMBIG_DETECTION"/>
/// prediction
/// mode is used, the parser is required to identify exact ambiguities so
/// <paramref name="exact"/>
@ -99,7 +99,7 @@ namespace Antlr4.Runtime
/// . This is always
/// <see langword="true"/>
/// when
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection"/>
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LL_EXACT_AMBIG_DETECTION"/>
/// is used.
/// </param>
/// <param name="ambigAlts">

View File

@ -156,11 +156,11 @@ namespace Antlr4.Runtime
/// During lookahead operations, this "token" signifies we hit rule end ATN state
/// and did not follow it despite needing to.
/// </remarks>
public const int Epsilon = -2;
public const int EPSILON = -2;
public const int MinUserTokenType = 1;
public const int Eof = IntStreamConstants.Eof;
public const int EOF = IntStreamConstants.EOF;
/// <summary>
/// All tokens go to the parser (unless skip() is called in that rule)

View File

@ -46,17 +46,17 @@ namespace Antlr4.Runtime
/// Get the
/// <see cref="IToken"/>
/// instance associated with the value returned by
/// <see cref="IIntStream.La(int)">LA(k)</see>
/// <see cref="IIntStream.LA(int)">LA(k)</see>
/// . This method has the same pre- and post-conditions as
/// <see cref="IIntStream.La(int)"/>
/// <see cref="IIntStream.LA(int)"/>
/// . In addition, when the preconditions of this method
/// are met, the return value is non-null and the value of
/// <c>LT(k).getType()==LA(k)</c>
/// .
/// </summary>
/// <seealso cref="IIntStream.La(int)"/>
/// <seealso cref="IIntStream.LA(int)"/>
[return: NotNull]
IToken Lt(int k);
IToken LT(int k);
/// <summary>
/// Gets the

View File

@ -121,7 +121,7 @@ namespace Antlr4.Runtime
/// <li>The implicitly defined
/// <c>EOF</c>
/// token, which has the token type
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// .</li>
/// </ul>
/// <p>The following table shows examples of lexer rules and the literal

View File

@ -46,7 +46,7 @@ namespace Antlr4.Runtime
/// </remarks>
public abstract class Lexer : Recognizer<int, LexerATNSimulator>, ITokenSource
{
public const int DefaultMode = 0;
public const int DEFAULT_MODE = 0;
public const int DefaultTokenChannel = TokenConstants.DefaultChannel;
@ -107,7 +107,7 @@ namespace Antlr4.Runtime
private readonly Stack<int> _modeStack = new Stack<int>();
private int _mode = Antlr4.Runtime.Lexer.DefaultMode;
private int _mode = Antlr4.Runtime.Lexer.DEFAULT_MODE;
/// <summary>
/// You can set the text for the current token to override what is in
@ -141,7 +141,7 @@ namespace Antlr4.Runtime
_tokenStartLine = -1;
_text = null;
_hitEOF = false;
_mode = Antlr4.Runtime.Lexer.DefaultMode;
_mode = Antlr4.Runtime.Lexer.DEFAULT_MODE;
_modeStack.Clear();
Interpreter.Reset();
}
@ -196,7 +196,7 @@ namespace Antlr4.Runtime
Recover(e);
ttype = TokenTypes.Skip;
}
if (_input.La(1) == IntStreamConstants.Eof)
if (_input.LA(1) == IntStreamConstants.EOF)
{
_hitEOF = true;
}
@ -355,7 +355,7 @@ outer_continue: ;
{
int cpos = Column;
int line = Line;
IToken eof = _factory.Create(_tokenFactorySourcePair, TokenConstants.Eof, null, TokenConstants.DefaultChannel, _input.Index, _input.Index - 1, line, cpos);
IToken eof = _factory.Create(_tokenFactorySourcePair, TokenConstants.EOF, null, TokenConstants.DefaultChannel, _input.Index, _input.Index - 1, line, cpos);
Emit(eof);
return eof;
}
@ -545,7 +545,7 @@ outer_continue: ;
{
IList<IToken> tokens = new List<IToken>();
IToken t = NextToken();
while (t.Type != TokenConstants.Eof)
while (t.Type != TokenConstants.EOF)
{
tokens.Add(t);
t = NextToken();
@ -555,7 +555,7 @@ outer_continue: ;
public virtual void Recover(LexerNoViableAltException e)
{
if (_input.La(1) != IntStreamConstants.Eof)
if (_input.LA(1) != IntStreamConstants.EOF)
{
// skip a char and try again
Interpreter.Consume(_input);
@ -585,7 +585,7 @@ outer_continue: ;
string s = ((char)c).ToString();
switch (c)
{
case TokenConstants.Eof:
case TokenConstants.EOF:
{
s = "<EOF>";
break;

View File

@ -62,7 +62,7 @@ namespace Antlr4.Runtime
this.ruleNames = ruleNames.ToArray();
this.modeNames = modeNames.ToArray();
this.vocabulary = vocabulary;
this.Interpreter = new LexerATNSimulator(this, atn);
this.Interpreter = new LexerATNSimulator(this, atn, null, null);
}
public override ATN Atn

View File

@ -42,7 +42,7 @@ namespace Antlr4.Runtime
/// <see cref="IToken"/>
/// objects.
/// <p>If the final token in the list is an
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// token, it will be used
/// as the EOF token for every call to
/// <see cref="NextToken()"/>
@ -223,12 +223,12 @@ namespace Antlr4.Runtime
}
}
int stop = Math.Max(-1, start - 1);
eofToken = _factory.Create(Tuple.Create((ITokenSource)this, InputStream), TokenConstants.Eof, "EOF", TokenConstants.DefaultChannel, start, stop, Line, Column);
eofToken = _factory.Create(Tuple.Create((ITokenSource)this, InputStream), TokenConstants.EOF, "EOF", TokenConstants.DefaultChannel, start, stop, Line, Column);
}
return eofToken;
}
IToken t = tokens[i];
if (i == tokens.Count - 1 && t.Type == TokenConstants.Eof)
if (i == tokens.Count - 1 && t.Type == TokenConstants.EOF)
{
eofToken = t;
}

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
namespace Antlr4.Runtime.Misc
{
public class DoubleKeyMap<K1, K2, V>
{
Dictionary<K1, Dictionary<K2, V>> data = new Dictionary<K1, Dictionary<K2, V>>();
public V put(K1 k1, K2 k2, V v)
{
Dictionary<K2, V> data2 = data.get(k1);
V prev = null;
if (data2 == null)
{
data2 = new Dict<K2, V>();
data.put(k1, data2);
}
else {
prev = data2.get(k2);
}
data2.put(k2, v);
return prev;
}
public V get(K1 k1, K2 k2)
{
Dictionary<K2, V> data2 = data.get(k1);
if (data2 == null) return null;
return data2.get(k2);
}
public Dictionary<K2, V> get(K1 k1) { return data.get(k1); }
/** Get all values associated with primary key */
public ICollection<V> values(K1 k1)
{
Dictionary<K2, V> data2 = data.get(k1);
if (data2 == null) return null;
return data2.values();
}
/** get all primary keys */
public HashSet<K1> keySet()
{
return data.keySet();
}
/** get all secondary keys associated with a primary key */
public HashSet<K2> keySet(K1 k1)
{
Dictionary<K2, V> data2 = data.get(k1);
if (data2 == null) return null;
return data2.keySet();
}
}
}

View File

@ -664,7 +664,7 @@ namespace Antlr4.Runtime.Misc
int b = I.b;
if (a == b)
{
if (a == TokenConstants.Eof)
if (a == TokenConstants.EOF)
{
buf.Append("<EOF>");
}
@ -746,13 +746,13 @@ namespace Antlr4.Runtime.Misc
[return: NotNull]
protected internal virtual string ElementName(IVocabulary vocabulary, int a)
{
if (a == TokenConstants.Eof)
if (a == TokenConstants.EOF)
{
return "<EOF>";
}
else
{
if (a == TokenConstants.Epsilon)
if (a == TokenConstants.EPSILON)
{
return "<EPSILON>";
}

View File

@ -0,0 +1,75 @@
/*
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 Sam Harwell
* Copyright (c) 2016 Eric Vergnaud
* 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.
*/
using System;
namespace Antlr4.Runtime.Misc
{
public class Pair<A, B>
{
public readonly A a;
public readonly B b;
public Pair(A a, B b)
{
this.a = a;
this.b = b;
}
public override bool Equals(Object obj)
{
if (obj == this)
{
return true;
}
else if (!(obj is Pair<A, B>)) {
return false;
}
Pair <A, B> other = (Pair <A, B>)obj;
return a==null ? other.a==null : a.Equals(other.b);
}
public override int GetHashCode()
{
int hash = MurmurHash.Initialize();
hash = MurmurHash.Update(hash, a);
hash = MurmurHash.Update(hash, b);
return MurmurHash.Finish(hash, 2);
}
public override String ToString()
{
return String.Format("(%s, %s)", a, b);
}
}
}

View File

@ -934,7 +934,7 @@ namespace Antlr4.Runtime.Misc
}
foreach (Transition transition in state.transitions)
{
if (transition.TransitionType != TransitionType.Rule)
if (transition.TransitionType != TransitionType.RULE)
{
continue;
}

View File

@ -50,12 +50,12 @@ namespace Antlr4.Runtime
{
public virtual void EnterEveryRule(ParserRuleContext ctx)
{
System.Console.Out.WriteLine("enter " + this._enclosing.RuleNames[ctx.RuleIndex] + ", LT(1)=" + this._enclosing._input.Lt(1).Text);
System.Console.Out.WriteLine("enter " + this._enclosing.RuleNames[ctx.RuleIndex] + ", LT(1)=" + this._enclosing._input.LT(1).Text);
}
public virtual void ExitEveryRule(ParserRuleContext ctx)
{
System.Console.Out.WriteLine("exit " + this._enclosing.RuleNames[ctx.RuleIndex] + ", LT(1)=" + this._enclosing._input.Lt(1).Text);
System.Console.Out.WriteLine("exit " + this._enclosing.RuleNames[ctx.RuleIndex] + ", LT(1)=" + this._enclosing._input.LT(1).Text);
}
public virtual void VisitErrorNode(IErrorNode node)
@ -683,7 +683,7 @@ namespace Antlr4.Runtime
{
get
{
return _input.Lt(1);
return _input.LT(1);
}
}
@ -795,7 +795,7 @@ namespace Antlr4.Runtime
{
State = state;
_ctx = localctx;
_ctx.Start = _input.Lt(1);
_ctx.Start = _input.LT(1);
if (_buildParseTrees)
{
AddContextToParseTree();
@ -817,7 +817,7 @@ namespace Antlr4.Runtime
localctx.AddChild(factoredContext);
}
_ctx = localctx;
_ctx.Start = _input.Lt(1);
_ctx.Start = _input.LT(1);
if (_buildParseTrees)
{
AddContextToParseTree();
@ -830,7 +830,7 @@ namespace Antlr4.Runtime
public virtual void ExitRule()
{
_ctx.Stop = _input.Lt(-1);
_ctx.Stop = _input.LT(-1);
// trigger event on _ctx, before it reverts to parent
if (_parseListeners != null)
{
@ -886,7 +886,7 @@ namespace Antlr4.Runtime
State = state;
_precedenceStack.Add(precedence);
_ctx = localctx;
_ctx.Start = _input.Lt(1);
_ctx.Start = _input.LT(1);
if (_parseListeners != null)
{
TriggerEnterRuleEvent();
@ -904,7 +904,7 @@ namespace Antlr4.Runtime
ParserRuleContext previous = _ctx;
previous.Parent = localctx;
previous.invokingState = state;
previous.Stop = _input.Lt(-1);
previous.Stop = _input.LT(-1);
_ctx = localctx;
_ctx.Start = previous.Start;
if (_buildParseTrees)
@ -921,7 +921,7 @@ namespace Antlr4.Runtime
public virtual void UnrollRecursionContexts(ParserRuleContext _parentctx)
{
_precedenceStack.RemoveAt(_precedenceStack.Count - 1);
_ctx.Stop = _input.Lt(-1);
_ctx.Stop = _input.LT(-1);
ParserRuleContext retctx = _ctx;
// save current ctx (return value)
// unroll so _ctx is as it was before call to recursive method
@ -978,7 +978,7 @@ namespace Antlr4.Runtime
return precedence >= _precedenceStack[_precedenceStack.Count - 1];
}
public override IAntlrErrorListener<IToken> ErrorListenerDispatch
public new IParserErrorListener ErrorListenerDispatch
{
get
{
@ -1026,11 +1026,11 @@ namespace Antlr4.Runtime
return true;
}
// System.out.println("following "+s+"="+following);
if (!following.Contains(TokenConstants.Epsilon))
if (!following.Contains(TokenConstants.EPSILON))
{
return false;
}
while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.Epsilon))
while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.EPSILON))
{
ATNState invokingState = atn.states[ctx.invokingState];
RuleTransition rt = (RuleTransition)invokingState.Transition(0);
@ -1041,7 +1041,7 @@ namespace Antlr4.Runtime
}
ctx = (ParserRuleContext)ctx.Parent;
}
if (following.Contains(TokenConstants.Epsilon) && symbol == TokenConstants.Eof)
if (following.Contains(TokenConstants.EPSILON) && symbol == TokenConstants.EOF)
{
return true;
}
@ -1219,7 +1219,7 @@ namespace Antlr4.Runtime
{
if (interp is ProfilingATNSimulator)
{
Interpreter = new ParserATNSimulator(this, Atn);
Interpreter = new ParserATNSimulator(this, Atn, null, null);
}
}
}

View File

@ -88,7 +88,7 @@ namespace Antlr4.Runtime
}
}
// get atn simulator that knows how to do predictions
Interpreter = new ParserATNSimulator(this, atn);
Interpreter = new ParserATNSimulator(this, atn, null, null);
}
public override ATN Atn
@ -211,7 +211,7 @@ namespace Antlr4.Runtime
Transition transition = p.Transition(edge - 1);
switch (transition.TransitionType)
{
case TransitionType.Epsilon:
case TransitionType.EPSILON:
{
if (pushRecursionContextStates.Get(p.stateNumber) && !(transition.target is LoopEndState))
{
@ -221,17 +221,17 @@ namespace Antlr4.Runtime
break;
}
case TransitionType.Atom:
case TransitionType.ATOM:
{
Match(((AtomTransition)transition).token);
break;
}
case TransitionType.Range:
case TransitionType.Set:
case TransitionType.NotSet:
case TransitionType.RANGE:
case TransitionType.SET:
case TransitionType.NOT_SET:
{
if (!transition.Matches(TokenStream.La(1), TokenConstants.MinUserTokenType, 65535))
if (!transition.Matches(TokenStream.LA(1), TokenConstants.MinUserTokenType, 65535))
{
ErrorHandler.RecoverInline(this);
}
@ -239,13 +239,13 @@ namespace Antlr4.Runtime
break;
}
case TransitionType.Wildcard:
case TransitionType.WILDCARD:
{
MatchWildcard();
break;
}
case TransitionType.Rule:
case TransitionType.RULE:
{
RuleStartState ruleStartState = (RuleStartState)transition.target;
int ruleIndex = ruleStartState.ruleIndex;
@ -261,7 +261,7 @@ namespace Antlr4.Runtime
break;
}
case TransitionType.Predicate:
case TransitionType.PREDICATE:
{
PredicateTransition predicateTransition = (PredicateTransition)transition;
if (!Sempred(RuleContext, predicateTransition.ruleIndex, predicateTransition.predIndex))
@ -271,14 +271,14 @@ namespace Antlr4.Runtime
break;
}
case TransitionType.Action:
case TransitionType.ACTION:
{
ActionTransition actionTransition = (ActionTransition)transition;
Action(RuleContext, actionTransition.ruleIndex, actionTransition.actionIndex);
break;
}
case TransitionType.Precedence:
case TransitionType.PRECEDENCE:
{
if (!Precpred(RuleContext, ((PrecedencePredicateTransition)transition).precedence))
{

View File

@ -59,7 +59,7 @@ namespace Antlr4.Runtime
/// </remarks>
public class ParserRuleContext : RuleContext
{
private static readonly Antlr4.Runtime.ParserRuleContext Empty = new Antlr4.Runtime.ParserRuleContext();
public static readonly Antlr4.Runtime.ParserRuleContext EMPTY = new Antlr4.Runtime.ParserRuleContext();
/// <summary>
/// If we are debugging or building a parse tree for a visitor,
@ -137,7 +137,7 @@ namespace Antlr4.Runtime
get
{
// public List<Integer> states;
return Empty;
return EMPTY;
}
}

View File

@ -125,7 +125,7 @@ namespace Antlr4.Runtime
result[symbolicName] = i;
}
}
result["EOF"] = TokenConstants.Eof;
result["EOF"] = TokenConstants.EOF;
return result;
}
@ -280,7 +280,7 @@ namespace Antlr4.Runtime
string s = t.Text;
if (s == null)
{
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
s = "<EOF>";
}

View File

@ -224,7 +224,7 @@ namespace Antlr4.Runtime
* option contextSuperClass.
* to set it.
*/
public virtual int getAltNumber() { return Atn.ATN.InvalidAltNumber; }
public virtual int getAltNumber() { return Atn.ATN.INVALID_ALT_NUMBER; }
/* Set the outer alternative number for this context node. Default
* implementation does nothing to avoid backing field overhead for

View File

@ -152,6 +152,18 @@ namespace Antlr4.Runtime.Sharpen
_data[element] &= ~(1UL << (index % BitsPerElement));
}
public bool this[int index]
{
get
{
return Get(index);
}
set
{
Set(index);
}
}
public bool Get(int index)
{
if (index < 0)

View File

@ -187,7 +187,7 @@ namespace Antlr4.Runtime
public override int Execute(StringBuilder buf)
{
buf.Append(text);
if (tokens.Get(index).Type != TokenConstants.Eof)
if (tokens.Get(index).Type != TokenConstants.EOF)
{
buf.Append(tokens.Get(index).Text);
}
@ -518,7 +518,7 @@ namespace Antlr4.Runtime
if (op == null)
{
// no operation at that index, just dump token
if (t.Type != TokenConstants.Eof)
if (t.Type != TokenConstants.EOF)
{
buf.Append(t.Text);
}

View File

@ -347,7 +347,7 @@ namespace Antlr4.Runtime.Tree.Pattern
throw new ParseTreePatternMatcher.CannotInvokeStartRule(e);
}
// Make sure tree pattern compilation checks for a complete parse
if (tokens.La(1) != TokenConstants.Eof)
if (tokens.LA(1) != TokenConstants.EOF)
{
throw new ParseTreePatternMatcher.StartRuleDoesNotConsumeFullPattern();
}
@ -587,7 +587,7 @@ namespace Antlr4.Runtime.Tree.Pattern
AntlrInputStream @in = new AntlrInputStream(textChunk.Text);
lexer.SetInputStream(@in);
IToken t = lexer.NextToken();
while (t.Type != TokenConstants.Eof)
while (t.Type != TokenConstants.EOF)
{
tokens.Add(t);
t = lexer.NextToken();

View File

@ -151,7 +151,7 @@ namespace Antlr4.Runtime.Tree
{
if (Symbol != null)
{
if (Symbol.Type == TokenConstants.Eof)
if (Symbol.Type == TokenConstants.EOF)
{
return "<EOF>";
}

View File

@ -117,7 +117,7 @@ namespace Antlr4.Runtime.Tree
int ruleIndex = ((RuleContext)t).RuleIndex;
string ruleName = ruleNames[ruleIndex];
int altNumber = ((RuleContext)t).getAltNumber();
if ( altNumber!=Atn.ATN.InvalidAltNumber ) {
if ( altNumber!=Atn.ATN.INVALID_ALT_NUMBER ) {
return ruleName+":"+altNumber;
}
return ruleName;

View File

@ -177,7 +177,7 @@ namespace Antlr4.Runtime.Tree.Xpath
break;
}
case TokenConstants.Eof:
case TokenConstants.EOF:
{
goto loop_break;
}
@ -224,7 +224,7 @@ loop_break: ;
/// </summary>
protected internal virtual XPathElement GetXPathElement(IToken wordToken, bool anywhere)
{
if (wordToken.Type == TokenConstants.Eof)
if (wordToken.Type == TokenConstants.EOF)
{
throw new ArgumentException("Missing path element at end of path");
}

View File

@ -42,7 +42,7 @@ public partial class XPathLexer : Lexer {
public XPathLexer(ICharStream input)
: base(input)
{
Interpreter = new LexerATNSimulator(this,_ATN);
Interpreter = new LexerATNSimulator(this, _ATN, null, null);
}
private static readonly string[] _LiteralNames = {

View File

@ -175,7 +175,7 @@ namespace Antlr4.Runtime
// prime
public virtual void Consume()
{
if (La(1) == IntStreamConstants.Eof)
if (LA(1) == IntStreamConstants.EOF)
{
throw new InvalidOperationException("cannot consume EOF");
}
@ -236,7 +236,7 @@ namespace Antlr4.Runtime
{
for (int i = 0; i < n; i++)
{
if (this.n > 0 && data[this.n - 1] == unchecked((char)IntStreamConstants.Eof))
if (this.n > 0 && data[this.n - 1] == unchecked((char)IntStreamConstants.EOF))
{
return i;
}
@ -267,7 +267,7 @@ namespace Antlr4.Runtime
data[n++] = (char)c;
}
public virtual int La(int i)
public virtual int LA(int i)
{
if (i == -1)
{
@ -282,12 +282,12 @@ namespace Antlr4.Runtime
}
if (index >= n)
{
return IntStreamConstants.Eof;
return IntStreamConstants.EOF;
}
char c = data[index];
if (c == unchecked((char)IntStreamConstants.Eof))
if (c == unchecked((char)IntStreamConstants.EOF))
{
return IntStreamConstants.Eof;
return IntStreamConstants.EOF;
}
return c;
}

View File

@ -149,7 +149,7 @@ namespace Antlr4.Runtime
return tokens[i - bufferStartIndex];
}
public virtual IToken Lt(int i)
public virtual IToken LT(int i)
{
if (i == -1)
{
@ -163,15 +163,15 @@ namespace Antlr4.Runtime
}
if (index >= n)
{
System.Diagnostics.Debug.Assert(n > 0 && tokens[n - 1].Type == TokenConstants.Eof);
System.Diagnostics.Debug.Assert(n > 0 && tokens[n - 1].Type == TokenConstants.EOF);
return tokens[n - 1];
}
return tokens[index];
}
public virtual int La(int i)
public virtual int LA(int i)
{
return Lt(i).Type;
return LT(i).Type;
}
public virtual ITokenSource TokenSource
@ -210,7 +210,7 @@ namespace Antlr4.Runtime
public virtual void Consume()
{
if (La(1) == TokenConstants.Eof)
if (LA(1) == TokenConstants.EOF)
{
throw new InvalidOperationException("cannot consume EOF");
}
@ -271,7 +271,7 @@ namespace Antlr4.Runtime
{
for (int i = 0; i < n; i++)
{
if (this.n > 0 && tokens[this.n - 1].Type == TokenConstants.Eof)
if (this.n > 0 && tokens[this.n - 1].Type == TokenConstants.EOF)
{
return i;
}

View File

@ -52,7 +52,7 @@ namespace Antlr4.Runtime
/// <see cref="GetDisplayName(int)"/>
/// returns the numeric value for all tokens
/// except
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// .</p>
/// </summary>
[NotNull]
@ -160,7 +160,7 @@ namespace Antlr4.Runtime
{
return symbolicNames[tokenType];
}
if (tokenType == TokenConstants.Eof)
if (tokenType == TokenConstants.EOF)
{
return "EOF";
}