/// <summary>
 /// Creates a copy of this transition but with another target
 /// state.
 /// </summary>
 /// <param name="state">The new target state</param>
 /// <returns>An identical copy of this transition</returns>
 public override NFATransition Copy(NFAState state)
 {
     return(new NFADotTransition(state));
 }
Example #2
0
        /** Fill a list of all NFA states visited during the parse */
        protected virtual void ParseEngine(string startRule,
                                           NFAState start,
                                           NFAState stop,
                                           IIntStream input,
                                           Stack <object> ruleInvocationStack,
                                           IDebugEventListener actions,
                                           IList <NFAState> visitedStates)
        {
            NFAState s = start;

            if (actions != null)
            {
                actions.EnterRule(s.nfa.grammar.FileName, start.enclosingRule.Name);
            }
            int t = input.LA(1);

            while (s != stop)
            {
                if (visitedStates != null)
                {
                    visitedStates.Add(s);
                }
                //Console.Out.WriteLine( "parse state " + s.stateNumber + " input=" + s.nfa.grammar.getTokenDisplayName( t ) );
                // CASE 1: decision state
                if (s.DecisionNumber > 0 && s.nfa.grammar.GetNumberOfAltsForDecisionNFA(s) > 1)
                {
                    // decision point, must predict and jump to alt
                    DFA dfa = s.nfa.grammar.GetLookaheadDFA(s.DecisionNumber);
                    //if ( s.nfa.grammar.type != GrammarType.Lexer )
                    //{
                    //    Console.Out.WriteLine( "decision: " +
                    //                   dfa.getNFADecisionStartState().Description +
                    //                   " input=" + s.nfa.grammar.getTokenDisplayName( t ) );
                    //}
                    int m            = input.Mark();
                    int predictedAlt = Predict(dfa);
                    if (predictedAlt == NFA.INVALID_ALT_NUMBER)
                    {
                        string description        = dfa.NFADecisionStartState.Description;
                        NoViableAltException nvae =
                            new NoViableAltException(description,
                                                     dfa.DecisionNumber,
                                                     s.stateNumber,
                                                     input);
                        if (actions != null)
                        {
                            actions.RecognitionException(nvae);
                        }
                        input.Consume(); // recover
                        throw nvae;
                    }
                    input.Rewind(m);
                    int parseAlt =
                        s.TranslateDisplayAltToWalkAlt(predictedAlt);
                    //if ( s.nfa.grammar.type != GrammarType.Lexer )
                    //{
                    //    Console.Out.WriteLine( "predicted alt " + predictedAlt + ", parseAlt " + parseAlt );
                    //}
                    NFAState alt;
                    if (parseAlt > s.nfa.grammar.GetNumberOfAltsForDecisionNFA(s))
                    {
                        // implied branch of loop etc...
                        alt = s.nfa.grammar.nfa.GetState(s.endOfBlockStateNumber);
                    }
                    else
                    {
                        alt = s.nfa.grammar.GetNFAStateForAltOfDecision(s, parseAlt);
                    }
                    s = (NFAState)alt.transition[0].target;
                    continue;
                }

                // CASE 2: finished matching a rule
                if (s.IsAcceptState)
                { // end of rule node
                    if (actions != null)
                    {
                        actions.ExitRule(s.nfa.grammar.FileName, s.enclosingRule.Name);
                    }
                    if (ruleInvocationStack.Count == 0)
                    {
                        // done parsing.  Hit the start state.
                        //Console.Out.WriteLine( "stack empty in stop state for " + s.enclosingRule );
                        break;
                    }
                    // pop invoking state off the stack to know where to return to
                    NFAState invokingState = (NFAState)ruleInvocationStack.Pop();
                    RuleClosureTransition invokingTransition =
                        (RuleClosureTransition)invokingState.transition[0];
                    // move to node after state that invoked this rule
                    s = invokingTransition.followState;
                    continue;
                }

                Transition trans = s.transition[0];
                Label      label = trans.label;
                if (label.IsSemanticPredicate)
                {
                    FailedPredicateException fpe =
                        new FailedPredicateException(input,
                                                     s.enclosingRule.Name,
                                                     "can't deal with predicates yet");
                    if (actions != null)
                    {
                        actions.RecognitionException(fpe);
                    }
                }

                // CASE 3: epsilon transition
                if (label.IsEpsilon)
                {
                    // CASE 3a: rule invocation state
                    if (trans is RuleClosureTransition)
                    {
                        ruleInvocationStack.Push(s);
                        s = (NFAState)trans.target;
                        //Console.Out.WriteLine( "call " + s.enclosingRule.name + " from " + s.nfa.grammar.getFileName() );
                        if (actions != null)
                        {
                            actions.EnterRule(s.nfa.grammar.FileName, s.enclosingRule.Name);
                        }
                        // could be jumping to new grammar, make sure DFA created
                        if (!s.nfa.grammar.AllDecisionDFAHaveBeenCreated)
                        {
                            s.nfa.grammar.CreateLookaheadDFAs();
                        }
                    }
                    // CASE 3b: plain old epsilon transition, just move
                    else
                    {
                        s = (NFAState)trans.target;
                    }
                }

                // CASE 4: match label on transition
                else if (label.Matches(t))
                {
                    if (actions != null)
                    {
                        if (s.nfa.grammar.type == GrammarType.Parser ||
                            s.nfa.grammar.type == GrammarType.Combined)
                        {
                            actions.ConsumeToken(((ITokenStream)input).LT(1));
                        }
                    }
                    s = (NFAState)s.transition[0].target;
                    input.Consume();
                    t = input.LA(1);
                }

                // CASE 5: error condition; label is inconsistent with input
                else
                {
                    if (label.IsAtom)
                    {
                        MismatchedTokenException mte =
                            new MismatchedTokenException(label.Atom, input);
                        if (actions != null)
                        {
                            actions.RecognitionException(mte);
                        }
                        input.Consume(); // recover
                        throw mte;
                    }
                    else if (label.IsSet)
                    {
                        MismatchedSetException mse =
                            new MismatchedSetException(((IntervalSet)label.Set).ToRuntimeBitSet(),
                                                       input);
                        if (actions != null)
                        {
                            actions.RecognitionException(mse);
                        }
                        input.Consume(); // recover
                        throw mse;
                    }
                    else if (label.IsSemanticPredicate)
                    {
                        FailedPredicateException fpe =
                            new FailedPredicateException(input,
                                                         s.enclosingRule.Name,
                                                         label.SemanticContext.ToString());
                        if (actions != null)
                        {
                            actions.RecognitionException(fpe);
                        }
                        input.Consume(); // recover
                        throw fpe;
                    }
                    else
                    {
                        throw new RecognitionException(input);   // unknown error
                    }
                }
            }
            //Console.Out.WriteLine( "hit stop state for " + stop.enclosingRule );
            if (actions != null)
            {
                actions.ExitRule(s.nfa.grammar.FileName, stop.enclosingRule.Name);
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="NFADotTransition"/> class.
 /// </summary>
 /// <param name="state">The target state</param>
 public NFADotTransition(NFAState state) : base(state)
 {
 }
Example #4
0
        /// <summary>
        /// Adds a unicode character span to an existing NFA automaton
        /// </summary>
        /// <param name="automata">The target NFA</param>
        /// <param name="span">The unicode span to add</param>
        private static void AddUnicodeSpanToNFA(NFA automata, UnicodeSpan span)
        {
            char[] b = span.Begin.GetUTF16();
            char[] e = span.End.GetUTF16();

            if (span.IsPlane0)
            {
                // this span is entirely in plane 0
                automata.StateEntry.AddTransition(new CharSpan(b[0], e[0]), automata.StateExit);
            }
            else if (span.Begin.IsPlane0)
            {
                // this span has only a part in plane 0
                if (b[0] < 0xD800)
                {
                    automata.StateEntry.AddTransition(new CharSpan(b[0], (char)0xD7FF), automata.StateExit);
                    automata.StateEntry.AddTransition(new CharSpan((char)0xE000, (char)0xFFFF), automata.StateExit);
                }
                else
                {
                    automata.StateEntry.AddTransition(new CharSpan(b[0], (char)0xFFFF), automata.StateExit);
                }
                NFAState intermediate = automata.AddNewState();
                automata.StateEntry.AddTransition(new CharSpan((char)0xD800, e[0]), intermediate);
                intermediate.AddTransition(new CharSpan((char)0xDC00, e[1]), automata.StateExit);
            }
            else
            {
                // this span has no part in plane 0
                if (b[0] == e[0])
                {
                    // same first surrogate
                    NFAState intermediate = automata.AddNewState();
                    automata.StateEntry.AddTransition(new CharSpan(b[0], b[0]), intermediate);
                    intermediate.AddTransition(new CharSpan(b[1], e[1]), automata.StateExit);
                }
                else if (e[0] == b[0] + 1)
                {
                    // the first surrogates are consecutive encodings
                    // build lower half
                    NFAState i1 = automata.AddNewState();
                    automata.StateEntry.AddTransition(new CharSpan(b[0], b[0]), i1);
                    i1.AddTransition(new CharSpan(b[1], (char)0xDFFF), automata.StateExit);
                    // build upper half
                    NFAState i2 = automata.AddNewState();
                    automata.StateEntry.AddTransition(new CharSpan(e[0], e[0]), i2);
                    i2.AddTransition(new CharSpan((char)0xDC00, e[1]), automata.StateExit);
                }
                else
                {
                    // there is at least one surrogate value between the first surrogates of begin and end
                    // build lower part
                    NFAState ia = automata.AddNewState();
                    automata.StateEntry.AddTransition(new CharSpan(b[0], b[0]), ia);
                    ia.AddTransition(new CharSpan(b[1], (char)0xDFFF), automata.StateExit);
                    // build intermediate part
                    NFAState im = automata.AddNewState();
                    automata.StateEntry.AddTransition(new CharSpan((char)(b[0] + 1), (char)(e[0] - 1)), im);
                    im.AddTransition(new CharSpan((char)0xDC00, (char)0xDFFF), automata.StateExit);
                    // build upper part
                    NFAState iz = automata.AddNewState();
                    automata.StateEntry.AddTransition(new CharSpan(e[0], e[0]), iz);
                    iz.AddTransition(new CharSpan((char)0xDC00, e[1]), automata.StateExit);
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="NFANonWordTransition"/> class
 /// </summary>
 /// <param name="state">The target state</param>
 public NFANonWordTransition(NFAState state) : base(state)
 {
 }
Example #6
0
        private string GetStateLabel(State state)
        {
            if (state == null)
            {
                return("null");
            }

            string   stateLabel = state.StateNumber.ToString();
            DFAState dfaState   = state as DFAState;
            NFAState nfaState   = state as NFAState;

            if (dfaState != null)
            {
                StringBuilder builder = new StringBuilder(250);
                builder.Append('s');
                builder.Append(state.StateNumber);
                if (AntlrTool.internalOption_ShowNFAConfigsInDFA)
                {
                    if (dfaState.AbortedDueToRecursionOverflow)
                    {
                        builder.AppendLine();
                        builder.AppendLine("AbortedDueToRecursionOverflow");
                    }

                    var alts = dfaState.AltSet;
                    if (alts != null)
                    {
                        builder.AppendLine();
                        List <int> altList = alts.OrderBy(i => i).ToList();
                        ICollection <NFAConfiguration> configurations = dfaState.NfaConfigurations;
                        for (int i = 0; i < altList.Count; i++)
                        {
                            int alt = altList[i];
                            if (i > 0)
                            {
                                builder.AppendLine();
                            }
                            builder.AppendFormat("alt{0}:", alt);
                            // get a list of configs for just this alt
                            // it will help us print better later
                            List <NFAConfiguration> configsInAlt = new List <NFAConfiguration>();
                            foreach (NFAConfiguration c in configurations)
                            {
                                if (c.Alt != alt)
                                {
                                    continue;
                                }

                                configsInAlt.Add(c);
                            }

                            int n = 0;
                            for (int cIndex = 0; cIndex < configsInAlt.Count; cIndex++)
                            {
                                NFAConfiguration c = configsInAlt[cIndex];
                                n++;
                                builder.Append(c.ToString(false));
                                if ((cIndex + 1) < configsInAlt.Count)
                                {
                                    builder.Append(", ");
                                }
                                if (n % 5 == 0 && (configsInAlt.Count - cIndex) > 3)
                                {
                                    builder.Append("\\n");
                                }
                            }
                        }
                    }
                }

                if (dfaState.IsAcceptState)
                {
                    builder.Append("⇒" + dfaState.GetUniquelyPredictedAlt());
                }

                stateLabel = builder.ToString();
            }
            else if (nfaState != null)
            {
                if (nfaState.IsDecisionState)
                {
                    stateLabel += ",d=" + nfaState.DecisionNumber;
                }

                if (nfaState.endOfBlockStateNumber != State.INVALID_STATE_NUMBER)
                {
                    stateLabel += ",eob=" + nfaState.endOfBlockStateNumber;
                }
            }

            return(stateLabel);
        }
Example #7
0
 public NFAEdge(NFAState targetState)
     : this()
 {
     TargetState = targetState;
 }
 /// <summary>
 /// Creates a copy of this transition but with another target
 /// state.
 /// </summary>
 /// <param name="state">The new target state</param>
 /// <returns>An identical copy of this transition</returns>
 public override NFATransition Copy(NFAState state)
 {
     return(new NFANonWhitespaceTransition(state));
 }
Example #9
0
        /** Do a depth-first walk of the state machine graph and
         *  fill a DOT description template.  Keep filling the
         *  states and edges attributes.  We know this is an NFA
         *  for a rule so don't traverse edges to other rules and
         *  don't go past rule end state.
         */
        protected virtual void WalkRuleNFACreatingDOT(StringTemplate dot,
                                                      State s)
        {
            if (markedStates.Contains(s.stateNumber))
            {
                return; // already visited this node
            }

            markedStates.Add(s.stateNumber);   // mark this node as completed.

            // first add this node
            StringTemplate stateST;

            if (s.IsAcceptState)
            {
                stateST = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "stopstate"));
            }
            else
            {
                stateST = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "state"));
            }
            stateST.SetAttribute("name", GetStateLabel(s));
            dot.SetAttribute("states", stateST);

            if (s.IsAcceptState)
            {
                return; // don't go past end of rule node to the follow states
            }

            // special case: if decision point, then line up the alt start states
            // unless it's an end of block
            if (((NFAState)s).IsDecisionState)
            {
                GrammarAST n = ((NFAState)s).associatedASTNode;
                if (n != null && n.Type != ANTLRParser.EOB)
                {
                    StringTemplate rankST = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "decision-rank"));
                    NFAState       alt    = (NFAState)s;
                    while (alt != null)
                    {
                        rankST.SetAttribute("states", GetStateLabel(alt));
                        if (alt.transition[1] != null)
                        {
                            alt = (NFAState)alt.transition[1].target;
                        }
                        else
                        {
                            alt = null;
                        }
                    }
                    dot.SetAttribute("decisionRanks", rankST);
                }
            }

            // make a DOT edge for each transition
            StringTemplate edgeST = null;

            for (int i = 0; i < s.NumberOfTransitions; i++)
            {
                Transition edge = (Transition)s.GetTransition(i);
                if (edge is RuleClosureTransition)
                {
                    RuleClosureTransition rr = ((RuleClosureTransition)edge);
                    // don't jump to other rules, but display edge to follow node
                    edgeST = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "edge"));
                    if (rr.rule.grammar != grammar)
                    {
                        edgeST.SetAttribute("label", "<" + rr.rule.grammar.name + "." + rr.rule.Name + ">");
                    }
                    else
                    {
                        edgeST.SetAttribute("label", "<" + rr.rule.Name + ">");
                    }
                    edgeST.SetAttribute("src", GetStateLabel(s));
                    edgeST.SetAttribute("target", GetStateLabel(rr.followState));
                    edgeST.SetAttribute("arrowhead", arrowhead);
                    dot.SetAttribute("edges", edgeST);
                    WalkRuleNFACreatingDOT(dot, rr.followState);
                    continue;
                }
                if (edge.IsAction)
                {
                    edgeST = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "action-edge"));
                }
                else if (edge.IsEpsilon)
                {
                    edgeST = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "epsilon-edge"));
                }
                else
                {
                    edgeST = stlib.GetInstanceOf(Path.Combine(dfaTemplateDirectoryName, "edge"));
                }
                edgeST.SetAttribute("label", GetEdgeLabel(edge));
                edgeST.SetAttribute("src", GetStateLabel(s));
                edgeST.SetAttribute("target", GetStateLabel(edge.target));
                edgeST.SetAttribute("arrowhead", arrowhead);
                dot.SetAttribute("edges", edgeST);
                WalkRuleNFACreatingDOT(dot, edge.target);   // keep walkin'
            }
        }
Example #10
0
        private void TransitionBetweenStates(NFAState a, NFAState b, int label)
        {
            Transition e = new Transition(label, b);

            a.AddTransition(e);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="NFANonWhitespaceTransition"/> class
 /// </summary>
 /// <param name="state">The target state</param>
 /// @param state          the target state
 public NFANonWhitespaceTransition(NFAState state) : base(state)
 {
 }
Example #12
0
        /** From A|B|..|Z alternative block build
         *
         *  o->o-A->o->o (last NFAState is blockEndNFAState pointed to by all alts)
         *  |          ^
         *  o->o-B->o--|
         *  |          |
         *  ...        |
         *  |          |
         *  o->o-Z->o--|
         *
         *  So every alternative gets begin NFAState connected by epsilon
         *  and every alt right side points at a block end NFAState.  There is a
         *  new NFAState in the NFAState in the StateCluster for each alt plus one for the
         *  end NFAState.
         *
         *  Special case: only one alternative: don't make a block with alt
         *  begin/end.
         *
         *  Special case: if just a list of tokens/chars/sets, then collapse
         *  to a single edge'd o-set->o graph.
         *
         *  Set alt number (1..n) in the left-Transition NFAState.
         */
        public virtual StateCluster BuildAlternativeBlock(ICollection <StateCluster> alternativeStateClusters)
        {
            StateCluster result = null;

            if (alternativeStateClusters == null || alternativeStateClusters.Count == 0)
            {
                return(null);
            }

            // single alt case
            if (alternativeStateClusters.Count == 1)
            {
                // single alt, no decision, just return only alt state cluster
                StateCluster g          = alternativeStateClusters.First();
                NFAState     startOfAlt = NewState(); // must have this no matter what
                TransitionBetweenStates(startOfAlt, g.Left, Label.EPSILON);

                //System.Console.Out.WriteLine( "### opt saved start/stop end in (...)" );
                return(new StateCluster(startOfAlt, g.Right));
            }

            // even if we can collapse for lookahead purposes, we will still
            // need to predict the alts of this subrule in case there are actions
            // etc...  This is the decision that is pointed to from the AST node
            // (always)
            NFAState prevAlternative  = null; // tracks prev so we can link to next alt
            NFAState firstAlt         = null;
            NFAState blockEndNFAState = NewState();

            blockEndNFAState.Description = "end block";
            int altNum = 1;

            foreach (StateCluster g in alternativeStateClusters)
            {
                // add begin NFAState for this alt connected by epsilon
                NFAState left = NewState();
                left.Description = "alt " + altNum + " of ()";
                TransitionBetweenStates(left, g.Left, Label.EPSILON);
                TransitionBetweenStates(g.Right, blockEndNFAState, Label.EPSILON);
                // Are we the first alternative?
                if (firstAlt == null)
                {
                    firstAlt = left; // track extreme left node of StateCluster
                }
                else
                {
                    // if not first alternative, must link to this alt from previous
                    TransitionBetweenStates(prevAlternative, left, Label.EPSILON);
                }
                prevAlternative = left;
                altNum++;
            }

            // return StateCluster pointing representing entire block
            // Points to first alt NFAState on left, block end on right
            result = new StateCluster(firstAlt, blockEndNFAState);

            firstAlt.decisionStateType = NFAState.BLOCK_START;

            // set EOB markers for Jean
            firstAlt.endOfBlockStateNumber = blockEndNFAState.StateNumber;

            return(result);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="NFAEpsilonTransition"/> class.
 /// </summary>
 /// <param name="state">The target state</param>
 public NFAEpsilonTransition(NFAState state) : base(state)
 {
 }
Example #14
0
        /// <summary>
        /// Builds a NFA from a character class
        /// </summary>
        /// <param name="node">An AST node representing a NFA</param>
        /// <returns>The equivalent NFA</returns>
        private NFA BuildNFAFromClass(ASTNode node)
        {
            // extract the value
            string value = node.Value;

            value = value.Substring(1, value.Length - 2);
            bool positive = true;

            if (value.Length > 0 && value[0] == '^')
            {
                value    = value.Substring(1);
                positive = false;
            }
            // build the character spans
            List <CharSpan> spans = new List <CharSpan>();

            for (int i = 0; i != value.Length;)
            {
                // read the first full unicode character
                CharValue b = GetCharValue(value, i);
                i += b.length;
                if (b.chars[0] >= 0xD800 && b.chars[0] <= 0xDFFF)
                {
                    OnError(node.Position, "Unsupported non-plane 0 Unicode character ({0}) in character class", new String(b.chars));
                    return(BuildEpsilonNFA());
                }
                if ((i <= value.Length - 2) && (value[i] == '-'))
                {
                    // this is a range, match the '-'
                    i++;
                    CharValue e = GetCharValue(value, i);
                    i += e.length;
                    if (e.chars[0] >= 0xD800 && e.chars[0] <= 0xDFFF)
                    {
                        OnError(node.Position, "Unsupported non-plane 0 Unicode character ({0}) in character class", new String(e.chars));
                        return(BuildEpsilonNFA());
                    }
                    char begin = b.chars.Length == 1 ? b.chars[0] : b.chars[1];
                    char end   = e.chars.Length == 1 ? e.chars[0] : e.chars[1];
                    if (begin < 0xD800 && end > 0xDFFF)
                    {
                        // oooh you ...
                        spans.Add(new CharSpan(begin, (char)0xD7FF));
                        spans.Add(new CharSpan((char)0xE000, end));
                    }
                    else
                    {
                        spans.Add(new CharSpan(begin, end));
                    }
                }
                else
                {
                    // this is a normal character
                    char begin = b.chars.Length == 1 ? b.chars[0] : b.chars[1];
                    spans.Add(new CharSpan(begin, begin));
                }
            }
            // build the result
            NFA automata = NFA.NewMinimal();

            if (positive)
            {
                foreach (CharSpan span in spans)
                {
                    automata.StateEntry.AddTransition(span, automata.StateExit);
                }
            }
            else
            {
                spans.Sort(new System.Comparison <CharSpan>(CharSpan.Compare));
                // TODO: Check for span intersections and overflow of b (when a span ends on 0xFFFF)
                char b = (char)0;
                for (int i = 0; i != spans.Count; i++)
                {
                    if (spans[i].Begin > b)
                    {
                        automata.StateEntry.AddTransition(new CharSpan(b, (char)(spans[i].Begin - 1)), automata.StateExit);
                    }
                    b = (char)(spans[i].End + 1);
                    // skip the surrogate encoding points
                    if (b >= 0xD800 && b <= 0xDFFF)
                    {
                        b = (char)0xE000;
                    }
                }
                if (b <= 0xD7FF)
                {
                    automata.StateEntry.AddTransition(new CharSpan(b, (char)0xD7FF), automata.StateExit);
                    automata.StateEntry.AddTransition(new CharSpan((char)0xE000, (char)0xFFFF), automata.StateExit);
                }
                else if (b != 0xFFFF)
                {
                    // here b >= 0xE000
                    automata.StateEntry.AddTransition(new CharSpan(b, (char)0xFFFF), automata.StateExit);
                }
                // surrogate pairs
                NFAState intermediate = automata.AddNewState();
                automata.StateEntry.AddTransition(new CharSpan((char)0xD800, (char)0xDBFF), intermediate);
                intermediate.AddTransition(new CharSpan((char)0xDC00, (char)0xDFFF), automata.StateExit);
            }
            return(automata);
        }
Example #15
0
        private void WalkRuleNfaCreatingDgml(State state)
        {
            if (!_markedStates.Add(state.StateNumber))
            {
                return;
            }

            NFAState nfaState = state as NFAState;

            // create the node
            string nodeCategory;

            if (state.IsAcceptState)
            {
                nodeCategory = Categories.StopState;
            }
            else if (nfaState != null && nfaState.IsDecisionState)
            {
                nodeCategory = Categories.DecisionState;
            }
            else
            {
                nodeCategory = Categories.State;
            }

            XElement node = new XElement(Elements.Node,
                                         new XAttribute(Attributes.Id, "state_" + state.StateNumber),
                                         new XAttribute(Attributes.Label, GetStateLabel(state)),
                                         new XAttribute(Attributes.Category, nodeCategory));

            if (nfaState != null && nfaState.IsDecisionState)
            {
                string baseFileName = _grammar.name;
                if (_grammar.implicitLexer)
                {
                    baseFileName += Grammar.grammarTypeToFileNameSuffix[(int)_grammar.type];
                }

                string decisionPath = string.Format("{0}.dec-{1}.dgml", baseFileName, nfaState.DecisionNumber);
                node.Add(new XAttribute(Attributes.Reference, decisionPath));
            }

            _nodes.Add(state, node);
            if (GroupNodes)
            {
                _extraLinks.Add(CreateContainmentLink(_groupId, "state_" + state.StateNumber));
            }

            // don't go past end of rule
            if (state.IsAcceptState)
            {
                return;
            }

            // create links for each transition
            for (int i = 0; i < state.NumberOfTransitions; i++)
            {
                Transition            edge = state.GetTransition(i);
                RuleClosureTransition rr   = edge as RuleClosureTransition;
                if (rr != null)
                {
                    string label;

                    if (rr.Rule.Grammar != _grammar)
                    {
                        label = string.Format("<{0}.{1}>", rr.Rule.Grammar.name, rr.Rule.Name);
                    }
                    else
                    {
                        label = string.Format("<{0}>", rr.Rule.Name);
                    }

                    XElement link = new XElement(Elements.Link,
                                                 new XAttribute(Attributes.Source, "state_" + state.StateNumber),
                                                 new XAttribute(Attributes.Target, "state_" + rr.FollowState),
                                                 new XAttribute(Attributes.Category, Categories.RuleClosureEdge),
                                                 new XAttribute(Attributes.Label, label));

                    _links.Add(new KeyValuePair <State, Transition>(state, edge), link);
                    WalkRuleNfaCreatingDgml(rr.FollowState);
                }
                else
                {
                    string edgeCategory;

                    if (edge.IsAction)
                    {
                        edgeCategory = Categories.ActionEdge;
                    }
                    else if (edge.IsEpsilon)
                    {
                        edgeCategory = Categories.EpsilonEdge;
                    }
                    else if (edge.Label.IsSet || edge.Label.IsAtom)
                    {
                        edgeCategory = Categories.AtomEdge;
                    }
                    else
                    {
                        edgeCategory = Categories.Edge;
                    }

                    XElement link = new XElement(Elements.Link,
                                                 new XAttribute(Attributes.Source, "state_" + state.StateNumber),
                                                 new XAttribute(Attributes.Target, "state_" + edge.Target.StateNumber),
                                                 new XAttribute(Attributes.Category, edgeCategory),
                                                 new XAttribute(Attributes.Label, GetEdgeLabel(edge)));

                    _links.Add(new KeyValuePair <State, Transition>(state, edge), link);
                    WalkRuleNfaCreatingDgml(edge.Target);
                }
            }
        }
Example #16
0
        protected virtual string GetStateLabel(State s)
        {
            if (s == null)
            {
                return("null");
            }
            string stateLabel = s.stateNumber.ToString();

            if (s is DFAState)
            {
                StringBuffer buf = new StringBuffer(250);
                buf.Append('s');
                buf.Append(s.stateNumber);
                if (AntlrTool.internalOption_ShowNFAConfigsInDFA)
                {
                    if (s is DFAState)
                    {
                        if (((DFAState)s).abortedDueToRecursionOverflow)
                        {
                            buf.Append("\\n");
                            buf.Append("abortedDueToRecursionOverflow");
                        }
                    }
                    var alts = ((DFAState)s).AltSet;
                    if (alts != null)
                    {
                        buf.Append("\\n");
                        // separate alts
                        //List altList = new ArrayList();
                        //altList.addAll( alts );
                        //Collections.sort( altList );
                        List <int> altList = alts.OrderBy(i => i).ToList();
                        ICollection <NFAConfiguration> configurations = ((DFAState)s).nfaConfigurations;
                        for (int altIndex = 0; altIndex < altList.Count; altIndex++)
                        {
                            object altI = altList[altIndex];
                            int    alt  = (int)altI;
                            if (altIndex > 0)
                            {
                                buf.Append("\\n");
                            }
                            buf.Append("alt");
                            buf.Append(alt);
                            buf.Append(':');
                            // get a list of configs for just this alt
                            // it will help us print better later
                            IList configsInAlt = new List <object>();
                            foreach (NFAConfiguration c in configurations)
                            {
                                if (c.alt != alt)
                                {
                                    continue;
                                }
                                configsInAlt.Add(c);
                            }
                            int n = 0;
                            for (int cIndex = 0; cIndex < configsInAlt.Count; cIndex++)
                            {
                                NFAConfiguration c =
                                    (NFAConfiguration)configsInAlt[cIndex];
                                n++;
                                buf.Append(c.ToString(false));
                                if ((cIndex + 1) < configsInAlt.Count)
                                {
                                    buf.Append(", ");
                                }
                                if (n % 5 == 0 && (configsInAlt.Count - cIndex) > 3)
                                {
                                    buf.Append("\\n");
                                }
                            }
                        }
                    }
                }
                stateLabel = buf.ToString();
            }
            if ((s is NFAState) && ((NFAState)s).IsDecisionState)
            {
                stateLabel = stateLabel + ",d=" +
                             ((NFAState)s).DecisionNumber;
                if (((NFAState)s).endOfBlockStateNumber != State.INVALID_STATE_NUMBER)
                {
                    stateLabel += ",eob=" + ((NFAState)s).endOfBlockStateNumber;
                }
            }
            else if ((s is NFAState) &&
                     ((NFAState)s).endOfBlockStateNumber != State.INVALID_STATE_NUMBER)
            {
                NFAState n = ((NFAState)s);
                stateLabel = stateLabel + ",eob=" + n.endOfBlockStateNumber;
            }
            else if (s is DFAState && ((DFAState)s).IsAcceptState)
            {
                stateLabel = stateLabel +
                             "=>" + ((DFAState)s).GetUniquelyPredictedAlt();
            }
            return('"' + stateLabel + '"');
        }
Example #17
0
 private int NumberOfIncomingTransition(NFAState state)
 {
     return(_links.Count(i => i.Key.Value.Target == state));
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="NFACharTransition"/> class.
 /// </summary>
 /// <param name="match">The character to match</param>
 /// <param name="state">The target state</param>
 public NFACharTransition(char match, NFAState state) : base(state)
 {
     this.match = match;
 }
Example #19
0
 public NFAEdge(int symbol, NFAState targetState)
     : this()
 {
     Symbol = symbol;
     TargetState = targetState;
 }
 /// <summary>
 /// Creates a copy of this transition but with another target
 /// state.
 /// </summary>
 /// <param name="state">The new target state</param>
 /// <returns>An identical copy of this transition</returns>
 public override NFATransition Copy(NFAState state)
 {
     return(new NFACharTransition(this.match, state));
 }
Example #21
0
 public StateCluster( NFAState left, NFAState right )
 {
     this._left = left;
     this._right = right;
 }
Example #22
0
 public StartOfStringNFAState(NFAState exit)
     : base(RegExType.StartOfString)
 {
     this.exit = exit;
 }