![JAR search and dependency download from the Maven repository](/logo.png)
org.antlr.v4.parse.GrammarTreeVisitor.g Maven / Gradle / Ivy
/*
* Copyright (c) 2012 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD-3-Clause license that
* can be found in the LICENSE.txt file in the project root.
*/
/** The definitive ANTLR v3 tree grammar to walk/visit ANTLR v4 grammars.
* Parses trees created by ANTLRParser.g.
*
* Rather than have multiple tree grammars, one for each visit, I'm
* creating this generic visitor that knows about context. All of the
* boilerplate pattern recognition is done here. Then, subclasses can
* override the methods they care about. This prevents a lot of the same
* context tracking stuff like "set current alternative for current
* rule node" that is repeated in lots of tree filters.
*/
tree grammar GrammarTreeVisitor;
options {
language = Java;
tokenVocab = ANTLRParser;
ASTLabelType = GrammarAST;
}
// Include the copyright in this source and also the generated source
@header {
/*
* Copyright (c) 2012 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD-3-Clause license that
* can be found in the LICENSE.txt file in the project root.
*/
package org.antlr.v4.parse;
import org.antlr.v4.Tool;
import org.antlr.v4.tool.*;
import org.antlr.v4.tool.ast.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
}
@members {
public String grammarName;
public GrammarAST currentRuleAST;
public String currentModeName = LexerGrammar.DEFAULT_MODE_NAME;
public String currentRuleName;
public GrammarAST currentOuterAltRoot;
public int currentOuterAltNumber = 1; // 1..n
public int rewriteEBNFLevel = 0;
public GrammarTreeVisitor() { this(null); }
// Should be abstract but can't make gen'd parser abstract;
// subclasses should implement else everything goes to stderr!
public ErrorManager getErrorManager() { return null; }
public void visitGrammar(GrammarAST t) { visit(t, "grammarSpec"); }
public void visit(GrammarAST t, String ruleName) {
CommonTreeNodeStream nodes = new CommonTreeNodeStream(new GrammarASTAdaptor(), t);
setTreeNodeStream(nodes);
try {
Method m = getClass().getMethod(ruleName);
m.invoke(this);
}
catch (Throwable e) {
ErrorManager errMgr = getErrorManager();
if ( e instanceof InvocationTargetException ) {
e = e.getCause();
}
if ( errMgr==null ) {
System.err.println("can't find rule "+ruleName+
" or tree structure error: "+t.toStringTree()
);
e.printStackTrace(System.err);
}
else errMgr.toolError(ErrorType.INTERNAL_ERROR, e);
}
}
public void discoverGrammar(GrammarRootAST root, GrammarAST ID) { }
public void finishPrequels(GrammarAST firstPrequel) { }
public void finishGrammar(GrammarRootAST root, GrammarAST ID) { }
public void grammarOption(GrammarAST ID, GrammarAST valueAST) { }
public void ruleOption(GrammarAST ID, GrammarAST valueAST) { }
public void blockOption(GrammarAST ID, GrammarAST valueAST) { }
public void defineToken(GrammarAST ID) { }
public void defineChannel(GrammarAST ID) { }
public void globalNamedAction(GrammarAST scope, GrammarAST ID, ActionAST action) { }
public void importGrammar(GrammarAST label, GrammarAST ID) { }
public void modeDef(GrammarAST m, GrammarAST ID) { }
public void discoverRules(GrammarAST rules) { }
public void finishRules(GrammarAST rule) { }
public void discoverRule(RuleAST rule, GrammarAST ID, List modifiers,
ActionAST arg, ActionAST returns, GrammarAST thrws,
GrammarAST options, ActionAST locals,
List actions,
GrammarAST block) { }
public void finishRule(RuleAST rule, GrammarAST ID, GrammarAST block) { }
public void discoverLexerRule(RuleAST rule, GrammarAST ID, List modifiers,
GrammarAST block) { }
public void finishLexerRule(RuleAST rule, GrammarAST ID, GrammarAST block) { }
public void ruleCatch(GrammarAST arg, ActionAST action) { }
public void finallyAction(ActionAST action) { }
public void discoverOuterAlt(AltAST alt) { }
public void finishOuterAlt(AltAST alt) { }
public void discoverAlt(AltAST alt) { }
public void finishAlt(AltAST alt) { }
public void ruleRef(GrammarAST ref, ActionAST arg) { }
public void tokenRef(TerminalAST ref) { }
public void elementOption(GrammarASTWithOptions t, GrammarAST ID, GrammarAST valueAST) { }
public void stringRef(TerminalAST ref) { }
public void wildcardRef(GrammarAST ref) { }
public void actionInAlt(ActionAST action) { }
public void sempredInAlt(PredAST pred) { }
public void label(GrammarAST op, GrammarAST ID, GrammarAST element) { }
public void lexerCallCommand(int outerAltNumber, GrammarAST ID, GrammarAST arg) { }
public void lexerCommand(int outerAltNumber, GrammarAST ID) { }
protected void enterGrammarSpec(GrammarAST tree) { }
protected void exitGrammarSpec(GrammarAST tree) { }
protected void enterPrequelConstructs(GrammarAST tree) { }
protected void exitPrequelConstructs(GrammarAST tree) { }
protected void enterPrequelConstruct(GrammarAST tree) { }
protected void exitPrequelConstruct(GrammarAST tree) { }
protected void enterOptionsSpec(GrammarAST tree) { }
protected void exitOptionsSpec(GrammarAST tree) { }
protected void enterOption(GrammarAST tree) { }
protected void exitOption(GrammarAST tree) { }
protected void enterOptionValue(GrammarAST tree) { }
protected void exitOptionValue(GrammarAST tree) { }
protected void enterDelegateGrammars(GrammarAST tree) { }
protected void exitDelegateGrammars(GrammarAST tree) { }
protected void enterDelegateGrammar(GrammarAST tree) { }
protected void exitDelegateGrammar(GrammarAST tree) { }
protected void enterTokensSpec(GrammarAST tree) { }
protected void exitTokensSpec(GrammarAST tree) { }
protected void enterTokenSpec(GrammarAST tree) { }
protected void exitTokenSpec(GrammarAST tree) { }
protected void enterChannelsSpec(GrammarAST tree) { }
protected void exitChannelsSpec(GrammarAST tree) { }
protected void enterChannelSpec(GrammarAST tree) { }
protected void exitChannelSpec(GrammarAST tree) { }
protected void enterAction(GrammarAST tree) { }
protected void exitAction(GrammarAST tree) { }
protected void enterRules(GrammarAST tree) { }
protected void exitRules(GrammarAST tree) { }
protected void enterMode(GrammarAST tree) { }
protected void exitMode(GrammarAST tree) { }
protected void enterLexerRule(GrammarAST tree) { }
protected void exitLexerRule(GrammarAST tree) { }
protected void enterRule(GrammarAST tree) { }
protected void exitRule(GrammarAST tree) { }
protected void enterExceptionGroup(GrammarAST tree) { }
protected void exitExceptionGroup(GrammarAST tree) { }
protected void enterExceptionHandler(GrammarAST tree) { }
protected void exitExceptionHandler(GrammarAST tree) { }
protected void enterFinallyClause(GrammarAST tree) { }
protected void exitFinallyClause(GrammarAST tree) { }
protected void enterLocals(GrammarAST tree) { }
protected void exitLocals(GrammarAST tree) { }
protected void enterRuleReturns(GrammarAST tree) { }
protected void exitRuleReturns(GrammarAST tree) { }
protected void enterThrowsSpec(GrammarAST tree) { }
protected void exitThrowsSpec(GrammarAST tree) { }
protected void enterRuleAction(GrammarAST tree) { }
protected void exitRuleAction(GrammarAST tree) { }
protected void enterRuleModifier(GrammarAST tree) { }
protected void exitRuleModifier(GrammarAST tree) { }
protected void enterLexerRuleBlock(GrammarAST tree) { }
protected void exitLexerRuleBlock(GrammarAST tree) { }
protected void enterRuleBlock(GrammarAST tree) { }
protected void exitRuleBlock(GrammarAST tree) { }
protected void enterLexerOuterAlternative(AltAST tree) { }
protected void exitLexerOuterAlternative(AltAST tree) { }
protected void enterOuterAlternative(AltAST tree) { }
protected void exitOuterAlternative(AltAST tree) { }
protected void enterLexerAlternative(GrammarAST tree) { }
protected void exitLexerAlternative(GrammarAST tree) { }
protected void enterLexerElements(GrammarAST tree) { }
protected void exitLexerElements(GrammarAST tree) { }
protected void enterLexerElement(GrammarAST tree) { }
protected void exitLexerElement(GrammarAST tree) { }
protected void enterLabeledLexerElement(GrammarAST tree) { }
protected void exitLabeledLexerElement(GrammarAST tree) { }
protected void enterLexerBlock(GrammarAST tree) { }
protected void exitLexerBlock(GrammarAST tree) { }
protected void enterLexerAtom(GrammarAST tree) { }
protected void exitLexerAtom(GrammarAST tree) { }
protected void enterActionElement(GrammarAST tree) { }
protected void exitActionElement(GrammarAST tree) { }
protected void enterAlternative(AltAST tree) { }
protected void exitAlternative(AltAST tree) { }
protected void enterLexerCommand(GrammarAST tree) { }
protected void exitLexerCommand(GrammarAST tree) { }
protected void enterLexerCommandExpr(GrammarAST tree) { }
protected void exitLexerCommandExpr(GrammarAST tree) { }
protected void enterElement(GrammarAST tree) { }
protected void exitElement(GrammarAST tree) { }
protected void enterAstOperand(GrammarAST tree) { }
protected void exitAstOperand(GrammarAST tree) { }
protected void enterLabeledElement(GrammarAST tree) { }
protected void exitLabeledElement(GrammarAST tree) { }
protected void enterSubrule(GrammarAST tree) { }
protected void exitSubrule(GrammarAST tree) { }
protected void enterLexerSubrule(GrammarAST tree) { }
protected void exitLexerSubrule(GrammarAST tree) { }
protected void enterBlockSuffix(GrammarAST tree) { }
protected void exitBlockSuffix(GrammarAST tree) { }
protected void enterEbnfSuffix(GrammarAST tree) { }
protected void exitEbnfSuffix(GrammarAST tree) { }
protected void enterAtom(GrammarAST tree) { }
protected void exitAtom(GrammarAST tree) { }
protected void enterBlockSet(GrammarAST tree) { }
protected void exitBlockSet(GrammarAST tree) { }
protected void enterSetElement(GrammarAST tree) { }
protected void exitSetElement(GrammarAST tree) { }
protected void enterBlock(GrammarAST tree) { }
protected void exitBlock(GrammarAST tree) { }
protected void enterRuleref(GrammarAST tree) { }
protected void exitRuleref(GrammarAST tree) { }
protected void enterRange(GrammarAST tree) { }
protected void exitRange(GrammarAST tree) { }
protected void enterTerminal(GrammarAST tree) { }
protected void exitTerminal(GrammarAST tree) { }
protected void enterElementOptions(GrammarAST tree) { }
protected void exitElementOptions(GrammarAST tree) { }
protected void enterElementOption(GrammarAST tree) { }
protected void exitElementOption(GrammarAST tree) { }
@Override
public void traceIn(String ruleName, int ruleIndex) {
System.err.println("enter "+ruleName+": "+input.LT(1));
}
@Override
public void traceOut(String ruleName, int ruleIndex) {
System.err.println("exit "+ruleName+": "+input.LT(1));
}
}
grammarSpec
@init {
enterGrammarSpec($start);
}
@after {
exitGrammarSpec($start);
}
: ^( GRAMMAR ID {grammarName=$ID.text;}
{discoverGrammar((GrammarRootAST)$GRAMMAR, $ID);}
prequelConstructs
{finishPrequels($prequelConstructs.firstOne);}
rules mode*
{finishGrammar((GrammarRootAST)$GRAMMAR, $ID);}
)
;
prequelConstructs returns [GrammarAST firstOne=null]
@init {
enterPrequelConstructs($start);
}
@after {
exitPrequelConstructs($start);
}
: {$firstOne=$start;} prequelConstruct+
|
;
prequelConstruct
@init {
enterPrequelConstructs($start);
}
@after {
exitPrequelConstructs($start);
}
: optionsSpec
| delegateGrammars
| tokensSpec
| channelsSpec
| action
;
optionsSpec
@init {
enterOptionsSpec($start);
}
@after {
exitOptionsSpec($start);
}
: ^(OPTIONS option*)
;
option
@init {
enterOption($start);
boolean rule = inContext("RULE ...");
boolean block = inContext("BLOCK ...");
}
@after {
exitOption($start);
}
: ^(a=ASSIGN ID v=optionValue)
{
if ( block ) blockOption($ID, $v.start); // most specific first
else if ( rule ) ruleOption($ID, $v.start);
else grammarOption($ID, $v.start);
}
;
optionValue returns [String v]
@init {
enterOptionValue($start);
$v = $start.token.getText();
}
@after {
exitOptionValue($start);
}
: ID
| STRING_LITERAL
| INT
;
delegateGrammars
@init {
enterDelegateGrammars($start);
}
@after {
exitDelegateGrammars($start);
}
: ^(IMPORT delegateGrammar+)
;
delegateGrammar
@init {
enterDelegateGrammar($start);
}
@after {
exitDelegateGrammar($start);
}
: ^(ASSIGN label=ID id=ID) {importGrammar($label, $id);}
| id=ID {importGrammar(null, $id);}
;
tokensSpec
@init {
enterTokensSpec($start);
}
@after {
exitTokensSpec($start);
}
: ^(TOKENS_SPEC tokenSpec+)
;
tokenSpec
@init {
enterTokenSpec($start);
}
@after {
exitTokenSpec($start);
}
: ID {defineToken($ID);}
;
channelsSpec
@init {
enterChannelsSpec($start);
}
@after {
exitChannelsSpec($start);
}
: ^(CHANNELS channelSpec*)
;
channelSpec
@init {
enterChannelSpec($start);
}
@after {
exitChannelSpec($start);
}
: ID {defineChannel($ID);}
;
action
@init {
enterAction($start);
}
@after {
exitAction($start);
}
: ^(AT sc=ID? name=ID ACTION) {globalNamedAction($sc, $name, (ActionAST)$ACTION);}
;
rules
@init {
enterRules($start);
}
@after {
exitRules($start);
}
: ^(RULES {discoverRules($RULES);} (rule|lexerRule)* {finishRules($RULES);})
;
mode
@init {
enterMode($start);
}
@after {
exitMode($start);
}
: ^( MODE ID {currentModeName=$ID.text; modeDef($MODE, $ID);} lexerRule* )
;
lexerRule
@init {
enterLexerRule($start);
List mods = new ArrayList();
currentOuterAltNumber=0;
}
@after {
exitLexerRule($start);
}
: ^( RULE TOKEN_REF
{currentRuleName=$TOKEN_REF.text; currentRuleAST=$RULE;}
(^(RULEMODIFIERS m=FRAGMENT {mods.add($m);}))?
{discoverLexerRule((RuleAST)$RULE, $TOKEN_REF, mods, (GrammarAST)input.LT(1));}
lexerRuleBlock
{
finishLexerRule((RuleAST)$RULE, $TOKEN_REF, $lexerRuleBlock.start);
currentRuleName=null; currentRuleAST=null;
}
)
;
rule
@init {
enterRule($start);
List mods = new ArrayList();
List actions = new ArrayList(); // track roots
currentOuterAltNumber=0;
}
@after {
exitRule($start);
}
: ^( RULE RULE_REF {currentRuleName=$RULE_REF.text; currentRuleAST=$RULE;}
(^(RULEMODIFIERS (m=ruleModifier{mods.add($m.start);})+))?
ARG_ACTION?
ret=ruleReturns?
thr=throwsSpec?
loc=locals?
( opts=optionsSpec
| a=ruleAction {actions.add($a.start);}
)*
{discoverRule((RuleAST)$RULE, $RULE_REF, mods, (ActionAST)$ARG_ACTION,
$ret.start!=null?(ActionAST)$ret.start.getChild(0):null,
$thr.start, $opts.start,
$loc.start!=null?(ActionAST)$loc.start.getChild(0):null,
actions, (GrammarAST)input.LT(1));}
ruleBlock exceptionGroup
{finishRule((RuleAST)$RULE, $RULE_REF, $ruleBlock.start); currentRuleName=null; currentRuleAST=null;}
)
;
exceptionGroup
@init {
enterExceptionGroup($start);
}
@after {
exitExceptionGroup($start);
}
: exceptionHandler* finallyClause?
;
exceptionHandler
@init {
enterExceptionHandler($start);
}
@after {
exitExceptionHandler($start);
}
: ^(CATCH ARG_ACTION ACTION) {ruleCatch($ARG_ACTION, (ActionAST)$ACTION);}
;
finallyClause
@init {
enterFinallyClause($start);
}
@after {
exitFinallyClause($start);
}
: ^(FINALLY ACTION) {finallyAction((ActionAST)$ACTION);}
;
locals
@init {
enterLocals($start);
}
@after {
exitLocals($start);
}
: ^(LOCALS ARG_ACTION)
;
ruleReturns
@init {
enterRuleReturns($start);
}
@after {
exitRuleReturns($start);
}
: ^(RETURNS ARG_ACTION)
;
throwsSpec
@init {
enterThrowsSpec($start);
}
@after {
exitThrowsSpec($start);
}
: ^(THROWS ID+)
;
ruleAction
@init {
enterRuleAction($start);
}
@after {
exitRuleAction($start);
}
: ^(AT ID ACTION)
;
ruleModifier
@init {
enterRuleModifier($start);
}
@after {
exitRuleModifier($start);
}
: PUBLIC
| PRIVATE
| PROTECTED
| FRAGMENT
;
lexerRuleBlock
@init {
enterLexerRuleBlock($start);
}
@after {
exitLexerRuleBlock($start);
}
: ^( BLOCK
( {
currentOuterAltRoot = (GrammarAST)input.LT(1);
currentOuterAltNumber++;
}
lexerOuterAlternative
)+
)
;
ruleBlock
@init {
enterRuleBlock($start);
}
@after {
exitRuleBlock($start);
}
: ^( BLOCK
( {
currentOuterAltRoot = (GrammarAST)input.LT(1);
currentOuterAltNumber++;
}
outerAlternative
)+
)
;
lexerOuterAlternative
@init {
enterLexerOuterAlternative((AltAST)$start);
discoverOuterAlt((AltAST)$start);
}
@after {
finishOuterAlt((AltAST)$start);
exitLexerOuterAlternative((AltAST)$start);
}
: lexerAlternative
;
outerAlternative
@init {
enterOuterAlternative((AltAST)$start);
discoverOuterAlt((AltAST)$start);
}
@after {
finishOuterAlt((AltAST)$start);
exitOuterAlternative((AltAST)$start);
}
: alternative
;
lexerAlternative
@init {
enterLexerAlternative($start);
}
@after {
exitLexerAlternative($start);
}
: ^(LEXER_ALT_ACTION lexerElements lexerCommand+)
| lexerElements
;
lexerElements
@init {
enterLexerElements($start);
}
@after {
exitLexerElements($start);
}
: ^(ALT lexerElement+)
;
lexerElement
@init {
enterLexerElement($start);
}
@after {
exitLexerElement($start);
}
: labeledLexerElement
| lexerAtom
| lexerSubrule
| ACTION {actionInAlt((ActionAST)$ACTION);}
| SEMPRED {sempredInAlt((PredAST)$SEMPRED);}
| ^(ACTION elementOptions) {actionInAlt((ActionAST)$ACTION);}
| ^(SEMPRED elementOptions) {sempredInAlt((PredAST)$SEMPRED);}
| EPSILON
;
labeledLexerElement
@init {
enterLabeledLexerElement($start);
}
@after {
exitLabeledLexerElement($start);
}
: ^((ASSIGN|PLUS_ASSIGN) ID (lexerAtom|block))
;
lexerBlock
@init {
enterLexerBlock($start);
}
@after {
exitLexerBlock($start);
}
: ^(BLOCK optionsSpec? lexerAlternative+)
;
lexerAtom
@init {
enterLexerAtom($start);
}
@after {
exitLexerAtom($start);
}
: terminal
| ^(NOT blockSet)
| blockSet
| ^(WILDCARD elementOptions)
| WILDCARD
| LEXER_CHAR_SET
| range
| ruleref
;
actionElement
@init {
enterActionElement($start);
}
@after {
exitActionElement($start);
}
: ACTION
| ^(ACTION elementOptions)
| SEMPRED
| ^(SEMPRED elementOptions)
;
alternative
@init {
enterAlternative((AltAST)$start);
discoverAlt((AltAST)$start);
}
@after {
finishAlt((AltAST)$start);
exitAlternative((AltAST)$start);
}
: ^(ALT elementOptions? element+)
| ^(ALT elementOptions? EPSILON)
;
lexerCommand
@init {
enterLexerCommand($start);
}
@after {
exitLexerCommand($start);
}
: ^(LEXER_ACTION_CALL ID lexerCommandExpr)
{lexerCallCommand(currentOuterAltNumber, $ID, $lexerCommandExpr.start);}
| ID
{lexerCommand(currentOuterAltNumber, $ID);}
;
lexerCommandExpr
@init {
enterLexerCommandExpr($start);
}
@after {
exitLexerCommandExpr($start);
}
: ID
| INT
;
element
@init {
enterElement($start);
}
@after {
exitElement($start);
}
: labeledElement
| atom
| subrule
| ACTION {actionInAlt((ActionAST)$ACTION);}
| SEMPRED {sempredInAlt((PredAST)$SEMPRED);}
| ^(ACTION elementOptions) {actionInAlt((ActionAST)$ACTION);}
| ^(SEMPRED elementOptions) {sempredInAlt((PredAST)$SEMPRED);}
| range
| ^(NOT blockSet)
| ^(NOT block)
;
astOperand
@init {
enterAstOperand($start);
}
@after {
exitAstOperand($start);
}
: atom
| ^(NOT blockSet)
| ^(NOT block)
;
labeledElement
@init {
enterLabeledElement($start);
}
@after {
exitLabeledElement($start);
}
: ^((ASSIGN|PLUS_ASSIGN) ID element) {label($start, $ID, $element.start);}
;
subrule
@init {
enterSubrule($start);
}
@after {
exitSubrule($start);
}
: ^(blockSuffix block)
| block
;
lexerSubrule
@init {
enterLexerSubrule($start);
}
@after {
exitLexerSubrule($start);
}
: ^(blockSuffix lexerBlock)
| lexerBlock
;
blockSuffix
@init {
enterBlockSuffix($start);
}
@after {
exitBlockSuffix($start);
}
: ebnfSuffix
;
ebnfSuffix
@init {
enterEbnfSuffix($start);
}
@after {
exitEbnfSuffix($start);
}
: OPTIONAL
| CLOSURE
| POSITIVE_CLOSURE
;
atom
@init {
enterAtom($start);
}
@after {
exitAtom($start);
}
: ^(DOT ID terminal)
| ^(DOT ID ruleref)
| ^(WILDCARD elementOptions) {wildcardRef($WILDCARD);}
| WILDCARD {wildcardRef($WILDCARD);}
| terminal
| blockSet
| ruleref
;
blockSet
@init {
enterBlockSet($start);
}
@after {
exitBlockSet($start);
}
: ^(SET setElement+)
;
setElement
@init {
enterSetElement($start);
}
@after {
exitSetElement($start);
}
: ^(STRING_LITERAL elementOptions) {stringRef((TerminalAST)$STRING_LITERAL);}
| ^(TOKEN_REF elementOptions) {tokenRef((TerminalAST)$TOKEN_REF);}
| STRING_LITERAL {stringRef((TerminalAST)$STRING_LITERAL);}
| TOKEN_REF {tokenRef((TerminalAST)$TOKEN_REF);}
| ^(RANGE a=STRING_LITERAL b=STRING_LITERAL)
{
stringRef((TerminalAST)$a);
stringRef((TerminalAST)$b);
}
| LEXER_CHAR_SET
;
block
@init {
enterBlock($start);
}
@after {
exitBlock($start);
}
: ^(BLOCK optionsSpec? ruleAction* ACTION? alternative+)
;
ruleref
@init {
enterRuleref($start);
}
@after {
exitRuleref($start);
}
: ^(RULE_REF arg=ARG_ACTION? elementOptions?)
{
ruleRef($RULE_REF, (ActionAST)$ARG_ACTION);
if ( $arg!=null ) actionInAlt((ActionAST)$arg);
}
;
range
@init {
enterRange($start);
}
@after {
exitRange($start);
}
: ^(RANGE STRING_LITERAL STRING_LITERAL)
;
terminal
@init {
enterTerminal($start);
}
@after {
exitTerminal($start);
}
: ^(STRING_LITERAL elementOptions)
{stringRef((TerminalAST)$STRING_LITERAL);}
| STRING_LITERAL {stringRef((TerminalAST)$STRING_LITERAL);}
| ^(TOKEN_REF elementOptions) {tokenRef((TerminalAST)$TOKEN_REF);}
| TOKEN_REF {tokenRef((TerminalAST)$TOKEN_REF);}
;
elementOptions
@init {
enterElementOptions($start);
}
@after {
exitElementOptions($start);
}
: ^(ELEMENT_OPTIONS elementOption[(GrammarASTWithOptions)$start.getParent()]*)
;
elementOption[GrammarASTWithOptions t]
@init {
enterElementOption($start);
}
@after {
exitElementOption($start);
}
: ID {elementOption(t, $ID, null);}
| ^(ASSIGN id=ID v=ID) {elementOption(t, $id, $v);}
| ^(ASSIGN ID v=STRING_LITERAL) {elementOption(t, $ID, $v);}
| ^(ASSIGN ID v=ACTION) {elementOption(t, $ID, $v);}
| ^(ASSIGN ID v=INT) {elementOption(t, $ID, $v);}
;
© 2015 - 2025 Weber Informatics LLC | Privacy Policy