TestLexerExec tests pass

This commit is contained in:
Eric Vergnaud 2016-12-12 00:52:09 +08:00
parent 612e3399ff
commit 19d70cd777
27 changed files with 344 additions and 530 deletions

View File

@ -98,7 +98,7 @@ PositionAdjustingLexer() ::= <<
public override IToken NextToken() {
if (!(Interpreter is PositionAdjustingLexerATNSimulator)) {
Interpreter = new PositionAdjustingLexerATNSimulator(this, _ATN);
Interpreter = new PositionAdjustingLexerATNSimulator(this, _ATN, decisionToDFA, sharedContextCache);
}
return base.NextToken();
@ -157,8 +157,8 @@ private static bool IsIdentifierChar(char c) {
public class PositionAdjustingLexerATNSimulator : LexerATNSimulator {
public PositionAdjustingLexerATNSimulator(Lexer recog, ATN atn)
: base(recog, atn)
public PositionAdjustingLexerATNSimulator(Lexer recog, ATN atn, DFA[] decisionToDFA, PredictionContextCache sharedContextCache)
: base(recog, atn, decisionToDFA, sharedContextCache)
{
}

View File

@ -1,31 +1,7 @@
/*
* [The "BSD license"]
* Copyright (c) 2012 Terence Parr
* Copyright (c) 2012 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.
* Copyright (c) 2012-2016 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
package org.antlr.v4.test.runtime.csharp;

View File

@ -87,7 +87,6 @@
<Compile Include="Atn\LookaheadEventInfo.cs" />
<Compile Include="Atn\LoopEndState.cs" />
<Compile Include="Atn\NotSetTransition.cs" />
<Compile Include="Atn\OrderedATNConfigSet.cs" />
<Compile Include="Atn\ParseInfo.cs" />
<Compile Include="Atn\ParserATNSimulator.cs" />
<Compile Include="Atn\PlusBlockStartState.cs" />
@ -235,6 +234,7 @@
<Compile Include="Misc\Pair.cs" />
<Compile Include="Atn\LexerATNConfig.cs" />
<Compile Include="Atn\MergeCache.cs" />
<Compile Include="Misc\ArrayList.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -31,11 +31,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
using IEnumerable = System.Collections.IEnumerable;
using IEnumerator = System.Collections.IEnumerator;
namespace Antlr4.Runtime.Atn
{
@ -58,7 +55,7 @@ namespace Antlr4.Runtime.Atn
public ConfigHashSet configLookup;
/** Track the elements as they are added to the set; supports get(i) */
public List<ATNConfig> configs = new List<ATNConfig>(7);
public ArrayList<ATNConfig> configs = new ArrayList<ATNConfig>(7);
// TODO: these fields make me pretty uncomfortable but nice to pack up info together, saves recomputation
// TODO: can we track conflicts as they are added to save scanning configs later?
@ -157,9 +154,15 @@ namespace Antlr4.Runtime.Atn
}
/** Return a List holding list of configs */
public List<ATNConfig> elements() { return configs; }
public List<ATNConfig> Elements
{
get
{
return configs;
}
}
public HashSet<ATNState> getStates()
public HashSet<ATNState> GetStates()
{
HashSet<ATNState> states = new HashSet<ATNState>();
foreach (ATNConfig c in configs)
@ -178,7 +181,7 @@ namespace Antlr4.Runtime.Atn
* @since 4.3
*/
public BitSet getAlts()
public BitSet GetAlts()
{
BitSet alts = new BitSet();
foreach (ATNConfig config in configs)
@ -188,7 +191,7 @@ namespace Antlr4.Runtime.Atn
return alts;
}
public List<SemanticContext> getPredicates()
public List<SemanticContext> GetPredicates()
{
List<SemanticContext> preds = new List<SemanticContext>();
foreach (ATNConfig c in configs)
@ -201,7 +204,7 @@ namespace Antlr4.Runtime.Atn
return preds;
}
public ATNConfig get(int i) { return configs[i]; }
public ATNConfig Get(int i) { return configs[i]; }
public void OptimizeConfigs(ATNSimulator interpreter)
{
@ -290,7 +293,7 @@ namespace Antlr4.Runtime.Atn
throw new Exception("This method is not implemented for readonly sets.");
}
return configLookup.Contains((ATNConfig)o);
return configLookup.ContainsKey((ATNConfig)o);
}
@ -319,7 +322,18 @@ namespace Antlr4.Runtime.Atn
public override String ToString()
{
StringBuilder buf = new StringBuilder();
buf.Append(elements().ToString());
buf.Append('[');
List<ATNConfig> cfgs = Elements;
if (cfgs.Count > 0)
{
foreach (ATNConfig c in cfgs)
{
buf.Append(c.ToString());
buf.Append(", ");
}
buf.Length = buf.Length - 2;
}
buf.Append(']');
if (hasSemanticContext)
buf.Append(",hasSemanticContext=")
.Append(hasSemanticContext);
@ -348,12 +362,31 @@ namespace Antlr4.Runtime.Atn
public class LexerConfigHashSet : ConfigHashSet
{
public LexerConfigHashSet()
: base(new ObjectEqualityComparator())
{
}
}
}
public class ObjectEqualityComparator : IEqualityComparer<ATNConfig>
{
public int GetHashCode(ATNConfig o)
{
if (o == null)
return 0;
else
return o.GetHashCode();
}
public bool Equals(ATNConfig a, ATNConfig b)
{
if (a == b) return true;
if (a == null || b == null) return false;
return a.Equals(b);
}
}
/**
* The reason that we need this is because we don't want the hash map to use
@ -362,8 +395,13 @@ namespace Antlr4.Runtime.Atn
* the number of objects associated with ATNConfigs. The other solution is to
* use a hash table that lets us specify the equals/hashcode operation.
*/
public class ConfigHashSet : HashSet<ATNConfig>
public class ConfigHashSet : Dictionary<ATNConfig, ATNConfig>
{
public ConfigHashSet(IEqualityComparer<ATNConfig> comparer)
: base(comparer)
{
}
public ConfigHashSet()
: base(new ConfigEqualityComparator())
@ -372,11 +410,12 @@ namespace Antlr4.Runtime.Atn
public ATNConfig GetOrAdd(ATNConfig config)
{
if (this.Contains(config))
return null; // TODO
ATNConfig existing;
if (this.TryGetValue(config, out existing))
return existing;
else
{
this.Add(config);
this.Put(config, config);
return config;
}
}

View File

@ -610,7 +610,7 @@ namespace Antlr4.Runtime.Atn
{
if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.Transition(0).target is RuleStopState)
{
((StarLoopEntryState)state).precedenceRuleDecision = true;
((StarLoopEntryState)state).isPrecedenceDecision = true;
}
}
}

View File

@ -30,68 +30,11 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// The following images show the relation of states and
/// <see cref="transitions"/>
/// for various grammar constructs.
/// <ul>
/// <li>Solid edges marked with an &#0949; indicate a required
/// <see cref="EpsilonTransition"/>
/// .</li>
/// <li>Dashed edges indicate locations where any transition derived from
/// <see cref="Transition"/>
/// might appear.</li>
/// <li>Dashed nodes are place holders for either a sequence of linked
/// <see cref="BasicState"/>
/// states or the inclusion of a block representing a nested
/// construct in one of the forms below.</li>
/// <li>Nodes showing multiple outgoing alternatives with a
/// <c>...</c>
/// support
/// any number of alternatives (one or more). Nodes without the
/// <c>...</c>
/// only
/// support the exact number of alternatives shown in the diagram.</li>
/// </ul>
/// <h2>Basic Blocks</h2>
/// <h3>Rule</h3>
/// <embed src="images/Rule.svg" type="image/svg+xml"/>
/// <h3>Block of 1 or more alternatives</h3>
/// <embed src="images/Block.svg" type="image/svg+xml"/>
/// <h2>Greedy Loops</h2>
/// <h3>Greedy Closure:
/// <c>(...)*</c>
/// </h3>
/// <embed src="images/ClosureGreedy.svg" type="image/svg+xml"/>
/// <h3>Greedy Positive Closure:
/// <c>(...)+</c>
/// </h3>
/// <embed src="images/PositiveClosureGreedy.svg" type="image/svg+xml"/>
/// <h3>Greedy Optional:
/// <c>(...)?</c>
/// </h3>
/// <embed src="images/OptionalGreedy.svg" type="image/svg+xml"/>
/// <h2>Non-Greedy Loops</h2>
/// <h3>Non-Greedy Closure:
/// <c>(...)*?</c>
/// </h3>
/// <embed src="images/ClosureNonGreedy.svg" type="image/svg+xml"/>
/// <h3>Non-Greedy Positive Closure:
/// <c>(...)+?</c>
/// </h3>
/// <embed src="images/PositiveClosureNonGreedy.svg" type="image/svg+xml"/>
/// <h3>Non-Greedy Optional:
/// <c>(...)??</c>
/// </h3>
/// <embed src="images/OptionalNonGreedy.svg" type="image/svg+xml"/>
/// </summary>
public abstract class ATNState
{
public const int InitialNumTransitions = 4;
@ -100,7 +43,6 @@ namespace Antlr4.Runtime.Atn
public const int InvalidStateNumber = -1;
/// <summary>Which ATN are we in?</summary>
public ATN atn = null;
public int stateNumber = InvalidStateNumber;
@ -109,26 +51,12 @@ namespace Antlr4.Runtime.Atn
public bool epsilonOnlyTransitions = false;
/// <summary>Track the transitions emanating from this ATN state.</summary>
/// <remarks>Track the transitions emanating from this ATN state.</remarks>
protected internal readonly List<Antlr4.Runtime.Atn.Transition> transitions = new List<Antlr4.Runtime.Atn.Transition>(InitialNumTransitions);
protected internal readonly List<Transition> transitions = new List<Transition>(InitialNumTransitions);
protected internal List<Antlr4.Runtime.Atn.Transition> optimizedTransitions;
protected internal List<Transition> optimizedTransitions;
/// <summary>Used to cache lookahead during parsing, not used during construction</summary>
public IntervalSet nextTokenWithinRule;
/// <summary>
/// For all states except
/// <see cref="RuleStopState"/>
/// , this returns the state
/// number. Returns -1 for stop states.
/// </summary>
/// <returns>
/// -1 for
/// <see cref="RuleStopState"/>
/// , otherwise the state number
/// </returns>
public virtual int NonStopStateNumber
{
get
@ -144,12 +72,8 @@ namespace Antlr4.Runtime.Atn
public override bool Equals(object o)
{
// are these states same object?
if (o is ATNState)
{
return stateNumber == ((ATNState)o).stateNumber;
}
return false;
return o==this ||
(o is ATNState && stateNumber == ((ATNState)o).stateNumber);
}
public virtual bool IsNonGreedyExitState

View File

@ -28,16 +28,14 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
#pragma warning disable 0659 // 'class' overrides Object.Equals(object o) but does not override Object.GetHashCode()
public class ArrayPredictionContext : PredictionContext
{
/** Parent can be null only if full ctx mode and we make an array

View File

@ -34,12 +34,12 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
#pragma warning disable 0659 // 'class' overrides Object.Equals(object o) but does not override Object.GetHashCode()
#pragma warning disable 0659 // 'class' overrides Object.Equals(object o) but does not override Object.GetHashCode()
public sealed class EmptyPredictionContext : SingletonPredictionContext
{
internal EmptyPredictionContext()
: base(null, EMPTY_RETURN_STATE)
: base(null, EMPTY_RETURN_STATE)
{
}
@ -47,12 +47,12 @@ namespace Antlr4.Runtime.Atn
public override PredictionContext GetParent(int index)
{
throw new ArgumentOutOfRangeException();
return null;
}
public override int GetReturnState(int index)
{
throw new ArgumentOutOfRangeException();
return returnState;
}
@ -60,7 +60,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return 0;
return 1;
}
}
@ -72,20 +72,17 @@ namespace Antlr4.Runtime.Atn
}
}
public override bool HasEmptyPath
{
get
{
return true;
}
}
public override bool Equals(object o)
{
return this == o;
}
public override string[] ToStrings(IRecognizer recognizer, int currentState)
public override string ToString()
{
return "$";
}
public override string[] ToStrings(IRecognizer recognizer, int currentState)
{
return new string[] { "[]" };
}

View File

@ -113,8 +113,9 @@ namespace Antlr4.Runtime.Atn
{
return MatchATN(input);
}
else {
return ExecATN(input, dfa.s0.Get());
else
{
return ExecATN(input, dfa.s0);
}
}
finally
@ -158,14 +159,14 @@ namespace Antlr4.Runtime.Atn
DFAState next = AddDFAState(s0_closure);
if (!suppressEdge)
{
decisionToDFA[mode].s0.Set(next);
decisionToDFA[mode].s0 = next;
}
int predict = ExecATN(input, next);
if (debug)
{
Console.WriteLine("DFA after matchATN: " + decisionToDFA[old_mode].ToLexerString());
Console.WriteLine("DFA after matchATN: " + decisionToDFA[old_mode].ToString());
}
return predict;
@ -760,8 +761,9 @@ namespace Antlr4.Runtime.Atn
DFA dfa = decisionToDFA[mode];
lock (dfa.states)
{
DFAState existing = dfa.states[proposed];
if (existing != null) return existing;
DFAState existing;
if(dfa.states.TryGetValue(proposed, out existing))
return existing;
DFAState newState = proposed;

View File

@ -1,69 +0,0 @@
/*
* [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.Atn;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/*
/// <author>Sam Harwell</author>
public class OrderedATNConfigSet : ATNConfigSet
{
public OrderedATNConfigSet()
{
}
public OrderedATNConfigSet(ATNConfigSet set, bool @readonly)
: base(set, @readonly)
{
}
public override ATNConfigSet Clone(bool @readonly)
{
Antlr4.Runtime.Atn.OrderedATNConfigSet copy = new Antlr4.Runtime.Atn.OrderedATNConfigSet(this, @readonly);
if (!@readonly && this.IsReadOnly)
{
copy.AddAll(this);
}
return copy;
}
protected internal override long GetKey(ATNConfig e)
{
return e.GetHashCode();
}
protected internal override bool CanMerge(ATNConfig left, long leftKey, ATNConfig right)
{
return left.Equals(right);
}
}
*/
}

View File

@ -356,11 +356,11 @@ namespace Antlr4.Runtime.Atn
{
// the start state for a precedence DFA depends on the current
// parser precedence, and is provided by a DFA method.
s0 = dfa.GetPrecedenceStartState(parser.Precedence, false);
s0 = dfa.GetPrecedenceStartState(parser.Precedence);
}
else {
// the start state for a "regular" DFA is just s0
s0 = dfa.s0.Get();
s0 = dfa.s0;
}
if (s0 == null)
@ -387,19 +387,20 @@ namespace Antlr4.Runtime.Atn
* appropriate start state for the precedence level rather
* than simply setting DFA.s0.
*/
dfa.s0.Get().configSet = s0_closure; // not used for prediction but useful to know start configs anyway
dfa.s0.configSet = s0_closure; // not used for prediction but useful to know start configs anyway
s0_closure = ApplyPrecedenceFilter(s0_closure);
s0 = AddDFAState(dfa, new DFAState(s0_closure));
dfa.SetPrecedenceStartState(parser.Precedence, s0);
}
else {
s0 = AddDFAState(dfa, new DFAState(s0_closure));
dfa.s0.Set(s0);
dfa.s0 = s0;
}
}
int alt = ExecATN(dfa, s0, input, index, outerContext);
if (debug) Console.WriteLine("DFA after predictATN: " + dfa.ToString(parser.Vocabulary));
if (debug)
Console.WriteLine("DFA after predictATN: " + dfa.ToString(parser.Vocabulary));
return alt;
}
finally
@ -803,8 +804,7 @@ namespace Antlr4.Runtime.Atn
the fact that we should predict alternative 1. We just can't say for
sure that there is an ambiguity without looking further.
*/
ReportAmbiguity(dfa, D, startIndex, input.Index, foundExactAmbig,
reach.getAlts(), reach);
ReportAmbiguity(dfa, D, startIndex, input.Index, foundExactAmbig, reach.GetAlts(), reach);
return predictedAlt;
}
@ -1792,7 +1792,7 @@ namespace Antlr4.Runtime.Atn
// the context has an empty stack case. If so, it would mean
// global FOLLOW so we can't perform optimization
if (p.StateType != StateType.StarLoopEntry ||
!((StarLoopEntryState)p).precedenceRuleDecision || // Are we the special loop entry/exit state?
!((StarLoopEntryState)p).isPrecedenceDecision || // Are we the special loop entry/exit state?
config.context.IsEmpty || // If SLL wildcard
config.context.HasEmptyPath)
{

View File

@ -27,11 +27,8 @@
* (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.Concurrent;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
@ -39,10 +36,10 @@ namespace Antlr4.Runtime.Atn
{
public abstract class PredictionContext
{
public static readonly EmptyPredictionContext EMPTY = new EmptyPredictionContext();
public static readonly int EMPTY_RETURN_STATE = int.MaxValue;
public static readonly EmptyPredictionContext EMPTY = new EmptyPredictionContext();
private static readonly int INITIAL_HASH = 1;
protected internal static int CalculateEmptyHashCode()

View File

@ -210,7 +210,7 @@ namespace Antlr4.Runtime.Atn
conflictingAltResolvedBySLL = conflictingAlts.NextSetBit(0);
}
else {
conflictingAltResolvedBySLL = configs.getAlts().NextSetBit(0);
conflictingAltResolvedBySLL = configs.GetAlts().NextSetBit(0);
}
decisions[currentDecision].LL_Fallback++;
base.ReportAttemptingFullContext(dfa, conflictingAlts, configs, startIndex, stopIndex);
@ -236,7 +236,7 @@ namespace Antlr4.Runtime.Atn
prediction = ambigAlts.NextSetBit(0);
}
else {
prediction = configSet.getAlts().NextSetBit(0);
prediction = configSet.GetAlts().NextSetBit(0);
}
if (configSet.fullCtx && prediction != conflictingAltResolvedBySLL)
{
@ -245,9 +245,7 @@ namespace Antlr4.Runtime.Atn
// are showing a conflict, hence an ambiguity, but if they resolve
// to different minimum alternatives we have also identified a
// context sensitivity.
decisions[currentDecision].contextSensitivities.Add(
new ContextSensitivityInfo(currentDecision, null /*configs*/, input, startIndex, stopIndex)
);
decisions[currentDecision].contextSensitivities.Add( new ContextSensitivityInfo(currentDecision, null /*configs*/, input, startIndex, stopIndex) );
}
decisions[currentDecision].ambiguities.Add(
new AmbiguityInfo(currentDecision, null /*configs, ambigAlts*/,

View File

@ -88,14 +88,6 @@ namespace Antlr4.Runtime.Atn
}
}
public override bool HasEmptyPath
{
get
{
return false;
}
}
public override bool Equals(object o)
{
if (o == this)
@ -109,12 +101,26 @@ namespace Antlr4.Runtime.Atn
return false;
}
}
Antlr4.Runtime.Atn.SingletonPredictionContext other = (Antlr4.Runtime.Atn.SingletonPredictionContext)o;
if (this.GetHashCode() != other.GetHashCode())
if (this.GetHashCode() != o.GetHashCode())
{
return false;
}
Antlr4.Runtime.Atn.SingletonPredictionContext other = (Antlr4.Runtime.Atn.SingletonPredictionContext)o;
return returnState == other.returnState && parent.Equals(other.parent);
}
public override string ToString()
{
string up = parent != null ? parent.ToString() : "";
if (up.Length == 0)
{
if (returnState == EMPTY_RETURN_STATE)
{
return "$";
}
return returnState.ToString();
}
return returnState.ToString() + " " + up;
}
}
}

