forked from jasder/antlr
Update to the latest working build of ANTLR 4
This commit is contained in:
parent
c78833e705
commit
c3a7bdce7b
|
@ -1 +1 @@
|
|||
Subproject commit 1930a7b29d4e0bcc47f22d68282d70ad2552dc2e
|
||||
Subproject commit 84f92bd938e05f803f81634f43902e4b47f08ab2
|
|
@ -27,7 +27,7 @@
|
|||
* (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.IO;
|
||||
using Antlr4.Runtime.Misc;
|
||||
using Antlr4.Runtime.Sharpen;
|
||||
|
||||
namespace Antlr4.Runtime
|
||||
|
@ -58,35 +58,8 @@ namespace Antlr4.Runtime
|
|||
/// <exception cref="System.IO.IOException"/>
|
||||
public virtual void Load(string fileName, string encoding)
|
||||
{
|
||||
if (fileName == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
FilePath f = new FilePath(fileName);
|
||||
int size = (int)f.Length();
|
||||
StreamReader isr;
|
||||
FileInputStream fis = new FileInputStream(fileName);
|
||||
if (encoding != null)
|
||||
{
|
||||
isr = new StreamReader(fis, encoding);
|
||||
}
|
||||
else
|
||||
{
|
||||
isr = new StreamReader(fis);
|
||||
}
|
||||
try
|
||||
{
|
||||
data = new char[size];
|
||||
n = isr.Read(data);
|
||||
if (n < data.Length)
|
||||
{
|
||||
data = Arrays.CopyOf(data, n);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
isr.Close();
|
||||
}
|
||||
data = Utils.ReadFile(fileName, encoding);
|
||||
this.n = data.Length;
|
||||
}
|
||||
|
||||
public override string SourceName
|
||||
|
|
|
@ -314,6 +314,10 @@ namespace Antlr4.Runtime
|
|||
{
|
||||
get
|
||||
{
|
||||
if (name == null || name.IsEmpty())
|
||||
{
|
||||
return IntStreamConstants.UnknownSourceName;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,10 +48,29 @@ namespace Antlr4.Runtime.Atn
|
|||
/// </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));
|
||||
|
||||
/// <summary>The ATN state associated with this configuration</summary>
|
||||
[NotNull]
|
||||
private 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;
|
||||
|
||||
/// <summary>
|
||||
|
@ -70,14 +89,14 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
System.Diagnostics.Debug.Assert((alt & unchecked((int)(0xFFFFFF))) == alt);
|
||||
this.state = state;
|
||||
this.altAndOuterContextDepth = alt & unchecked((int)(0x7FFFFFFF));
|
||||
this.altAndOuterContextDepth = alt;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
protected internal ATNConfig(Antlr4.Runtime.Atn.ATNConfig c, ATNState state, PredictionContext context)
|
||||
{
|
||||
this.state = state;
|
||||
this.altAndOuterContextDepth = c.altAndOuterContextDepth & unchecked((int)(0x7FFFFFFF));
|
||||
this.altAndOuterContextDepth = c.altAndOuterContextDepth;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
|
@ -137,25 +156,6 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
}
|
||||
|
||||
public virtual bool IsHidden
|
||||
{
|
||||
get
|
||||
{
|
||||
return altAndOuterContextDepth < 0;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
altAndOuterContextDepth |= unchecked((int)(0x80000000));
|
||||
}
|
||||
else
|
||||
{
|
||||
altAndOuterContextDepth &= ~unchecked((int)(0x80000000));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual PredictionContext Context
|
||||
{
|
||||
get
|
||||
|
@ -187,9 +187,10 @@ namespace Antlr4.Runtime.Atn
|
|||
/// no way to do this efficiently, we simply cannot evaluate
|
||||
/// dependent predicates unless we are in the rule that initially
|
||||
/// invokes the ATN simulator.
|
||||
/// closure() tracks the depth of how far we dip into the
|
||||
/// outer context: depth > 0. Note that it may not be totally
|
||||
/// accurate depth since I don't ever decrement. TODO: make it a boolean then
|
||||
/// <p>
|
||||
/// closure() tracks the depth of how far we dip into the outer context:
|
||||
/// depth > 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
|
||||
{
|
||||
|
@ -346,6 +347,25 @@ namespace Antlr4.Runtime.Atn
|
|||
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
|
||||
|
@ -378,7 +398,7 @@ namespace Antlr4.Runtime.Atn
|
|||
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.PassedThroughNonGreedyDecision == other.PassedThroughNonGreedyDecision && ObjectEqualityComparator.Instance.Equals(this.ActionExecutor, other.ActionExecutor);
|
||||
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 && ObjectEqualityComparator.Instance.Equals(this.ActionExecutor, other.ActionExecutor);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace Antlr4.Runtime.Atn
|
|||
|
||||
private int uniqueAlt;
|
||||
|
||||
private BitSet conflictingAlts;
|
||||
private ConflictInfo conflictInfo;
|
||||
|
||||
private bool hasSemanticContext;
|
||||
|
||||
|
@ -144,7 +144,7 @@ namespace Antlr4.Runtime.Atn
|
|||
if (@readonly || !set.IsReadOnly)
|
||||
{
|
||||
this.uniqueAlt = set.uniqueAlt;
|
||||
this.conflictingAlts = set.conflictingAlts;
|
||||
this.conflictInfo = set.conflictInfo;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,9 +161,9 @@ namespace Antlr4.Runtime.Atn
|
|||
get
|
||||
{
|
||||
// if (!readonly && set.isReadOnly()) -> addAll is called from clone()
|
||||
if (conflictingAlts != null)
|
||||
if (conflictInfo != null)
|
||||
{
|
||||
return (BitSet)conflictingAlts.Clone();
|
||||
return (BitSet)conflictInfo.ConflictedAlts.Clone();
|
||||
}
|
||||
BitSet alts = new BitSet();
|
||||
foreach (ATNConfig config in this)
|
||||
|
@ -182,35 +182,6 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
}
|
||||
|
||||
public void StripHiddenConfigs()
|
||||
{
|
||||
EnsureWritable();
|
||||
IEnumerator<KeyValuePair<long, ATNConfig>> iterator = mergedConfigs.EntrySet().GetEnumerator();
|
||||
while (iterator.HasNext())
|
||||
{
|
||||
if (iterator.Next().Value.IsHidden)
|
||||
{
|
||||
iterator.Remove();
|
||||
}
|
||||
}
|
||||
IListIterator<ATNConfig> iterator2 = unmerged.ListIterator();
|
||||
while (iterator2.HasNext())
|
||||
{
|
||||
if (iterator2.Next().IsHidden)
|
||||
{
|
||||
iterator2.Remove();
|
||||
}
|
||||
}
|
||||
iterator2 = configs.ListIterator();
|
||||
while (iterator2.HasNext())
|
||||
{
|
||||
if (iterator2.Next().IsHidden)
|
||||
{
|
||||
iterator2.Remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsOutermostConfigSet
|
||||
{
|
||||
get
|
||||
|
@ -320,7 +291,6 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
EnsureWritable();
|
||||
System.Diagnostics.Debug.Assert(!outermostConfigSet || !e.ReachesIntoOuterContext);
|
||||
System.Diagnostics.Debug.Assert(!e.IsHidden);
|
||||
if (contextCache == null)
|
||||
{
|
||||
contextCache = PredictionContextCache.Uncached;
|
||||
|
@ -332,6 +302,10 @@ namespace Antlr4.Runtime.Atn
|
|||
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)
|
||||
|
@ -347,6 +321,10 @@ namespace Antlr4.Runtime.Atn
|
|||
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)
|
||||
|
@ -481,7 +459,7 @@ namespace Antlr4.Runtime.Atn
|
|||
dipsIntoOuterContext = false;
|
||||
hasSemanticContext = false;
|
||||
uniqueAlt = ATN.InvalidAltNumber;
|
||||
conflictingAlts = null;
|
||||
conflictInfo = null;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
|
@ -495,7 +473,7 @@ namespace Antlr4.Runtime.Atn
|
|||
return false;
|
||||
}
|
||||
Antlr4.Runtime.Atn.ATNConfigSet other = (Antlr4.Runtime.Atn.ATNConfigSet)obj;
|
||||
return this.outermostConfigSet == other.outermostConfigSet && Utils.Equals(conflictingAlts, other.conflictingAlts) && configs.Equals(other.configs);
|
||||
return this.outermostConfigSet == other.outermostConfigSet && Utils.Equals(conflictInfo, other.conflictInfo) && configs.Equals(other.configs);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
|
@ -523,7 +501,7 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
IList<ATNConfig> sortedConfigs = new List<ATNConfig>(configs);
|
||||
sortedConfigs.Sort(new _IComparer_495());
|
||||
sortedConfigs.Sort(new _IComparer_475());
|
||||
buf.Append("[");
|
||||
for (int i = 0; i < sortedConfigs.Count; i++)
|
||||
{
|
||||
|
@ -542,9 +520,13 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
buf.Append(",uniqueAlt=").Append(uniqueAlt);
|
||||
}
|
||||
if (conflictingAlts != null)
|
||||
if (conflictInfo != null)
|
||||
{
|
||||
buf.Append(",conflictingAlts=").Append(conflictingAlts);
|
||||
buf.Append(",conflictingAlts=").Append(conflictInfo.ConflictedAlts);
|
||||
if (!conflictInfo.IsExact)
|
||||
{
|
||||
buf.Append("*");
|
||||
}
|
||||
}
|
||||
if (dipsIntoOuterContext)
|
||||
{
|
||||
|
@ -553,9 +535,9 @@ namespace Antlr4.Runtime.Atn
|
|||
return buf.ToString();
|
||||
}
|
||||
|
||||
private sealed class _IComparer_495 : IComparer<ATNConfig>
|
||||
private sealed class _IComparer_475 : IComparer<ATNConfig>
|
||||
{
|
||||
public _IComparer_495()
|
||||
public _IComparer_475()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -607,17 +589,41 @@ namespace Antlr4.Runtime.Atn
|
|||
hasSemanticContext = true;
|
||||
}
|
||||
|
||||
public virtual ConflictInfo ConflictInformation
|
||||
{
|
||||
get
|
||||
{
|
||||
return conflictInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
ConflictInfo conflictInfo = value;
|
||||
EnsureWritable();
|
||||
this.conflictInfo = conflictInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BitSet ConflictingAlts
|
||||
{
|
||||
get
|
||||
{
|
||||
return conflictingAlts;
|
||||
if (conflictInfo == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return conflictInfo.ConflictedAlts;
|
||||
}
|
||||
set
|
||||
}
|
||||
|
||||
public virtual bool IsExactConflict
|
||||
{
|
||||
get
|
||||
{
|
||||
BitSet conflictingAlts = value;
|
||||
EnsureWritable();
|
||||
this.conflictingAlts = conflictingAlts;
|
||||
if (conflictInfo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return conflictInfo.IsExact;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -354,7 +354,16 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
continue;
|
||||
}
|
||||
atn.ruleToStopState[ruleTransition.target.ruleIndex].AddTransition(new EpsilonTransition(ruleTransition.followState));
|
||||
int outermostPrecedenceReturn = -1;
|
||||
if (atn.ruleToStartState[ruleTransition.target.ruleIndex].isPrecedenceRule)
|
||||
{
|
||||
if (ruleTransition.precedence == 0)
|
||||
{
|
||||
outermostPrecedenceReturn = ruleTransition.target.ruleIndex;
|
||||
}
|
||||
}
|
||||
EpsilonTransition returnTransition = new EpsilonTransition(ruleTransition.followState, outermostPrecedenceReturn);
|
||||
atn.ruleToStopState[ruleTransition.target.ruleIndex].AddTransition(returnTransition);
|
||||
}
|
||||
}
|
||||
foreach (ATNState state_2 in atn.states)
|
||||
|
@ -847,7 +856,7 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
Transition transition = state.GetOptimizedTransition(i);
|
||||
ATNState intermediate = transition.target;
|
||||
if (transition.TransitionType != TransitionType.Epsilon || intermediate.StateType != StateType.Basic || !intermediate.OnlyHasEpsilonTransitions)
|
||||
if (transition.TransitionType != TransitionType.Epsilon || ((EpsilonTransition)transition).OutermostPrecedenceReturn != -1 || intermediate.StateType != StateType.Basic || !intermediate.OnlyHasEpsilonTransitions)
|
||||
{
|
||||
if (optimizedTransitions != null)
|
||||
{
|
||||
|
@ -857,7 +866,7 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
for (int j = 0; j < intermediate.NumberOfOptimizedTransitions; j++)
|
||||
{
|
||||
if (intermediate.GetOptimizedTransition(j).TransitionType != TransitionType.Epsilon)
|
||||
if (intermediate.GetOptimizedTransition(j).TransitionType != TransitionType.Epsilon || ((EpsilonTransition)intermediate.GetOptimizedTransition(j)).OutermostPrecedenceReturn != -1)
|
||||
{
|
||||
if (optimizedTransitions != null)
|
||||
{
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace Antlr4.Runtime.Atn
|
|||
|
||||
static ATNSimulator()
|
||||
{
|
||||
Error = new DFAState(new ATNConfigSet(), 0, 0);
|
||||
Error = new DFAState(new EmptyEdgeMap<DFAState>(0, -1), new EmptyEdgeMap<DFAState>(0, -1), new ATNConfigSet());
|
||||
Error.stateNumber = int.MaxValue;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* [The "BSD license"]
|
||||
* Copyright (c) 2013 Terence Parr
|
||||
* Copyright (c) 2013 Sam Harwell
|
||||
* 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 Antlr4.Runtime.Misc;
|
||||
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
|
||||
{
|
||||
private readonly BitSet conflictedAlts;
|
||||
|
||||
private readonly bool exact;
|
||||
|
||||
public ConflictInfo(BitSet conflictedAlts, bool exact)
|
||||
{
|
||||
this.conflictedAlts = conflictedAlts;
|
||||
this.exact = exact;
|
||||
}
|
||||
|
||||
/// <summary>Gets the set of conflicting alternatives for the configuration set.</summary>
|
||||
/// <remarks>Gets the set of conflicting alternatives for the configuration set.</remarks>
|
||||
public BitSet ConflictedAlts
|
||||
{
|
||||
get
|
||||
{
|
||||
return conflictedAlts;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets whether or not the configuration conflict is an exact conflict.</summary>
|
||||
/// <remarks>
|
||||
/// Gets whether or not the configuration conflict is an exact conflict.
|
||||
/// An exact conflict occurs when the prediction algorithm determines that
|
||||
/// the represented alternatives for a particular configuration set cannot be
|
||||
/// further reduced by consuming additional input. After reaching an exact
|
||||
/// conflict during an SLL prediction, only switch to full-context prediction
|
||||
/// could reduce the set of viable alternatives. In LL prediction, an exact
|
||||
/// conflict indicates a true ambiguity in the input.
|
||||
/// <p>
|
||||
/// For the
|
||||
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
|
||||
/// prediction mode,
|
||||
/// accept states are conflicting but not exact are treated as non-accept
|
||||
/// states.</p>
|
||||
/// </remarks>
|
||||
public bool IsExact
|
||||
{
|
||||
get
|
||||
{
|
||||
return exact;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(obj is Antlr4.Runtime.Atn.ConflictInfo))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Antlr4.Runtime.Atn.ConflictInfo other = (Antlr4.Runtime.Atn.ConflictInfo)obj;
|
||||
return IsExact == other.IsExact && Utils.Equals(ConflictedAlts, other.ConflictedAlts);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ConflictedAlts.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,9 +35,32 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
public sealed class EpsilonTransition : Transition
|
||||
{
|
||||
private readonly int outermostPrecedenceReturn;
|
||||
|
||||
public EpsilonTransition(ATNState target)
|
||||
: this(target, -1)
|
||||
{
|
||||
}
|
||||
|
||||
public EpsilonTransition(ATNState target, int outermostPrecedenceReturn)
|
||||
: base(target)
|
||||
{
|
||||
this.outermostPrecedenceReturn = outermostPrecedenceReturn;
|
||||
}
|
||||
|
||||
/// <returns>
|
||||
/// the rule index of a precedence rule for which this transition is
|
||||
/// returning from, where the precedence value is 0; otherwise, -1.
|
||||
/// </returns>
|
||||
/// <seealso cref="ATNConfig.PrecedenceFilterSuppressed()"/>
|
||||
/// <seealso cref="ParserATNSimulator.ApplyPrecedenceFilter(ATNConfigSet, Antlr4.Runtime.ParserRuleContext, PredictionContextCache)"/>
|
||||
/// <since>4.4.1</since>
|
||||
public int OutermostPrecedenceReturn
|
||||
{
|
||||
get
|
||||
{
|
||||
return outermostPrecedenceReturn;
|
||||
}
|
||||
}
|
||||
|
||||
public override Antlr4.Runtime.Atn.TransitionType TransitionType
|
||||
|
|
|
@ -190,6 +190,13 @@ namespace Antlr4.Runtime.Atn
|
|||
protected internal virtual int ExecATN(ICharStream input, DFAState ds0)
|
||||
{
|
||||
//System.out.println("enter exec index "+input.index()+" from "+ds0.configs);
|
||||
if (ds0.IsAcceptState)
|
||||
{
|
||||
// allow zero-length tokens
|
||||
CaptureSimState(prevAccept, input, ds0);
|
||||
// adjust index since the current input character was not yet consumed
|
||||
prevAccept.index--;
|
||||
}
|
||||
int t = input.La(1);
|
||||
DFAState s = ds0;
|
||||
// s is current/from DFA state
|
||||
|
@ -222,7 +229,7 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
break;
|
||||
}
|
||||
if (target.isAcceptState)
|
||||
if (target.IsAcceptState)
|
||||
{
|
||||
CaptureSimState(prevAccept, input, target);
|
||||
if (t == IntStreamConstants.Eof)
|
||||
|
@ -318,9 +325,9 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
if (prevAccept.dfaState != null)
|
||||
{
|
||||
LexerActionExecutor lexerActionExecutor = prevAccept.dfaState.lexerActionExecutor;
|
||||
LexerActionExecutor lexerActionExecutor = prevAccept.dfaState.LexerActionExecutor;
|
||||
Accept(input, lexerActionExecutor, startIndex, prevAccept.index, prevAccept.line, prevAccept.charPos);
|
||||
return prevAccept.dfaState.prediction;
|
||||
return prevAccept.dfaState.Prediction;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -719,14 +726,14 @@ namespace Antlr4.Runtime.Atn
|
|||
protected internal virtual DFAState AddDFAState(ATNConfigSet configs)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(!configs.HasSemanticContext);
|
||||
DFAState proposed = new DFAState(configs, 0, MaxDfaEdge);
|
||||
DFAState proposed = new DFAState(atn.modeToDFA[mode], configs);
|
||||
DFAState existing = atn.modeToDFA[mode].states.Get(proposed);
|
||||
if (existing != null)
|
||||
{
|
||||
return existing;
|
||||
}
|
||||
configs.OptimizeConfigs(this);
|
||||
DFAState newState = new DFAState(configs.Clone(true), 0, MaxDfaEdge);
|
||||
DFAState newState = new DFAState(atn.modeToDFA[mode], configs.Clone(true));
|
||||
ATNConfig firstConfigWithRuleStopState = null;
|
||||
foreach (ATNConfig c in configs)
|
||||
{
|
||||
|
@ -738,9 +745,9 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
if (firstConfigWithRuleStopState != null)
|
||||
{
|
||||
newState.isAcceptState = true;
|
||||
newState.lexerActionExecutor = firstConfigWithRuleStopState.ActionExecutor;
|
||||
newState.prediction = atn.ruleToTokenType[firstConfigWithRuleStopState.State.ruleIndex];
|
||||
int prediction = atn.ruleToTokenType[firstConfigWithRuleStopState.State.ruleIndex];
|
||||
LexerActionExecutor lexerActionExecutor = firstConfigWithRuleStopState.ActionExecutor;
|
||||
newState.AcceptStateInfo = new AcceptStateInfo(prediction, lexerActionExecutor);
|
||||
}
|
||||
return atn.modeToDFA[mode].AddState(newState);
|
||||
}
|
||||
|
|
|
@ -341,6 +341,7 @@ namespace Antlr4.Runtime.Atn
|
|||
|
||||
public bool optimize_ll1 = true;
|
||||
|
||||
[System.ObsoleteAttribute(@"This flag is not currently used by the ATN simulator.")]
|
||||
public bool optimize_hidden_conflicted_configs = false;
|
||||
|
||||
public bool optimize_tail_calls = true;
|
||||
|
@ -386,6 +387,8 @@ namespace Antlr4.Runtime.Atn
|
|||
/// </remarks>
|
||||
protected internal bool userWantsCtxSensitive = true;
|
||||
|
||||
private DFA dfa;
|
||||
|
||||
/// <summary>Testing only!</summary>
|
||||
public ParserATNSimulator(ATN atn)
|
||||
: this(null, atn)
|
||||
|
@ -437,6 +440,7 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
}
|
||||
}
|
||||
this.dfa = dfa;
|
||||
if (force_global_context)
|
||||
{
|
||||
useContext = true;
|
||||
|
@ -475,6 +479,7 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
finally
|
||||
{
|
||||
this.dfa = null;
|
||||
input.Seek(index);
|
||||
input.Release(m);
|
||||
}
|
||||
|
@ -568,7 +573,7 @@ namespace Antlr4.Runtime.Atn
|
|||
s = next;
|
||||
}
|
||||
}
|
||||
if (s.isAcceptState)
|
||||
if (IsAcceptState(s, state.useContext))
|
||||
{
|
||||
if (s.predicates != null)
|
||||
{
|
||||
|
@ -580,14 +585,14 @@ namespace Antlr4.Runtime.Atn
|
|||
break;
|
||||
}
|
||||
// t is not updated if one of these states is reached
|
||||
System.Diagnostics.Debug.Assert(!s.isAcceptState);
|
||||
System.Diagnostics.Debug.Assert(!IsAcceptState(s, state.useContext));
|
||||
// if no edge, pop over to ATN interpreter, update DFA and return
|
||||
DFAState target = GetExistingTargetState(s, t);
|
||||
if (target == null)
|
||||
{
|
||||
if (dfa_debug && t >= 0)
|
||||
{
|
||||
System.Console.Out.WriteLine("no edge for " + parser.TokenNames[t]);
|
||||
System.Console.Out.WriteLine("no edge for " + parser.Vocabulary.GetDisplayName(t));
|
||||
}
|
||||
int alt;
|
||||
SimulatorState initialState = new SimulatorState(outerContext, s, state.useContext, remainingOuterContext);
|
||||
|
@ -606,7 +611,7 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
}
|
||||
s = target;
|
||||
if (!s.isAcceptState && t != IntStreamConstants.Eof)
|
||||
if (!IsAcceptState(s, state.useContext) && t != IntStreamConstants.Eof)
|
||||
{
|
||||
input.Consume();
|
||||
t = input.La(1);
|
||||
|
@ -616,11 +621,11 @@ namespace Antlr4.Runtime.Atn
|
|||
// if ( debug ) System.out.println("!!! no viable alt in dfa");
|
||||
// return -1;
|
||||
// }
|
||||
if (s.configs.ConflictingAlts != null)
|
||||
if (!state.useContext && s.configs.ConflictInformation != null)
|
||||
{
|
||||
if (dfa.atnStartState is DecisionState)
|
||||
{
|
||||
if (!userWantsCtxSensitive || !s.configs.DipsIntoOuterContext || (treat_sllk1_conflict_as_ambiguity && input.Index == startIndex))
|
||||
if (!userWantsCtxSensitive || (!s.configs.DipsIntoOuterContext && s.configs.IsExactConflict) || (treat_sllk1_conflict_as_ambiguity && input.Index == startIndex))
|
||||
{
|
||||
}
|
||||
else
|
||||
|
@ -695,12 +700,82 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
input.Seek(stopIndex);
|
||||
}
|
||||
ReportAmbiguity(dfa, s, startIndex, stopIndex, predictionMode == Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection, alts, s.configs);
|
||||
ReportAmbiguity(dfa, s, startIndex, stopIndex, s.configs.IsExactConflict, alts, s.configs);
|
||||
return alts.NextSetBit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return s.prediction;
|
||||
return s.Prediction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a particular DFA state should be treated as an accept state
|
||||
/// for the current prediction mode.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Determines if a particular DFA state should be treated as an accept state
|
||||
/// for the current prediction mode. In addition to the
|
||||
/// <paramref name="useContext"/>
|
||||
/// parameter, the
|
||||
/// <see cref="PredictionMode()"/>
|
||||
/// method provides the
|
||||
/// prediction mode controlling the prediction algorithm as a whole.
|
||||
/// <p>
|
||||
/// The default implementation simply returns the value of
|
||||
/// <see cref="Antlr4.Runtime.Dfa.DFAState.IsAcceptState()"/>
|
||||
/// except for conflict states when
|
||||
/// <paramref name="useContext"/>
|
||||
/// is
|
||||
/// <see langword="true"/>
|
||||
/// and
|
||||
/// <see cref="PredictionMode()"/>
|
||||
/// is
|
||||
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
|
||||
/// . In that case, only
|
||||
/// conflict states where
|
||||
/// <see cref="ATNConfigSet.IsExactConflict()"/>
|
||||
/// is
|
||||
/// <see langword="true"/>
|
||||
/// are considered accept states.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <param name="state">The DFA state to check.</param>
|
||||
/// <param name="useContext">
|
||||
///
|
||||
/// <see langword="true"/>
|
||||
/// if the prediction algorithm is currently
|
||||
/// considering the full parser context; otherwise,
|
||||
/// <see langword="false"/>
|
||||
/// if the
|
||||
/// algorithm is currently performing a local context prediction.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
///
|
||||
/// <see langword="true"/>
|
||||
/// if the specified
|
||||
/// <paramref name="state"/>
|
||||
/// is an accept state;
|
||||
/// otherwise,
|
||||
/// <see langword="false"/>
|
||||
/// .
|
||||
/// </returns>
|
||||
protected internal virtual bool IsAcceptState(DFAState state, bool useContext)
|
||||
{
|
||||
if (!state.IsAcceptState)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (state.configs.ConflictingAlts == null)
|
||||
{
|
||||
// unambiguous
|
||||
return true;
|
||||
}
|
||||
// More picky when we need exact conflicts
|
||||
if (useContext && predictionMode == Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection)
|
||||
{
|
||||
return state.configs.IsExactConflict;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -764,13 +839,13 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
DFAState D = nextState.s0;
|
||||
// predicted alt => accept state
|
||||
System.Diagnostics.Debug.Assert(D.isAcceptState || GetUniqueAlt(D.configs) == ATN.InvalidAltNumber);
|
||||
System.Diagnostics.Debug.Assert(D.IsAcceptState || D.Prediction == ATN.InvalidAltNumber);
|
||||
// conflicted => accept state
|
||||
System.Diagnostics.Debug.Assert(D.isAcceptState || D.configs.ConflictingAlts == null);
|
||||
if (D.isAcceptState)
|
||||
System.Diagnostics.Debug.Assert(D.IsAcceptState || D.configs.ConflictInformation == null);
|
||||
if (IsAcceptState(D, useContext))
|
||||
{
|
||||
BitSet conflictingAlts = D.configs.ConflictingAlts;
|
||||
int predictedAlt = conflictingAlts == null ? GetUniqueAlt(D.configs) : ATN.InvalidAltNumber;
|
||||
int predictedAlt = conflictingAlts == null ? D.Prediction : ATN.InvalidAltNumber;
|
||||
if (predictedAlt != ATN.InvalidAltNumber)
|
||||
{
|
||||
if (optimize_ll1 && input.Index == startIndex && !dfa.IsPrecedenceDfa && nextState.outerContext == nextState.remainingOuterContext && dfa.decision >= 0 && !D.configs.HasSemanticContext)
|
||||
|
@ -786,20 +861,15 @@ namespace Antlr4.Runtime.Atn
|
|||
ReportContextSensitivity(dfa, predictedAlt, nextState, startIndex, input.Index);
|
||||
}
|
||||
}
|
||||
predictedAlt = D.prediction;
|
||||
predictedAlt = D.Prediction;
|
||||
// int k = input.index() - startIndex + 1; // how much input we used
|
||||
// System.out.println("used k="+k);
|
||||
bool attemptFullContext = conflictingAlts != null && userWantsCtxSensitive;
|
||||
if (attemptFullContext)
|
||||
{
|
||||
if (predictionMode == Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection)
|
||||
{
|
||||
attemptFullContext = !useContext && (D.configs.DipsIntoOuterContext || D.configs.ConflictingAlts.Cardinality() > 2) && (!treat_sllk1_conflict_as_ambiguity || input.Index != startIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
attemptFullContext = D.configs.DipsIntoOuterContext && (!treat_sllk1_conflict_as_ambiguity || input.Index != startIndex);
|
||||
}
|
||||
// Only exact conflicts are known to be ambiguous when local
|
||||
// prediction does not step out of the decision rule.
|
||||
attemptFullContext = !useContext && (D.configs.DipsIntoOuterContext || !D.configs.IsExactConflict) && (!treat_sllk1_conflict_as_ambiguity || input.Index != startIndex);
|
||||
}
|
||||
if (D.configs.HasSemanticContext)
|
||||
{
|
||||
|
@ -844,7 +914,7 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
if (reportAmbiguities && conflictingAlts.Cardinality() > 1)
|
||||
{
|
||||
ReportAmbiguity(dfa, D, startIndex, input.Index, predictionMode == Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection, conflictingAlts, D.configs);
|
||||
ReportAmbiguity(dfa, D, startIndex, input.Index, D.configs.IsExactConflict, conflictingAlts, D.configs);
|
||||
}
|
||||
predictedAlt = conflictingAlts.NextSetBit(0);
|
||||
}
|
||||
|
@ -853,7 +923,7 @@ namespace Antlr4.Runtime.Atn
|
|||
else
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(!useContext);
|
||||
System.Diagnostics.Debug.Assert(D.isAcceptState);
|
||||
System.Diagnostics.Debug.Assert(IsAcceptState(D, false));
|
||||
SimulatorState fullContextState = ComputeStartState(dfa, outerContext, true);
|
||||
if (reportAmbiguities)
|
||||
{
|
||||
|
@ -1055,8 +1125,8 @@ namespace Antlr4.Runtime.Atn
|
|||
s = next;
|
||||
}
|
||||
}
|
||||
System.Diagnostics.Debug.Assert(!s.isAcceptState);
|
||||
if (s.isAcceptState)
|
||||
System.Diagnostics.Debug.Assert(!IsAcceptState(s, useContext));
|
||||
if (IsAcceptState(s, useContext))
|
||||
{
|
||||
return new SimulatorState(previous.outerContext, s, useContext, remainingGlobalContext);
|
||||
}
|
||||
|
@ -1357,6 +1427,16 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
configs.IsOutermostConfigSet = true;
|
||||
}
|
||||
if (!useContext || enable_global_context_dfa)
|
||||
{
|
||||
if (!dfa.IsPrecedenceDfa && dfa.atnStartState is StarLoopEntryState)
|
||||
{
|
||||
if (((StarLoopEntryState)dfa.atnStartState).precedenceRuleDecision)
|
||||
{
|
||||
dfa.IsPrecedenceDfa = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool collectPredicates = true;
|
||||
Closure(reachIntermediate, configs, collectPredicates, hasMoreContext, contextCache, false);
|
||||
bool stepIntoGlobal = configs.DipsIntoOuterContext;
|
||||
|
@ -1370,13 +1450,6 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
if (s0 == null)
|
||||
{
|
||||
if (!dfa.IsPrecedenceDfa && dfa.atnStartState is StarLoopEntryState)
|
||||
{
|
||||
if (((StarLoopEntryState)dfa.atnStartState).precedenceRuleDecision)
|
||||
{
|
||||
dfa.IsPrecedenceDfa = true;
|
||||
}
|
||||
}
|
||||
if (!dfa.IsPrecedenceDfa)
|
||||
{
|
||||
AtomicReference<DFAState> reference = useContext ? dfa.s0full : dfa.s0;
|
||||
|
@ -1441,8 +1514,13 @@ namespace Antlr4.Runtime.Atn
|
|||
/// <li>Evaluate the precedence predicates for each configuration using
|
||||
/// <see cref="SemanticContext.EvalPrecedence(Antlr4.Runtime.Recognizer{Symbol, ATNInterpreter}, Antlr4.Runtime.RuleContext)"/>
|
||||
/// .</li>
|
||||
/// <li>Remove all configurations which predict an alternative greater than
|
||||
/// 1, for which another configuration that predicts alternative 1 is in the
|
||||
/// <li>When
|
||||
/// <see cref="ATNConfig.PrecedenceFilterSuppressed()"/>
|
||||
/// is
|
||||
/// <see langword="false"/>
|
||||
/// ,
|
||||
/// remove all configurations which predict an alternative greater than 1,
|
||||
/// for which another configuration that predicts alternative 1 is in the
|
||||
/// same ATN state with the same prediction context. This transformation is
|
||||
/// valid for the following reasons:
|
||||
/// <ul>
|
||||
|
@ -1454,7 +1532,11 @@ namespace Antlr4.Runtime.Atn
|
|||
/// epsilon transition, so the only way an alternative other than 1 can exist
|
||||
/// in a state that is also reachable via alternative 1 is by nesting calls
|
||||
/// to the left-recursive rule, with the outer calls not being at the
|
||||
/// preferred precedence level.</li>
|
||||
/// preferred precedence level. The
|
||||
/// <see cref="ATNConfig.PrecedenceFilterSuppressed()"/>
|
||||
/// property marks ATN
|
||||
/// configurations which do not meet this condition, and therefore are not
|
||||
/// eligible for elimination during the filtering process.</li>
|
||||
/// </ul>
|
||||
/// </li>
|
||||
/// </ol>
|
||||
|
@ -1535,11 +1617,14 @@ namespace Antlr4.Runtime.Atn
|
|||
// already handled
|
||||
continue;
|
||||
}
|
||||
PredictionContext context = statesFromAlt1.Get(config_1.State.stateNumber);
|
||||
if (context != null && context.Equals(config_1.Context))
|
||||
if (!config_1.PrecedenceFilterSuppressed)
|
||||
{
|
||||
// eliminated
|
||||
continue;
|
||||
PredictionContext context = statesFromAlt1.Get(config_1.State.stateNumber);
|
||||
if (context != null && context.Equals(config_1.Context))
|
||||
{
|
||||
// eliminated
|
||||
continue;
|
||||
}
|
||||
}
|
||||
configSet.Add(config_1, contextCache);
|
||||
}
|
||||
|
@ -1569,9 +1654,7 @@ namespace Antlr4.Runtime.Atn
|
|||
// Update DFA so reach becomes accept state with predicate
|
||||
predPredictions = GetPredicatePredictions(conflictingAlts, altToPred);
|
||||
D.predicates = predPredictions;
|
||||
D.prediction = ATN.InvalidAltNumber;
|
||||
}
|
||||
// make sure we use preds
|
||||
return predPredictions;
|
||||
}
|
||||
|
||||
|
@ -1767,6 +1850,7 @@ namespace Antlr4.Runtime.Atn
|
|||
// gotten that context AFTER having fallen off a rule.
|
||||
// Make sure we track that we are now out of context.
|
||||
c.OuterContextDepth = config.OuterContextDepth;
|
||||
c.PrecedenceFilterSuppressed = config.PrecedenceFilterSuppressed;
|
||||
System.Diagnostics.Debug.Assert(depth > int.MinValue);
|
||||
Closure(c, configs, intermediate, closureBusy, collectPredicates, hasMoreContexts, contextCache, depth - 1, treatEofAsEpsilon);
|
||||
}
|
||||
|
@ -1791,6 +1875,14 @@ namespace Antlr4.Runtime.Atn
|
|||
// no need to keep full context overhead when we step out
|
||||
config = config.Transform(config.State, PredictionContext.EmptyLocal, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!config.ReachesIntoOuterContext && PredictionContext.IsEmptyLocal(config.Context))
|
||||
{
|
||||
// add stop state when leaving decision rule for the first time
|
||||
configs.Add(config, contextCache);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1835,6 +1927,14 @@ namespace Antlr4.Runtime.Atn
|
|||
// avoid infinite recursion for right-recursive rules
|
||||
continue;
|
||||
}
|
||||
if (dfa != null && dfa.IsPrecedenceDfa)
|
||||
{
|
||||
int outermostPrecedenceReturn = ((EpsilonTransition)t).OutermostPrecedenceReturn;
|
||||
if (outermostPrecedenceReturn == dfa.atnStartState.ruleIndex)
|
||||
{
|
||||
c.PrecedenceFilterSuppressed = true;
|
||||
}
|
||||
}
|
||||
c.OuterContextDepth = c.OuterContextDepth + 1;
|
||||
System.Diagnostics.Debug.Assert(newDepth > int.MinValue);
|
||||
newDepth--;
|
||||
|
@ -1997,9 +2097,9 @@ namespace Antlr4.Runtime.Atn
|
|||
return config.Transform(t.target, newContext, false);
|
||||
}
|
||||
|
||||
private sealed class _IComparer_1928 : IComparer<ATNConfig>
|
||||
private sealed class _IComparer_1996 : IComparer<ATNConfig>
|
||||
{
|
||||
public _IComparer_1928()
|
||||
public _IComparer_1996()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2019,9 +2119,9 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
}
|
||||
|
||||
private static readonly IComparer<ATNConfig> StateAltSortComparator = new _IComparer_1928();
|
||||
private static readonly IComparer<ATNConfig> StateAltSortComparator = new _IComparer_1996();
|
||||
|
||||
private BitSet IsConflicted(ATNConfigSet configset, PredictionContextCache contextCache)
|
||||
private ConflictInfo IsConflicted(ATNConfigSet configset, PredictionContextCache contextCache)
|
||||
{
|
||||
if (configset.UniqueAlt != ATN.InvalidAltNumber || configset.Count <= 1)
|
||||
{
|
||||
|
@ -2029,7 +2129,7 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
IList<ATNConfig> configs = new List<ATNConfig>(configset);
|
||||
configs.Sort(StateAltSortComparator);
|
||||
bool exact = !configset.DipsIntoOuterContext && predictionMode == Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection;
|
||||
bool exact = !configset.DipsIntoOuterContext;
|
||||
BitSet alts = new BitSet();
|
||||
int minAlt = configs[0].Alt;
|
||||
alts.Set(minAlt);
|
||||
|
@ -2077,7 +2177,8 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
if (currentAlt != maxAlt)
|
||||
{
|
||||
return null;
|
||||
exact = false;
|
||||
break;
|
||||
}
|
||||
currentState = stateNumber;
|
||||
currentAlt = minAlt;
|
||||
|
@ -2088,7 +2189,8 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
if (alt != representedAlts.NextSetBit(currentAlt + 1))
|
||||
{
|
||||
return null;
|
||||
exact = false;
|
||||
break;
|
||||
}
|
||||
currentAlt = alt;
|
||||
}
|
||||
|
@ -2159,43 +2261,15 @@ namespace Antlr4.Runtime.Atn
|
|||
joinedCheckContext2 = contextCache.Join(joinedCheckContext2, config2.Context);
|
||||
}
|
||||
i_1 = lastIndexCurrentStateCurrentAlt;
|
||||
if (exact)
|
||||
PredictionContext check = contextCache.Join(joinedCheckContext, joinedCheckContext2);
|
||||
if (!joinedCheckContext.Equals(check))
|
||||
{
|
||||
if (!joinedCheckContext.Equals(joinedCheckContext2))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PredictionContext check = contextCache.Join(joinedCheckContext, joinedCheckContext2);
|
||||
if (!joinedCheckContext.Equals(check))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (!exact && optimize_hidden_conflicted_configs)
|
||||
{
|
||||
for (int j = firstIndexCurrentState; j_1 <= lastIndexCurrentStateMinAlt; j_1++)
|
||||
{
|
||||
ATNConfig checkConfig = configs[j_1];
|
||||
if (checkConfig.SemanticContext != SemanticContext.None && !checkConfig.SemanticContext.Equals(config_1.SemanticContext))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (joinedCheckContext != checkConfig.Context)
|
||||
{
|
||||
PredictionContext check = contextCache.Join(checkConfig.Context, config_1.Context);
|
||||
if (!checkConfig.Context.Equals(check))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
config_1.IsHidden = true;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
// update exact if necessary
|
||||
exact = exact && joinedCheckContext.Equals(joinedCheckContext2);
|
||||
}
|
||||
return alts;
|
||||
return new ConflictInfo(alts, exact);
|
||||
}
|
||||
|
||||
protected internal virtual BitSet GetConflictingAltsFromConfigSet(ATNConfigSet configs)
|
||||
|
@ -2209,14 +2283,6 @@ namespace Antlr4.Runtime.Atn
|
|||
return conflictingAlts;
|
||||
}
|
||||
|
||||
protected internal virtual int ResolveToMinAlt(DFAState D, BitSet conflictingAlts)
|
||||
{
|
||||
// kill dead alts so we don't chase them ever
|
||||
// killAlts(conflictingAlts, D.configset);
|
||||
D.prediction = conflictingAlts.NextSetBit(0);
|
||||
return D.prediction;
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
public virtual string GetTokenName(int t)
|
||||
{
|
||||
|
@ -2224,20 +2290,13 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
return "EOF";
|
||||
}
|
||||
if (parser != null && parser.TokenNames != null)
|
||||
IVocabulary vocabulary = parser != null ? parser.Vocabulary : Vocabulary.EmptyVocabulary;
|
||||
string displayName = vocabulary.GetDisplayName(t);
|
||||
if (displayName.Equals(Antlr4.Runtime.Sharpen.Extensions.ToString(t)))
|
||||
{
|
||||
string[] tokensNames = parser.TokenNames;
|
||||
if (t >= tokensNames.Length)
|
||||
{
|
||||
System.Console.Error.WriteLine(t + " ttype out of range: " + Arrays.ToString(tokensNames));
|
||||
System.Console.Error.WriteLine(((CommonTokenStream)((ITokenStream)parser.InputStream)).GetTokens());
|
||||
}
|
||||
else
|
||||
{
|
||||
return tokensNames[t] + "<" + t + ">";
|
||||
}
|
||||
return displayName;
|
||||
}
|
||||
return t.ToString();
|
||||
return displayName + "<" + t + ">";
|
||||
}
|
||||
|
||||
public virtual string GetLookaheadName(ITokenStream input)
|
||||
|
@ -2393,7 +2452,7 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
configs.OptimizeConfigs(this);
|
||||
}
|
||||
DFAState proposed = CreateDFAState(configs);
|
||||
DFAState proposed = CreateDFAState(dfa, configs);
|
||||
DFAState existing = dfa.states.Get(proposed);
|
||||
if (existing != null)
|
||||
{
|
||||
|
@ -2402,42 +2461,26 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
if (!configs.IsReadOnly)
|
||||
{
|
||||
if (configs.ConflictingAlts == null)
|
||||
if (configs.ConflictInformation == null)
|
||||
{
|
||||
configs.ConflictingAlts = IsConflicted(configs, contextCache);
|
||||
if (optimize_hidden_conflicted_configs && configs.ConflictingAlts != null)
|
||||
{
|
||||
int size = configs.Count;
|
||||
configs.StripHiddenConfigs();
|
||||
if (enableDfa && configs.Count < size)
|
||||
{
|
||||
DFAState proposed = CreateDFAState(configs);
|
||||
DFAState existing = dfa.states.Get(proposed);
|
||||
if (existing != null)
|
||||
{
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
}
|
||||
configs.ConflictInformation = IsConflicted(configs, contextCache);
|
||||
}
|
||||
}
|
||||
DFAState newState = CreateDFAState(configs.Clone(true));
|
||||
DFAState newState = CreateDFAState(dfa, configs.Clone(true));
|
||||
DecisionState decisionState = atn.GetDecisionState(dfa.decision);
|
||||
int predictedAlt = GetUniqueAlt(configs);
|
||||
if (predictedAlt != ATN.InvalidAltNumber)
|
||||
{
|
||||
newState.isAcceptState = true;
|
||||
newState.prediction = predictedAlt;
|
||||
newState.AcceptStateInfo = new AcceptStateInfo(predictedAlt);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (configs.ConflictingAlts != null)
|
||||
{
|
||||
newState.isAcceptState = true;
|
||||
newState.prediction = ResolveToMinAlt(newState, newState.configs.ConflictingAlts);
|
||||
newState.AcceptStateInfo = new AcceptStateInfo(newState.configs.ConflictingAlts.NextSetBit(0));
|
||||
}
|
||||
}
|
||||
if (newState.isAcceptState && configs.HasSemanticContext)
|
||||
if (newState.IsAcceptState && configs.HasSemanticContext)
|
||||
{
|
||||
PredicateDFAState(newState, configs, decisionState.NumberOfTransitions);
|
||||
}
|
||||
|
@ -2454,9 +2497,9 @@ namespace Antlr4.Runtime.Atn
|
|||
}
|
||||
|
||||
[NotNull]
|
||||
protected internal virtual DFAState CreateDFAState(ATNConfigSet configs)
|
||||
protected internal virtual DFAState CreateDFAState(DFA dfa, ATNConfigSet configs)
|
||||
{
|
||||
return new DFAState(configs, -1, atn.maxTokenType);
|
||||
return new DFAState(dfa, configs);
|
||||
}
|
||||
|
||||
protected internal virtual void ReportAttemptingFullContext(DFA dfa, BitSet conflictingAlts, SimulatorState conflictState, int startIndex, int stopIndex)
|
||||
|
|
|
@ -91,7 +91,8 @@ namespace Antlr4.Runtime.Atn
|
|||
{
|
||||
this._input = input;
|
||||
this._startIndex = input.Index;
|
||||
this._sllStopIndex = -1;
|
||||
// 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;
|
||||
|
|
|
@ -376,7 +376,7 @@ namespace Antlr4.Runtime
|
|||
/// <param name="e">the recognition exception</param>
|
||||
protected internal virtual void ReportInputMismatch(Parser recognizer, InputMismatchException e)
|
||||
{
|
||||
string msg = "mismatched input " + GetTokenErrorDisplay(e.OffendingToken) + " expecting " + e.GetExpectedTokens().ToString(recognizer.TokenNames);
|
||||
string msg = "mismatched input " + GetTokenErrorDisplay(e.OffendingToken) + " expecting " + e.GetExpectedTokens().ToString(recognizer.Vocabulary);
|
||||
NotifyErrorListeners(recognizer, msg, e);
|
||||
}
|
||||
|
||||
|
@ -434,7 +434,7 @@ namespace Antlr4.Runtime
|
|||
IToken t = recognizer.CurrentToken;
|
||||
string tokenName = GetTokenErrorDisplay(t);
|
||||
IntervalSet expecting = GetExpectedTokens(recognizer);
|
||||
string msg = "extraneous input " + tokenName + " expecting " + expecting.ToString(recognizer.TokenNames);
|
||||
string msg = "extraneous input " + tokenName + " expecting " + expecting.ToString(recognizer.Vocabulary);
|
||||
recognizer.NotifyErrorListeners(t, msg, null);
|
||||
}
|
||||
|
||||
|
@ -472,7 +472,7 @@ namespace Antlr4.Runtime
|
|||
BeginErrorCondition(recognizer);
|
||||
IToken t = recognizer.CurrentToken;
|
||||
IntervalSet expecting = GetExpectedTokens(recognizer);
|
||||
string msg = "missing " + expecting.ToString(recognizer.TokenNames) + " at " + GetTokenErrorDisplay(t);
|
||||
string msg = "missing " + expecting.ToString(recognizer.Vocabulary) + " at " + GetTokenErrorDisplay(t);
|
||||
recognizer.NotifyErrorListeners(t, msg, null);
|
||||
}
|
||||
|
||||
|
@ -713,7 +713,7 @@ namespace Antlr4.Runtime
|
|||
}
|
||||
else
|
||||
{
|
||||
tokenText = "<missing " + recognizer.TokenNames[expectedTokenType] + ">";
|
||||
tokenText = "<missing " + recognizer.Vocabulary.GetDisplayName(expectedTokenType) + ">";
|
||||
}
|
||||
IToken current = currentSymbol;
|
||||
IToken lookback = ((ITokenStream)recognizer.InputStream).Lt(-1);
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* [The "BSD license"]
|
||||
* Copyright (c) 2013 Terence Parr
|
||||
* Copyright (c) 2013 Sam Harwell
|
||||
* 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 Antlr4.Runtime.Sharpen;
|
||||
|
||||
namespace Antlr4.Runtime.Dfa
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores information about a
|
||||
/// <see cref="DFAState"/>
|
||||
/// which is an accept state under
|
||||
/// some condition. Certain settings, such as
|
||||
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator.PredictionMode()"/>
|
||||
/// , may be used in addition to
|
||||
/// this information to determine whether or not a particular state is an accept
|
||||
/// state.
|
||||
/// </summary>
|
||||
/// <author>Sam Harwell</author>
|
||||
public class AcceptStateInfo
|
||||
{
|
||||
private readonly int prediction;
|
||||
|
||||
private readonly Antlr4.Runtime.Atn.LexerActionExecutor lexerActionExecutor;
|
||||
|
||||
public AcceptStateInfo(int prediction)
|
||||
{
|
||||
this.prediction = prediction;
|
||||
this.lexerActionExecutor = null;
|
||||
}
|
||||
|
||||
public AcceptStateInfo(int prediction, Antlr4.Runtime.Atn.LexerActionExecutor lexerActionExecutor)
|
||||
{
|
||||
this.prediction = prediction;
|
||||
this.lexerActionExecutor = lexerActionExecutor;
|
||||
}
|
||||
|
||||
/// <summary>Gets the prediction made by this accept state.</summary>
|
||||
/// <remarks>
|
||||
/// Gets the prediction made by this accept state. Note that this value
|
||||
/// assumes the predicates, if any, in the
|
||||
/// <see cref="DFAState"/>
|
||||
/// evaluate to
|
||||
/// <see langword="true"/>
|
||||
/// . If predicate evaluation is enabled, the final prediction of
|
||||
/// the accept state will be determined by the result of predicate
|
||||
/// evaluation.
|
||||
/// </remarks>
|
||||
public virtual int Prediction
|
||||
{
|
||||
get
|
||||
{
|
||||
return prediction;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the
|
||||
/// <see cref="Antlr4.Runtime.Atn.LexerActionExecutor"/>
|
||||
/// which can be used to execute actions
|
||||
/// and/or commands after the lexer matches a token.
|
||||
/// </summary>
|
||||
public virtual Antlr4.Runtime.Atn.LexerActionExecutor LexerActionExecutor
|
||||
{
|
||||
get
|
||||
{
|
||||
return lexerActionExecutor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,24 +34,25 @@ using Antlr4.Runtime.Sharpen;
|
|||
|
||||
namespace Antlr4.Runtime.Dfa
|
||||
{
|
||||
/// <author>sam</author>
|
||||
public class ArrayEdgeMap<T> : AbstractEdgeMap<T>
|
||||
/// <author>Sam Harwell</author>
|
||||
public sealed class ArrayEdgeMap<T> : AbstractEdgeMap<T>
|
||||
{
|
||||
private readonly T[] arrayData;
|
||||
private readonly AtomicReferenceArray<T> arrayData;
|
||||
|
||||
private int size;
|
||||
private readonly AtomicInteger size;
|
||||
|
||||
public ArrayEdgeMap(int minIndex, int maxIndex)
|
||||
: base(minIndex, maxIndex)
|
||||
{
|
||||
arrayData = (T[])new object[maxIndex - minIndex + 1];
|
||||
arrayData = new AtomicReferenceArray<T>(maxIndex - minIndex + 1);
|
||||
size = new AtomicInteger();
|
||||
}
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return size;
|
||||
return size.Get();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,7 +60,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
get
|
||||
{
|
||||
return size == 0;
|
||||
return Count == 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -76,7 +77,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
return null;
|
||||
}
|
||||
return arrayData[key - minIndex];
|
||||
return arrayData.Get(key - minIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,17 +85,16 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
if (key >= minIndex && key <= maxIndex)
|
||||
{
|
||||
T existing = arrayData[key - minIndex];
|
||||
arrayData[key - minIndex] = value;
|
||||
T existing = arrayData.GetAndSet(key - minIndex, value);
|
||||
if (existing == null && value != null)
|
||||
{
|
||||
size++;
|
||||
size.IncrementAndGet();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (existing != null && value == null)
|
||||
{
|
||||
size--;
|
||||
size.DecrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,17 +117,12 @@ namespace Antlr4.Runtime.Dfa
|
|||
Antlr4.Runtime.Dfa.ArrayEdgeMap<T> other = (Antlr4.Runtime.Dfa.ArrayEdgeMap<T>)m;
|
||||
int minOverlap = Math.Max(minIndex, other.minIndex);
|
||||
int maxOverlap = Math.Min(maxIndex, other.maxIndex);
|
||||
Antlr4.Runtime.Dfa.ArrayEdgeMap<T> result = this;
|
||||
for (int i = minOverlap; i <= maxOverlap; i++)
|
||||
{
|
||||
T target = other.arrayData[i - other.minIndex];
|
||||
if (target != null)
|
||||
{
|
||||
T current = this.arrayData[i - this.minIndex];
|
||||
this.arrayData[i - this.minIndex] = target;
|
||||
size += (current != null ? 0 : 1);
|
||||
}
|
||||
result = ((Antlr4.Runtime.Dfa.ArrayEdgeMap<T>)result.Put(i, m[i]));
|
||||
}
|
||||
return this;
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -142,14 +137,17 @@ namespace Antlr4.Runtime.Dfa
|
|||
if (m is SparseEdgeMap<object>)
|
||||
{
|
||||
SparseEdgeMap<T> other = (SparseEdgeMap<T>)m;
|
||||
int[] keys = other.Keys;
|
||||
IList<T> values = other.Values;
|
||||
Antlr4.Runtime.Dfa.ArrayEdgeMap<T> result = this;
|
||||
for (int i = 0; i < values.Count; i++)
|
||||
lock (other)
|
||||
{
|
||||
result = ((Antlr4.Runtime.Dfa.ArrayEdgeMap<T>)result.Put(keys[i], values[i]));
|
||||
int[] keys = other.Keys;
|
||||
IList<T> values = other.Values;
|
||||
Antlr4.Runtime.Dfa.ArrayEdgeMap<T> result = this;
|
||||
for (int i = 0; i < values.Count; i++)
|
||||
{
|
||||
result = ((Antlr4.Runtime.Dfa.ArrayEdgeMap<T>)result.Put(keys[i], values[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -161,8 +159,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
|
||||
public override AbstractEdgeMap<T> Clear()
|
||||
{
|
||||
Arrays.Fill(arrayData, null);
|
||||
return this;
|
||||
return new EmptyEdgeMap<T>(minIndex, maxIndex);
|
||||
}
|
||||
|
||||
public override IDictionary<int, T> ToMap()
|
||||
|
@ -172,13 +169,14 @@ namespace Antlr4.Runtime.Dfa
|
|||
return Antlr4.Runtime.Sharpen.Collections.EmptyMap();
|
||||
}
|
||||
IDictionary<int, T> result = new LinkedHashMap<int, T>();
|
||||
for (int i = 0; i < arrayData.Length; i++)
|
||||
for (int i = 0; i < arrayData.Length(); i++)
|
||||
{
|
||||
if (arrayData[i] == null)
|
||||
T element = arrayData.Get(i);
|
||||
if (element == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
result.Put(i + minIndex, arrayData[i]);
|
||||
result.Put(i + minIndex, element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
*/
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Antlr4.Runtime;
|
||||
using Antlr4.Runtime.Atn;
|
||||
using Antlr4.Runtime.Dfa;
|
||||
using Antlr4.Runtime.Misc;
|
||||
|
@ -64,6 +65,19 @@ namespace Antlr4.Runtime.Dfa
|
|||
|
||||
private readonly AtomicInteger nextStateNumber = new AtomicInteger();
|
||||
|
||||
private readonly int minDfaEdge;
|
||||
|
||||
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;
|
||||
|
||||
[NotNull]
|
||||
private readonly Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> emptyContextEdgeMap;
|
||||
|
||||
/// <summary>
|
||||
/// <see langword="true"/>
|
||||
/// if this DFA is for a precedence decision; otherwise,
|
||||
|
@ -85,6 +99,50 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
this.atnStartState = atnStartState;
|
||||
this.decision = decision;
|
||||
if (this.atnStartState.atn.grammarType == ATNType.Lexer)
|
||||
{
|
||||
minDfaEdge = LexerATNSimulator.MinDfaEdge;
|
||||
maxDfaEdge = LexerATNSimulator.MaxDfaEdge;
|
||||
}
|
||||
else
|
||||
{
|
||||
minDfaEdge = TokenConstants.Eof;
|
||||
maxDfaEdge = atnStartState.atn.maxTokenType;
|
||||
}
|
||||
this.emptyEdgeMap = new Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState>(minDfaEdge, maxDfaEdge);
|
||||
this.emptyContextEdgeMap = new Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState>(-1, atnStartState.atn.states.Count - 1);
|
||||
}
|
||||
|
||||
public int MinDfaEdge
|
||||
{
|
||||
get
|
||||
{
|
||||
return minDfaEdge;
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxDfaEdge
|
||||
{
|
||||
get
|
||||
{
|
||||
return maxDfaEdge;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> EmptyEdgeMap
|
||||
{
|
||||
get
|
||||
{
|
||||
return emptyEdgeMap;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> EmptyContextEdgeMap
|
||||
{
|
||||
get
|
||||
{
|
||||
return emptyContextEdgeMap;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets whether this DFA is a precedence DFA.</summary>
|
||||
|
@ -161,12 +219,8 @@ namespace Antlr4.Runtime.Dfa
|
|||
this.states.Clear();
|
||||
if (precedenceDfa)
|
||||
{
|
||||
DFAState precedenceState = new DFAState(new ATNConfigSet(), 0, 200);
|
||||
precedenceState.isAcceptState = false;
|
||||
this.s0.Set(precedenceState);
|
||||
DFAState fullContextPrecedenceState = new DFAState(new ATNConfigSet(), 0, 200);
|
||||
fullContextPrecedenceState.isAcceptState = false;
|
||||
this.s0full.Set(fullContextPrecedenceState);
|
||||
this.s0.Set(new DFAState(emptyPrecedenceEdges, EmptyContextEdgeMap, new ATNConfigSet()));
|
||||
this.s0full.Set(new DFAState(emptyPrecedenceEdges, EmptyContextEdgeMap, new ATNConfigSet()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -277,9 +331,10 @@ namespace Antlr4.Runtime.Dfa
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(null);
|
||||
return ToString(Vocabulary.EmptyVocabulary);
|
||||
}
|
||||
|
||||
[System.ObsoleteAttribute(@"Use ToString(Antlr4.Runtime.IVocabulary) instead.")]
|
||||
public virtual string ToString(string[] tokenNames)
|
||||
{
|
||||
if (s0.Get() == null)
|
||||
|
@ -290,6 +345,17 @@ namespace Antlr4.Runtime.Dfa
|
|||
return serializer.ToString();
|
||||
}
|
||||
|
||||
public virtual string ToString(IVocabulary vocabulary)
|
||||
{
|
||||
if (s0.Get() == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
DFASerializer serializer = new DFASerializer(this, vocabulary);
|
||||
return serializer.ToString();
|
||||
}
|
||||
|
||||
[System.ObsoleteAttribute(@"Use ToString(Antlr4.Runtime.IVocabulary, string[]) instead.")]
|
||||
public virtual string ToString(string[] tokenNames, string[] ruleNames)
|
||||
{
|
||||
if (s0.Get() == null)
|
||||
|
@ -300,6 +366,16 @@ namespace Antlr4.Runtime.Dfa
|
|||
return serializer.ToString();
|
||||
}
|
||||
|
||||
public virtual string ToString(IVocabulary vocabulary, string[] ruleNames)
|
||||
{
|
||||
if (s0.Get() == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
DFASerializer serializer = new DFASerializer(this, vocabulary, ruleNames, atnStartState.atn);
|
||||
return serializer.ToString();
|
||||
}
|
||||
|
||||
public virtual string ToLexerString()
|
||||
{
|
||||
if (s0.Get() == null)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
* (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 System.Text;
|
||||
using Antlr4.Runtime;
|
||||
|
@ -42,10 +43,10 @@ namespace Antlr4.Runtime.Dfa
|
|||
public class DFASerializer
|
||||
{
|
||||
[NotNull]
|
||||
internal readonly DFA dfa;
|
||||
private readonly DFA dfa;
|
||||
|
||||
[Nullable]
|
||||
internal readonly string[] tokenNames;
|
||||
[NotNull]
|
||||
private readonly IVocabulary vocabulary;
|
||||
|
||||
[Nullable]
|
||||
internal readonly string[] ruleNames;
|
||||
|
@ -53,20 +54,32 @@ namespace Antlr4.Runtime.Dfa
|
|||
[Nullable]
|
||||
internal readonly ATN atn;
|
||||
|
||||
[System.ObsoleteAttribute(@"Use DFASerializer(DFA, Antlr4.Runtime.IVocabulary) instead.")]
|
||||
public DFASerializer(DFA dfa, string[] tokenNames)
|
||||
: this(dfa, tokenNames, null, null)
|
||||
: this(dfa, Vocabulary.FromTokenNames(tokenNames), null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DFASerializer(DFA dfa, IVocabulary vocabulary)
|
||||
: this(dfa, vocabulary, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public DFASerializer(DFA dfa, Recognizer<object, object> parser)
|
||||
: this(dfa, parser != null ? parser.TokenNames : null, parser != null ? parser.RuleNames : null, parser != null ? parser.Atn : null)
|
||||
: this(dfa, parser != null ? parser.Vocabulary : Vocabulary.EmptyVocabulary, parser != null ? parser.RuleNames : null, parser != null ? parser.Atn : null)
|
||||
{
|
||||
}
|
||||
|
||||
[System.ObsoleteAttribute(@"Use DFASerializer(DFA, Antlr4.Runtime.IVocabulary, string[], Antlr4.Runtime.Atn.ATN) instead.")]
|
||||
public DFASerializer(DFA dfa, string[] tokenNames, string[] ruleNames, ATN atn)
|
||||
: this(dfa, Vocabulary.FromTokenNames(tokenNames), ruleNames, atn)
|
||||
{
|
||||
}
|
||||
|
||||
public DFASerializer(DFA dfa, IVocabulary vocabulary, string[] ruleNames, ATN atn)
|
||||
{
|
||||
this.dfa = dfa;
|
||||
this.tokenNames = tokenNames;
|
||||
this.vocabulary = vocabulary;
|
||||
this.ruleNames = ruleNames;
|
||||
this.atn = atn;
|
||||
}
|
||||
|
@ -81,7 +94,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
if (dfa.states != null)
|
||||
{
|
||||
IList<DFAState> states = new List<DFAState>(dfa.states.Values);
|
||||
states.Sort(new _IComparer_85());
|
||||
states.Sort(new _IComparer_103());
|
||||
foreach (DFAState s in states)
|
||||
{
|
||||
IDictionary<int, DFAState> edges = s.EdgeMap;
|
||||
|
@ -130,9 +143,9 @@ namespace Antlr4.Runtime.Dfa
|
|||
return output;
|
||||
}
|
||||
|
||||
private sealed class _IComparer_85 : IComparer<DFAState>
|
||||
private sealed class _IComparer_103 : IComparer<DFAState>
|
||||
{
|
||||
public _IComparer_85()
|
||||
public _IComparer_103()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -169,20 +182,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
|
||||
protected internal virtual string GetEdgeLabel(int i)
|
||||
{
|
||||
string label;
|
||||
if (i == -1)
|
||||
{
|
||||
return "EOF";
|
||||
}
|
||||
if (tokenNames != null)
|
||||
{
|
||||
label = tokenNames[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
label = i.ToString();
|
||||
}
|
||||
return label;
|
||||
return vocabulary.GetDisplayName(i);
|
||||
}
|
||||
|
||||
internal virtual string GetStateString(DFAState s)
|
||||
|
@ -193,7 +193,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
}
|
||||
int n = s.stateNumber;
|
||||
string stateStr = "s" + n;
|
||||
if (s.isAcceptState)
|
||||
if (s.IsAcceptState)
|
||||
{
|
||||
if (s.predicates != null)
|
||||
{
|
||||
|
@ -201,7 +201,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
}
|
||||
else
|
||||
{
|
||||
stateStr = ":s" + n + "=>" + s.prediction;
|
||||
stateStr = ":s" + n + "=>" + s.Prediction;
|
||||
}
|
||||
}
|
||||
if (s.IsContextSensitive)
|
||||
|
|
|
@ -72,32 +72,15 @@ namespace Antlr4.Runtime.Dfa
|
|||
/// <c>edges.get(symbol)</c>
|
||||
/// points to target of symbol.
|
||||
/// </summary>
|
||||
[Nullable]
|
||||
private AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> edges;
|
||||
[NotNull]
|
||||
private volatile AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> edges;
|
||||
|
||||
private readonly int minSymbol;
|
||||
|
||||
private readonly int maxSymbol;
|
||||
|
||||
public bool isAcceptState = false;
|
||||
|
||||
/// <summary>
|
||||
/// if accept state, what ttype do we match or alt do we predict?
|
||||
/// This is set to
|
||||
/// <see cref="Antlr4.Runtime.Atn.ATN.InvalidAltNumber"/>
|
||||
/// when
|
||||
/// <see cref="predicates"/>
|
||||
/// <c>!=null</c>
|
||||
/// .
|
||||
/// </summary>
|
||||
public int prediction;
|
||||
|
||||
public LexerActionExecutor lexerActionExecutor;
|
||||
private Antlr4.Runtime.Dfa.AcceptStateInfo acceptStateInfo;
|
||||
|
||||
/// <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>
|
||||
[Nullable]
|
||||
private AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> contextEdges;
|
||||
[NotNull]
|
||||
private volatile AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> contextEdges;
|
||||
|
||||
/// <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>
|
||||
|
@ -134,86 +117,120 @@ namespace Antlr4.Runtime.Dfa
|
|||
}
|
||||
}
|
||||
|
||||
public DFAState(ATNConfigSet configs, int minSymbol, int maxSymbol)
|
||||
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.minSymbol = minSymbol;
|
||||
this.maxSymbol = maxSymbol;
|
||||
this.edges = emptyEdges;
|
||||
this.contextEdges = emptyContextEdges;
|
||||
}
|
||||
|
||||
public bool IsContextSensitive
|
||||
{
|
||||
get
|
||||
{
|
||||
return contextEdges != null;
|
||||
return contextSymbols != null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsContextSymbol(int symbol)
|
||||
{
|
||||
if (!IsContextSensitive || symbol < minSymbol)
|
||||
if (!IsContextSensitive || symbol < edges.minIndex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return contextSymbols.Get(symbol - minSymbol);
|
||||
return contextSymbols.Get(symbol - edges.minIndex);
|
||||
}
|
||||
|
||||
public void SetContextSymbol(int symbol)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(IsContextSensitive);
|
||||
if (symbol < minSymbol)
|
||||
if (symbol < edges.minIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
contextSymbols.Set(symbol - minSymbol);
|
||||
contextSymbols.Set(symbol - edges.minIndex);
|
||||
}
|
||||
|
||||
public virtual void SetContextSensitive(ATN atn)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(!configs.IsOutermostConfigSet);
|
||||
if (IsContextSensitive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
lock (this)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(!configs.IsOutermostConfigSet);
|
||||
if (IsContextSensitive)
|
||||
if (contextSymbols == null)
|
||||
{
|
||||
return;
|
||||
contextSymbols = new BitSet();
|
||||
}
|
||||
contextSymbols = new BitSet();
|
||||
contextEdges = new SingletonEdgeMap<DFAState>(-1, atn.states.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
public AcceptStateInfo AcceptStateInfo
|
||||
{
|
||||
get
|
||||
{
|
||||
return acceptStateInfo;
|
||||
}
|
||||
set
|
||||
{
|
||||
AcceptStateInfo acceptStateInfo = value;
|
||||
this.acceptStateInfo = acceptStateInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAcceptState
|
||||
{
|
||||
get
|
||||
{
|
||||
return acceptStateInfo != null;
|
||||
}
|
||||
}
|
||||
|
||||
public int Prediction
|
||||
{
|
||||
get
|
||||
{
|
||||
if (acceptStateInfo == null)
|
||||
{
|
||||
return ATN.InvalidAltNumber;
|
||||
}
|
||||
return acceptStateInfo.Prediction;
|
||||
}
|
||||
}
|
||||
|
||||
public LexerActionExecutor LexerActionExecutor
|
||||
{
|
||||
get
|
||||
{
|
||||
if (acceptStateInfo == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return acceptStateInfo.LexerActionExecutor;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual DFAState GetTarget(int symbol)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (edges == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return edges[symbol];
|
||||
}
|
||||
return edges[symbol];
|
||||
}
|
||||
|
||||
public virtual void SetTarget(int symbol, DFAState target)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (edges == null)
|
||||
{
|
||||
edges = new SingletonEdgeMap<DFAState>(minSymbol, maxSymbol);
|
||||
}
|
||||
edges = edges.Put(symbol, target);
|
||||
}
|
||||
edges = edges.Put(symbol, target);
|
||||
}
|
||||
|
||||
public virtual IDictionary<int, DFAState> EdgeMap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (edges == null)
|
||||
{
|
||||
return Antlr4.Runtime.Sharpen.Collections.EmptyMap();
|
||||
}
|
||||
return edges.ToMap();
|
||||
}
|
||||
}
|
||||
|
@ -222,10 +239,6 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
lock (this)
|
||||
{
|
||||
if (contextEdges == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (invokingState == PredictionContext.EmptyFullStateKey)
|
||||
{
|
||||
invokingState = -1;
|
||||
|
@ -238,7 +251,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
lock (this)
|
||||
{
|
||||
if (contextEdges == null)
|
||||
if (!IsContextSensitive)
|
||||
{
|
||||
throw new InvalidOperationException("The state is not context sensitive.");
|
||||
}
|
||||
|
@ -254,10 +267,6 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
get
|
||||
{
|
||||
if (contextEdges == null)
|
||||
{
|
||||
return Antlr4.Runtime.Sharpen.Collections.EmptyMap();
|
||||
}
|
||||
IDictionary<int, DFAState> map = contextEdges.ToMap();
|
||||
if (map.ContainsKey(-1))
|
||||
{
|
||||
|
@ -327,7 +336,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.Append(stateNumber).Append(":").Append(configs);
|
||||
if (isAcceptState)
|
||||
if (IsAcceptState)
|
||||
{
|
||||
buf.Append("=>");
|
||||
if (predicates != null)
|
||||
|
@ -336,7 +345,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
}
|
||||
else
|
||||
{
|
||||
buf.Append(prediction);
|
||||
buf.Append(Prediction);
|
||||
}
|
||||
}
|
||||
return buf.ToString();
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* [The "BSD license"]
|
||||
* Copyright (c) 2013 Terence Parr
|
||||
* Copyright (c) 2013 Sam Harwell
|
||||
* 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.Collections.Generic;
|
||||
using Antlr4.Runtime.Dfa;
|
||||
using Antlr4.Runtime.Sharpen;
|
||||
|
||||
namespace Antlr4.Runtime.Dfa
|
||||
{
|
||||
/// <summary>
|
||||
/// This implementation of
|
||||
/// <see cref="AbstractEdgeMap{T}"/>
|
||||
/// represents an empty edge map.
|
||||
/// </summary>
|
||||
/// <author>Sam Harwell</author>
|
||||
public sealed class EmptyEdgeMap<T> : AbstractEdgeMap<T>
|
||||
{
|
||||
public EmptyEdgeMap(int minIndex, int maxIndex)
|
||||
: base(minIndex, maxIndex)
|
||||
{
|
||||
}
|
||||
|
||||
public override AbstractEdgeMap<T> Put(int key, T value)
|
||||
{
|
||||
if (value == null || key < minIndex || key > maxIndex)
|
||||
{
|
||||
// remains empty
|
||||
return this;
|
||||
}
|
||||
return new SingletonEdgeMap<T>(minIndex, maxIndex, key, value);
|
||||
}
|
||||
|
||||
public override AbstractEdgeMap<T> Clear()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public override AbstractEdgeMap<T> Remove(int key)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
public override int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsEmpty
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ContainsKey(int key)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override T this[int key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public override IDictionary<int, T> ToMap()
|
||||
{
|
||||
return Antlr4.Runtime.Sharpen.Collections.EmptyMap();
|
||||
}
|
||||
|
||||
public override HashSet<KeyValuePair<int, T>> EntrySet()
|
||||
{
|
||||
return Antlr4.Runtime.Sharpen.Collections.EmptyMap<int, T>().EntrySet();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -27,6 +27,7 @@
|
|||
* (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 Antlr4.Runtime;
|
||||
using Antlr4.Runtime.Dfa;
|
||||
using Antlr4.Runtime.Misc;
|
||||
using Antlr4.Runtime.Sharpen;
|
||||
|
@ -36,7 +37,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
public class LexerDFASerializer : DFASerializer
|
||||
{
|
||||
public LexerDFASerializer(DFA dfa)
|
||||
: base(dfa, (string[])null)
|
||||
: base(dfa, Vocabulary.EmptyVocabulary)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -34,19 +34,12 @@ using Antlr4.Runtime.Sharpen;
|
|||
namespace Antlr4.Runtime.Dfa
|
||||
{
|
||||
/// <author>Sam Harwell</author>
|
||||
public class SingletonEdgeMap<T> : AbstractEdgeMap<T>
|
||||
public sealed class SingletonEdgeMap<T> : AbstractEdgeMap<T>
|
||||
{
|
||||
private readonly int key;
|
||||
|
||||
private readonly T value;
|
||||
|
||||
public SingletonEdgeMap(int minIndex, int maxIndex)
|
||||
: base(minIndex, maxIndex)
|
||||
{
|
||||
this.key = 0;
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
public SingletonEdgeMap(int minIndex, int maxIndex, int key, T value)
|
||||
: base(minIndex, maxIndex)
|
||||
{
|
||||
|
@ -62,7 +55,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
}
|
||||
}
|
||||
|
||||
public virtual int Key
|
||||
public int Key
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -70,7 +63,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
}
|
||||
}
|
||||
|
||||
public virtual T Value
|
||||
public T Value
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -141,7 +134,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
if (key == this.key && this.value != null)
|
||||
{
|
||||
return new Antlr4.Runtime.Dfa.SingletonEdgeMap<T>(minIndex, maxIndex);
|
||||
return new EmptyEdgeMap<T>(minIndex, maxIndex);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -150,7 +143,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
if (this.value != null)
|
||||
{
|
||||
return new Antlr4.Runtime.Dfa.SingletonEdgeMap<T>(minIndex, maxIndex);
|
||||
return new EmptyEdgeMap<T>(minIndex, maxIndex);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ using Antlr4.Runtime.Sharpen;
|
|||
namespace Antlr4.Runtime.Dfa
|
||||
{
|
||||
/// <author>Sam Harwell</author>
|
||||
public class SparseEdgeMap<T> : AbstractEdgeMap<T>
|
||||
public sealed class SparseEdgeMap<T> : AbstractEdgeMap<T>
|
||||
{
|
||||
private const int DefaultMaxSize = 5;
|
||||
|
||||
|
@ -58,16 +58,19 @@ namespace Antlr4.Runtime.Dfa
|
|||
private SparseEdgeMap(Antlr4.Runtime.Dfa.SparseEdgeMap<T> map, int maxSparseSize)
|
||||
: base(map.minIndex, map.maxIndex)
|
||||
{
|
||||
if (maxSparseSize < map.values.Count)
|
||||
lock (map)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
if (maxSparseSize < map.values.Count)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
keys = Arrays.CopyOf(map.keys, maxSparseSize);
|
||||
values = new List<T>(maxSparseSize);
|
||||
Sharpen.Collections.AddAll(values, map.values);
|
||||
}
|
||||
keys = Arrays.CopyOf(map.keys, maxSparseSize);
|
||||
values = new List<T>(maxSparseSize);
|
||||
Sharpen.Collections.AddAll(values, map.values);
|
||||
}
|
||||
|
||||
public virtual int[] Keys
|
||||
public int[] Keys
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -75,7 +78,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
}
|
||||
}
|
||||
|
||||
public virtual IList<T> Values
|
||||
public IList<T> Values
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -83,7 +86,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
}
|
||||
}
|
||||
|
||||
public virtual int MaxSparseSize
|
||||
public int MaxSparseSize
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -116,6 +119,9 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
get
|
||||
{
|
||||
// Special property of this collection: values are only even added to
|
||||
// the end, else a new object is returned from put(). Therefore no lock
|
||||
// is required in this method.
|
||||
int index = System.Array.BinarySearch(keys, 0, Count, key);
|
||||
if (index < 0)
|
||||
{
|
||||
|
@ -135,7 +141,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
return ((Antlr4.Runtime.Dfa.SparseEdgeMap<T>)Remove(key));
|
||||
}
|
||||
lock (values)
|
||||
lock (this)
|
||||
{
|
||||
int index = System.Array.BinarySearch(keys, 0, Count, key);
|
||||
if (index >= 0)
|
||||
|
@ -166,7 +172,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
else
|
||||
{
|
||||
Antlr4.Runtime.Dfa.SparseEdgeMap<T> resized = new Antlr4.Runtime.Dfa.SparseEdgeMap<T>(this, desiredSize);
|
||||
System.Array.Copy(resized.keys, insertIndex, resized.keys, insertIndex + 1, resized.keys.Length - insertIndex - 1);
|
||||
System.Array.Copy(resized.keys, insertIndex, resized.keys, insertIndex + 1, Count - insertIndex);
|
||||
resized.keys[insertIndex] = key;
|
||||
resized.values.Add(insertIndex, value);
|
||||
return resized;
|
||||
|
@ -176,20 +182,18 @@ namespace Antlr4.Runtime.Dfa
|
|||
|
||||
public override AbstractEdgeMap<T> Remove(int key)
|
||||
{
|
||||
int index = System.Array.BinarySearch(keys, 0, Count, key);
|
||||
if (index < 0)
|
||||
lock (this)
|
||||
{
|
||||
return this;
|
||||
int index = System.Array.BinarySearch(keys, 0, Count, key);
|
||||
if (index < 0)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
Antlr4.Runtime.Dfa.SparseEdgeMap<T> result = new Antlr4.Runtime.Dfa.SparseEdgeMap<T>(this, MaxSparseSize);
|
||||
System.Array.Copy(result.keys, index + 1, result.keys, index, Count - index - 1);
|
||||
result.values.RemoveAt(index);
|
||||
return result;
|
||||
}
|
||||
if (index == values.Count - 1)
|
||||
{
|
||||
values.RemoveAt(index);
|
||||
return this;
|
||||
}
|
||||
Antlr4.Runtime.Dfa.SparseEdgeMap<T> result = new Antlr4.Runtime.Dfa.SparseEdgeMap<T>(this, MaxSparseSize);
|
||||
System.Array.Copy(result.keys, index + 1, result.keys, index, Count - index - 1);
|
||||
result.values.RemoveAt(index);
|
||||
return result;
|
||||
}
|
||||
|
||||
public override AbstractEdgeMap<T> Clear()
|
||||
|
@ -198,9 +202,7 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
return this;
|
||||
}
|
||||
Antlr4.Runtime.Dfa.SparseEdgeMap<T> result = new Antlr4.Runtime.Dfa.SparseEdgeMap<T>(this, MaxSparseSize);
|
||||
result.values.Clear();
|
||||
return result;
|
||||
return new EmptyEdgeMap<T>(minIndex, maxIndex);
|
||||
}
|
||||
|
||||
public override IDictionary<int, T> ToMap()
|
||||
|
@ -209,12 +211,15 @@ namespace Antlr4.Runtime.Dfa
|
|||
{
|
||||
return Antlr4.Runtime.Sharpen.Collections.EmptyMap();
|
||||
}
|
||||
IDictionary<int, T> result = new LinkedHashMap<int, T>();
|
||||
for (int i = 0; i < Count; i++)
|
||||
lock (this)
|
||||
{
|
||||
result.Put(keys[i], values[i]);
|
||||
IDictionary<int, T> result = new LinkedHashMap<int, T>();
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
result.Put(keys[i], values[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -182,5 +182,25 @@ namespace Antlr4.Runtime
|
|||
/// by parser.
|
||||
/// </remarks>
|
||||
public const int HiddenChannel = 1;
|
||||
|
||||
/// <summary>
|
||||
/// This is the minimum constant value which can be assigned to a
|
||||
/// user-defined token channel.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the minimum constant value which can be assigned to a
|
||||
/// user-defined token channel.
|
||||
/// <p>
|
||||
/// The non-negative numbers less than
|
||||
/// <see cref="MinUserChannelValue"/>
|
||||
/// are
|
||||
/// assigned to the predefined channels
|
||||
/// <see cref="DefaultChannel"/>
|
||||
/// and
|
||||
/// <see cref="HiddenChannel"/>
|
||||
/// .</p>
|
||||
/// </remarks>
|
||||
/// <seealso cref="Channel()"/>
|
||||
public const int MinUserChannelValue = 2;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* [The "BSD license"]
|
||||
* Copyright (c) 2013 Terence Parr
|
||||
* Copyright (c) 2013 Sam Harwell
|
||||
* 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 Antlr4.Runtime;
|
||||
using Antlr4.Runtime.Misc;
|
||||
using Antlr4.Runtime.Sharpen;
|
||||
|
||||
namespace Antlr4.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface provides information about the vocabulary used by a
|
||||
/// recognizer.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This interface provides information about the vocabulary used by a
|
||||
/// recognizer.
|
||||
/// </remarks>
|
||||
/// <seealso cref="Recognizer{Symbol, ATNInterpreter}.Vocabulary()"/>
|
||||
/// <author>Sam Harwell</author>
|
||||
public interface IVocabulary
|
||||
{
|
||||
/// <summary>Gets the string literal associated with a token type.</summary>
|
||||
/// <remarks>
|
||||
/// Gets the string literal associated with a token type. The string returned
|
||||
/// by this method, when not
|
||||
/// <see langword="null"/>
|
||||
/// , can be used unaltered in a parser
|
||||
/// grammar to represent this token type.
|
||||
/// <p>The following table shows examples of lexer rules and the literal
|
||||
/// names assigned to the corresponding token types.</p>
|
||||
/// <table>
|
||||
/// <tr>
|
||||
/// <th>Rule</th>
|
||||
/// <th>Literal Name</th>
|
||||
/// <th>Java String Literal</th>
|
||||
/// </tr>
|
||||
/// <tr>
|
||||
/// <td>
|
||||
/// <c>THIS : 'this';</c>
|
||||
/// </td>
|
||||
/// <td>
|
||||
/// <c>'this'</c>
|
||||
/// </td>
|
||||
/// <td>
|
||||
/// <c>"'this'"</c>
|
||||
/// </td>
|
||||
/// </tr>
|
||||
/// <tr>
|
||||
/// <td>
|
||||
/// <c>SQUOTE : '\'';</c>
|
||||
/// </td>
|
||||
/// <td>
|
||||
/// <c>'\''</c>
|
||||
/// </td>
|
||||
/// <td>
|
||||
/// <c>"'\\''"</c>
|
||||
/// </td>
|
||||
/// </tr>
|
||||
/// <tr>
|
||||
/// <td>
|
||||
/// <c>ID : [A-Z]+;</c>
|
||||
/// </td>
|
||||
/// <td>n/a</td>
|
||||
/// <td>
|
||||
/// <see langword="null"/>
|
||||
/// </td>
|
||||
/// </tr>
|
||||
/// </table>
|
||||
/// </remarks>
|
||||
/// <param name="tokenType">The token type.</param>
|
||||
/// <returns>
|
||||
/// The string literal associated with the specified token type, or
|
||||
/// <see langword="null"/>
|
||||
/// if no string literal is associated with the type.
|
||||
/// </returns>
|
||||
[Nullable]
|
||||
string GetLiteralName(int tokenType);
|
||||
|
||||
/// <summary>Gets the symbolic name associated with a token type.</summary>
|
||||
/// <remarks>
|
||||
/// Gets the symbolic name associated with a token type. The string returned
|
||||
/// by this method, when not
|
||||
/// <see langword="null"/>
|
||||
/// , can be used unaltered in a parser
|
||||
/// grammar to represent this token type.
|
||||
/// <p>This method supports token types defined by any of the following
|
||||
/// methods:</p>
|
||||
/// <ul>
|
||||
/// <li>Tokens created by lexer rules.</li>
|
||||
/// <li>Tokens defined in a
|
||||
/// <c/>
|
||||
/// tokens
|
||||
/// block in a lexer or parser
|
||||
/// grammar.</li>
|
||||
/// <li>The implicitly defined
|
||||
/// <c>EOF</c>
|
||||
/// token, which has the token type
|
||||
/// <see cref="IToken.Eof"/>
|
||||
/// .</li>
|
||||
/// </ul>
|
||||
/// <p>The following table shows examples of lexer rules and the literal
|
||||
/// names assigned to the corresponding token types.</p>
|
||||
/// <table>
|
||||
/// <tr>
|
||||
/// <th>Rule</th>
|
||||
/// <th>Symbolic Name</th>
|
||||
/// </tr>
|
||||
/// <tr>
|
||||
/// <td>
|
||||
/// <c>THIS : 'this';</c>
|
||||
/// </td>
|
||||
/// <td>
|
||||
/// <c>THIS</c>
|
||||
/// </td>
|
||||
/// </tr>
|
||||
/// <tr>
|
||||
/// <td>
|
||||
/// <c>SQUOTE : '\'';</c>
|
||||
/// </td>
|
||||
/// <td>
|
||||
/// <c>SQUOTE</c>
|
||||
/// </td>
|
||||
/// </tr>
|
||||
/// <tr>
|
||||
/// <td>
|
||||
/// <c>ID : [A-Z]+;</c>
|
||||
/// </td>
|
||||
/// <td>
|
||||
/// <c>ID</c>
|
||||
/// </td>
|
||||
/// </tr>
|
||||
/// </table>
|
||||
/// </remarks>
|
||||
/// <param name="tokenType">The token type.</param>
|
||||
/// <returns>
|
||||
/// The symbolic name associated with the specified token type, or
|
||||
/// <see langword="null"/>
|
||||
/// if no symbolic name is associated with the type.
|
||||
/// </returns>
|
||||
[Nullable]
|
||||
string GetSymbolicName(int tokenType);
|
||||
|
||||
/// <summary>Gets the display name of a token type.</summary>
|
||||
/// <remarks>
|
||||
/// Gets the display name of a token type.
|
||||
/// <p>ANTLR provides a default implementation of this method, but
|
||||
/// applications are free to override the behavior in any manner which makes
|
||||
/// sense for the application. The default implementation returns the first
|
||||
/// result from the following list which produces a non-
|
||||
/// <see langword="null"/>
|
||||
/// result.</p>
|
||||
/// <ol>
|
||||
/// <li>The result of
|
||||
/// <see cref="GetLiteralName(int)"/>
|
||||
/// </li>
|
||||
/// <li>The result of
|
||||
/// <see cref="GetSymbolicName(int)"/>
|
||||
/// </li>
|
||||
/// <li>The result of
|
||||
/// <see cref="int.ToString()"/>
|
||||
/// </li>
|
||||
/// </ol>
|
||||
/// </remarks>
|
||||
/// <param name="tokenType">The token type.</param>
|
||||
/// <returns>
|
||||
/// The display name of the token type, for use in error reporting or
|
||||
/// other user-visible messages which reference specific token types.
|
||||
/// </returns>
|
||||
[NotNull]
|
||||
string GetDisplayName(int tokenType);
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Antlr4.Runtime;
|
||||
using Antlr4.Runtime.Atn;
|
||||
using Antlr4.Runtime.Misc;
|
||||
using Antlr4.Runtime.Sharpen;
|
||||
|
||||
namespace Antlr4.Runtime
|
||||
|
@ -41,13 +42,23 @@ namespace Antlr4.Runtime
|
|||
|
||||
protected internal readonly ATN atn;
|
||||
|
||||
[Obsolete]
|
||||
protected internal readonly string[] tokenNames;
|
||||
|
||||
protected internal readonly string[] ruleNames;
|
||||
|
||||
protected internal readonly string[] modeNames;
|
||||
|
||||
[NotNull]
|
||||
private readonly IVocabulary vocabulary;
|
||||
|
||||
[Obsolete]
|
||||
public LexerInterpreter(string grammarFileName, ICollection<string> tokenNames, ICollection<string> ruleNames, ICollection<string> modeNames, ATN atn, ICharStream input)
|
||||
: this(grammarFileName, Antlr4.Runtime.Vocabulary.FromTokenNames(Sharpen.Collections.ToArray(tokenNames, new string[tokenNames.Count])), ruleNames, modeNames, atn, input)
|
||||
{
|
||||
}
|
||||
|
||||
public LexerInterpreter(string grammarFileName, IVocabulary vocabulary, ICollection<string> ruleNames, ICollection<string> modeNames, ATN atn, ICharStream input)
|
||||
: base(input)
|
||||
{
|
||||
if (atn.grammarType != ATNType.Lexer)
|
||||
|
@ -56,9 +67,14 @@ namespace Antlr4.Runtime
|
|||
}
|
||||
this.grammarFileName = grammarFileName;
|
||||
this.atn = atn;
|
||||
this.tokenNames = Sharpen.Collections.ToArray(tokenNames, new string[tokenNames.Count]);
|
||||
this.tokenNames = new string[atn.maxTokenType];
|
||||
for (int i = 0; i < tokenNames.Length; i++)
|
||||
{
|
||||
tokenNames[i] = vocabulary.GetDisplayName(i);
|
||||
}
|
||||
this.ruleNames = Sharpen.Collections.ToArray(ruleNames, new string[ruleNames.Count]);
|
||||
this.modeNames = Sharpen.Collections.ToArray(modeNames, new string[modeNames.Count]);
|
||||
this.vocabulary = vocabulary;
|
||||
this._interp = new LexerATNSimulator(this, atn);
|
||||
}
|
||||
|
||||
|
@ -101,5 +117,17 @@ namespace Antlr4.Runtime
|
|||
return modeNames;
|
||||
}
|
||||
}
|
||||
|
||||
public override IVocabulary Vocabulary
|
||||
{
|
||||
get
|
||||
{
|
||||
if (vocabulary != null)
|
||||
{
|
||||
return vocabulary;
|
||||
}
|
||||
return base.Vocabulary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -703,7 +703,13 @@ namespace Antlr4.Runtime.Misc
|
|||
return buf.ToString();
|
||||
}
|
||||
|
||||
[System.ObsoleteAttribute(@"Use ToString(Antlr4.Runtime.IVocabulary) instead.")]
|
||||
public virtual string ToString(string[] tokenNames)
|
||||
{
|
||||
return ToString(Vocabulary.FromTokenNames(tokenNames));
|
||||
}
|
||||
|
||||
public virtual string ToString(IVocabulary vocabulary)
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if (this.intervals == null || this.intervals.IsEmpty())
|
||||
|
@ -722,7 +728,7 @@ namespace Antlr4.Runtime.Misc
|
|||
int b = I.b;
|
||||
if (a == b)
|
||||
{
|
||||
buf.Append(ElementName(tokenNames, a));
|
||||
buf.Append(ElementName(vocabulary, a));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -732,7 +738,7 @@ namespace Antlr4.Runtime.Misc
|
|||
{
|
||||
buf.Append(", ");
|
||||
}
|
||||
buf.Append(ElementName(tokenNames, i));
|
||||
buf.Append(ElementName(vocabulary, i));
|
||||
}
|
||||
}
|
||||
if (iter.HasNext())
|
||||
|
@ -747,7 +753,14 @@ namespace Antlr4.Runtime.Misc
|
|||
return buf.ToString();
|
||||
}
|
||||
|
||||
[System.ObsoleteAttribute(@"Use ElementName(Antlr4.Runtime.IVocabulary, int) instead.")]
|
||||
protected internal virtual string ElementName(string[] tokenNames, int a)
|
||||
{
|
||||
return ElementName(Vocabulary.FromTokenNames(tokenNames), a);
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
protected internal virtual string ElementName(IVocabulary vocabulary, int a)
|
||||
{
|
||||
if (a == TokenConstants.Eof)
|
||||
{
|
||||
|
@ -761,7 +774,7 @@ namespace Antlr4.Runtime.Misc
|
|||
}
|
||||
else
|
||||
{
|
||||
return tokenNames[a];
|
||||
return vocabulary.GetDisplayName(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ using Antlr4.Runtime.Misc;
|
|||
using Antlr4.Runtime.Sharpen;
|
||||
using Antlr4.Runtime.Sharpen.Annotation;
|
||||
using Javax.Annotation.Processing;
|
||||
using Javax.Lang.Model;
|
||||
using Javax.Lang.Model.Element;
|
||||
using Javax.Lang.Model.Type;
|
||||
using Javax.Tools;
|
||||
|
@ -59,6 +60,27 @@ namespace Antlr4.Runtime.Misc
|
|||
{
|
||||
}
|
||||
|
||||
public override SourceVersion GetSupportedSourceVersion()
|
||||
{
|
||||
SourceVersion latestSupported = SourceVersion.LatestSupported();
|
||||
if ((int)(latestSupported) <= 6)
|
||||
{
|
||||
return SourceVersion.Release6;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((int)(latestSupported) <= 8)
|
||||
{
|
||||
return latestSupported;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this annotation processor is tested through Java 8
|
||||
return SourceVersion.Values()[8];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Process<_T0>(HashSet<_T0> annotations, IRoundEnvironment roundEnv)
|
||||
{
|
||||
if (!CheckClassNameConstants())
|
||||
|
|
|
@ -1134,7 +1134,7 @@ namespace Antlr4.Runtime
|
|||
for (int d = 0; d < _interp.atn.decisionToDFA.Length; d++)
|
||||
{
|
||||
DFA dfa = _interp.atn.decisionToDFA[d];
|
||||
s.Add(dfa.ToString(TokenNames, RuleNames));
|
||||
s.Add(dfa.ToString(Vocabulary, RuleNames));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
@ -1154,7 +1154,7 @@ namespace Antlr4.Runtime
|
|||
System.Console.Out.WriteLine();
|
||||
}
|
||||
System.Console.Out.WriteLine("Decision " + dfa.decision + ":");
|
||||
System.Console.Out.Write(dfa.ToString(TokenNames, RuleNames));
|
||||
System.Console.Out.Write(dfa.ToString(Vocabulary, RuleNames));
|
||||
seenOne = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using Antlr4.Runtime;
|
||||
using Antlr4.Runtime.Atn;
|
||||
using Antlr4.Runtime.Misc;
|
||||
using Antlr4.Runtime.Sharpen;
|
||||
|
||||
namespace Antlr4.Runtime
|
||||
|
@ -58,19 +59,34 @@ namespace Antlr4.Runtime
|
|||
|
||||
protected internal readonly BitSet pushRecursionContextStates;
|
||||
|
||||
[Obsolete]
|
||||
protected internal readonly string[] tokenNames;
|
||||
|
||||
protected internal readonly string[] ruleNames;
|
||||
|
||||
[NotNull]
|
||||
private readonly IVocabulary vocabulary;
|
||||
|
||||
protected internal readonly Stack<Tuple<ParserRuleContext, int>> _parentContextStack = new Stack<Tuple<ParserRuleContext, int>>();
|
||||
|
||||
[System.ObsoleteAttribute(@"Use ParserInterpreter(string, IVocabulary, System.Collections.Generic.ICollection{E}, Antlr4.Runtime.Atn.ATN, ITokenStream) instead.")]
|
||||
public ParserInterpreter(string grammarFileName, ICollection<string> tokenNames, ICollection<string> ruleNames, ATN atn, ITokenStream input)
|
||||
: this(grammarFileName, Antlr4.Runtime.Vocabulary.FromTokenNames(Sharpen.Collections.ToArray(tokenNames, new string[tokenNames.Count])), ruleNames, atn, input)
|
||||
{
|
||||
}
|
||||
|
||||
public ParserInterpreter(string grammarFileName, IVocabulary vocabulary, ICollection<string> ruleNames, ATN atn, ITokenStream input)
|
||||
: base(input)
|
||||
{
|
||||
this.grammarFileName = grammarFileName;
|
||||
this.atn = atn;
|
||||
this.tokenNames = Sharpen.Collections.ToArray(tokenNames, new string[tokenNames.Count]);
|
||||
this.tokenNames = new string[atn.maxTokenType];
|
||||
for (int i = 0; i < tokenNames.Length; i++)
|
||||
{
|
||||
tokenNames[i] = vocabulary.GetDisplayName(i);
|
||||
}
|
||||
this.ruleNames = Sharpen.Collections.ToArray(ruleNames, new string[ruleNames.Count]);
|
||||
this.vocabulary = vocabulary;
|
||||
// identify the ATN states where pushNewRecursionContext must be called
|
||||
this.pushRecursionContextStates = new BitSet(atn.states.Count);
|
||||
foreach (ATNState state in atn.states)
|
||||
|
@ -104,6 +120,14 @@ namespace Antlr4.Runtime
|
|||
}
|
||||
}
|
||||
|
||||
public override IVocabulary Vocabulary
|
||||
{
|
||||
get
|
||||
{
|
||||
return vocabulary;
|
||||
}
|
||||
}
|
||||
|
||||
public override string[] RuleNames
|
||||
{
|
||||
get
|
||||
|
|
|
@ -41,13 +41,13 @@ namespace Antlr4.Runtime
|
|||
{
|
||||
public const int Eof = -1;
|
||||
|
||||
private static readonly IDictionary<string[], IDictionary<string, int>> tokenTypeMapCache = new WeakHashMap<string[], IDictionary<string, int>>();
|
||||
private static readonly IDictionary<IVocabulary, IDictionary<string, int>> tokenTypeMapCache = new WeakHashMap<IVocabulary, IDictionary<string, int>>();
|
||||
|
||||
private static readonly IDictionary<string[], IDictionary<string, int>> ruleIndexMapCache = new WeakHashMap<string[], IDictionary<string, int>>();
|
||||
|
||||
private sealed class _CopyOnWriteArrayList_59 : CopyOnWriteArrayList<IAntlrErrorListener<Symbol>>
|
||||
private sealed class _CopyOnWriteArrayList_60 : CopyOnWriteArrayList<IAntlrErrorListener<Symbol>>
|
||||
{
|
||||
public _CopyOnWriteArrayList_59()
|
||||
public _CopyOnWriteArrayList_60()
|
||||
{
|
||||
{
|
||||
this.Add(ConsoleErrorListener.Instance);
|
||||
|
@ -56,7 +56,7 @@ namespace Antlr4.Runtime
|
|||
}
|
||||
|
||||
[NotNull]
|
||||
private IList<IAntlrErrorListener<Symbol>> _listeners = new _CopyOnWriteArrayList_59();
|
||||
private IList<IAntlrErrorListener<Symbol>> _listeners = new _CopyOnWriteArrayList_60();
|
||||
|
||||
protected internal ATNInterpreter _interp;
|
||||
|
||||
|
@ -71,6 +71,7 @@ namespace Antlr4.Runtime
|
|||
/// error reporting. The generated parsers implement a method
|
||||
/// that overrides this to point to their String[] tokenNames.
|
||||
/// </remarks>
|
||||
[System.ObsoleteAttribute(@"Use Recognizer{Symbol, ATNInterpreter}.Vocabulary() instead.")]
|
||||
public abstract string[] TokenNames
|
||||
{
|
||||
get;
|
||||
|
@ -81,6 +82,22 @@ namespace Antlr4.Runtime
|
|||
get;
|
||||
}
|
||||
|
||||
/// <summary>Get the vocabulary used by the recognizer.</summary>
|
||||
/// <remarks>Get the vocabulary used by the recognizer.</remarks>
|
||||
/// <returns>
|
||||
/// A
|
||||
/// <see cref="IVocabulary"/>
|
||||
/// instance providing information about the
|
||||
/// vocabulary used by the grammar.
|
||||
/// </returns>
|
||||
public virtual IVocabulary Vocabulary
|
||||
{
|
||||
get
|
||||
{
|
||||
return Antlr4.Runtime.Vocabulary.FromTokenNames(TokenNames);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Get a map from token names to token types.</summary>
|
||||
/// <remarks>
|
||||
/// Get a map from token names to token types.
|
||||
|
@ -90,20 +107,29 @@ namespace Antlr4.Runtime
|
|||
{
|
||||
get
|
||||
{
|
||||
string[] tokenNames = TokenNames;
|
||||
if (tokenNames == null)
|
||||
{
|
||||
throw new NotSupportedException("The current recognizer does not provide a list of token names.");
|
||||
}
|
||||
IVocabulary vocabulary = Vocabulary;
|
||||
lock (tokenTypeMapCache)
|
||||
{
|
||||
IDictionary<string, int> result = tokenTypeMapCache.Get(tokenNames);
|
||||
IDictionary<string, int> result = tokenTypeMapCache.Get(vocabulary);
|
||||
if (result == null)
|
||||
{
|
||||
result = Utils.ToMap(tokenNames);
|
||||
result = new Dictionary<string, int>();
|
||||
for (int i = 0; i < Atn.maxTokenType; i++)
|
||||
{
|
||||
string literalName = vocabulary.GetLiteralName(i);
|
||||
if (literalName != null)
|
||||
{
|
||||
result.Put(literalName, i);
|
||||
}
|
||||
string symbolicName = vocabulary.GetSymbolicName(i);
|
||||
if (symbolicName != null)
|
||||
{
|
||||
result.Put(symbolicName, i);
|
||||
}
|
||||
}
|
||||
result.Put("EOF", TokenConstants.Eof);
|
||||
result = Antlr4.Runtime.Sharpen.Collections.UnmodifiableMap(result);
|
||||
tokenTypeMapCache.Put(tokenNames, result);
|
||||
tokenTypeMapCache.Put(vocabulary, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -274,7 +274,7 @@ namespace Antlr4.Runtime
|
|||
/// <remarks>
|
||||
/// Rollback the instruction stream for a program so that
|
||||
/// the indicated instruction (via instructionIndex) is no
|
||||
/// longer in the stream. UNTESTED!
|
||||
/// longer in the stream. UNTESTED!
|
||||
/// </remarks>
|
||||
public virtual void Rollback(string programName, int instructionIndex)
|
||||
{
|
||||
|
@ -549,8 +549,8 @@ namespace Antlr4.Runtime
|
|||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We need to combine operations and report invalid operations (like
|
||||
/// overlapping replaces that are not completed nested). Inserts to
|
||||
/// same index need to be combined etc... Here are the cases:
|
||||
/// overlapping replaces that are not completed nested). Inserts to
|
||||
/// same index need to be combined etc... Here are the cases:
|
||||
/// I.i.u I.j.v leave alone, nonoverlapping
|
||||
/// I.i.u I.i.v combine: Iivu
|
||||
/// R.i-j.u R.x-y.v | i-j in x-y delete first R
|
||||
|
@ -567,7 +567,7 @@ namespace Antlr4.Runtime
|
|||
/// R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping
|
||||
/// I.i.u = insert u before op @ index i
|
||||
/// R.x-y.u = replace x-y indexed tokens with u
|
||||
/// First we need to examine replaces. For any replace op:
|
||||
/// First we need to examine replaces. For any replace op:
|
||||
/// 1. wipe out any insertions before op within that range.
|
||||
/// 2. Drop any replace op before that is contained completely within
|
||||
/// that range.
|
||||
|
@ -580,7 +580,7 @@ namespace Antlr4.Runtime
|
|||
/// Don't actually delete; make op null in list. Easier to walk list.
|
||||
/// Later we can throw as we add to index → op map.
|
||||
/// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the
|
||||
/// inserted stuff would be before the replace range. But, if you
|
||||
/// inserted stuff would be before the replace range. But, if you
|
||||
/// add tokens in front of a method body '{' and then delete the method
|
||||
/// body, I think the stuff before the '{' you added should disappear too.
|
||||
/// Return a map from token index to operation.
|
||||
|
|
|
@ -326,7 +326,7 @@ namespace Antlr4.Runtime.Tree.Pattern
|
|||
IList<IToken> tokenList = Tokenize(pattern);
|
||||
ListTokenSource tokenSrc = new ListTokenSource(tokenList);
|
||||
CommonTokenStream tokens = new CommonTokenStream(tokenSrc);
|
||||
ParserInterpreter parserInterp = new ParserInterpreter(parser.GrammarFileName, Arrays.AsList(parser.TokenNames), Arrays.AsList(parser.RuleNames), parser.GetATNWithBypassAlts(), tokens);
|
||||
ParserInterpreter parserInterp = new ParserInterpreter(parser.GrammarFileName, parser.Vocabulary, Arrays.AsList(parser.RuleNames), parser.GetATNWithBypassAlts(), tokens);
|
||||
IParseTree tree = null;
|
||||
try
|
||||
{
|
||||
|
|
|
@ -411,6 +411,10 @@ namespace Antlr4.Runtime
|
|||
{
|
||||
get
|
||||
{
|
||||
if (name == null || name.IsEmpty())
|
||||
{
|
||||
return IntStreamConstants.UnknownSourceName;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
/*
|
||||
* [The "BSD license"]
|
||||
* Copyright (c) 2013 Terence Parr
|
||||
* Copyright (c) 2013 Sam Harwell
|
||||
* 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 Antlr4.Runtime;
|
||||
using Antlr4.Runtime.Misc;
|
||||
using Antlr4.Runtime.Sharpen;
|
||||
|
||||
namespace Antlr4.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// This class provides a default implementation of the
|
||||
/// <see cref="IVocabulary"/>
|
||||
/// interface.
|
||||
/// </summary>
|
||||
/// <author>Sam Harwell</author>
|
||||
public class Vocabulary : IVocabulary
|
||||
{
|
||||
private static readonly string[] EmptyNames = new string[0];
|
||||
|
||||
/// <summary>
|
||||
/// Gets an empty
|
||||
/// <see cref="IVocabulary"/>
|
||||
/// instance.
|
||||
/// <p>
|
||||
/// No literal or symbol names are assigned to token types, so
|
||||
/// <see cref="GetDisplayName(int)"/>
|
||||
/// returns the numeric value for all tokens
|
||||
/// except
|
||||
/// <see cref="IToken.Eof"/>
|
||||
/// .</p>
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
public static readonly Vocabulary EmptyVocabulary = new Vocabulary(EmptyNames, EmptyNames, EmptyNames);
|
||||
|
||||
[NotNull]
|
||||
private readonly string[] literalNames;
|
||||
|
||||
[NotNull]
|
||||
private readonly string[] symbolicNames;
|
||||
|
||||
[NotNull]
|
||||
private readonly string[] displayNames;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of
|
||||
/// <see cref="Vocabulary"/>
|
||||
/// from the specified
|
||||
/// literal and symbolic token names.
|
||||
/// </summary>
|
||||
/// <param name="literalNames">
|
||||
/// The literal names assigned to tokens, or
|
||||
/// <see langword="null"/>
|
||||
/// if no literal names are assigned.
|
||||
/// </param>
|
||||
/// <param name="symbolicNames">
|
||||
/// The symbolic names assigned to tokens, or
|
||||
/// <see langword="null"/>
|
||||
/// if no symbolic names are assigned.
|
||||
/// </param>
|
||||
/// <seealso cref="GetLiteralName(int)"/>
|
||||
/// <seealso cref="GetSymbolicName(int)"/>
|
||||
public Vocabulary(string[] literalNames, string[] symbolicNames)
|
||||
: this(literalNames, symbolicNames, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a new instance of
|
||||
/// <see cref="Vocabulary"/>
|
||||
/// from the specified
|
||||
/// literal, symbolic, and display token names.
|
||||
/// </summary>
|
||||
/// <param name="literalNames">
|
||||
/// The literal names assigned to tokens, or
|
||||
/// <see langword="null"/>
|
||||
/// if no literal names are assigned.
|
||||
/// </param>
|
||||
/// <param name="symbolicNames">
|
||||
/// The symbolic names assigned to tokens, or
|
||||
/// <see langword="null"/>
|
||||
/// if no symbolic names are assigned.
|
||||
/// </param>
|
||||
/// <param name="displayNames">
|
||||
/// The display names assigned to tokens, or
|
||||
/// <see langword="null"/>
|
||||
/// to use the values in
|
||||
/// <paramref name="literalNames"/>
|
||||
/// and
|
||||
/// <paramref name="symbolicNames"/>
|
||||
/// as
|
||||
/// the source of display names, as described in
|
||||
/// <see cref="GetDisplayName(int)"/>
|
||||
/// .
|
||||
/// </param>
|
||||
/// <seealso cref="GetLiteralName(int)"/>
|
||||
/// <seealso cref="GetSymbolicName(int)"/>
|
||||
/// <seealso cref="GetDisplayName(int)"/>
|
||||
public Vocabulary(string[] literalNames, string[] symbolicNames, string[] displayNames)
|
||||
{
|
||||
this.literalNames = literalNames != null ? literalNames : EmptyNames;
|
||||
this.symbolicNames = symbolicNames != null ? symbolicNames : EmptyNames;
|
||||
this.displayNames = displayNames != null ? displayNames : EmptyNames;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a
|
||||
/// <see cref="Vocabulary"/>
|
||||
/// instance from the specified set of token
|
||||
/// names. This method acts as a compatibility layer for the single
|
||||
/// <paramref name="tokenNames"/>
|
||||
/// array generated by previous releases of ANTLR.
|
||||
/// <p>The resulting vocabulary instance returns
|
||||
/// <see langword="null"/>
|
||||
/// for
|
||||
/// <see cref="GetLiteralName(int)"/>
|
||||
/// and
|
||||
/// <see cref="GetSymbolicName(int)"/>
|
||||
/// , and the
|
||||
/// value from
|
||||
/// <paramref name="tokenNames"/>
|
||||
/// for the display names.</p>
|
||||
/// </summary>
|
||||
/// <param name="tokenNames">
|
||||
/// The token names, or
|
||||
/// <see langword="null"/>
|
||||
/// if no token names are
|
||||
/// available.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A
|
||||
/// <see cref="IVocabulary"/>
|
||||
/// instance which uses
|
||||
/// <paramref name="tokenNames"/>
|
||||
/// for
|
||||
/// the display names of tokens.
|
||||
/// </returns>
|
||||
public static IVocabulary FromTokenNames(string[] tokenNames)
|
||||
{
|
||||
if (tokenNames == null || tokenNames.Length == 0)
|
||||
{
|
||||
return EmptyVocabulary;
|
||||
}
|
||||
string[] literalNames = Arrays.CopyOf(tokenNames, tokenNames.Length);
|
||||
string[] symbolicNames = Arrays.CopyOf(tokenNames, tokenNames.Length);
|
||||
for (int i = 0; i < tokenNames.Length; i++)
|
||||
{
|
||||
string tokenName = tokenNames[i];
|
||||
if (tokenName == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!tokenName.IsEmpty())
|
||||
{
|
||||
char firstChar = tokenName[0];
|
||||
if (firstChar == '\'')
|
||||
{
|
||||
symbolicNames[i] = null;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (System.Char.IsUpper(firstChar))
|
||||
{
|
||||
literalNames[i] = null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// wasn't a literal or symbolic name
|
||||
literalNames[i] = null;
|
||||
symbolicNames[i] = null;
|
||||
}
|
||||
return new Vocabulary(literalNames, symbolicNames, tokenNames);
|
||||
}
|
||||
|
||||
[Nullable]
|
||||
public virtual string GetLiteralName(int tokenType)
|
||||
{
|
||||
if (tokenType >= 0 && tokenType < literalNames.Length)
|
||||
{
|
||||
return literalNames[tokenType];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[Nullable]
|
||||
public virtual string GetSymbolicName(int tokenType)
|
||||
{
|
||||
if (tokenType >= 0 && tokenType < symbolicNames.Length)
|
||||
{
|
||||
return symbolicNames[tokenType];
|
||||
}
|
||||
if (tokenType == TokenConstants.Eof)
|
||||
{
|
||||
return "EOF";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[NotNull]
|
||||
public virtual string GetDisplayName(int tokenType)
|
||||
{
|
||||
if (tokenType >= 0 && tokenType < displayNames.Length)
|
||||
{
|
||||
string displayName = displayNames[tokenType];
|
||||
if (displayName != null)
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
}
|
||||
string literalName = GetLiteralName(tokenType);
|
||||
if (literalName != null)
|
||||
{
|
||||
return literalName;
|
||||
}
|
||||
string symbolicName = GetSymbolicName(tokenType);
|
||||
if (symbolicName != null)
|
||||
{
|
||||
return symbolicName;
|
||||
}
|
||||
return Antlr4.Runtime.Sharpen.Extensions.ToString(tokenType);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue