Ejemplo n.º 1
0
        /** identify the ATN states where we need to set the outer alt number.
         *  For regular rules, that's the block at the target to rule start state.
         *  For left-recursive rules, we track the primary block, which looks just
         *  like a regular rule's outer block, and the star loop block (always
         *  there even if 1 alt).
         */
        public virtual BitSet FindOuterMostDecisionStates()
        {
            BitSet track             = new BitSet(atn.states.Count);
            int    numberOfDecisions = atn.NumberOfDecisions;

            for (int i = 0; i < numberOfDecisions; i++)
            {
                DecisionState  decisionState = atn.GetDecisionState(i);
                RuleStartState startState    = atn.ruleToStartState[decisionState.ruleIndex];
                // Look for StarLoopEntryState that is in any left recursive rule
                if (decisionState is StarLoopEntryState)
                {
                    StarLoopEntryState loopEntry = (StarLoopEntryState)decisionState;
                    if (loopEntry.precedenceRuleDecision)
                    {
                        // Recursive alts always result in a (...)* in the transformed
                        // left recursive rule and that always has a BasicBlockStartState
                        // even if just 1 recursive alt exists.
                        ATNState blockStart = loopEntry.Transition(0).target;
                        // track the StarBlockStartState associated with the recursive alternatives
                        track.Set(blockStart.stateNumber);
                    }
                }
                else if (startState.Transition(0).target == decisionState)
                {
                    // always track outermost block for any rule if it exists
                    track.Set(decisionState.stateNumber);
                }
            }
            return(track);
        }
Ejemplo n.º 2
0
        public StarBlock(OutputModelFactory factory,
                         GrammarAST blkOrEbnfRootAST,
                         IList <CodeBlockForAlt> alts)
            : base(factory, blkOrEbnfRootAST, alts)
        {
            loopLabel = factory.GetTarget().GetLoopLabel(blkOrEbnfRootAST);
            StarLoopEntryState star = (StarLoopEntryState)blkOrEbnfRootAST.atnState;

            loopBackStateNumber = star.loopBackState.stateNumber;
            decision            = star.decision;
        }
Ejemplo n.º 3
0
        public LL1StarBlockSingleAlt(OutputModelFactory factory, GrammarAST starRoot, IList <CodeBlockForAlt> alts)
            : base(factory, starRoot, alts)
        {
            StarLoopEntryState star = (StarLoopEntryState)starRoot.atnState;

            loopBackStateNumber = star.loopBackState.stateNumber;
            this.decision       = star.decision;
            IntervalSet[] altLookSets = factory.GetGrammar().decisionLOOK[decision];
            Debug.Assert(altLookSets.Length == 2);
            IntervalSet enterLook = altLookSets[0];
            IntervalSet exitLook  = altLookSets[1];

            loopExpr = AddCodeForLoopLookaheadTempVar(enterLook);
        }
Ejemplo n.º 4
0
        public virtual Handle Star([NotNull] GrammarAST starAST, [NotNull] Handle elem)
        {
            StarBlockStartState blkStart = (StarBlockStartState)elem.left;

            BlockEndState blkEnd = (BlockEndState)elem.right;

            preventEpsilonClosureBlocks.Add(Tuple.Create <Rule, ATNState, ATNState>(currentRule, blkStart, blkEnd));

            StarLoopEntryState entry = NewState <StarLoopEntryState>(starAST);

            entry.nonGreedy = !((QuantifierAST)starAST).GetGreedy();
            entry.sll       = false; // no way to express SLL restriction
            atn.DefineDecisionState(entry);
            LoopEndState      end  = NewState <LoopEndState>(starAST);
            StarLoopbackState loop = NewState <StarLoopbackState>(starAST);

            entry.loopBackState = loop;
            end.loopBackState   = loop;

            BlockAST blkAST = (BlockAST)starAST.GetChild(0);

            if (((QuantifierAST)starAST).GetGreedy())
            {
                if (ExpectNonGreedy(blkAST))
                {
                    g.tool.errMgr.GrammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, starAST.Token, starAST.Token.Text);
                }

                Epsilon(entry, blkStart);   // loop enter edge (alt 1)
                Epsilon(entry, end);        // bypass loop edge (alt 2)
            }
            else
            {
                // if not greedy, priority to exit branch; make it first
                Epsilon(entry, end);      // bypass loop edge (alt 1)
                Epsilon(entry, blkStart); // loop enter edge (alt 2)
            }
            Epsilon(blkEnd, loop);        // block end hits loop back
            Epsilon(loop, entry);         // loop back to entry/exit decision

            starAST.atnState = entry;     // decision is to enter/exit; blk is its own decision
            return(new Handle(entry, end));
        }