📄 ruby.stg
字号:
<< raise "filteringActionGate not implemented">>// S U B R U L E S/** A (...) subrule with multiple alternatives */block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::=<<<switchBlock(...)>>>/** A rule block with multiple alternatives */ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::=<<<switchBlock(...)>>>/** * decision, decisionNumber don't seem to be relevant in this template * alts actually has a single element */ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::=<<<plainBlock(...)>>>/** A special case of a (...) subrule with a single alternative */blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description) ::=<<<plainBlock(...)>>>/** A (..)+ block with 0 or more alternatives */positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::=<<# <description>matchedOnce<decisionNumber> = false<decls>while true alt<decisionNumber> = <maxAlt> <decision> case alt<decisionNumber> <alts:switchCase(); separator="\n"> else break end matchedOnce<decisionNumber> = trueendif !matchedOnce<decisionNumber> raise "Expected at least one match: <description>"end>>positiveClosureBlockSingleAlt ::= positiveClosureBlock/** A (..)* block with 0 or more alternatives */closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description) ::=<<# <description><decls>while true alt<decisionNumber> = <maxAlt> <decision> case alt<decisionNumber> <alts:switchCase(); separator="\n"> else break endend>>closureBlockSingleAlt ::= closureBlock/** Optional blocks (x)? are translated to (x|) by before code generation * so we can just use the normal block template */optionalBlock ::= blockoptionalBlockSingleAlt ::= block/** An alternative is just a list of elements; at outermost level */alt(elements,altNum,description,autoAST,outerAlt)::=<<# <description><elements: element(); separator="\n">>>// E L E M E N T S/** match a token optionally with a label in front */tokenRef(token,label,elementIndex)::=<<<if(label)>_<label> = @input.look_ahead(1)<\n><endif>match(:<token>)>>/** ids+=ID */tokenRefAndListLabel(token,label,elementIndex)::=<<<tokenRef(...)><listLabel(...)>>>listLabel(label,elem)::=<<list_<label> ||= []list_<label> \<\< _<label>>>/** match a character */charRef(char,label)::=<<<if(label)>_<label> = <char><\n><endif>match(<char>)>>/** match a character range */charRangeRef(a,b)::=<<match_range(<a>, <b>)>>/** For now, sets are interval tests and must be tested inline */matchSet(s,label,elementIndex,postmatchCode)::=<<<if(label)>_<label> = <LA(1)><\n><endif>if <s> <postmatchCode> match()else raise "Expected set"end>>matchSetAndListLabel(s,label,elementIndex,postmatchCode)::=<<<matchSet(...)><listLabel(...)>>>/** Match a string literal */lexerStringRef(string,label)::=<<<if(label)>_<label> = <string><\n><else>match(<string>)<\n><endif>>>wildcard(label, elementIndex)::=<<<if(label)>_<label> = <LA(1)><\n><endif>match()>>wildcardAndListLabel(label,elementIndex)::=<<<wildcard(...)><listLabel(...)>>>/** Match . wildcard in lexer */wildcardChar(label, elementIndex)::=<<<if(label)>_<label> = <LA(1)><\n><endif>match()>>wildcardCharListLabel(label, elementIndex)::=<< raise "wildcardCharListLabel not implemented">>/** Match a rule reference by invoking it possibly with arguments * and a return value or values. */ruleRef(rule,label,elementIndex,args)::=<<<if(label)><label> = <rule>(<args; separator=", ">)<\n><else><rule>(<args; separator=", ">)<\n><endif>>>/** ids+=ID */ruleRefAndListLabel(rule,label,elementIndex,args)::=<< raise "ruleRefAndListLabel not implemented">>/** A lexer rule reference */lexerRuleRef(rule,label,args)::=<<match_<rule>(<args; separator=", ">)>>/** EOF in the lexer */lexerMatchEOF(label)::=<<<if(label)>_<label> = :EOF<\n><endif>match(:EOF)>>/** match ^(root children) in tree parser */tree(root, children, nullableChildList)::=<< raise "tree not implemented">>/** Every predicate is used as a validating predicate (even when it is * also hoisted into a prediction expression). */validateSemanticPredicate(pred,description)::=<<# <description>if !<evalPredicate(...)> raise "Semantic predicate failed: #{<description>}"end>>// F i x e d D F A (if-then-else)dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>look_ahead<decisionNumber>_<stateNumber> = <LA(k)><if(LEXER)>look_ahead<decisionNumber>_<stateNumber> = -1 if look_ahead<decisionNumber>_<stateNumber> == :EOF<endif>if <edges; separator="\nelsif ">else<if(eotPredictsAlt)> alt<decisionNumber> = <eotPredictsAlt><\n><else> raise "Expected: <description>"<\n><endif>end>>/** Same as a normal DFA state except that we don't examine lookahead * for the bypass alternative. It delays error detection but this * is faster, smaller, and more what people expect. For (X)? people * expect "if ( LA(1)==X ) match(X);" and that's it. * * If a semPredState, don't force lookahead lookup; preds might not * need. */dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>look_ahead<decisionNumber>_<stateNumber> = <LA(k)><if(LEXER)>look_ahead<decisionNumber>_<stateNumber> = -1 if look_ahead<decisionNumber>_<stateNumber> == :EOF<endif>if <edges; separator="\nelsif ">end>>/** A DFA state that is actually the loopback decision of a closure * loop. If end-of-token (EOT) predicts any of the targets then it * should act like a default clause (i.e., no error can be generated). * This is used only in the lexer so that for ('a')* on the end of a * rule anything other than 'a' predicts exiting. * * If a semPredState, don't force lookahead lookup; preds might not * need. */dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>look_ahead<decisionNumber>_<stateNumber> = <LA(k)><if(LEXER)>look_ahead<decisionNumber>_<stateNumber> = -1 if look_ahead<decisionNumber>_<stateNumber> == :EOF<endif>if <edges; separator="\nelsif "><if(eotPredictsAlt)>else alt<decisionNumber> = <eotPredictsAlt><endif>end>>/** An accept state indicates a unique alternative has been predicted *//** It is not clear that decisionNumber is available here */dfaAcceptState(alt) ::= "alt<decisionNumber> = <alt>"/** A simple edge with an expression. If the expression is satisfied, * enter to the target state. To handle gated productions, we may * have to evaluate some predicates for this edge. */dfaEdge(labelExpr, targetState, predicates)::=<<<labelExpr> <if(predicates)>&& <predicates><endif> <targetState>>>// F i x e d D F A (switch case)/** A DFA state where a SWITCH may be generated. The code generator * decides if this is possible: CodeGenerator.canGenerateSwitch(). */dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>case <LA(k)> <edges; separator="\n"> else <if(eotPredictsAlt)> alt<decisionNumber> = <eotPredictsAlt><\n> <else> raise "Expected: <description>"<\n> <endif>end>>/** * eotPredictsAlt is not relevant here */dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>case <LA(k)> <edges; separator="\n">end>>dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState)::=<<# <description>case <LA(k)> <edges; separator="\n"> <if(eotPredictsAlt)><\n> else alt<decisionNumber> = <eotPredictsAlt> <endif>end>>dfaEdgeSwitch(labels, targetState)::=<<<if(PARSER)>when <labels:{:<it>}; separator=","><\n><else>when <labels:{<it>}; separator=","><\n><endif> <targetState>>>// C y c l i c D F A/** The code to initiate execution of a cyclic DFA; this is used * in the rule to predict an alt just like the fixed DFA case. * The <name> attribute is inherited via the parser, lexer, ... */dfaDecision(decisionNumber,description)::=<<alt<decisionNumber> = DFA<decisionNumber>.predict(self, @input)>>/** Generate the tables and support code needed for the DFAState object * argument. Unless there is a semantic predicate (or syn pred, which * become sem preds), all states should be encoded in the state tables. * Consequently, cyclicDFAState/cyclicDFAEdge,eotDFAEdge templates are * not used except for special DFA states that cannot be encoded as * a transition table. */cyclicDFA(dfa)::=<<DFA<dfa.decisionNumber> = DFA.new( [<dfa.eot; wrap="\n ", separator=",", null="-1">], [<dfa.eof; wrap="\n ", separator=",", null="-1">], [<dfa.min; wrap="\n ", separator=",", null="0">], [<dfa.max; wrap="\n ", separator=",", null="0">], [<dfa.accept; wrap="\n ", separator=",", null="-1">], [<dfa.special; wrap="\n ", separator=",", null="-1">], [ <dfa.transition:{s | [<s; wrap="\n ", separator=",", null="-1">]}; separator=",\n", null=""> ])def special_state_transition(s) <if(dfa.specialStateSTs)> case s <dfa.specialStateSTs:{state | when <i0> <state>}; separator="\n"> end raise "Expected: <dfa.description>" <else> -1 <endif>endpublic :special_state_transition>>/** A special state in a cyclic DFA; special means has a semantic predicate * or it's a huge set of symbols to check. */cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState)::=<< <if(semPredState)> @input.rewind(0) <else>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -