📄 cpp.stg
字号:
*/dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<<if(!semPredState)><tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(<k>);<endif><edges; separator="\nelse ">>>/** 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. */dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<<if(!semPredState)><tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(<k>);<endif><edges; separator="\nelse "><\n><if(eotPredictsAlt)>else { alt<decisionNumber> = <eotPredictsAlt>;}<\n><endif>>>/** An accept state indicates a unique alternative has been predicted */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) ::= <<if ( (<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) ::= <<switch ( input.LA(<k>) ) {<edges; separator="\n">default:<if(eotPredictsAlt)> alt<decisionNumber> = <eotPredictsAlt>;<else> NoViableAltException nvae( input.getPosition(), "<description>", <decisionNumber>, <stateNumber> );<\n> <@noViableAltException()> throw nvae;<\n><endif>}<\n>>>dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<switch ( input.LA(<k>) ) { <edges; separator="\n">}<\n>>>dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState) ::= <<switch ( input.LA(<k>) ) {<edges; separator="\n"><\n><if(eotPredictsAlt)>default: alt<decisionNumber> = <eotPredictsAlt>; break;<\n><endif>}<\n>>>dfaEdgeSwitch(labels, targetState) ::= <<<labels:{case <it>:}; separator="\n"> { <targetState>} break;>>// 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) ::= <<// dfaDecisionalt<decisionNumber> = predictDFA<decisionNumber>(input);>>/** The overall cyclic DFA chunk; contains all the DFA states */cyclicDFA(dfa) ::= <</* cyclicDFA=<dfa>*/// cyclic = <dfa.cyclic>// numstates = <dfa.numberOfStates>// startState = <dfa.startState>// startState.numberOfTransitions = <dfa.startState.NumberOfTransitions>// startState.lookaheadDepth = <dfa.startState.LookaheadDepth>const static short <name>dfa<dfa.decisionNumber>_eot[<dfa.numberOfStates>] = { <dfa.eot; wrap="\n ", separator=",", null="-1">};const static short <name>dfa<dfa.decisionNumber>_eof[<dfa.numberOfStates>] = { <dfa.eof; wrap="\n ", separator=",", null="-1">};const static unichar <name>dfa<dfa.decisionNumber>_min[<dfa.numberOfStates>] = { <dfa.min; wrap="\n ", separator=",", null="0">};const static unichar <name>dfa<dfa.decisionNumber>_max[<dfa.numberOfStates>] = { <dfa.max; wrap="\n ", separator=",", null="0">};const static short <name>dfa<dfa.decisionNumber>_accept[<dfa.numberOfStates>] = { <dfa.accept; wrap="\n ", separator=",", null="-1">};const static short <name>dfa<dfa.decisionNumber>_special[<dfa.numberOfStates>] = { <dfa.special; wrap="\n ", separator=",", null="-1">};<dfa.edgeTransitionClassMap.keys:{ table |const static short <name>dfa<dfa.decisionNumber>_transition<i0>[] = { <table; separator=", ", wrap="\n ", null="-1">};}; null="">const static short <name>dfa<dfa.decisionNumber>_transition[] = { <dfa.transitionEdgeTables:{whichTable|<name>dfa<dfa.decisionNumber>_transition<whichTable>,}; separator="\n", null="0 /* fixme? */">}; <! add attribute for the DFA !> DFA\<char_type> dfa<dfa.decisionNumber>;<! this should go in the initializer of the thing- (id) init{ if ((self = [super init]) != nil) { eot = <name>dfa<dfa.decisionNumber>_eot; eof = <name>dfa<dfa.decisionNumber>_eof; min = <name>dfa<dfa.decisionNumber>_min; max = <name>dfa<dfa.decisionNumber>_max; accept = <name>dfa<dfa.decisionNumber>_accept; special = <name>dfa<dfa.decisionNumber>_special; if (!(transition = calloc(<dfa.numberOfStates>, sizeof(void*)))) { [self release]; return nil; } <dfa.transitionEdgeTables:{whichTable|transition[<i0>] = <name>dfa<dfa.decisionNumber>_transition<whichTable>;}; separator="\n", null=""> } return self;}!><if(dfa.specialStateSTs)>int specialStateTransition( int state ){ int s = state; switch ( s ) { <dfa.specialStateSTs:{state | case <i0> : <! compressed special state numbers 0..n-1 !> <state>}; separator="\n"> }<if(backtracking)> if ( recognizer.isBacktracking() ) { recognizer.setFailed(); return -1; }<\n><endif> noViableAlt(s, input);}<\n><endif><\n>// <dfa.description>decision_type predictDFA<dfa.decisionNumber>( StreamType& input ){ /* mark current location (rewind automatically when the rewinder goes * out of scope */ antlr3::Rewinder\<position_type> markPoint(input.getPosition()); goto s0; // goto start... // ... throw NoViableAltException( input.getPosition(), "<dfa.description>", <dfa.decisionNumber>, 0 /* fixme */ );<\n>}<\n>>>/** A state in a cyclic DFA */cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState) ::= <<// cyclicDFAStates<stateNumber>: { <if(semPredState)> input.rewind();<\n> <else> <tokenid_type()> LA<decisionNumber>_<stateNumber> = input.LA(1); <endif> <edges> <if(needErrorClause)> throw NoViableAltException( input.getPosition(), "<description>", <decisionNumber>, <stateNumber> );<\n> <endif><\n>}<\n>>>/** Just like a fixed DFA edge, test the lookahead and indicate what * state to jump to next if successful. */cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates) ::= <<// cyclicDFAEdgeif ( (<labelExpr>) <if(predicates)>&& (<predicates>)<endif>){ input.consume(); goto s<targetStateNumber>;}<\n>>>/** An edge pointing at end-of-token; essentially matches any char; * always jump to the target. */eotDFAEdge(targetStateNumber,edgeNumber, predicates) ::= "goto s<targetStateNumber>;"// D F A E X P R E S S I O N SandPredicates(left,right) ::= "(<left> && <right>)"orPredicates(operands) ::= "(<first(operands)><rest(operands):{o | ||<o>}>)"notPredicate(pred) ::= "!(<pred>)"evalPredicate(pred,description) ::= "<pred>"evalSynPredicate(pred,description) ::= "<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) ::= "input.LA(<k>)==<atom>"lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= <<(LA<decisionNumber>_<stateNumber>\>=<lower> && LA<decisionNumber>_<stateNumber>\<=<upper>)>>isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt) ::= "(input.LA(<k>)\>=<lower> && input.LA(<k>)\<=<upper>)"setTest(ranges) ::= "<ranges; separator=\"||\">"// A T T R I B U T E SglobalAttributeScope(scope) ::= <<<if(scope.attributes)>protected static class <scope.name> { <scope.attributes:{<it.decl>;}; separator="\n">}protected Stack <scope.name>_stack = new Stack();<\n><endif>>>ruleAttributeScope(scope) ::= <<<if(scope.attributes)>protected static class <scope.name>_scope { <scope.attributes:{<it.decl>;}; separator="\n">}protected Stack <scope.name>_stack = new Stack();<\n><endif>>>returnType() ::= <<<if(ruleDescriptor.hasMultipleReturnValues)><ruleDescriptor.name>_return<else><if(ruleDescriptor.singleValueReturnType)><ruleDescriptor.singleValueReturnType><else>void<endif><endif>>>ruleLabelType(referencedRule) ::= <<<if(referencedRule.hasMultipleReturnValues)><referencedRule.name>_return<else><if(referencedRule.singleValueReturnType)><referencedRule.singleValueReturnType><else>void<endif><endif>>>/** Using a type to init value map, try to init a type; if not in table * must be an object, default value is "null". */initValue(typeName) ::= <<<javaTypeInitMap.(typeName)>>>ruleLabelDef(label) ::= <<<ruleLabelType(referencedRule=label.referencedRule)> <label.label.text> = <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;<\n>>>returnScope(scope) ::= <<<if(ruleDescriptor.hasMultipleReturnValues)>public static class <returnType()> { <labelType> start, stop;<if(buildAST)> <ASTLabelType> tree;<else><if(buildTemplate)> StringTemplate st;<endif><endif> <scope.attributes:{<it.decl>;}; separator="\n">};<endif>>>parameterScope(scope) ::= <<<scope.attributes:{<it.decl>}; separator=", ">>>/** Used in codegen.g to translate $x.y references. * I could have left actions as StringTemplates to be inserted in * the output (so they could use attributes inherited from surrounding * templates), but really wanted to pass in AttributeScope and Attribute * objects so this translation could query them. So, translation of * $x.y to executable code occurs before recognizerST.toString() occurs. * I.e., actions are just text strings during final code generation. */globalAttributeRef(scope,attr) ::= <<((<scope>)<scope>_stack.peek()).<attr.name>>>parameterAttributeRef(attr) ::= "<attr.name>"scopeAttributeRef(scope,attr,index,negIndex) ::= <<<if(negIndex)>((<scope>_scope)<scope>_stack.elementAt(<scope>_stack.size()-<negIndex>-1)).<attr.name><else><if(index)>((<scope>_scope)<scope>_stack.elementAt(<index>)).<attr.name><else>((<scope>_scope)<scope>_stack.peek()).<attr.name><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) ::= "<scope>_stack"/** reference an attribute of rule; might only have single return value */ruleLabelRef(referencedRule,scope,attr) ::= <<<if(referencedRule.singleValueReturnType)><scope><else><scope>.<attr.name><endif>>>returnAttributeRef(ruleDescriptor,attr) ::= <<<if(ruleDescriptor.singleValueReturnType)><attr.name><else>retval.<attr.name><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>.getText()"tokenLabelPropertyRef_type(scope,attr) ::= "<scope>.getType()"tokenLabelPropertyRef_line(scope,attr) ::= "<scope>.getLine()"tokenLabelPropertyRef_pos(scope,attr) ::= "<scope>.getCharPositionInLine()"tokenLabelPropertyRef_channel(scope,attr) ::= "<scope>.getChannel()"tokenLabelPropertyRef_index(scope,attr) ::= "<scope>.getTokenIndex()"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) ::= "input.toString(<scope>.start,<scope>.stop)"ruleLabelPropertyRef_st(scope,attr) ::= "<scope>.st"/** Isolated $RULE ref ok in lexer as it's a Token */lexerRuleLabel(label) ::= "<label>"lexerRuleLabelPropertyRef_type(scope,attr) ::= "<scope>.getType()"lexerRuleLabelPropertyRef_line(scope,attr) ::= "<scope>.getLine()"lexerRuleLabelPropertyRef_pos(scope,attr) ::= "<scope>.getCharPositionInLine()"lexerRuleLabelPropertyRef_channel(scope,attr) ::= "<scope>.getChannel()"lexerRuleLabelPropertyRef_index(scope,attr) ::= "<scope>.getTokenIndex()"lexerRuleLabelPropertyRef_text(scope,attr) ::= "<scope>.getText()"// Somebody may ref $template or $tree or $stop within a rule:rulePropertyRef_start(scope,attr) ::= "((<labelType>)retval.start)"rulePropertyRef_stop(scope,attr) ::= "((<labelType>)retval.stop)"rulePropertyRef_tree(scope,attr) ::= "((<ASTLabelType>)retval.tree)"rulePropertyRef_text(scope,attr) ::= "input.toString(retval.start,input.LT(-1))"rulePropertyRef_st(scope,attr) ::= "retval.st"// A C T I O N Semit(type) ::= "emit(<type>);"setType(type) ::= "setType(<type>);"/** How to execute an action */execAction(action) ::= <<<if(backtracking)><if(actions.(actionScope).synpredgate)>if ( <actions.(actionScope).synpredgate> ) { <action>}<else>if ( backtracking == 0 ) { <action>}<endif><else><action><endif>>>// M I S C (properties, etc...)bitset(name, words64) ::= <<public static final BitSet <name> = new BitSet(new long[]{<words64:{<it>L};separator=",">});<\n>>>tokenPrefix() ::= "TOK_"codeFileExtension() ::= ".cpp"// used in CPPTarget.java to generate the headerfile extensionheaderFileExtension() ::= ".h"true() ::= "true"false() ::= "false"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -