📄 actiontranslator.g
字号:
else { st = template("ruleLabelRef"); st.setAttribute("referencedRule", refdRule); st.setAttribute("scope", label); st.setAttribute("attr", scope.getAttribute($y.text)); } } ;/** $label either a token label or token/rule list label like label+=expr */LABEL_REF : '$' ID {enclosingRule!=null && getElementLabel($ID.text)!=null && enclosingRule.getRuleLabel($ID.text)==null}? // {System.out.println("found \$label");} { StringTemplate st; Grammar.LabelElementPair pair = getElementLabel($ID.text); if ( pair.type==Grammar.TOKEN_LABEL || pair.type==Grammar.CHAR_LABEL ) { st = template("tokenLabelRef"); } else { st = template("listLabelRef"); } st.setAttribute("label", $ID.text); } ;/** $tokenref in a non-lexer grammar */ISOLATED_TOKEN_REF : '$' ID {grammar.type!=Grammar.LEXER && enclosingRule!=null && isTokenRefInAlt($ID.text)}? //{System.out.println("found \$tokenref");} { String label = enclosingRule.getElementLabel($ID.text, outerAltNum, generator); checkElementRefUniqueness($ID.text, true); if ( label==null ) { ErrorManager.grammarError(ErrorManager.MSG_FORWARD_ELEMENT_REF, grammar, actionToken, $ID.text); } else { StringTemplate st = template("tokenLabelRef"); st.setAttribute("label", label); } } ;/** $lexerruleref from within the lexer */ISOLATED_LEXER_RULE_REF : '$' ID {grammar.type==Grammar.LEXER && enclosingRule!=null && isRuleRefInAlt($ID.text)}? //{System.out.println("found \$lexerruleref");} { String label = enclosingRule.getElementLabel($ID.text, outerAltNum, generator); checkElementRefUniqueness($ID.text, false); if ( label==null ) { ErrorManager.grammarError(ErrorManager.MSG_FORWARD_ELEMENT_REF, grammar, actionToken, $ID.text); } else { StringTemplate st = template("lexerRuleLabel"); st.setAttribute("label", label); } } ;/** $y return value, parameter, predefined rule property, or token/rule * reference within enclosing rule's outermost alt. * y must be a "local" reference; i.e., it must be referring to * something defined within the enclosing rule. * * r[int i] returns [int j] * : {$i, $j, $start, $stop, $st, $tree} * ; * * TODO: this might get the dynamic scope's elements too.!!!!!!!!! */SET_LOCAL_ATTR : '$' ID WS? '=' expr=ATTR_VALUE_EXPR ';' {enclosingRule!=null && enclosingRule.getLocalAttributeScope($ID.text)!=null && !enclosingRule.getLocalAttributeScope($ID.text).isPredefinedLexerRuleScope}? //{System.out.println("found set \$localattr");} { StringTemplate st; AttributeScope scope = enclosingRule.getLocalAttributeScope($ID.text); if ( scope.isPredefinedRuleScope ) { if ($ID.text.equals("tree") || $ID.text.equals("st")) { st = template("ruleSetPropertyRef_"+$ID.text); grammar.referenceRuleLabelPredefinedAttribute(enclosingRule.name); st.setAttribute("scope", enclosingRule.name); st.setAttribute("attr", $ID.text); st.setAttribute("expr", translateAction($expr.text)); } else { ErrorManager.grammarError(ErrorManager.MSG_WRITE_TO_READONLY_ATTR, grammar, actionToken, $ID.text, ""); } } else if ( scope.isParameterScope ) { st = template("parameterSetAttributeRef"); st.setAttribute("attr", scope.getAttribute($ID.text)); st.setAttribute("expr", translateAction($expr.text)); } else { st = template("returnSetAttributeRef"); st.setAttribute("ruleDescriptor", enclosingRule); st.setAttribute("attr", scope.getAttribute($ID.text)); st.setAttribute("expr", translateAction($expr.text)); } } ;LOCAL_ATTR : '$' ID {enclosingRule!=null && enclosingRule.getLocalAttributeScope($ID.text)!=null}? //{System.out.println("found \$localattr");} { StringTemplate st; AttributeScope scope = enclosingRule.getLocalAttributeScope($ID.text); if ( scope.isPredefinedRuleScope ) { st = template("rulePropertyRef_"+$ID.text); grammar.referenceRuleLabelPredefinedAttribute(enclosingRule.name); st.setAttribute("scope", enclosingRule.name); st.setAttribute("attr", $ID.text); } else if ( scope.isPredefinedLexerRuleScope ) { st = template("lexerRulePropertyRef_"+$ID.text); st.setAttribute("scope", enclosingRule.name); st.setAttribute("attr", $ID.text); } else if ( scope.isParameterScope ) { st = template("parameterAttributeRef"); st.setAttribute("attr", scope.getAttribute($ID.text)); } else { st = template("returnAttributeRef"); st.setAttribute("ruleDescriptor", enclosingRule); st.setAttribute("attr", scope.getAttribute($ID.text)); } } ;/** $x::y the only way to access the attributes within a dynamic scope * regardless of whether or not you are in the defining rule. * * scope Symbols { List names; } * r * scope {int i;} * scope Symbols; * : {$r::i=3;} s {$Symbols::names;} * ; * s : {$r::i; $Symbols::names;} * ; */SET_DYNAMIC_SCOPE_ATTR : '$' x=ID '::' y=ID WS? '=' expr=ATTR_VALUE_EXPR ';' {resolveDynamicScope($x.text)!=null && resolveDynamicScope($x.text).getAttribute($y.text)!=null}? //{System.out.println("found set \$scope::attr "+ $x.text + "::" + $y.text + " to " + $expr.text);} { AttributeScope scope = resolveDynamicScope($x.text); if ( scope!=null ) { StringTemplate st = template("scopeSetAttributeRef"); st.setAttribute("scope", $x.text); st.setAttribute("attr", scope.getAttribute($y.text)); st.setAttribute("expr", translateAction($expr.text)); } else { // error: invalid dynamic attribute } } ;DYNAMIC_SCOPE_ATTR : '$' x=ID '::' y=ID {resolveDynamicScope($x.text)!=null && resolveDynamicScope($x.text).getAttribute($y.text)!=null}? //{System.out.println("found \$scope::attr "+ $x.text + "::" + $y.text);} { AttributeScope scope = resolveDynamicScope($x.text); if ( scope!=null ) { StringTemplate st = template("scopeAttributeRef"); st.setAttribute("scope", $x.text); st.setAttribute("attr", scope.getAttribute($y.text)); } else { // error: invalid dynamic attribute } } ;ERROR_SCOPED_XY : '$' x=ID '::' y=ID { chunks.add(getText()); generator.issueInvalidScopeError($x.text,$y.text, enclosingRule,actionToken, outerAltNum); } ; /** To access deeper (than top of stack) scopes, use the notation: * * $x[-1]::y previous (just under top of stack) * $x[-i]::y top of stack - i where the '-' MUST BE PRESENT; * i.e., i cannot simply be negative without the '-' sign! * $x[i]::y absolute index i (0..size-1) * $x[0]::y is the absolute 0 indexed element (bottom of the stack) */DYNAMIC_NEGATIVE_INDEXED_SCOPE_ATTR : '$' x=ID '[' '-' expr=SCOPE_INDEX_EXPR ']' '::' y=ID // {System.out.println("found \$scope[-...]::attr");} { StringTemplate st = template("scopeAttributeRef"); st.setAttribute("scope", $x.text); st.setAttribute("attr", resolveDynamicScope($x.text).getAttribute($y.text)); st.setAttribute("negIndex", $expr.text); } ;DYNAMIC_ABSOLUTE_INDEXED_SCOPE_ATTR : '$' x=ID '[' expr=SCOPE_INDEX_EXPR ']' '::' y=ID // {System.out.println("found \$scope[...]::attr");} { StringTemplate st = template("scopeAttributeRef"); st.setAttribute("scope", $x.text); st.setAttribute("attr", resolveDynamicScope($x.text).getAttribute($y.text)); st.setAttribute("index", $expr.text); } ;fragmentSCOPE_INDEX_EXPR : (~']')+ ; /** $r y is a rule's dynamic scope or a global shared scope. * Isolated $rulename is not allowed unless it has a dynamic scope *and* * there is no reference to rulename in the enclosing alternative, * which would be ambiguous. See TestAttributes.testAmbiguousRuleRef() */ISOLATED_DYNAMIC_SCOPE : '$' ID {resolveDynamicScope($ID.text)!=null}? // {System.out.println("found isolated \$scope where scope is a dynamic scope");} { StringTemplate st = template("isolatedDynamicScopeRef"); st.setAttribute("scope", $ID.text); } ; // antlr.g then codegen.g does these first two currently.// don't want to duplicate that code./** %foo(a={},b={},...) ctor */TEMPLATE_INSTANCE : '%' ID '(' ( WS? ARG (',' WS? ARG)* WS? )? ')' // {System.out.println("found \%foo(args)");} { String action = getText().substring(1,getText().length()); String ruleName = "<outside-of-rule>"; if ( enclosingRule!=null ) { ruleName = enclosingRule.name; } StringTemplate st = generator.translateTemplateConstructor(ruleName, outerAltNum, actionToken, action); if ( st!=null ) { chunks.add(st); } } ;/** %({name-expr})(a={},...) indirect template ctor reference */INDIRECT_TEMPLATE_INSTANCE : '%' '(' ACTION ')' '(' ( WS? ARG (',' WS? ARG)* WS? )? ')' // {System.out.println("found \%({...})(args)");} { String action = getText().substring(1,getText().length()); StringTemplate st = generator.translateTemplateConstructor(enclosingRule.name, outerAltNum, actionToken, action); chunks.add(st); } ;fragmentARG : ID '=' ACTION ;/** %{expr}.y = z; template attribute y of StringTemplate-typed expr to z */SET_EXPR_ATTRIBUTE : '%' a=ACTION '.' ID WS? '=' expr=ATTR_VALUE_EXPR ';' // {System.out.println("found \%{expr}.y = z;");} { StringTemplate st = template("actionSetAttribute"); String action = $a.text; action = action.substring(1,action.length()-1); // stuff inside {...} st.setAttribute("st", translateAction(action)); st.setAttribute("attrName", $ID.text); st.setAttribute("expr", translateAction($expr.text)); } ; /* %x.y = z; set template attribute y of x (always set never get attr) * to z [languages like python without ';' must still use the * ';' which the code generator is free to remove during code gen] */SET_ATTRIBUTE : '%' x=ID '.' y=ID WS? '=' expr=ATTR_VALUE_EXPR ';' // {System.out.println("found \%x.y = z;");} { StringTemplate st = template("actionSetAttribute"); st.setAttribute("st", $x.text); st.setAttribute("attrName", $y.text); st.setAttribute("expr", translateAction($expr.text)); } ;/** Don't allow an = as first char to prevent $x == 3; kind of stuff. */fragmentATTR_VALUE_EXPR : ~'=' (~';')* ; /** %{string-expr} anonymous template from string expr */TEMPLATE_EXPR : '%' a=ACTION // {System.out.println("found \%{expr}");} { StringTemplate st = template("actionStringConstructor"); String action = $a.text; action = action.substring(1,action.length()-1); // stuff inside {...} st.setAttribute("stringExpr", translateAction(action)); } ; fragmentACTION : '{' (options {greedy=false;}:.)* '}' ; ESC : '\\' '$' {chunks.add("\$");} | '\\' '%' {chunks.add("\%");} | '\\' ~('$'|'%') {chunks.add(getText());} ; ERROR_XY : '$' x=ID '.' y=ID { chunks.add(getText()); generator.issueInvalidAttributeError($x.text,$y.text, enclosingRule,actionToken, outerAltNum); } ; ERROR_X : '$' x=ID { chunks.add(getText()); generator.issueInvalidAttributeError($x.text, enclosingRule,actionToken, outerAltNum); } ; UNKNOWN_SYNTAX : '$' { chunks.add(getText()); // shouldn't need an error here. Just accept \$ if it doesn't look like anything } | '%' (ID|'.'|'('|')'|','|'{'|'}'|'"')* { chunks.add(getText()); ErrorManager.grammarError(ErrorManager.MSG_INVALID_TEMPLATE_ACTION, grammar, actionToken, getText()); } ;TEXT: ~('$'|'%'|'\\')+ {chunks.add(getText());} ; fragmentID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')* ;fragmentINT : '0'..'9'+ ;fragmentWS : (' '|'\t'|'\n')+ ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -