📄 buildnfa.g
字号:
{ if ( blk.setValue!=null ) { b = factory.build_AlternativeBlockFromSet(b); } g = factory.build_Aplus(b); // don't make a decision on left edge, can reuse loop end decision // track the loop back / exit decision point b.right.setDescription("()+ loopback of "+grammar.grammarTreeToString(#ebnf,false)); int d = grammar.assignDecisionNumber( b.right ); grammar.setDecisionNFA(d, b.right); grammar.setDecisionBlockAST(d, blk); b.right.setDecisionASTNode(eob); // make block entry state also have same decision for interpreting grammar NFAState altBlockState = (NFAState)g.left.transition(0).target; altBlockState.setDecisionASTNode(#ebnf); altBlockState.setDecisionNumber(d); } ;tree returns [StateCluster g=null]{StateCluster e=null;GrammarAST el=null;StateCluster down=null, up=null;} : #( TREE_BEGIN {el=(GrammarAST)_t;} g=element { down = factory.build_Atom(Label.DOWN); // TODO set following states for imaginary nodes? //el.followingNFAState = down.right; g = factory.build_AB(g,down); } ( {el=(GrammarAST)_t;} e=element {g = factory.build_AB(g,e);} )* { up = factory.build_Atom(Label.UP); //el.followingNFAState = up.right; g = factory.build_AB(g,up); // tree roots point at right edge of DOWN for LOOK computation later #tree.NFATreeDownState = down.left; } ) ;atom_or_notatom returns [StateCluster g=null] : g=atom | #( n:NOT ( c:CHAR_LITERAL (ast1:ast_suffix)? { int ttype=0; if ( grammar.type==Grammar.LEXER ) { ttype = Grammar.getCharValueFromGrammarCharLiteral(#c.getText()); } else { ttype = grammar.getTokenType(#c.getText()); } IntSet notAtom = grammar.complement(ttype); if ( notAtom.isNil() ) { ErrorManager.grammarError(ErrorManager.MSG_EMPTY_COMPLEMENT, grammar, #c.token, #c.getText()); } g=factory.build_Set(notAtom); } | t:TOKEN_REF (ast3:ast_suffix)? { int ttype=0; IntSet notAtom = null; if ( grammar.type==Grammar.LEXER ) { notAtom = grammar.getSetFromRule(this,#t.getText()); if ( notAtom==null ) { ErrorManager.grammarError(ErrorManager.MSG_RULE_INVALID_SET, grammar, #t.token, #t.getText()); } else { notAtom = grammar.complement(notAtom); } } else { ttype = grammar.getTokenType(#t.getText()); notAtom = grammar.complement(ttype); } if ( notAtom==null || notAtom.isNil() ) { ErrorManager.grammarError(ErrorManager.MSG_EMPTY_COMPLEMENT, grammar, #t.token, #t.getText()); } g=factory.build_Set(notAtom); } | g=set { GrammarAST stNode = (GrammarAST)n.getFirstChild(); //IntSet notSet = grammar.complement(stNode.getSetValue()); // let code generator complement the sets IntSet s = stNode.getSetValue(); stNode.setSetValue(s); // let code gen do the complement again; here we compute // for NFA construction s = grammar.complement(s); if ( s.isNil() ) { ErrorManager.grammarError(ErrorManager.MSG_EMPTY_COMPLEMENT, grammar, #n.token); } g=factory.build_Set(s); } ) {#n.followingNFAState = g.right;} ) ;atom returns [StateCluster g=null] : #( r:RULE_REF (rarg:ARG_ACTION)? (as1:ast_suffix)? ) { NFAState start = grammar.getRuleStartState(r.getText()); if ( start!=null ) { int ruleIndex = grammar.getRuleIndex(r.getText()); g = factory.build_RuleRef(ruleIndex, start); r.followingNFAState = g.right; if ( g.left.transition(0) instanceof RuleClosureTransition && grammar.type!=Grammar.LEXER ) { addFollowTransition(r.getText(), g.right); } // else rule ref got inlined to a set } } | #( t:TOKEN_REF (targ:ARG_ACTION)? (as2:ast_suffix)? ) { if ( grammar.type==Grammar.LEXER ) { NFAState start = grammar.getRuleStartState(t.getText()); if ( start!=null ) { int ruleIndex = grammar.getRuleIndex(t.getText()); g = factory.build_RuleRef(ruleIndex, start); // don't add FOLLOW transitions in the lexer; // only exact context should be used. } } else { int tokenType = grammar.getTokenType(t.getText()); g = factory.build_Atom(tokenType); t.followingNFAState = g.right; } } | #( c:CHAR_LITERAL (as3:ast_suffix)? ) { if ( grammar.type==Grammar.LEXER ) { g = factory.build_CharLiteralAtom(c.getText()); } else { int tokenType = grammar.getTokenType(c.getText()); g = factory.build_Atom(tokenType); c.followingNFAState = g.right; } } | #( s:STRING_LITERAL (as4:ast_suffix)? ) { if ( grammar.type==Grammar.LEXER ) { g = factory.build_StringLiteralAtom(s.getText()); } else { int tokenType = grammar.getTokenType(s.getText()); g = factory.build_Atom(tokenType); s.followingNFAState = g.right; } } | #( w:WILDCARD (as5:ast_suffix)? ) {g = factory.build_Wildcard();} //| g=set ;ast_suffix{if ( grammar.getOption("output")==null ) { ErrorManager.grammarError(ErrorManager.MSG_REWRITE_OR_OP_WITH_NO_OUTPUT_OPTION, grammar, #ast_suffix.token, currentRuleName);}} : ROOT | BANG ;set returns [StateCluster g=null]{IntSet elements=new IntervalSet();#set.setSetValue(elements); // track set for use by code gen} : #( b:BLOCK (#(ALT (BACKTRACK_SEMPRED)? setElement[elements] EOA))+ EOB ) { g = factory.build_Set(elements); #b.followingNFAState = g.right; #b.setValue = elements; // track set value of this block } //{System.out.println("set elements="+elements.toString(grammar));} ;setRule returns [IntSet elements=new IntervalSet()]{IntSet s=null;} : #( RULE id:ID (modifier)? ARG RET ( OPTIONS )? ( ruleScopeSpec )? (AMPERSAND)* #( BLOCK ( OPTIONS )? ( #(ALT setElement[elements] EOA) )+ EOB ) (exceptionGroup)? EOR ) ; exception catch[RecognitionException re] {throw re;}setElement[IntSet elements]{ int ttype; IntSet ns=null; StateCluster gset;} : c:CHAR_LITERAL { if ( grammar.type==Grammar.LEXER ) { ttype = Grammar.getCharValueFromGrammarCharLiteral(c.getText()); } else { ttype = grammar.getTokenType(c.getText()); } if ( elements.member(ttype) ) { ErrorManager.grammarError(ErrorManager.MSG_DUPLICATE_SET_ENTRY, grammar, #c.token, #c.getText()); } elements.add(ttype); } | t:TOKEN_REF { if ( grammar.type==Grammar.LEXER ) { // recursively will invoke this rule to match elements in target rule ref IntSet ruleSet = grammar.getSetFromRule(this,#t.getText()); if ( ruleSet==null ) { ErrorManager.grammarError(ErrorManager.MSG_RULE_INVALID_SET, grammar, #t.token, #t.getText()); } else { elements.addAll(ruleSet); } } else { ttype = grammar.getTokenType(t.getText()); if ( elements.member(ttype) ) { ErrorManager.grammarError(ErrorManager.MSG_DUPLICATE_SET_ENTRY, grammar, #t.token, #t.getText()); } elements.add(ttype); } } | s:STRING_LITERAL { ttype = grammar.getTokenType(s.getText()); if ( elements.member(ttype) ) { ErrorManager.grammarError(ErrorManager.MSG_DUPLICATE_SET_ENTRY, grammar, #s.token, #s.getText()); } elements.add(ttype); } | #(CHAR_RANGE c1:CHAR_LITERAL c2:CHAR_LITERAL) { if ( grammar.type==Grammar.LEXER ) { int a = Grammar.getCharValueFromGrammarCharLiteral(c1.getText()); int b = Grammar.getCharValueFromGrammarCharLiteral(c2.getText()); elements.addAll(IntervalSet.of(a,b)); } } | gset=set { Transition setTrans = gset.left.transition(0); elements.addAll(setTrans.label.getSet()); } | #( NOT {ns=new IntervalSet();} setElement[ns] { IntSet not = grammar.complement(ns); elements.addAll(not); } ) ;/** Check to see if this block can be a set. Can't have actions * etc... Also can't be in a rule with a rewrite as we need * to track what's inside set for use in rewrite. */testBlockAsSet{ int nAlts=0; Rule r = grammar.getRule(currentRuleName);} : #( BLOCK ( #(ALT (BACKTRACK_SEMPRED)? testSetElement {nAlts++;} EOA) {!r.hasRewrite(outerAltNum)}? )+ EOB ) {nAlts>1}? // set of 1 element is not good ; exception catch[RecognitionException re] {throw re;}testSetRule : #( RULE id:ID (modifier)? ARG RET ( OPTIONS )? ( ruleScopeSpec )? (AMPERSAND)* #( BLOCK ( #(ALT (BACKTRACK_SEMPRED)? testSetElement EOA) )+ EOB ) (exceptionGroup)? EOR ) ; exception catch[RecognitionException re] {throw re;}/** Match just an element; no ast suffix etc.. */testSetElement{AST r = _t;} : c:CHAR_LITERAL | t:TOKEN_REF { if ( grammar.type==Grammar.LEXER ) { Rule rule = grammar.getRule(#t.getText()); if ( rule==null ) { throw new RecognitionException("invalid rule"); } // recursively will invoke this rule to match elements in target rule ref testSetRule(rule.tree); } } | {grammar.type!=Grammar.LEXER}? s:STRING_LITERAL | #(CHAR_RANGE c1:CHAR_LITERAL c2:CHAR_LITERAL) | testBlockAsSet | #( NOT testSetElement ) ; exception catch[RecognitionException re] {throw re;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -