antlr/Antlr4.Runtime/Atn/ATNSimulator.cs

996 lines
27 KiB
C#
Raw Normal View History

2013-02-16 05:30:47 +08:00
/*
* [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;
using System.Collections.Generic;
using System.IO;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public abstract class ATNSimulator
{
public static readonly int SerializedVersion;
static ATNSimulator()
{
SerializedVersion = 5;
}
public const char RuleVariantDelimiter = '$';
public static readonly string RuleLfVariantMarker = "$lf$";
public static readonly string RuleNolfVariantMarker = "$nolf$";
/// <summary>Must distinguish between missing edge and edge we know leads nowhere</summary>
[NotNull]
public static readonly DFAState Error;
[NotNull]
public readonly ATN atn;
static ATNSimulator()
{
Error = new DFAState(new ATNConfigSet(), 0, 0);
Error.stateNumber = int.MaxValue;
}
public ATNSimulator(ATN atn)
{
this.atn = atn;
}
public abstract void Reset();
public static ATN Deserialize(char[] data)
{
return Deserialize(data, true);
}
public static ATN Deserialize(char[] data, bool optimize)
{
data = data.Clone();
// don't adjust the first value since that's the version number
for (int i = 1; i < data.Length; i++)
{
data[i] = (char)(data[i] - 2);
}
ATN atn = new ATN();
IList<IntervalSet> sets = new List<IntervalSet>();
2013-02-16 05:30:47 +08:00
int p = 0;
int version = ToInt(data[p++]);
if (version != SerializedVersion)
{
string reason = string.Format("Could not deserialize ATN with version %d (expected %d)."
, version, SerializedVersion);
throw new NotSupportedException(new InvalidClassException(typeof(ATN).FullName, reason
));
}
atn.grammarType = ToInt(data[p++]);
atn.maxTokenType = ToInt(data[p++]);
//
// STATES
//
IList<Tuple<LoopEndState, int>> loopBackStateNumbers = new List<Tuple<LoopEndState
2013-02-16 05:30:47 +08:00
, int>>();
IList<Tuple<BlockStartState, int>> endStateNumbers = new List<Tuple<BlockStartState
2013-02-16 05:30:47 +08:00
, int>>();
int nstates = ToInt(data[p++]);
for (int i_1 = 1; i_1 <= nstates; i_1++)
{
int stype = ToInt(data[p++]);
// ignore bad type of states
if (stype == ATNState.InvalidType)
{
atn.AddState(null);
continue;
}
int ruleIndex = ToInt(data[p++]);
ATNState s = StateFactory(stype, ruleIndex);
if (stype == ATNState.LoopEnd)
{
// special case
int loopBackStateNumber = ToInt(data[p++]);
loopBackStateNumbers.AddItem(Tuple.Create((LoopEndState)s, loopBackStateNumber));
}
else
{
if (s is BlockStartState)
{
int endStateNumber = ToInt(data[p++]);
endStateNumbers.AddItem(Tuple.Create((BlockStartState)s, endStateNumber));
}
}
atn.AddState(s);
}
// delay the assignment of loop back and end states until we know all the state instances have been initialized
foreach (Tuple<LoopEndState, int> pair in loopBackStateNumbers)
{
pair.GetItem1().loopBackState = atn.states[pair.GetItem2()];
}
foreach (Tuple<BlockStartState, int> pair_1 in endStateNumbers)
{
pair_1.GetItem1().endState = (BlockEndState)atn.states[pair_1.GetItem2()];
}
int numNonGreedyStates = ToInt(data[p++]);
for (int i_2 = 0; i_2 < numNonGreedyStates; i_2++)
{
int stateNumber = ToInt(data[p++]);
((DecisionState)atn.states[stateNumber]).nonGreedy = true;
}
int numSllDecisions = ToInt(data[p++]);
for (int i_3 = 0; i_3 < numSllDecisions; i_3++)
{
int stateNumber = ToInt(data[p++]);
((DecisionState)atn.states[stateNumber]).sll = true;
}
int numPrecedenceStates = ToInt(data[p++]);
for (int i_4 = 0; i_4 < numPrecedenceStates; i_4++)
{
int stateNumber = ToInt(data[p++]);
((RuleStartState)atn.states[stateNumber]).isPrecedenceRule = true;
}
//
// RULES
//
int nrules = ToInt(data[p++]);
if (atn.grammarType == ATN.Lexer)
{
atn.ruleToTokenType = new int[nrules];
atn.ruleToActionIndex = new int[nrules];
}
atn.ruleToStartState = new RuleStartState[nrules];
for (int i_5 = 0; i_5 < nrules; i_5++)
{
int s = ToInt(data[p++]);
RuleStartState startState = (RuleStartState)atn.states[s];
startState.leftFactored = ToInt(data[p++]) != 0;
atn.ruleToStartState[i_5] = startState;
if (atn.grammarType == ATN.Lexer)
{
int tokenType = ToInt(data[p++]);
atn.ruleToTokenType[i_5] = tokenType;
int actionIndex = ToInt(data[p++]);
atn.ruleToActionIndex[i_5] = actionIndex;
}
}
atn.ruleToStopState = new RuleStopState[nrules];
foreach (ATNState state in atn.states)
{
if (!(state is RuleStopState))
{
continue;
}
RuleStopState stopState = (RuleStopState)state;
atn.ruleToStopState[state.ruleIndex] = stopState;
atn.ruleToStartState[state.ruleIndex].stopState = stopState;
}
//
// MODES
//
int nmodes = ToInt(data[p++]);
for (int i_6 = 0; i_6 < nmodes; i_6++)
{
int s = ToInt(data[p++]);
atn.modeToStartState.AddItem((TokensStartState)atn.states[s]);
}
atn.modeToDFA = new DFA[nmodes];
for (int i_7 = 0; i_7 < nmodes; i_7++)
{
atn.modeToDFA[i_7] = new DFA(atn.modeToStartState[i_7]);
}
//
// SETS
//
int nsets = ToInt(data[p++]);
for (int i_8 = 1; i_8 <= nsets; i_8++)
{
int nintervals = ToInt(data[p]);
p++;
IntervalSet set = new IntervalSet();
sets.AddItem(set);
for (int j = 1; j <= nintervals; j++)
{
set.Add(ToInt(data[p]), ToInt(data[p + 1]));
p += 2;
}
}
//
// EDGES
//
int nedges = ToInt(data[p++]);
for (int i_9 = 1; i_9 <= nedges; i_9++)
{
int src = ToInt(data[p]);
int trg = ToInt(data[p + 1]);
int ttype = ToInt(data[p + 2]);
int arg1 = ToInt(data[p + 3]);
int arg2 = ToInt(data[p + 4]);
int arg3 = ToInt(data[p + 5]);
Transition trans = EdgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets);
// System.out.println("EDGE "+trans.getClass().getSimpleName()+" "+
// src+"->"+trg+
// " "+Transition.serializationNames[ttype]+
// " "+arg1+","+arg2+","+arg3);
ATNState srcState = atn.states[src];
srcState.AddTransition(trans);
p += 6;
}
// edges for rule stop states can be derived, so they aren't serialized
foreach (ATNState state_1 in atn.states)
{
bool returningToLeftFactored = state_1.ruleIndex >= 0 && atn.ruleToStartState[state_1
.ruleIndex].leftFactored;
for (int i_10 = 0; i_10 < state_1.GetNumberOfTransitions(); i_10++)
{
Transition t = state_1.Transition(i_10);
if (!(t is RuleTransition))
{
continue;
}
RuleTransition ruleTransition = (RuleTransition)t;
bool returningFromLeftFactored = atn.ruleToStartState[ruleTransition.target.ruleIndex
].leftFactored;
if (!returningFromLeftFactored && returningToLeftFactored)
{
continue;
}
atn.ruleToStopState[ruleTransition.target.ruleIndex].AddTransition(new EpsilonTransition
(ruleTransition.followState));
}
}
foreach (ATNState state_2 in atn.states)
{
if (state_2 is BlockStartState)
{
// we need to know the end state to set its start state
if (((BlockStartState)state_2).endState == null)
{
throw new InvalidOperationException();
}
// block end states can only be associated to a single block start state
if (((BlockStartState)state_2).endState.startState != null)
{
throw new InvalidOperationException();
}
((BlockStartState)state_2).endState.startState = (BlockStartState)state_2;
}
if (state_2 is PlusLoopbackState)
{
PlusLoopbackState loopbackState = (PlusLoopbackState)state_2;
for (int i_10 = 0; i_10 < loopbackState.GetNumberOfTransitions(); i_10++)
{
ATNState target = loopbackState.Transition(i_10).target;
if (target is PlusBlockStartState)
{
((PlusBlockStartState)target).loopBackState = loopbackState;
}
}
}
else
{
if (state_2 is StarLoopbackState)
{
StarLoopbackState loopbackState = (StarLoopbackState)state_2;
for (int i_10 = 0; i_10 < loopbackState.GetNumberOfTransitions(); i_10++)
{
ATNState target = loopbackState.Transition(i_10).target;
if (target is StarLoopEntryState)
{
((StarLoopEntryState)target).loopBackState = loopbackState;
}
}
}
}
}
//
// DECISIONS
//
int ndecisions = ToInt(data[p++]);
for (int i_11 = 1; i_11 <= ndecisions; i_11++)
{
int s = ToInt(data[p++]);
DecisionState decState = (DecisionState)atn.states[s];
atn.decisionToState.AddItem(decState);
decState.decision = i_11 - 1;
}
atn.decisionToDFA = new DFA[ndecisions];
for (int i_12 = 0; i_12 < ndecisions; i_12++)
{
atn.decisionToDFA[i_12] = new DFA(atn.decisionToState[i_12], i_12);
}
if (optimize)
{
while (true)
{
int optimizationCount = 0;
optimizationCount += InlineSetRules(atn);
optimizationCount += CombineChainedEpsilons(atn);
bool preserveOrder = atn.grammarType == ATN.Lexer;
optimizationCount += OptimizeSets(atn, preserveOrder);
if (optimizationCount == 0)
{
break;
}
}
}
IdentifyTailCalls(atn);
VerifyATN(atn);
return atn;
}
private static void VerifyATN(ATN atn)
{
// verify assumptions
foreach (ATNState state in atn.states)
{
if (state == null)
{
continue;
}
CheckCondition(state.OnlyHasEpsilonTransitions() || state.GetNumberOfTransitions(
) <= 1);
if (state is PlusBlockStartState)
{
CheckCondition(((PlusBlockStartState)state).loopBackState != null);
}
if (state is StarLoopEntryState)
{
StarLoopEntryState starLoopEntryState = (StarLoopEntryState)state;
CheckCondition(starLoopEntryState.loopBackState != null);
CheckCondition(starLoopEntryState.GetNumberOfTransitions() == 2);
if (starLoopEntryState.Transition(0).target is StarBlockStartState)
{
CheckCondition(starLoopEntryState.Transition(1).target is LoopEndState);
CheckCondition(!starLoopEntryState.nonGreedy);
}
else
{
if (starLoopEntryState.Transition(0).target is LoopEndState)
{
CheckCondition(starLoopEntryState.Transition(1).target is StarBlockStartState);
CheckCondition(starLoopEntryState.nonGreedy);
}
else
{
throw new InvalidOperationException();
}
}
}
if (state is StarLoopbackState)
{
CheckCondition(state.GetNumberOfTransitions() == 1);
CheckCondition(state.Transition(0).target is StarLoopEntryState);
}
if (state is LoopEndState)
{
CheckCondition(((LoopEndState)state).loopBackState != null);
}
if (state is RuleStartState)
{
CheckCondition(((RuleStartState)state).stopState != null);
}
if (state is BlockStartState)
{
CheckCondition(((BlockStartState)state).endState != null);
}
if (state is BlockEndState)
{
CheckCondition(((BlockEndState)state).startState != null);
}
if (state is DecisionState)
{
DecisionState decisionState = (DecisionState)state;
CheckCondition(decisionState.GetNumberOfTransitions() <= 1 || decisionState.decision
>= 0);
}
else
{
CheckCondition(state.GetNumberOfTransitions() <= 1 || state is RuleStopState);
}
}
}
public static void CheckCondition(bool condition)
{
CheckCondition(condition, null);
}
public static void CheckCondition(bool condition, string message)
{
if (!condition)
{
throw new InvalidOperationException(message);
}
}
private static int InlineSetRules(ATN atn)
{
int inlinedCalls = 0;
Transition[] ruleToInlineTransition = new Transition[atn.ruleToStartState.Length]
;
for (int i = 0; i < atn.ruleToStartState.Length; i++)
{
RuleStartState startState = atn.ruleToStartState[i];
ATNState middleState = startState;
while (middleState.OnlyHasEpsilonTransitions() && middleState.GetNumberOfOptimizedTransitions
() == 1 && middleState.GetOptimizedTransition(0).SerializationType == Transition
2013-02-16 05:30:47 +08:00
.Epsilon)
{
middleState = middleState.GetOptimizedTransition(0).target;
}
if (middleState.GetNumberOfOptimizedTransitions() != 1)
{
continue;
}
Transition matchTransition = middleState.GetOptimizedTransition(0);
ATNState matchTarget = matchTransition.target;
if (matchTransition.IsEpsilon || !matchTarget.OnlyHasEpsilonTransitions() || matchTarget
2013-02-16 05:30:47 +08:00
.GetNumberOfOptimizedTransitions() != 1 || !(matchTarget.GetOptimizedTransition(
0).target is RuleStopState))
{
continue;
}
switch (matchTransition.SerializationType)
2013-02-16 05:30:47 +08:00
{
case Transition.Atom:
case Transition.Range:
case Transition.Set:
{
ruleToInlineTransition[i] = matchTransition;
break;
}
case Transition.NotSet:
case Transition.Wildcard:
{
// not implemented yet
continue;
goto default;
}
default:
{
continue;
break;
}
}
}
for (int stateNumber = 0; stateNumber < atn.states.Count; stateNumber++)
{
ATNState state = atn.states[stateNumber];
if (state.ruleIndex < 0)
{
continue;
}
IList<Transition> optimizedTransitions = null;
for (int i_1 = 0; i_1 < state.GetNumberOfOptimizedTransitions(); i_1++)
{
Transition transition = state.GetOptimizedTransition(i_1);
if (!(transition is RuleTransition))
{
if (optimizedTransitions != null)
{
optimizedTransitions.AddItem(transition);
}
continue;
}
RuleTransition ruleTransition = (RuleTransition)transition;
Transition effective = ruleToInlineTransition[ruleTransition.target.ruleIndex];
if (effective == null)
{
if (optimizedTransitions != null)
{
optimizedTransitions.AddItem(transition);
}
continue;
}
if (optimizedTransitions == null)
{
optimizedTransitions = new List<Transition>();
2013-02-16 05:30:47 +08:00
for (int j = 0; j < i_1; j++)
{
optimizedTransitions.AddItem(state.GetOptimizedTransition(i_1));
}
}
inlinedCalls++;
ATNState target = ruleTransition.followState;
ATNState intermediateState = new BasicState();
intermediateState.SetRuleIndex(target.ruleIndex);
atn.AddState(intermediateState);
optimizedTransitions.AddItem(new EpsilonTransition(intermediateState));
switch (effective.SerializationType)
2013-02-16 05:30:47 +08:00
{
case Transition.Atom:
{
intermediateState.AddTransition(new AtomTransition(target, ((AtomTransition)effective
).label));
break;
}
case Transition.Range:
{
intermediateState.AddTransition(new RangeTransition(target, ((RangeTransition)effective
).from, ((RangeTransition)effective).to));
break;
}
case Transition.Set:
{
intermediateState.AddTransition(new SetTransition(target, effective.Label));
2013-02-16 05:30:47 +08:00
break;
}
default:
{
throw new NotSupportedException();
}
}
}
if (optimizedTransitions != null)
{
if (state.IsOptimized())
{
while (state.GetNumberOfOptimizedTransitions() > 0)
{
state.RemoveOptimizedTransition(state.GetNumberOfOptimizedTransitions() - 1);
}
}
foreach (Transition transition in optimizedTransitions)
{
state.AddOptimizedTransition(transition);
}
}
}
return inlinedCalls;
}
private static int CombineChainedEpsilons(ATN atn)
{
int removedEdges = 0;
foreach (ATNState state in atn.states)
{
if (!state.OnlyHasEpsilonTransitions() || state is RuleStopState)
{
continue;
}
IList<Transition> optimizedTransitions = null;
for (int i = 0; i < state.GetNumberOfOptimizedTransitions(); i++)
{
Transition transition = state.GetOptimizedTransition(i);
ATNState intermediate = transition.target;
if (transition.SerializationType != Transition.Epsilon || intermediate.GetStateType
2013-02-16 05:30:47 +08:00
() != ATNState.Basic || !intermediate.OnlyHasEpsilonTransitions())
{
if (optimizedTransitions != null)
{
optimizedTransitions.AddItem(transition);
}
goto nextTransition_continue;
}
for (int j = 0; j < intermediate.GetNumberOfOptimizedTransitions(); j++)
{
if (intermediate.GetOptimizedTransition(j).SerializationType != Transition.Epsilon)
2013-02-16 05:30:47 +08:00
{
if (optimizedTransitions != null)
{
optimizedTransitions.AddItem(transition);
}
goto nextTransition_continue;
}
}
removedEdges++;
if (optimizedTransitions == null)
{
optimizedTransitions = new List<Transition>();
2013-02-16 05:30:47 +08:00
for (int j_1 = 0; j_1 < i; j_1++)
{
optimizedTransitions.AddItem(state.GetOptimizedTransition(j_1));
}
}
for (int j_2 = 0; j_2 < intermediate.GetNumberOfOptimizedTransitions(); j_2++)
{
ATNState target = intermediate.GetOptimizedTransition(j_2).target;
optimizedTransitions.AddItem(new EpsilonTransition(target));
}
nextTransition_continue: ;
}
nextTransition_break: ;
if (optimizedTransitions != null)
{
if (state.IsOptimized())
{
while (state.GetNumberOfOptimizedTransitions() > 0)
{
state.RemoveOptimizedTransition(state.GetNumberOfOptimizedTransitions() - 1);
}
}
foreach (Transition transition in optimizedTransitions)
{
state.AddOptimizedTransition(transition);
}
}
}
nextState_break: ;
return removedEdges;
}
private static int OptimizeSets(ATN atn, bool preserveOrder)
{
if (preserveOrder)
{
// this optimization currently doesn't preserve edge order.
return 0;
}
int removedPaths = 0;
IList<DecisionState> decisions = atn.decisionToState;
foreach (DecisionState decision in decisions)
{
IntervalSet setTransitions = new IntervalSet();
for (int i = 0; i < decision.GetNumberOfOptimizedTransitions(); i++)
{
Transition epsTransition = decision.GetOptimizedTransition(i);
if (!(epsTransition is EpsilonTransition))
{
continue;
}
if (epsTransition.target.GetNumberOfOptimizedTransitions() != 1)
{
continue;
}
Transition transition = epsTransition.target.GetOptimizedTransition(0);
if (!(transition.target is BlockEndState))
{
continue;
}
if (transition is NotSetTransition)
{
// TODO: not yet implemented
continue;
}
if (transition is AtomTransition || transition is RangeTransition || transition is
SetTransition)
{
setTransitions.Add(i);
}
}
if (setTransitions.Size() <= 1)
{
continue;
}
IList<Transition> optimizedTransitions = new List<Transition>();
2013-02-16 05:30:47 +08:00
for (int i_1 = 0; i_1 < decision.GetNumberOfOptimizedTransitions(); i_1++)
{
if (!setTransitions.Contains(i_1))
{
optimizedTransitions.AddItem(decision.GetOptimizedTransition(i_1));
}
}
ATNState blockEndState = decision.GetOptimizedTransition(setTransitions.GetMinElement
()).target.GetOptimizedTransition(0).target;
IntervalSet matchSet = new IntervalSet();
for (int i_2 = 0; i_2 < setTransitions.GetIntervals().Count; i_2++)
{
Interval interval = setTransitions.GetIntervals()[i_2];
for (int j = interval.a; j <= interval.b; j++)
{
Transition matchTransition = decision.GetOptimizedTransition(j).target.GetOptimizedTransition
(0);
if (matchTransition is NotSetTransition)
{
throw new NotSupportedException("Not yet implemented.");
}
else
{
matchSet.AddAll(matchTransition.Label);
2013-02-16 05:30:47 +08:00
}
}
}
Transition newTransition;
if (matchSet.GetIntervals().Count == 1)
{
if (matchSet.Size() == 1)
{
newTransition = new AtomTransition(blockEndState, matchSet.GetMinElement());
}
else
{
Interval matchInterval = matchSet.GetIntervals()[0];
newTransition = new RangeTransition(blockEndState, matchInterval.a, matchInterval
.b);
}
}
else
{
newTransition = new SetTransition(blockEndState, matchSet);
}
ATNState setOptimizedState = new BasicState();
setOptimizedState.SetRuleIndex(decision.ruleIndex);
atn.AddState(setOptimizedState);
setOptimizedState.AddTransition(newTransition);
optimizedTransitions.AddItem(new EpsilonTransition(setOptimizedState));
removedPaths += decision.GetNumberOfOptimizedTransitions() - optimizedTransitions
.Count;
if (decision.IsOptimized())
{
while (decision.GetNumberOfOptimizedTransitions() > 0)
{
decision.RemoveOptimizedTransition(decision.GetNumberOfOptimizedTransitions() - 1
);
}
}
foreach (Transition transition_1 in optimizedTransitions)
{
decision.AddOptimizedTransition(transition_1);
}
}
return removedPaths;
}
private static void IdentifyTailCalls(ATN atn)
{
foreach (ATNState state in atn.states)
{
foreach (Transition transition in state.transitions)
{
if (!(transition is RuleTransition))
{
continue;
}
RuleTransition ruleTransition = (RuleTransition)transition;
ruleTransition.tailCall = TestTailCall(atn, ruleTransition, false);
ruleTransition.optimizedTailCall = TestTailCall(atn, ruleTransition, true);
}
if (!state.IsOptimized())
{
continue;
}
foreach (Transition transition_1 in state.optimizedTransitions)
{
if (!(transition_1 is RuleTransition))
{
continue;
}
RuleTransition ruleTransition = (RuleTransition)transition_1;
ruleTransition.tailCall = TestTailCall(atn, ruleTransition, false);
ruleTransition.optimizedTailCall = TestTailCall(atn, ruleTransition, true);
}
}
}
private static bool TestTailCall(ATN atn, RuleTransition transition, bool optimizedPath
)
{
if (!optimizedPath && transition.tailCall)
{
return true;
}
if (optimizedPath && transition.optimizedTailCall)
{
return true;
}
BitSet reachable = new BitSet(atn.states.Count);
IDeque<ATNState> worklist = new ArrayDeque<ATNState>();
2013-02-16 05:30:47 +08:00
worklist.AddItem(transition.followState);
while (!worklist.IsEmpty())
{
ATNState state = worklist.Pop();
if (reachable.Get(state.stateNumber))
{
continue;
}
if (state is RuleStopState)
{
continue;
}
if (!state.OnlyHasEpsilonTransitions())
{
return false;
}
IList<Transition> transitions = optimizedPath ? state.optimizedTransitions : state
.transitions;
foreach (Transition t in transitions)
{
if (t.SerializationType != Transition.Epsilon)
2013-02-16 05:30:47 +08:00
{
return false;
}
worklist.AddItem(t.target);
}
}
return true;
}
public static int ToInt(char c)
{
return c == 65535 ? -1 : c;
}
[NotNull]
public static Transition EdgeFactory(ATN atn, int type, int src, int trg, int arg1
, int arg2, int arg3, IList<IntervalSet> sets)
{
ATNState target = atn.states[trg];
switch (type)
{
case Transition.Epsilon:
{
return new EpsilonTransition(target);
}
case Transition.Range:
{
return new RangeTransition(target, arg1, arg2);
}
case Transition.Rule:
{
RuleTransition rt = new RuleTransition((RuleStartState)atn.states[arg1], arg2, arg3
, target);
return rt;
}
case Transition.Predicate:
{
PredicateTransition pt = new PredicateTransition(target, arg1, arg2, arg3 != 0);
return pt;
}
case Transition.Precedence:
{
return new PrecedencePredicateTransition(target, arg1);
}
case Transition.Atom:
{
return new AtomTransition(target, arg1);
}
case Transition.Action:
{
ActionTransition a = new ActionTransition(target, arg1, arg2, arg3 != 0);
return a;
}
case Transition.Set:
{
return new SetTransition(target, sets[arg1]);
}
case Transition.NotSet:
{
return new NotSetTransition(target, sets[arg1]);
}
case Transition.Wildcard:
{
return new WildcardTransition(target);
}
}
throw new ArgumentException("The specified transition type is not valid.");
}
public static ATNState StateFactory(int type, int ruleIndex)
{
ATNState s;
switch (type)
{
case ATNState.InvalidType:
{
return null;
}
case ATNState.Basic:
{
s = new BasicState();
break;
}
case ATNState.RuleStart:
{
s = new RuleStartState();
break;
}
case ATNState.BlockStart:
{
s = new BasicBlockStartState();
break;
}
case ATNState.PlusBlockStart:
{
s = new PlusBlockStartState();
break;
}
case ATNState.StarBlockStart:
{
s = new StarBlockStartState();
break;
}
case ATNState.TokenStart:
{
s = new TokensStartState();
break;
}
case ATNState.RuleStop:
{
s = new RuleStopState();
break;
}
case ATNState.BlockEnd:
{
s = new BlockEndState();
break;
}
case ATNState.StarLoopBack:
{
s = new StarLoopbackState();
break;
}
case ATNState.StarLoopEntry:
{
s = new StarLoopEntryState();
break;
}
case ATNState.PlusLoopBack:
{
s = new PlusLoopbackState();
break;
}
case ATNState.LoopEnd:
{
s = new LoopEndState();
break;
}
default:
{
string message = string.Format("The specified state type %d is not valid.", type);
throw new ArgumentException(message);
}
}
s.ruleIndex = ruleIndex;
return s;
}
}
}