📄 python.stg
字号:
/** 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) ::= <<if (<labelExpr>) <if(predicates)>and (<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) ::= <<<! FIXME: this is one of the few occasion, where I miss a switch statement in Python. ATM this is implemented as a list of if .. elif .. This may be replaced by faster a dictionary lookup, when I find a solution for the cases when an edge is not a plain dfaAcceptState.!>LA<decisionNumber> = self.input.LA(<k>)<edges; separator="\nel">else:<if(eotPredictsAlt)> alt<decisionNumber> = <eotPredictsAlt><else> <ruleBacktrackFailure()> nvae = NoViableAltException("<description>", <decisionNumber>, <stateNumber>, self.input)<\n> <@noViableAltException()> raise nvae<\n><endif>>>dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<LA<decisionNumber> = self.input.LA(<k>)<edges; separator="\nel">>>dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<LA<decisionNumber> = self.input.LA(<k>)<edges; separator="\nel"><if(eotPredictsAlt)>else: alt<decisionNumber> = <eotPredictsAlt><endif>>>dfaEdgeSwitch(labels, targetState) ::= <<if <labels:{LA<decisionNumber> == <it>}; separator=" or ">: <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> = self.dfa<decisionNumber>.predict(self.input)>>/* Dump DFA tables as run-length-encoded Strings of octal values. * Can't use hex as compiler translates them before compilation. * These strings are split into multiple, concatenated strings. * Java puts them back together at compile time thankfully. * Java cannot handle large static arrays, so we're stuck with this * encode/decode approach. See analysis and runtime DFA for * the encoding methods. */cyclicDFA(dfa) ::= <<# lookup tables for DFA #<dfa.decisionNumber>DFA<dfa.decisionNumber>_eot = DFA.unpack( u"<dfa.javaCompressedEOT; wrap="\"\n u\"">" )DFA<dfa.decisionNumber>_eof = DFA.unpack( u"<dfa.javaCompressedEOF; wrap="\"\n u\"">" )DFA<dfa.decisionNumber>_min = DFA.unpack( u"<dfa.javaCompressedMin; wrap="\"\n u\"">" )DFA<dfa.decisionNumber>_max = DFA.unpack( u"<dfa.javaCompressedMax; wrap="\"\n u\"">" )DFA<dfa.decisionNumber>_accept = DFA.unpack( u"<dfa.javaCompressedAccept; wrap="\"\n u\"">" )DFA<dfa.decisionNumber>_special = DFA.unpack( u"<dfa.javaCompressedSpecial; wrap="\"\n u\"">" ) DFA<dfa.decisionNumber>_transition = [ <dfa.javaCompressedTransition:{s|DFA.unpack(u"<s; wrap="\"\nu\"">")}; separator=",\n">]# class definition for DFA #<dfa.decisionNumber><if(dfa.specialStateSTs)>class DFA<dfa.decisionNumber>(DFA): def specialStateTransition(self_, s, input): # convince pylint that my self_ magic is ok ;) # pylint: disable-msg=E0213 # pretend we are a member of the recognizer # thus semantic predicates can be evaluated self = self_.recognizer _s = s <dfa.specialStateSTs:{state |if s == <i0>: <! compressed special state numbers 0..n-1 !> <state>}; separator="\nel"><if(backtracking)> if self.backtracking >0: self.failed = True return -1<\n><endif> nvae = NoViableAltException(self_.getDescription(), <dfa.decisionNumber>, _s, input) self_.error(nvae) raise nvae<\n><else>DFA<dfa.decisionNumber> = DFA<\n><endif>>>cyclicDFAInit(dfa) ::= <<self.dfa<dfa.decisionNumber> = self.DFA<dfa.decisionNumber>( self, <dfa.decisionNumber>, eot = self.DFA<dfa.decisionNumber>_eot, eof = self.DFA<dfa.decisionNumber>_eof, min = self.DFA<dfa.decisionNumber>_min, max = self.DFA<dfa.decisionNumber>_max, accept = self.DFA<dfa.decisionNumber>_accept, special = self.DFA<dfa.decisionNumber>_special, transition = self.DFA<dfa.decisionNumber>_transition )<\n>>>/** A state in a cyclic DFA; it's a special state and part of a big switch on * state. */cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= <<LA<decisionNumber>_<stateNumber> = input.LA(1)<\n><if(semPredState)> <! get next lookahead symbol to test edges, then rewind !>index<decisionNumber>_<stateNumber> = input.index()input.rewind()<\n><endif>s = -1<edges; separator="\nel"><if(semPredState)> <! return input cursor to state before we rewound !>input.seek(index<decisionNumber>_<stateNumber>)<\n><endif>if s >= 0: return s>>/** Just like a fixed DFA edge, test the lookahead and indicate what * state to jump to next if successful. */cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<if (<labelExpr>)<if(predicates)> and (<predicates>)<endif>: s = <targetStateNumber><\n>>>/** An edge pointing at end-of-token; essentially matches any char; * always jump to the target. */eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= <<se: s = <targetStateNumber><\n>>>// D F A E X P R E S S I O N SandPredicates(left,right) ::= "(<left> and <right>)"orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | or <o>}>)"notPredicate(pred) ::= "not (<evalPredicate(...)>)"evalPredicate(pred,description) ::= "<pred>"evalSynPredicate(pred,description) ::= "self.<pred>()"lookaheadTest(atom,k,atomAsInt) ::= "LA<decisionNumber>_<stateNumber> == <atom>"/** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable * somewhere. Must ask for the lookahead directly. */isolatedLookaheadTest(atom,k,atomAsInt) ::= "self.input.LA(<k>) == <atom>"lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <<(LA<decisionNumber>_<stateNumber> \>= <lower> and LA<decisionNumber>_<stateNumber> \<= <upper>)>>isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(self.input.LA(<k>) \>= <lower> and self.input.LA(<k>) \<= <upper>)"setTest(ranges) ::= "<ranges; separator=\" or \">"// A T T R I B U T E SglobalAttributeScopeClass(scope) ::= <<<if(scope.attributes)>class <scope.name>_scope(object): def __init__(self): <scope.attributes:{self.<it.decl> = None}; separator="\n"><endif>>>globalAttributeScopeStack(scope) ::= <<<if(scope.attributes)>self.<scope.name>_stack = []<\n><endif>>>ruleAttributeScopeClass(scope) ::= <<<if(scope.attributes)>class <scope.name>_scope(object): def __init__(self): <scope.attributes:{self.<it.decl> = None}; separator="\n"><endif>>>ruleAttributeScopeStack(scope) ::= <<<if(scope.attributes)>self.<scope.name>_stack = []<\n><endif>>>/** Define a rule label including default value */ruleLabelDef(label) ::= <<<label.label.text> = None<\n>>>/** Define a return struct for a rule if the code needs to access its * start/stop tokens, tree stuff, attributes, ... Leave a hole for * subgroups to stick in members. */returnScope(scope) ::= <<<if(ruleDescriptor.hasMultipleReturnValues)>class <ruleDescriptor.name>_return(object): def __init__(self): self.start = None self.stop = None <if(TREE_PARSER)> self.tree = None <endif> <scope.attributes:{self.<it.decl> = None}; separator="\n"> <@ruleReturnMembers()><endif>>>parameterScope(scope) ::= <<<scope.attributes:{<it.decl>}; separator=", ">>>parameterAttributeRef(attr) ::= "<attr.name>"parameterSetAttributeRef(attr,expr) ::= "<attr.name> = <expr>"scopeAttributeRef(scope,attr,index,negIndex) ::= <<<if(negIndex)>self.<scope>_stack[-<negIndex>].<attr.name><else><if(index)>self.<scope>_stack[<index>].<attr.name><else>self.<scope>_stack[-1].<attr.name><endif><endif>>>scopeSetAttributeRef(scope,attr,expr,index,negIndex) ::= <<<if(negIndex)><!FIXME: this seems not to be used by ActionTranslator...!>self.<scope>_stack[-<negIndex>].<attr.name> = <expr><else><if(index)><!FIXME: this seems not to be used by ActionTranslator...!>self.<scope>_stack[<index>].<attr.name> = <expr><else>self.<scope>_stack[-1].<attr.name> = <expr><endif><endif>>>/** $x is either global scope or x is rule with dynamic scope; refers * to stack itself not top of stack. This is useful for predicates * like {$function.size()>0 && $function::name.equals("foo")}? */isolatedDynamicScopeRef(scope) ::= "self.<scope>_stack"/** reference an attribute of rule; might only have single return value */ruleLabelRef(referencedRule,scope,attr) ::= <<<if(referencedRule.hasMultipleReturnValues)><scope>.<attr.name><else><scope><endif>>>returnAttributeRef(ruleDescriptor,attr) ::= <<<if(ruleDescriptor.hasMultipleReturnValues)>retval.<attr.name><else><attr.name><endif>>>returnSetAttributeRef(ruleDescriptor,attr,expr) ::= <<<if(ruleDescriptor.hasMultipleReturnValues)>retval.<attr.name> = <expr><else><attr.name> = <expr><endif>>>/** How to translate $tokenLabel */tokenLabelRef(label) ::= "<label>"/** ids+=ID {$ids} or e+=expr {$e} */listLabelRef(label) ::= "list_<label>"// not sure the next are the right approach; and they are evaluated early;// they cannot see TREE_PARSER or PARSER attributes for example. :(tokenLabelPropertyRef_text(scope,attr) ::= "<scope>.text"tokenLabelPropertyRef_type(scope,attr) ::= "<scope>.type"tokenLabelPropertyRef_line(scope,attr) ::= "<scope>.line"tokenLabelPropertyRef_pos(scope,attr) ::= "<scope>.charPositionInLine"tokenLabelPropertyRef_channel(scope,attr) ::= "<scope>.channel"tokenLabelPropertyRef_index(scope,attr) ::= "<scope>.index"tokenLabelPropertyRef_tree(scope,attr) ::= "<scope>_tree"ruleLabelPropertyRef_start(scope,attr) ::= "<scope>.start"ruleLabelPropertyRef_stop(scope,attr) ::= "<scope>.stop"ruleLabelPropertyRef_tree(scope,attr) ::= "<scope>.tree"ruleLabelPropertyRef_text(scope,attr) ::= <<<if(TREE_PARSER)>self.input.getTokenStream().toString( self.input.getTreeAdaptor().getTokenStartIndex(<scope>.start), self.input.getTreeAdaptor().getTokenStopIndex(<scope>.start) )<else>self.input.toString(<scope>.start,<scope>.stop)<endif>>>ruleLabelPropertyRef_st(scope,attr) ::= "<!FIXME(201:ST)!><scope>.st"/** Isolated $RULE ref ok in lexer as it's a Token */lexerRuleLabel(label) ::= "<label>"lexerRuleLabelPropertyRef_type(scope,attr) ::= "<scope>.type"lexerRuleLabelPropertyRef_line(scope,attr) ::= "<scope>.line"lexerRuleLabelPropertyRef_pos(scope,attr) ::= "<scope>.charPositionInLine"lexerRuleLabelPropertyRef_channel(scope,attr) ::= "<scope>.channel"lexerRuleLabelPropertyRef_index(scope,attr) ::= "<scope>.index"lexerRuleLabelPropertyRef_text(scope,attr) ::= "<scope>.text"// Somebody may ref $template or $tree or $stop within a rule:rulePropertyRef_start(scope,attr) ::= "retval.start"rulePropertyRef_stop(scope,attr) ::= "retval.stop" //mmm... or input.LT(-1)??rulePropertyRef_tree(scope,attr) ::= "retval.tree"rulePropertyRef_text(scope,attr) ::= "self.input.toString(retval.start, self.input.LT(-1))"rulePropertyRef_st(scope,attr) ::= "<!FIXME(203:ST)!>retval.st"lexerRulePropertyRef_text(scope,attr) ::= "self.text"lexerRulePropertyRef_type(scope,attr) ::= "self.type"lexerRulePropertyRef_line(scope,attr) ::= "self.tokenStartLine"lexerRulePropertyRef_pos(scope,attr) ::= "self.tokenStartCharPositionInLine"lexerRulePropertyRef_index(scope,attr) ::= "-1" // undefined token index in lexerlexerRulePropertyRef_channel(scope,attr) ::= "self.channel"lexerRulePropertyRef_start(scope,attr) ::= "self.tokenStartCharIndex"lexerRulePropertyRef_stop(scope,attr) ::= "(self.getCharIndex()-1)"// setting $st and $tree is allowed in local rule. everything else// is flagged as errorruleSetPropertyRef_tree(scope,attr,expr) ::= "retval.tree =<expr>"ruleSetPropertyRef_st(scope,attr,expr) ::= "<!FIXME(205:ST)!>retval.st =<expr>"/** How to execute an action */execAction(action) ::= <<<if(backtracking)><if(actions.(actionScope).synpredgate)>if <actions.(actionScope).synpredgate>: <action><else>if self.backtracking == 0: <action><endif><else>#action start<action>#action end<endif>>>// M I S C (properties, etc...)codeFileExtension() ::= ".py"true() ::= "True"false() ::= "False"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -