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)); }
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)); }