public PlusBlock(OutputModelFactory factory, GrammarAST plusRoot, IList <CodeBlockForAlt> alts) : base(factory, plusRoot, alts) { BlockAST blkAST = (BlockAST)plusRoot.GetChild(0); PlusBlockStartState blkStart = (PlusBlockStartState)blkAST.atnState; PlusLoopbackState loop = blkStart.loopBackState; stateNumber = blkStart.loopBackState.stateNumber; blockStartStateNumber = blkStart.stateNumber; loopBackStateNumber = loop.stateNumber; this.error = GetThrowNoViableAlt(factory, plusRoot, null); decision = loop.decision; }
public virtual Handle Plus([NotNull] GrammarAST plusAST, [NotNull] Handle blk) { PlusBlockStartState blkStart = (PlusBlockStartState)blk.left; BlockEndState blkEnd = (BlockEndState)blk.right; preventEpsilonClosureBlocks.Add(Tuple.Create <Rule, ATNState, ATNState>(currentRule, blkStart, blkEnd)); PlusLoopbackState loop = NewState <PlusLoopbackState>(plusAST); loop.nonGreedy = !((QuantifierAST)plusAST).GetGreedy(); loop.sll = false; // no way to express SLL restriction atn.DefineDecisionState(loop); LoopEndState end = NewState <LoopEndState>(plusAST); blkStart.loopBackState = loop; end.loopBackState = loop; plusAST.atnState = loop; Epsilon(blkEnd, loop); // blk can see loop back BlockAST blkAST = (BlockAST)plusAST.GetChild(0); if (((QuantifierAST)plusAST).GetGreedy()) { if (ExpectNonGreedy(blkAST)) { g.tool.errMgr.GrammarError(ErrorType.EXPECTED_NON_GREEDY_WILDCARD_BLOCK, g.fileName, plusAST.Token, plusAST.Token.Text); } Epsilon(loop, blkStart); // loop back to start Epsilon(loop, end); // or exit } else { // if not greedy, priority to exit branch; make it first Epsilon(loop, end); // exit Epsilon(loop, blkStart); // loop back to start } return(new Handle(blkStart, end)); }