View File

@ -51,7 +51,7 @@ namespace Antlr4.Runtime.Atn
/// .</p>
/// </remarks>
/// <seealso cref="Antlr4.Runtime.Dfa.DFA.IsPrecedenceDfa()"/>
public bool precedenceRuleDecision;
public bool isPrecedenceDecision;
public override Antlr4.Runtime.Atn.StateType StateType
{

View File

@ -39,287 +39,161 @@ using Interlocked = System.Threading.Interlocked;
namespace Antlr4.Runtime.Dfa
{
public class DFA
{
/// <summary>A set of all DFA states.</summary>
/// <remarks>
/// A set of all DFA states. Use
/// <see cref="System.Collections.Generic.IDictionary{K, V}"/>
/// so we can get old state back
/// (
/// <see cref="HashSet{T}"/>
/// only allows you to see if it's there).
/// </remarks>
[NotNull]
public readonly ConcurrentDictionary<DFAState, DFAState> states = new ConcurrentDictionary<DFAState, DFAState>();
public class DFA
{
/** A set of all DFA states. Use {@link Map} so we can get old state back
* ({@link Set} only allows you to see if it's there).
*/
[NotNull]
public readonly AtomicReference<DFAState> s0 = new AtomicReference<DFAState>();
public Dictionary<DFAState, DFAState> states = new Dictionary<DFAState, DFAState>();
public readonly int decision;
public DFAState s0;
/// <summary>From which ATN state did we create this DFA?</summary>
[NotNull]
public readonly ATNState atnStartState;
public int decision;
private int nextStateNumber;
/** From which ATN state did we create this DFA? */
private readonly int minDfaEdge;
public DecisionState atnStartState;
private readonly int maxDfaEdge;
/**
* {@code true} if this DFA is for a precedence decision; otherwise,
* {@code false}. This is the backing field for {@link #isPrecedenceDfa}.
*/
private bool precedenceDfa;
[NotNull]
private readonly Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> emptyEdgeMap;
public DFA(DecisionState atnStartState)
: this(atnStartState, 0)
{
}
[NotNull]
private readonly Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> emptyContextEdgeMap;
public DFA(DecisionState atnStartState, int decision)
{
this.atnStartState = atnStartState;
this.decision = decision;
/// <summary>
/// <see langword="true"/>
/// if this DFA is for a precedence decision; otherwise,
/// <see langword="false"/>
/// . This is the backing field for <see cref="IsPrecedenceDfa"/>.
/// </summary>
private volatile bool precedenceDfa;
this.precedenceDfa = false;
if (atnStartState is StarLoopEntryState && ((StarLoopEntryState)atnStartState).isPrecedenceDecision)
{
this.precedenceDfa = true;
DFAState precedenceState = new DFAState(new ATNConfigSet());
precedenceState.edges = new DFAState[0];
precedenceState.isAcceptState = false;
precedenceState.requiresFullContext = false;
this.s0 = precedenceState;
}
}
public DFA(ATNState atnStartState)
: this(atnStartState, 0)
{
}
/**
* Gets whether this DFA is a precedence DFA. Precedence DFAs use a special
* start state {@link #s0} which is not stored in {@link #states}. The
* {@link DFAState#edges} array for this start state contains outgoing edges
* supplying individual start states corresponding to specific precedence
* values.
*
* @return {@code true} if this is a precedence DFA; otherwise,
* {@code false}.
* @see Parser#getPrecedence()
*/
public bool IsPrecedenceDfa
{
get
{
return precedenceDfa;
}
}
public DFA(ATNState atnStartState, int decision)
{
this.atnStartState = atnStartState;
this.decision = decision;
if (this.atnStartState.atn.grammarType == ATNType.Lexer)
{
minDfaEdge = LexerATNSimulator.MIN_DFA_EDGE;
maxDfaEdge = LexerATNSimulator.MAX_DFA_EDGE;
}
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);
}
/**
* Get the start state for a specific precedence value.
*
* @param precedence The current precedence.
* @return The start state corresponding to the specified precedence, or
* {@code null} if no start state exists for the specified precedence.
*
* @throws IllegalStateException if this is not a precedence DFA.
* @see #isPrecedenceDfa()
*/
public DFAState GetPrecedenceStartState(int precedence)
{
if (!IsPrecedenceDfa)
{
throw new Exception("Only precedence DFAs may contain a precedence start state.");
}
public int MinDfaEdge
{
get
{
return minDfaEdge;
}
}
// s0.edges is never null for a precedence DFA
if (precedence < 0 || precedence >= s0.edges.Length)
{
return null;
}
public int MaxDfaEdge
{
get
{
return maxDfaEdge;
}
}
return s0.edges[precedence];
}
public virtual Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> EmptyEdgeMap
{
get
{
return emptyEdgeMap;
}
}
/**
* Set the start state for a specific precedence value.
*
* @param precedence The current precedence.
* @param startState The start state corresponding to the specified
* precedence.
*
* @throws IllegalStateException if this is not a precedence DFA.
* @see #isPrecedenceDfa()
*/
public void SetPrecedenceStartState(int precedence, DFAState startState)
{
if (!IsPrecedenceDfa)
{
throw new Exception("Only precedence DFAs may contain a precedence start state.");
}
public virtual Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> EmptyContextEdgeMap
{
get
{
return emptyContextEdgeMap;
}
}
if (precedence < 0)
{
return;
}
/// <summary>Gets whether this DFA is a precedence DFA.</summary>
/// <remarks>
/// Gets whether this DFA is a precedence DFA. Precedence DFAs use a special
/// start state
/// <see cref="s0"/>
/// which is not stored in
/// <see cref="states"/>
/// . The
/// <see cref="DFAState.edges"/>
/// array for this start state contains outgoing edges
/// supplying individual start states corresponding to specific precedence
/// values.
/// </remarks>
/// <returns>
///
/// <see langword="true"/>
/// if this is a precedence DFA; otherwise,
/// <see langword="false"/>
/// .
/// </returns>
/// <seealso cref="Antlr4.Runtime.Parser.Precedence()"/>
/// <summary>Sets whether this is a precedence DFA.</summary>
/// <remarks>
/// Sets whether this is a precedence DFA. If the specified value differs
/// from the current DFA configuration, the following actions are taken;
/// otherwise no changes are made to the current DFA.
/// <ul>
/// <li>The
/// <see cref="states"/>
/// map is cleared</li>
/// <li>If
/// <c>precedenceDfa</c>
/// is
/// <see langword="false"/>
/// , the initial state
/// <see cref="s0"/>
/// is set to
/// <see langword="null"/>
/// ; otherwise, it is initialized to a new
/// <see cref="DFAState"/>
/// with an empty outgoing
/// <see cref="DFAState.edges"/>
/// array to
/// store the start states for individual precedence values.</li>
/// <li>The
/// <see cref="precedenceDfa"/>
/// field is updated</li>
/// </ul>
/// </remarks>
/// <value>
///
/// <see langword="true"/>
/// if this is a precedence DFA; otherwise,
/// <see langword="false"/>
/// </value>
public bool IsPrecedenceDfa
{
get
{
return precedenceDfa;
}
set
{
// s0.get() and s0full.get() are never null for a precedence DFA
// s0full.get() is never null for a precedence DFA
// s0.get() is never null for a precedence DFA
lock (this)
{
if (this.precedenceDfa != value)
{
this.states.Clear();
if (value)
{
this.s0.Set(new DFAState(new ATNConfigSet()));
}
else
{
this.s0.Set(null);
}
this.precedenceDfa = value;
}
}
}
}
// synchronization on s0 here is ok. when the DFA is turned into a
// precedence DFA, s0 will be initialized once and not updated again
lock (s0)
{
// s0.edges is never null for a precedence DFA
if (precedence >= s0.edges.Length)
{
s0.edges = Arrays.CopyOf(s0.edges, precedence + 1);
}
/// <summary>Get the start state for a specific precedence value.</summary>
/// <remarks>Get the start state for a specific precedence value.</remarks>
/// <param name="precedence">The current precedence.</param>
/// <param name="fullContext">Whether to get from local of full context.</param>
/// <returns>
/// The start state corresponding to the specified precedence, or
/// <see langword="null"/>
/// if no start state exists for the specified precedence.
/// </returns>
/// <exception cref="System.InvalidOperationException">if this is not a precedence DFA.</exception>
/// <seealso cref="IsPrecedenceDfa()"/>
public DFAState GetPrecedenceStartState(int precedence, bool fullContext)
{
if (!IsPrecedenceDfa)
{
throw new InvalidOperationException("Only precedence DFAs may contain a precedence start state.");
}
return s0.Get().edges[precedence];
}
s0.edges[precedence] = startState;
}
}
/// <summary>Set the start state for a specific precedence value.</summary>
/// <remarks>Set the start state for a specific precedence value.</remarks>
/// <param name="precedence">The current precedence.</param>
/// <param name="fullContext">Whether to set local of full context.</param>
/// <param name="startState">
/// The start state corresponding to the specified
/// precedence.
/// </param>
/// <exception cref="System.InvalidOperationException">if this is not a precedence DFA.</exception>
/// <seealso cref="IsPrecedenceDfa()"/>
public void SetPrecedenceStartState(int precedence, DFAState startState)
{
if (!IsPrecedenceDfa)
{
throw new InvalidOperationException("Only precedence DFAs may contain a precedence start state.");
}
if (precedence < 0)
{
return;
}
lock (s0)
{
s0.Get().edges[precedence] = startState;
}
}
/**
* Return a list of all states in this DFA, ordered by state number.
*/
public virtual bool IsEmpty
{
get
{
if (IsPrecedenceDfa)
return s0.Get().edges.Length == 0 ;
else
return s0.Get() == null;
}
}
public List<DFAState> GetStates()
{
List<DFAState> result = new List<DFAState>(states.Keys);
result.Sort((x, y) => x.stateNumber - y.stateNumber);
return result;
}
public virtual DFAState AddState(DFAState state)
{
state.stateNumber = Interlocked.Increment(ref nextStateNumber) - 1;
return states.GetOrAdd(state, state);
}
public override String ToString() { return ToString(Vocabulary.EmptyVocabulary); }
public override string ToString()
{
return ToString(Vocabulary.EmptyVocabulary);
}
public virtual string ToString(IVocabulary vocabulary)
{
if (s0.Get() == null)
{
return string.Empty;
}
DFASerializer serializer = new DFASerializer(this, vocabulary);
return serializer.ToString();
}
public String ToString(IVocabulary vocabulary)
{
if (s0 == null)
{
return "";
}
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();
}
DFASerializer serializer = new DFASerializer(this, vocabulary);
return serializer.ToString();
}
public virtual string ToLexerString()
{
if (s0.Get() == null)
{
return string.Empty;
}
DFASerializer serializer = new LexerDFASerializer(this);
return serializer.ToString();
}
}
public String toLexerString()
{
if (s0 == null) return "";
DFASerializer serializer = new LexerDFASerializer(this);
return serializer.ToString();
}
}
}

View File

@ -74,7 +74,7 @@ namespace Antlr4.Runtime.Dfa
public override string ToString()
{
if (dfa.s0.Get() == null)
if (dfa.s0 == null)
{
return null;
}

View File

@ -32,6 +32,7 @@ using System.Collections.Generic;
using System.Linq;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
@ -50,6 +51,9 @@ namespace Antlr4.Runtime
[NotNull]
private readonly IVocabulary vocabulary;
protected DFA[] decisionToDFA;
protected PredictionContextCache sharedContextCache = new PredictionContextCache();
public LexerInterpreter(string grammarFileName, IVocabulary vocabulary, IEnumerable<string> ruleNames, IEnumerable<string> modeNames, ATN atn, ICharStream input)
: base(input)
{
@ -62,7 +66,12 @@ namespace Antlr4.Runtime
this.ruleNames = ruleNames.ToArray();
this.modeNames = modeNames.ToArray();
this.vocabulary = vocabulary;
this.Interpreter = new LexerATNSimulator(this, atn, null, null);
this.decisionToDFA = new DFA[atn.NumberOfDecisions];
for (int i = 0; i < decisionToDFA.Length; i++)
{
decisionToDFA[i] = new DFA(atn.GetDecisionState(i), i);
}
this.Interpreter = new LexerATNSimulator(this, atn, decisionToDFA, sharedContextCache);
}
public override ATN Atn

View File

@ -0,0 +1,49 @@
using System.Collections.Generic;
namespace Antlr4.Runtime.Misc
{
public class ArrayList<T> : List<T>
{
public ArrayList()
{
}
public ArrayList(int count)
: base(count)
{
}
public override int GetHashCode()
{
int hash = MurmurHash.Initialize(1);
foreach (T t in this)
hash = MurmurHash.Update(hash, t.GetHashCode());
hash = MurmurHash.Finish(hash, this.Count);
return hash;
}
public override bool Equals(object o)
{
return o == this
|| (o is List<T> && this.Equals((List<T>)o));
}
public bool Equals(List<T> o)
{
if (this.Count != o.Count)
return false;
IEnumerator<T> thisItems = this.GetEnumerator();
IEnumerator<T> otherItems = o.GetEnumerator();
while (thisItems.MoveNext() && otherItems.MoveNext())
{
if (!thisItems.Current.Equals(otherItems.Current))
return false;
}
return true;
}
}
}

View File

@ -86,12 +86,12 @@ namespace Antlr4.Runtime.Misc
{
if (els == null)
{
intervals = new List<Interval>(2);
intervals = new ArrayList<Interval>(2);
}
else
{
// most sets are 1 or 2 elements
intervals = new List<Interval>(els.Length);
intervals = new ArrayList<Interval>(els.Length);
foreach (int e in els)
{
Add(e);
@ -783,9 +783,9 @@ namespace Antlr4.Runtime.Misc
}
}
public virtual List<int> ToIntegerList()
public virtual ArrayList<int> ToIntegerList()
{
List<int> values = new List<int>(Count);
ArrayList<int> values = new ArrayList<int>(Count);
int n = intervals.Count;
for (int i = 0; i < n; i++)
{
@ -802,7 +802,7 @@ namespace Antlr4.Runtime.Misc
public virtual IList<int> ToList()
{
IList<int> values = new List<int>();
IList<int> values = new ArrayList<int>();
int n = intervals.Count;
for (int i = 0; i < n; i++)
{

View File

@ -44,7 +44,7 @@ namespace Antlr4.Runtime.Misc
IList<V> elementsForKey;
if (!TryGetValue(key, out elementsForKey))
{
elementsForKey = new List<V>();
elementsForKey = new ArrayList<V>();
this[key] = elementsForKey;
}
elementsForKey.Add(value);
@ -52,7 +52,7 @@ namespace Antlr4.Runtime.Misc
public virtual IList<Tuple<K, V>> GetPairs()
{
IList<Tuple<K, V>> pairs = new List<Tuple<K, V>>();
IList<Tuple<K, V>> pairs = new ArrayList<Tuple<K, V>>();
foreach (KeyValuePair<K, IList<V>> pair in this)
{
foreach (V value in pair.Value)

View File

@ -611,7 +611,7 @@ namespace Antlr4.Runtime.Misc
}
IList<Type> typesToCheck = GetTypesToCheck(assembly);
List<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> dependencies = new List<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
ArrayList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> dependencies = new ArrayList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
foreach (Type clazz in typesToCheck)
{
dependencies.AddRange(GetDependencies(clazz));
@ -626,7 +626,7 @@ namespace Antlr4.Runtime.Misc
IList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> list;
if (!recognizerDependencies.TryGetValue(recognizerType, out list))
{
list = new List<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
list = new ArrayList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
recognizerDependencies[recognizerType] = list;
}
list.Add(dependency);
@ -876,7 +876,7 @@ namespace Antlr4.Runtime.Misc
public static IList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> GetDependencies(Type clazz)
{
IList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> result = new List<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
IList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> result = new ArrayList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
GetElementDependencies(AsCustomAttributeProvider(clazz), result);
foreach (ConstructorInfo ctor in clazz.GetConstructors(AllDeclaredMembers))

View File

@ -42,7 +42,7 @@ namespace Antlr4.Runtime.Misc
#if NET40PLUS
return string.Join(separator, items);
#else
List<string> elements = new List<string>();
ArrayList<string> elements = new ArrayList<string>();
foreach (T item in items)
{
if (item == null)
@ -158,7 +158,7 @@ namespace Antlr4.Runtime.Misc
return m;
}
public static char[] ToCharArray(List<int> data)
public static char[] ToCharArray(ArrayList<int> data)
{
if (data == null)
{

View File

@ -1152,7 +1152,7 @@ namespace Antlr4.Runtime
for (int d = 0; d < Interpreter.atn.decisionToDFA.Length; d++)
{
DFA dfa = Interpreter.atn.decisionToDFA[d];
s.Add(dfa.ToString(Vocabulary, RuleNames));
s.Add(dfa.ToString(Vocabulary));
}
return s;
}
@ -1166,14 +1166,14 @@ namespace Antlr4.Runtime
for (int d = 0; d < Interpreter.atn.decisionToDFA.Length; d++)
{
DFA dfa = Interpreter.atn.decisionToDFA[d];
if (!dfa.IsEmpty)
if (dfa.states.Count>0)
{
if (seenOne)
{
System.Console.Out.WriteLine();
}
System.Console.Out.WriteLine("Decision " + dfa.decision + ":");
System.Console.Out.Write(dfa.ToString(Vocabulary, RuleNames));
System.Console.Out.Write(dfa.ToString(Vocabulary));
seenOne = true;
}
}

View File

@ -82,7 +82,7 @@ namespace Antlr4.Runtime
{
continue;
}
if (((StarLoopEntryState)state).precedenceRuleDecision)
if (((StarLoopEntryState)state).isPrecedenceDecision)
{
this.pushRecursionContextStates.Set(state.stateNumber);
}

View File

@ -29,9 +29,10 @@
*/
namespace Antlr4.Runtime.Sharpen
{
using System.Collections.Generic;
using System.Collections.Generic;
using Antlr4.Runtime.Misc;
internal static class ListExtensions
internal static class ListExtensions
{
public static T Set<T>(this IList<T> list, int index, T value)
where T : class
@ -40,5 +41,8 @@ namespace Antlr4.Runtime.Sharpen
list[index] = value;
return previous;
}
}
}
}

View File

@ -964,6 +964,8 @@ Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= <<
[System.CodeDom.Compiler.GeneratedCode("ANTLR", "<file.ANTLRVersion>")]
[System.CLSCompliant(false)]
public partial class <csIdentifier.(lexer.name)> : <superClass; null="Lexer"> {
protected static DFA[] decisionToDFA;
protected static PredictionContextCache sharedContextCache = new PredictionContextCache();
public const int
<lexer.tokens:{k | <tokenType.(k)>=<lexer.tokens.(k)>}; separator=", ", wrap, anchor>;
<if(lexer.channels)>
@ -984,7 +986,7 @@ public partial class <csIdentifier.(lexer.name)> : <superClass; null="Lexer"> {
public <csIdentifier.(lexer.name)>(ICharStream input)
: base(input)
{
Interpreter = new LexerATNSimulator(this,_ATN);
Interpreter = new LexerATNSimulator(this, _ATN, decisionToDFA, sharedContextCache);
}
<vocabulary(lexer.literalNames, lexer.symbolicNames)>
@ -997,6 +999,12 @@ public partial class <csIdentifier.(lexer.name)> : <superClass; null="Lexer"> {
public override string SerializedAtn { get { return _serializedATN; } }
static <csIdentifier.(lexer.name)>() {
decisionToDFA = new DFA[_ATN.NumberOfDecisions];
for (int i = 0; i \< _ATN.NumberOfDecisions; i++) {
decisionToDFA[i] = new DFA(_ATN.GetDecisionState(i), i);
}
}
<dumpActions(lexer, "", actionFuncs, sempredFuncs)>
<atn>
}
@ -1014,6 +1022,8 @@ private static string _serializeATN()
public static readonly ATN _ATN =
new ATNDeserializer().Deserialize(_serializedATN.ToCharArray());
>>
initValue(typeName) ::= <<