[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6876]
This commit is contained in:
parrt 2010-05-19 16:42:08 -08:00
parent 3324f181f4
commit 1b0186329c
37 changed files with 988 additions and 667 deletions

View File

@ -170,11 +170,11 @@ cases(ttypes) ::= <<
>>
InvokeRule(r) ::= <<
<if(r.label)><r.label> = <endif><r.name>(new <r.ctxName>(<r.argExprs:{e|<e>,}><r.follow.name>));
<if(r.labels)><r.labels:{l | <l> = }><endif><r.name>(new <r.ctxName>(<r.argExprs:{e|<e>,}><r.follow.name>));
>>
MatchToken(m) ::= <<
<if(m.label)><m.label> = (Token)<endif>match(<m.name>, <m.follow.name>);
<if(m.labels)><m.labels:{l | <l> = }>(Token)<endif>match(<m.name>, <m.follow.name>);
>>
// ACTION STUFF
@ -188,6 +188,8 @@ if (!(<p.ast.text>)) throw new FailedPredicateException(input, "<ruleName>", "<d
ActionText(t) ::= "<t.text>"
ArgRef(a) ::= "_ctx.<a.name>"
RetValueRef(a) ::= "_ctx.<a.name>"
/** How to translate $tokenLabel */
TokenRef(t) ::= "<t.name>"
SetAttr(s,rhsChunks) ::= "_ctx.<s.name> = <rhsChunks>;"
AddToList(a) ::= "<a.listName>.add(<a.opWithResultToAdd.label>);"

View File

@ -8,6 +8,8 @@ import org.antlr.v4.parse.ActionSplitter;
import org.antlr.v4.parse.ActionSplitterListener;
import org.antlr.v4.tool.ActionAST;
import org.antlr.v4.tool.Attribute;
import org.antlr.v4.tool.ErrorType;
import org.antlr.v4.tool.Rule;
import java.util.ArrayList;
import java.util.List;
@ -17,16 +19,37 @@ public class ActionTranslator implements ActionSplitterListener {
ActionAST node;
RuleFunction rf;
List<ActionChunk> chunks = new ArrayList<ActionChunk>();
OutputModelFactory factory;
public ActionTranslator(ActionAST node) {
public ActionTranslator(OutputModelFactory factory, ActionAST node) {
this.factory = factory;
this.node = node;
}
public static List<ActionChunk> translateAction(RuleFunction rf, Token tokenWithinAction, ActionAST node) {
ActionTranslator translator = new ActionTranslator(node);
public static List<ActionChunk> translateAction(OutputModelFactory factory,
RuleFunction rf,
Token tokenWithinAction,
ActionAST node)
{
String action = tokenWithinAction.getText();
int firstCurly = action.indexOf('{');
int lastCurly = action.lastIndexOf('}');
if ( firstCurly>=0 && lastCurly>=0 ) {
action = action.substring(firstCurly+1, lastCurly); // trim {...}
}
return translateActionChunk(factory, rf, action, node);
}
public static List<ActionChunk> translateActionChunk(OutputModelFactory factory,
RuleFunction rf,
String action,
ActionAST node)
{
Token tokenWithinAction = node.token;
ActionTranslator translator = new ActionTranslator(factory, node);
translator.rf = rf;
System.out.println("translate "+tokenWithinAction);
ANTLRStringStream in = new ANTLRStringStream(tokenWithinAction.getText());
System.out.println("translate "+action);
ANTLRStringStream in = new ANTLRStringStream(action);
in.setLine(tokenWithinAction.getLine());
in.setCharPositionInLine(tokenWithinAction.getCharPositionInLine());
ActionSplitter trigger = new ActionSplitter(in, translator);
@ -37,28 +60,75 @@ public class ActionTranslator implements ActionSplitterListener {
public void attr(String expr, Token x) {
System.out.println("attr "+x);
Attribute a = node.resolver.resolveToAttribute(x.getText(), node);
switch ( a.dict.type ) {
case ARG: chunks.add(new ArgRef(x.getText())); break;
case RET: chunks.add(new RetValueRef(x.getText())); break;
if ( a!=null ) {
switch ( a.dict.type ) {
case ARG: chunks.add(new ArgRef(x.getText())); break;
case RET: chunks.add(new RetValueRef(x.getText())); break;
// case PREDEFINED_RULE: chunks.add(new RetValueRef(x.getText())); break;
// case PREDEFINED_TREE_RULE: chunks.add(new RetValueRef(x.getText())); break;
}
}
if ( node.resolver.resolveToDynamicScope(x.getText(), node)!=null ) {
return; // $S for scope S is ok
}
if ( node.resolver.resolvesToToken(x.getText(), node) ) {
if ( node.resolver.resolvesToLabel(x.getText(), node) ) {
chunks.add(new TokenRef(x.getText())); // $label
}
else { // $ID for token ref or label of token; find label
String label = factory.gen.target.getImplicitTokenLabel(x.getText());
chunks.add(new TokenRef(label)); // $label
}
return;
}
if ( node.resolver.resolvesToListLabel(x.getText(), node) ) {
return; // $ids for ids+=ID etc...
}
// switch ( a.dict.type ) {
// case ARG: chunks.add(new ArgRef(x.getText())); break;
// case RET: chunks.add(new RetValueRef(x.getText())); break;
// case PREDEFINED_RULE: chunks.add(new RetValueRef(x.getText())); break;
// case PREDEFINED_LEXER_RULE: chunks.add(new RetValueRef(x.getText())); break;
// case PREDEFINED_TREE_RULE: chunks.add(new RetValueRef(x.getText())); break;
// case GLOBAL_SCOPE: chunks.add(new RetValueRef(x.getText())); break;
// case RULE_SCOPE: chunks.add(new RetValueRef(x.getText())); break;
// case TOKEN: chunks.add(new RetValueRef(x.getText())); break;
}
// case TOKEN: chunks.add(new TokenRef(x.getText())); break;
// }
}
public void setQualifiedAttr(String expr, Token x, Token y, Token rhs) {
}
public void qualifiedAttr(String expr, Token x, Token y) {
System.out.println("qattr "+x+"."+y);
if ( node.resolver.resolveToAttribute(x.getText(), y.getText(), node)==null ) {
Rule rref = isolatedRuleRef(x.getText());
if ( rref!=null ) {
if ( rref!=null && rref.args!=null && rref.args.get(y.getText())!=null ) {
g.tool.errMgr.grammarError(ErrorType.INVALID_RULE_PARAMETER_REF,
g.fileName, y, y.getText(), expr);
}
else {
errMgr.grammarError(ErrorType.UNKNOWN_RULE_ATTRIBUTE,
g.fileName, y, y.getText(), rref.name, expr);
}
}
else if ( !node.resolver.resolvesToAttributeDict(x.getText(), node) ) {
errMgr.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
g.fileName, x, x.getText(), expr);
}
else {
errMgr.grammarError(ErrorType.UNKNOWN_ATTRIBUTE_IN_SCOPE,
g.fileName, y, y.getText(), expr);
}
}
}
public void setAttr(String expr, Token x, Token rhs) {
System.out.println("setAttr "+x+" "+rhs);
List<ActionChunk> exprchunks = translateAction(rf,rhs,node);
List<ActionChunk> exprchunks = translateActionChunk(factory,rf,rhs.getText(),node);
chunks.add(new SetAttr(x.getText(), exprchunks));
}
@ -101,4 +171,13 @@ public class ActionTranslator implements ActionSplitterListener {
public void text(String text) {
chunks.add(new ActionText(text));
}
// public String getTokenLabel(String x, ActionAST node) {
// Alternative alt = node.resolver.
// Rule r = node.nfaState.rule;
// if ( r.tokenRefs.get(x)!=null ) return true;
// LabelElementPair anyLabelDef = getAnyLabelDef(x);
// if ( anyLabelDef!=null && anyLabelDef.type== LabelType.TOKEN_LABEL ) return true;
// return false;
// }
}

View File

@ -10,6 +10,19 @@ public class CodeGenPipeline {
}
public void process() {
CodeGenerator gen = new CodeGenerator(g);
// for (Rule r : g.rules.values()) {
// for (int i=1; i<=r.numberOfAlts; i++) {
// Alternative alt = r.alt[i];
// for (String ref : alt.tokenRefs.keySet()) {
// if ( alt.tokenRefsInActions.get(ref)!=null ) {
// String label = gen.target.getImplicitTokenLabel(ast);
// alt.implicitTokenLabels.put(, label);
// }
// }
// }
// }
ST outputFileST = gen.generate();
gen.write(outputFileST);
// if ( g.isLexer() ) processLexer();

View File

@ -4,6 +4,7 @@ import org.antlr.v4.automata.DFA;
import org.antlr.v4.codegen.src.*;
import org.antlr.v4.misc.IntervalSet;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.tool.Alternative;
import org.antlr.v4.tool.BlockAST;
import org.antlr.v4.tool.Grammar;
import org.antlr.v4.tool.GrammarAST;
@ -18,7 +19,8 @@ public abstract class OutputModelFactory {
// Context ptrs
public OutputModelObject file; // root
public Stack<RuleFunction> currentRule = new Stack<RuleFunction>();
public Stack<RuleFunction> currentRule = new Stack<RuleFunction>();
public Alternative currentAlt;
protected OutputModelFactory(CodeGenerator gen) {
this.gen = gen;

View File

@ -32,8 +32,8 @@ public class ParserFactory extends OutputModelFactory {
public List<SrcOp> ruleRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
InvokeRule r = new InvokeRule(this, ID, label);
AddToList a = null;
if ( label!=null && label.parent.getType()== ANTLRParser.PLUS_ASSIGN ) {
a = new AddToList(this, gen.target.getListLabel(r.label), r);
if ( label!=null && label.parent.getType()==ANTLRParser.PLUS_ASSIGN ) {
a = new AddToList(this, gen.target.getListLabel(label.getText()), r);
}
return Utils.list(r, a);
}
@ -42,8 +42,8 @@ public class ParserFactory extends OutputModelFactory {
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
MatchToken m = new MatchToken(this, (TerminalAST) ID, label);
AddToList a = null;
if ( label!=null && label.parent.getType()== ANTLRParser.PLUS_ASSIGN ) {
a = new AddToList(this, gen.target.getListLabel(m.label), m);
if ( label!=null && label.parent.getType()==ANTLRParser.PLUS_ASSIGN ) {
a = new AddToList(this, gen.target.getListLabel(label.getText()), m);
}
return Utils.list(m, a);
}

View File

@ -36,7 +36,11 @@ block[GrammarAST label, GrammarAST ebnfRoot] returns [SrcOp omo]
;
alternative returns [CodeBlock omo]
@init {List<SrcOp> elems = new ArrayList<SrcOp>();}
@init {
List<SrcOp> elems = new ArrayList<SrcOp>();
if ( ((AltAST)$start).alt!=null ) factory.currentAlt = ((AltAST)$start).alt;
}
: ^(ALT_REWRITE a=alternative .)
| ^(ALT EPSILON) {$omo = factory.epsilon();}
| ^( ALT ( element {elems.addAll($element.omos);} )+ ) {$omo = factory.alternative(elems);}

View File

@ -1,13 +1,15 @@
// $ANTLR ${project.version} ${buildNumber} SourceGenTriggers.g 2010-05-12 16:26:01
// $ANTLR ${project.version} ${buildNumber} SourceGenTriggers.g 2010-05-19 15:23:17
package org.antlr.v4.codegen;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.TreeNodeStream;
import org.antlr.runtime.tree.TreeParser;
import org.antlr.runtime.tree.TreeRuleReturnScope;
import org.antlr.v4.codegen.src.CodeBlock;
import org.antlr.v4.codegen.src.SrcOp;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.tool.AltAST;
import org.antlr.v4.tool.BlockAST;
import org.antlr.v4.tool.GrammarAST;
@ -151,7 +153,7 @@ public class SourceGenTriggers extends TreeParser {
SrcOp omo = null;
GrammarAST blk=null;
CodeBlock alternative1 = null;
SourceGenTriggers.alternative_return alternative1 = null;
try {
@ -238,7 +240,7 @@ public class SourceGenTriggers extends TreeParser {
state._fsp--;
alts.add(alternative1);
alts.add((alternative1!=null?alternative1.omo:null));
}
break;
@ -272,20 +274,28 @@ public class SourceGenTriggers extends TreeParser {
}
// $ANTLR end "block"
public static class alternative_return extends TreeRuleReturnScope {
public CodeBlock omo;
};
// $ANTLR start "alternative"
// SourceGenTriggers.g:38:1: alternative returns [CodeBlock omo] : ( ^( ALT_REWRITE a= alternative . ) | ^( ALT EPSILON ) | ^( ALT ( element )+ ) );
public final CodeBlock alternative() throws RecognitionException {
CodeBlock omo = null;
public final SourceGenTriggers.alternative_return alternative() throws RecognitionException {
SourceGenTriggers.alternative_return retval = new SourceGenTriggers.alternative_return();
retval.start = input.LT(1);
CodeBlock a = null;
SourceGenTriggers.alternative_return a = null;
List<SrcOp> element2 = null;
List<SrcOp> elems = new ArrayList<SrcOp>();
List<SrcOp> elems = new ArrayList<SrcOp>();
if ( ((AltAST)((GrammarAST)retval.start)).alt!=null ) factory.currentAlt = ((AltAST)((GrammarAST)retval.start)).alt;
try {
// SourceGenTriggers.g:40:5: ( ^( ALT_REWRITE a= alternative . ) | ^( ALT EPSILON ) | ^( ALT ( element )+ ) )
// SourceGenTriggers.g:44:5: ( ^( ALT_REWRITE a= alternative . ) | ^( ALT EPSILON ) | ^( ALT ( element )+ ) )
int alt5=3;
int LA5_0 = input.LA(1);
@ -326,7 +336,7 @@ public class SourceGenTriggers extends TreeParser {
}
switch (alt5) {
case 1 :
// SourceGenTriggers.g:40:7: ^( ALT_REWRITE a= alternative . )
// SourceGenTriggers.g:44:7: ^( ALT_REWRITE a= alternative . )
{
match(input,ALT_REWRITE,FOLLOW_ALT_REWRITE_in_alternative141);
@ -343,7 +353,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 2 :
// SourceGenTriggers.g:41:7: ^( ALT EPSILON )
// SourceGenTriggers.g:45:7: ^( ALT EPSILON )
{
match(input,ALT,FOLLOW_ALT_in_alternative158);
@ -351,17 +361,17 @@ public class SourceGenTriggers extends TreeParser {
match(input,EPSILON,FOLLOW_EPSILON_in_alternative160);
match(input, Token.UP, null);
omo = factory.epsilon();
retval.omo = factory.epsilon();
}
break;
case 3 :
// SourceGenTriggers.g:42:9: ^( ALT ( element )+ )
// SourceGenTriggers.g:46:9: ^( ALT ( element )+ )
{
match(input,ALT,FOLLOW_ALT_in_alternative175);
match(input, Token.DOWN, null);
// SourceGenTriggers.g:42:16: ( element )+
// SourceGenTriggers.g:46:16: ( element )+
int cnt4=0;
loop4:
do {
@ -375,7 +385,7 @@ public class SourceGenTriggers extends TreeParser {
switch (alt4) {
case 1 :
// SourceGenTriggers.g:42:18: element
// SourceGenTriggers.g:46:18: element
{
pushFollow(FOLLOW_element_in_alternative179);
element2=element();
@ -398,7 +408,7 @@ public class SourceGenTriggers extends TreeParser {
match(input, Token.UP, null);
omo = factory.alternative(elems);
retval.omo = factory.alternative(elems);
}
break;
@ -411,13 +421,13 @@ public class SourceGenTriggers extends TreeParser {
}
finally {
}
return omo;
return retval;
}
// $ANTLR end "alternative"
// $ANTLR start "element"
// SourceGenTriggers.g:45:1: element returns [List<SrcOp> omos] : ( labeledElement | atom[null] | ebnf | ACTION | SEMPRED | GATED_SEMPRED | treeSpec );
// SourceGenTriggers.g:49:1: element returns [List<SrcOp> omos] : ( labeledElement | atom[null] | ebnf | ACTION | SEMPRED | GATED_SEMPRED | treeSpec );
public final List<SrcOp> element() throws RecognitionException {
List<SrcOp> omos = null;
@ -431,12 +441,12 @@ public class SourceGenTriggers extends TreeParser {
try {
// SourceGenTriggers.g:46:2: ( labeledElement | atom[null] | ebnf | ACTION | SEMPRED | GATED_SEMPRED | treeSpec )
// SourceGenTriggers.g:50:2: ( labeledElement | atom[null] | ebnf | ACTION | SEMPRED | GATED_SEMPRED | treeSpec )
int alt6=7;
alt6 = dfa6.predict(input);
switch (alt6) {
case 1 :
// SourceGenTriggers.g:46:4: labeledElement
// SourceGenTriggers.g:50:4: labeledElement
{
pushFollow(FOLLOW_labeledElement_in_element206);
labeledElement3=labeledElement();
@ -448,7 +458,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 2 :
// SourceGenTriggers.g:47:4: atom[null]
// SourceGenTriggers.g:51:4: atom[null]
{
pushFollow(FOLLOW_atom_in_element217);
atom4=atom(null);
@ -460,7 +470,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 3 :
// SourceGenTriggers.g:48:4: ebnf
// SourceGenTriggers.g:52:4: ebnf
{
pushFollow(FOLLOW_ebnf_in_element230);
ebnf5=ebnf();
@ -472,7 +482,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 4 :
// SourceGenTriggers.g:49:6: ACTION
// SourceGenTriggers.g:53:6: ACTION
{
ACTION6=(GrammarAST)match(input,ACTION,FOLLOW_ACTION_in_element245);
omos = Utils.list(factory.action(ACTION6));
@ -480,7 +490,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 5 :
// SourceGenTriggers.g:50:6: SEMPRED
// SourceGenTriggers.g:54:6: SEMPRED
{
SEMPRED7=(GrammarAST)match(input,SEMPRED,FOLLOW_SEMPRED_in_element260);
omos = Utils.list(factory.sempred(SEMPRED7));
@ -488,14 +498,14 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 6 :
// SourceGenTriggers.g:51:4: GATED_SEMPRED
// SourceGenTriggers.g:55:4: GATED_SEMPRED
{
match(input,GATED_SEMPRED,FOLLOW_GATED_SEMPRED_in_element273);
}
break;
case 7 :
// SourceGenTriggers.g:52:4: treeSpec
// SourceGenTriggers.g:56:4: treeSpec
{
pushFollow(FOLLOW_treeSpec_in_element279);
treeSpec();
@ -520,7 +530,7 @@ public class SourceGenTriggers extends TreeParser {
// $ANTLR start "labeledElement"
// SourceGenTriggers.g:55:1: labeledElement returns [List<SrcOp> omos] : ( ^( ASSIGN ID atom[$ID] ) | ^( ASSIGN ID block[$ID,null] ) | ^( PLUS_ASSIGN ID atom[$ID] ) | ^( PLUS_ASSIGN ID block[$ID,null] ) );
// SourceGenTriggers.g:59:1: labeledElement returns [List<SrcOp> omos] : ( ^( ASSIGN ID atom[$ID] ) | ^( ASSIGN ID block[$ID,null] ) | ^( PLUS_ASSIGN ID atom[$ID] ) | ^( PLUS_ASSIGN ID block[$ID,null] ) );
public final List<SrcOp> labeledElement() throws RecognitionException {
List<SrcOp> omos = null;
@ -538,12 +548,12 @@ public class SourceGenTriggers extends TreeParser {
try {
// SourceGenTriggers.g:56:2: ( ^( ASSIGN ID atom[$ID] ) | ^( ASSIGN ID block[$ID,null] ) | ^( PLUS_ASSIGN ID atom[$ID] ) | ^( PLUS_ASSIGN ID block[$ID,null] ) )
// SourceGenTriggers.g:60:2: ( ^( ASSIGN ID atom[$ID] ) | ^( ASSIGN ID block[$ID,null] ) | ^( PLUS_ASSIGN ID atom[$ID] ) | ^( PLUS_ASSIGN ID block[$ID,null] ) )
int alt7=4;
alt7 = dfa7.predict(input);
switch (alt7) {
case 1 :
// SourceGenTriggers.g:56:4: ^( ASSIGN ID atom[$ID] )
// SourceGenTriggers.g:60:4: ^( ASSIGN ID atom[$ID] )
{
match(input,ASSIGN,FOLLOW_ASSIGN_in_labeledElement301);
@ -561,7 +571,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 2 :
// SourceGenTriggers.g:57:4: ^( ASSIGN ID block[$ID,null] )
// SourceGenTriggers.g:61:4: ^( ASSIGN ID block[$ID,null] )
{
match(input,ASSIGN,FOLLOW_ASSIGN_in_labeledElement319);
@ -579,7 +589,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 3 :
// SourceGenTriggers.g:58:4: ^( PLUS_ASSIGN ID atom[$ID] )
// SourceGenTriggers.g:62:4: ^( PLUS_ASSIGN ID atom[$ID] )
{
match(input,PLUS_ASSIGN,FOLLOW_PLUS_ASSIGN_in_labeledElement334);
@ -597,7 +607,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 4 :
// SourceGenTriggers.g:59:4: ^( PLUS_ASSIGN ID block[$ID,null] )
// SourceGenTriggers.g:63:4: ^( PLUS_ASSIGN ID block[$ID,null] )
{
match(input,PLUS_ASSIGN,FOLLOW_PLUS_ASSIGN_in_labeledElement350);
@ -629,7 +639,7 @@ public class SourceGenTriggers extends TreeParser {
// $ANTLR start "treeSpec"
// SourceGenTriggers.g:62:1: treeSpec returns [SrcOp omo] : ^( TREE_BEGIN (e= element )+ ) ;
// SourceGenTriggers.g:66:1: treeSpec returns [SrcOp omo] : ^( TREE_BEGIN (e= element )+ ) ;
public final SrcOp treeSpec() throws RecognitionException {
SrcOp omo = null;
@ -637,13 +647,13 @@ public class SourceGenTriggers extends TreeParser {
try {
// SourceGenTriggers.g:63:5: ( ^( TREE_BEGIN (e= element )+ ) )
// SourceGenTriggers.g:63:7: ^( TREE_BEGIN (e= element )+ )
// SourceGenTriggers.g:67:5: ( ^( TREE_BEGIN (e= element )+ ) )
// SourceGenTriggers.g:67:7: ^( TREE_BEGIN (e= element )+ )
{
match(input,TREE_BEGIN,FOLLOW_TREE_BEGIN_in_treeSpec378);
match(input, Token.DOWN, null);
// SourceGenTriggers.g:63:21: (e= element )+
// SourceGenTriggers.g:67:21: (e= element )+
int cnt8=0;
loop8:
do {
@ -657,7 +667,7 @@ public class SourceGenTriggers extends TreeParser {
switch (alt8) {
case 1 :
// SourceGenTriggers.g:63:22: e= element
// SourceGenTriggers.g:67:22: e= element
{
pushFollow(FOLLOW_element_in_treeSpec384);
e=element();
@ -695,7 +705,7 @@ public class SourceGenTriggers extends TreeParser {
// $ANTLR start "ebnf"
// SourceGenTriggers.g:66:1: ebnf returns [SrcOp omo] : ( ^( astBlockSuffix block[null,null] ) | ^( OPTIONAL block[null,$OPTIONAL] ) | ^( CLOSURE block[null,$CLOSURE] ) | ^( POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE] ) | block[null, null] );
// SourceGenTriggers.g:70:1: ebnf returns [SrcOp omo] : ( ^( astBlockSuffix block[null,null] ) | ^( OPTIONAL block[null,$OPTIONAL] ) | ^( CLOSURE block[null,$CLOSURE] ) | ^( POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE] ) | block[null, null] );
public final SrcOp ebnf() throws RecognitionException {
SrcOp omo = null;
@ -712,7 +722,7 @@ public class SourceGenTriggers extends TreeParser {
try {
// SourceGenTriggers.g:67:2: ( ^( astBlockSuffix block[null,null] ) | ^( OPTIONAL block[null,$OPTIONAL] ) | ^( CLOSURE block[null,$CLOSURE] ) | ^( POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE] ) | block[null, null] )
// SourceGenTriggers.g:71:2: ( ^( astBlockSuffix block[null,null] ) | ^( OPTIONAL block[null,$OPTIONAL] ) | ^( CLOSURE block[null,$CLOSURE] ) | ^( POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE] ) | block[null, null] )
int alt9=5;
switch ( input.LA(1) ) {
case IMPLIES:
@ -751,7 +761,7 @@ public class SourceGenTriggers extends TreeParser {
switch (alt9) {
case 1 :
// SourceGenTriggers.g:67:4: ^( astBlockSuffix block[null,null] )
// SourceGenTriggers.g:71:4: ^( astBlockSuffix block[null,null] )
{
pushFollow(FOLLOW_astBlockSuffix_in_ebnf408);
astBlockSuffix();
@ -771,7 +781,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 2 :
// SourceGenTriggers.g:68:4: ^( OPTIONAL block[null,$OPTIONAL] )
// SourceGenTriggers.g:72:4: ^( OPTIONAL block[null,$OPTIONAL] )
{
OPTIONAL16=(GrammarAST)match(input,OPTIONAL,FOLLOW_OPTIONAL_in_ebnf420);
@ -788,7 +798,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 3 :
// SourceGenTriggers.g:69:4: ^( CLOSURE block[null,$CLOSURE] )
// SourceGenTriggers.g:73:4: ^( CLOSURE block[null,$CLOSURE] )
{
CLOSURE18=(GrammarAST)match(input,CLOSURE,FOLLOW_CLOSURE_in_ebnf434);
@ -805,7 +815,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 4 :
// SourceGenTriggers.g:70:4: ^( POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE] )
// SourceGenTriggers.g:74:4: ^( POSITIVE_CLOSURE block[null,$POSITIVE_CLOSURE] )
{
POSITIVE_CLOSURE20=(GrammarAST)match(input,POSITIVE_CLOSURE,FOLLOW_POSITIVE_CLOSURE_in_ebnf449);
@ -822,7 +832,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 5 :
// SourceGenTriggers.g:72:5: block[null, null]
// SourceGenTriggers.g:76:5: block[null, null]
{
pushFollow(FOLLOW_block_in_ebnf475);
block22=block(null, null);
@ -848,10 +858,10 @@ public class SourceGenTriggers extends TreeParser {
// $ANTLR start "astBlockSuffix"
// SourceGenTriggers.g:75:1: astBlockSuffix : ( ROOT | IMPLIES | BANG );
// SourceGenTriggers.g:79:1: astBlockSuffix : ( ROOT | IMPLIES | BANG );
public final void astBlockSuffix() throws RecognitionException {
try {
// SourceGenTriggers.g:76:5: ( ROOT | IMPLIES | BANG )
// SourceGenTriggers.g:80:5: ( ROOT | IMPLIES | BANG )
// SourceGenTriggers.g:
{
if ( input.LA(1)==IMPLIES||input.LA(1)==BANG||input.LA(1)==ROOT ) {
@ -879,7 +889,7 @@ public class SourceGenTriggers extends TreeParser {
// $ANTLR start "atom"
// SourceGenTriggers.g:83:1: atom[GrammarAST label] returns [List<SrcOp> omos] : ( ^( ROOT range[label] ) | ^( BANG range[label] ) | ^( ROOT notSet[label] ) | ^( BANG notSet[label] ) | notSet[label] | range[label] | ^( DOT ID terminal[label] ) | ^( DOT ID ruleref[label] ) | ^( WILDCARD . ) | WILDCARD | terminal[label] | ruleref[label] );
// SourceGenTriggers.g:87:1: atom[GrammarAST label] returns [List<SrcOp> omos] : ( ^( ROOT range[label] ) | ^( BANG range[label] ) | ^( ROOT notSet[label] ) | ^( BANG notSet[label] ) | notSet[label] | range[label] | ^( DOT ID terminal[label] ) | ^( DOT ID ruleref[label] ) | ^( WILDCARD . ) | WILDCARD | terminal[label] | ruleref[label] );
public final List<SrcOp> atom(GrammarAST label) throws RecognitionException {
List<SrcOp> omos = null;
@ -895,12 +905,12 @@ public class SourceGenTriggers extends TreeParser {
try {
// SourceGenTriggers.g:84:2: ( ^( ROOT range[label] ) | ^( BANG range[label] ) | ^( ROOT notSet[label] ) | ^( BANG notSet[label] ) | notSet[label] | range[label] | ^( DOT ID terminal[label] ) | ^( DOT ID ruleref[label] ) | ^( WILDCARD . ) | WILDCARD | terminal[label] | ruleref[label] )
// SourceGenTriggers.g:88:2: ( ^( ROOT range[label] ) | ^( BANG range[label] ) | ^( ROOT notSet[label] ) | ^( BANG notSet[label] ) | notSet[label] | range[label] | ^( DOT ID terminal[label] ) | ^( DOT ID ruleref[label] ) | ^( WILDCARD . ) | WILDCARD | terminal[label] | ruleref[label] )
int alt10=12;
alt10 = dfa10.predict(input);
switch (alt10) {
case 1 :
// SourceGenTriggers.g:84:4: ^( ROOT range[label] )
// SourceGenTriggers.g:88:4: ^( ROOT range[label] )
{
match(input,ROOT,FOLLOW_ROOT_in_atom537);
@ -916,7 +926,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 2 :
// SourceGenTriggers.g:85:4: ^( BANG range[label] )
// SourceGenTriggers.g:89:4: ^( BANG range[label] )
{
match(input,BANG,FOLLOW_BANG_in_atom550);
@ -933,7 +943,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 3 :
// SourceGenTriggers.g:86:4: ^( ROOT notSet[label] )
// SourceGenTriggers.g:90:4: ^( ROOT notSet[label] )
{
match(input,ROOT,FOLLOW_ROOT_in_atom564);
@ -949,7 +959,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 4 :
// SourceGenTriggers.g:87:4: ^( BANG notSet[label] )
// SourceGenTriggers.g:91:4: ^( BANG notSet[label] )
{
match(input,BANG,FOLLOW_BANG_in_atom577);
@ -966,7 +976,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 5 :
// SourceGenTriggers.g:88:4: notSet[label]
// SourceGenTriggers.g:92:4: notSet[label]
{
pushFollow(FOLLOW_notSet_in_atom590);
notSet(label);
@ -977,7 +987,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 6 :
// SourceGenTriggers.g:89:4: range[label]
// SourceGenTriggers.g:93:4: range[label]
{
pushFollow(FOLLOW_range_in_atom601);
range25=range(label);
@ -989,7 +999,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 7 :
// SourceGenTriggers.g:90:4: ^( DOT ID terminal[label] )
// SourceGenTriggers.g:94:4: ^( DOT ID terminal[label] )
{
match(input,DOT,FOLLOW_DOT_in_atom614);
@ -1006,7 +1016,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 8 :
// SourceGenTriggers.g:91:4: ^( DOT ID ruleref[label] )
// SourceGenTriggers.g:95:4: ^( DOT ID ruleref[label] )
{
match(input,DOT,FOLLOW_DOT_in_atom626);
@ -1023,7 +1033,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 9 :
// SourceGenTriggers.g:92:7: ^( WILDCARD . )
// SourceGenTriggers.g:96:7: ^( WILDCARD . )
{
match(input,WILDCARD,FOLLOW_WILDCARD_in_atom641);
@ -1035,14 +1045,14 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 10 :
// SourceGenTriggers.g:93:7: WILDCARD
// SourceGenTriggers.g:97:7: WILDCARD
{
match(input,WILDCARD,FOLLOW_WILDCARD_in_atom656);
}
break;
case 11 :
// SourceGenTriggers.g:94:9: terminal[label]
// SourceGenTriggers.g:98:9: terminal[label]
{
pushFollow(FOLLOW_terminal_in_atom670);
terminal26=terminal(label);
@ -1054,7 +1064,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 12 :
// SourceGenTriggers.g:95:9: ruleref[label]
// SourceGenTriggers.g:99:9: ruleref[label]
{
pushFollow(FOLLOW_ruleref_in_atom686);
ruleref27=ruleref(label);
@ -1080,12 +1090,12 @@ public class SourceGenTriggers extends TreeParser {
// $ANTLR start "notSet"
// SourceGenTriggers.g:98:1: notSet[GrammarAST label] returns [List<SrcOp> omos] : ( ^( NOT terminal[label] ) | ^( NOT block[label,null] ) );
// SourceGenTriggers.g:102:1: notSet[GrammarAST label] returns [List<SrcOp> omos] : ( ^( NOT terminal[label] ) | ^( NOT block[label,null] ) );
public final List<SrcOp> notSet(GrammarAST label) throws RecognitionException {
List<SrcOp> omos = null;
try {
// SourceGenTriggers.g:99:5: ( ^( NOT terminal[label] ) | ^( NOT block[label,null] ) )
// SourceGenTriggers.g:103:5: ( ^( NOT terminal[label] ) | ^( NOT block[label,null] ) )
int alt11=2;
int LA11_0 = input.LA(1);
@ -1123,7 +1133,7 @@ public class SourceGenTriggers extends TreeParser {
}
switch (alt11) {
case 1 :
// SourceGenTriggers.g:99:7: ^( NOT terminal[label] )
// SourceGenTriggers.g:103:7: ^( NOT terminal[label] )
{
match(input,NOT,FOLLOW_NOT_in_notSet715);
@ -1139,7 +1149,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 2 :
// SourceGenTriggers.g:100:7: ^( NOT block[label,null] )
// SourceGenTriggers.g:104:7: ^( NOT block[label,null] )
{
match(input,NOT,FOLLOW_NOT_in_notSet730);
@ -1169,7 +1179,7 @@ public class SourceGenTriggers extends TreeParser {
// $ANTLR start "ruleref"
// SourceGenTriggers.g:103:1: ruleref[GrammarAST label] returns [List<SrcOp> omos] : ( ^( ROOT ^( RULE_REF ( ARG_ACTION )? ) ) | ^( BANG ^( RULE_REF ( ARG_ACTION )? ) ) | ^( RULE_REF ( ARG_ACTION )? ) );
// SourceGenTriggers.g:107:1: ruleref[GrammarAST label] returns [List<SrcOp> omos] : ( ^( ROOT ^( RULE_REF ( ARG_ACTION )? ) ) | ^( BANG ^( RULE_REF ( ARG_ACTION )? ) ) | ^( RULE_REF ( ARG_ACTION )? ) );
public final List<SrcOp> ruleref(GrammarAST label) throws RecognitionException {
List<SrcOp> omos = null;
@ -1179,7 +1189,7 @@ public class SourceGenTriggers extends TreeParser {
GrammarAST ARG_ACTION31=null;
try {
// SourceGenTriggers.g:104:5: ( ^( ROOT ^( RULE_REF ( ARG_ACTION )? ) ) | ^( BANG ^( RULE_REF ( ARG_ACTION )? ) ) | ^( RULE_REF ( ARG_ACTION )? ) )
// SourceGenTriggers.g:108:5: ( ^( ROOT ^( RULE_REF ( ARG_ACTION )? ) ) | ^( BANG ^( RULE_REF ( ARG_ACTION )? ) ) | ^( RULE_REF ( ARG_ACTION )? ) )
int alt15=3;
switch ( input.LA(1) ) {
case ROOT:
@ -1206,7 +1216,7 @@ public class SourceGenTriggers extends TreeParser {
switch (alt15) {
case 1 :
// SourceGenTriggers.g:104:7: ^( ROOT ^( RULE_REF ( ARG_ACTION )? ) )
// SourceGenTriggers.g:108:7: ^( ROOT ^( RULE_REF ( ARG_ACTION )? ) )
{
match(input,ROOT,FOLLOW_ROOT_in_ruleref760);
@ -1215,7 +1225,7 @@ public class SourceGenTriggers extends TreeParser {
if ( input.LA(1)==Token.DOWN ) {
match(input, Token.DOWN, null);
// SourceGenTriggers.g:104:25: ( ARG_ACTION )?
// SourceGenTriggers.g:108:25: ( ARG_ACTION )?
int alt12=2;
int LA12_0 = input.LA(1);
@ -1224,7 +1234,7 @@ public class SourceGenTriggers extends TreeParser {
}
switch (alt12) {
case 1 :
// SourceGenTriggers.g:104:25: ARG_ACTION
// SourceGenTriggers.g:108:25: ARG_ACTION
{
match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_ruleref765);
@ -1242,7 +1252,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 2 :
// SourceGenTriggers.g:105:7: ^( BANG ^( RULE_REF ( ARG_ACTION )? ) )
// SourceGenTriggers.g:109:7: ^( BANG ^( RULE_REF ( ARG_ACTION )? ) )
{
match(input,BANG,FOLLOW_BANG_in_ruleref777);
@ -1251,7 +1261,7 @@ public class SourceGenTriggers extends TreeParser {
if ( input.LA(1)==Token.DOWN ) {
match(input, Token.DOWN, null);
// SourceGenTriggers.g:105:25: ( ARG_ACTION )?
// SourceGenTriggers.g:109:25: ( ARG_ACTION )?
int alt13=2;
int LA13_0 = input.LA(1);
@ -1260,7 +1270,7 @@ public class SourceGenTriggers extends TreeParser {
}
switch (alt13) {
case 1 :
// SourceGenTriggers.g:105:25: ARG_ACTION
// SourceGenTriggers.g:109:25: ARG_ACTION
{
ARG_ACTION29=(GrammarAST)match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_ruleref782);
@ -1279,13 +1289,13 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 3 :
// SourceGenTriggers.g:106:7: ^( RULE_REF ( ARG_ACTION )? )
// SourceGenTriggers.g:110:7: ^( RULE_REF ( ARG_ACTION )? )
{
RULE_REF30=(GrammarAST)match(input,RULE_REF,FOLLOW_RULE_REF_in_ruleref796);
if ( input.LA(1)==Token.DOWN ) {
match(input, Token.DOWN, null);
// SourceGenTriggers.g:106:18: ( ARG_ACTION )?
// SourceGenTriggers.g:110:18: ( ARG_ACTION )?
int alt14=2;
int LA14_0 = input.LA(1);
@ -1294,7 +1304,7 @@ public class SourceGenTriggers extends TreeParser {
}
switch (alt14) {
case 1 :
// SourceGenTriggers.g:106:18: ARG_ACTION
// SourceGenTriggers.g:110:18: ARG_ACTION
{
ARG_ACTION31=(GrammarAST)match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_ruleref798);
@ -1325,7 +1335,7 @@ public class SourceGenTriggers extends TreeParser {
// $ANTLR start "range"
// SourceGenTriggers.g:109:1: range[GrammarAST label] returns [List<SrcOp> omos] : ^( RANGE a= STRING_LITERAL b= STRING_LITERAL ) ;
// SourceGenTriggers.g:113:1: range[GrammarAST label] returns [List<SrcOp> omos] : ^( RANGE a= STRING_LITERAL b= STRING_LITERAL ) ;
public final List<SrcOp> range(GrammarAST label) throws RecognitionException {
List<SrcOp> omos = null;
@ -1333,8 +1343,8 @@ public class SourceGenTriggers extends TreeParser {
GrammarAST b=null;
try {
// SourceGenTriggers.g:110:5: ( ^( RANGE a= STRING_LITERAL b= STRING_LITERAL ) )
// SourceGenTriggers.g:110:7: ^( RANGE a= STRING_LITERAL b= STRING_LITERAL )
// SourceGenTriggers.g:114:5: ( ^( RANGE a= STRING_LITERAL b= STRING_LITERAL ) )
// SourceGenTriggers.g:114:7: ^( RANGE a= STRING_LITERAL b= STRING_LITERAL )
{
match(input,RANGE,FOLLOW_RANGE_in_range827);
@ -1359,7 +1369,7 @@ public class SourceGenTriggers extends TreeParser {
// $ANTLR start "terminal"
// SourceGenTriggers.g:113:1: terminal[GrammarAST label] returns [List<SrcOp> omos] : ( ^( STRING_LITERAL . ) | STRING_LITERAL | ^( TOKEN_REF ARG_ACTION . ) | ^( TOKEN_REF . ) | TOKEN_REF | ^( ROOT terminal[label] ) | ^( BANG terminal[label] ) );
// SourceGenTriggers.g:117:1: terminal[GrammarAST label] returns [List<SrcOp> omos] : ( ^( STRING_LITERAL . ) | STRING_LITERAL | ^( TOKEN_REF ARG_ACTION . ) | ^( TOKEN_REF . ) | TOKEN_REF | ^( ROOT terminal[label] ) | ^( BANG terminal[label] ) );
public final List<SrcOp> terminal(GrammarAST label) throws RecognitionException {
List<SrcOp> omos = null;
@ -1371,12 +1381,12 @@ public class SourceGenTriggers extends TreeParser {
GrammarAST TOKEN_REF37=null;
try {
// SourceGenTriggers.g:114:5: ( ^( STRING_LITERAL . ) | STRING_LITERAL | ^( TOKEN_REF ARG_ACTION . ) | ^( TOKEN_REF . ) | TOKEN_REF | ^( ROOT terminal[label] ) | ^( BANG terminal[label] ) )
// SourceGenTriggers.g:118:5: ( ^( STRING_LITERAL . ) | STRING_LITERAL | ^( TOKEN_REF ARG_ACTION . ) | ^( TOKEN_REF . ) | TOKEN_REF | ^( ROOT terminal[label] ) | ^( BANG terminal[label] ) )
int alt16=7;
alt16 = dfa16.predict(input);
switch (alt16) {
case 1 :
// SourceGenTriggers.g:114:8: ^( STRING_LITERAL . )
// SourceGenTriggers.g:118:8: ^( STRING_LITERAL . )
{
STRING_LITERAL32=(GrammarAST)match(input,STRING_LITERAL,FOLLOW_STRING_LITERAL_in_terminal865);
@ -1389,7 +1399,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 2 :
// SourceGenTriggers.g:115:7: STRING_LITERAL
// SourceGenTriggers.g:119:7: STRING_LITERAL
{
STRING_LITERAL33=(GrammarAST)match(input,STRING_LITERAL,FOLLOW_STRING_LITERAL_in_terminal880);
omos = factory.stringRef(STRING_LITERAL33, label);
@ -1397,7 +1407,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 3 :
// SourceGenTriggers.g:116:7: ^( TOKEN_REF ARG_ACTION . )
// SourceGenTriggers.g:120:7: ^( TOKEN_REF ARG_ACTION . )
{
TOKEN_REF34=(GrammarAST)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal894);
@ -1411,7 +1421,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 4 :
// SourceGenTriggers.g:117:7: ^( TOKEN_REF . )
// SourceGenTriggers.g:121:7: ^( TOKEN_REF . )
{
TOKEN_REF36=(GrammarAST)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal910);
@ -1424,7 +1434,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 5 :
// SourceGenTriggers.g:118:7: TOKEN_REF
// SourceGenTriggers.g:122:7: TOKEN_REF
{
TOKEN_REF37=(GrammarAST)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal926);
omos = factory.tokenRef(TOKEN_REF37, label, null);
@ -1432,7 +1442,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 6 :
// SourceGenTriggers.g:119:7: ^( ROOT terminal[label] )
// SourceGenTriggers.g:123:7: ^( ROOT terminal[label] )
{
match(input,ROOT,FOLLOW_ROOT_in_terminal941);
@ -1448,7 +1458,7 @@ public class SourceGenTriggers extends TreeParser {
}
break;
case 7 :
// SourceGenTriggers.g:120:7: ^( BANG terminal[label] )
// SourceGenTriggers.g:124:7: ^( BANG terminal[label] )
{
match(input,BANG,FOLLOW_BANG_in_terminal957);
@ -1545,7 +1555,7 @@ public class SourceGenTriggers extends TreeParser {
this.transition = DFA6_transition;
}
public String getDescription() {
return "45:1: element returns [List<SrcOp> omos] : ( labeledElement | atom[null] | ebnf | ACTION | SEMPRED | GATED_SEMPRED | treeSpec );";
return "49:1: element returns [List<SrcOp> omos] : ( labeledElement | atom[null] | ebnf | ACTION | SEMPRED | GATED_SEMPRED | treeSpec );";
}
}
static final String DFA7_eotS =
@ -1606,7 +1616,7 @@ public class SourceGenTriggers extends TreeParser {
this.transition = DFA7_transition;
}
public String getDescription() {
return "55:1: labeledElement returns [List<SrcOp> omos] : ( ^( ASSIGN ID atom[$ID] ) | ^( ASSIGN ID block[$ID,null] ) | ^( PLUS_ASSIGN ID atom[$ID] ) | ^( PLUS_ASSIGN ID block[$ID,null] ) );";
return "59:1: labeledElement returns [List<SrcOp> omos] : ( ^( ASSIGN ID atom[$ID] ) | ^( ASSIGN ID block[$ID,null] ) | ^( PLUS_ASSIGN ID atom[$ID] ) | ^( PLUS_ASSIGN ID block[$ID,null] ) );";
}
}
static final String DFA10_eotS =
@ -1688,7 +1698,7 @@ public class SourceGenTriggers extends TreeParser {
this.transition = DFA10_transition;
}
public String getDescription() {
return "83:1: atom[GrammarAST label] returns [List<SrcOp> omos] : ( ^( ROOT range[label] ) | ^( BANG range[label] ) | ^( ROOT notSet[label] ) | ^( BANG notSet[label] ) | notSet[label] | range[label] | ^( DOT ID terminal[label] ) | ^( DOT ID ruleref[label] ) | ^( WILDCARD . ) | WILDCARD | terminal[label] | ruleref[label] );";
return "87:1: atom[GrammarAST label] returns [List<SrcOp> omos] : ( ^( ROOT range[label] ) | ^( BANG range[label] ) | ^( ROOT notSet[label] ) | ^( BANG notSet[label] ) | notSet[label] | range[label] | ^( DOT ID terminal[label] ) | ^( DOT ID ruleref[label] ) | ^( WILDCARD . ) | WILDCARD | terminal[label] | ruleref[label] );";
}
}
static final String DFA16_eotS =
@ -1754,7 +1764,7 @@ public class SourceGenTriggers extends TreeParser {
this.transition = DFA16_transition;
}
public String getDescription() {
return "113:1: terminal[GrammarAST label] returns [List<SrcOp> omos] : ( ^( STRING_LITERAL . ) | STRING_LITERAL | ^( TOKEN_REF ARG_ACTION . ) | ^( TOKEN_REF . ) | TOKEN_REF | ^( ROOT terminal[label] ) | ^( BANG terminal[label] ) );";
return "117:1: terminal[GrammarAST label] returns [List<SrcOp> omos] : ( ^( STRING_LITERAL . ) | STRING_LITERAL | ^( TOKEN_REF ARG_ACTION . ) | ^( TOKEN_REF . ) | TOKEN_REF | ^( ROOT terminal[label] ) | ^( BANG terminal[label] ) );";
}
}

View File

@ -136,6 +136,10 @@ public class Target {
return r.name+"_ctx";
}
public String getDynamicScopeStructName(String ruleName) { return ruleName+"_scope"; }
// should be same for all refs to same token like $ID within single rule function
public String getImplicitTokenLabel(String tokenName) { return "_t"+tokenName; }
public String getImplicitRuleLabel(String ruleName) { return "_r"+ruleName; }
public int getInlineTestsVsBitsetThreshold() { return 20; }
}

View File

@ -15,7 +15,7 @@ public class Action extends SrcOp {
public Action(OutputModelFactory factory, GrammarAST ast) {
super(factory,ast);
RuleFunction rf = factory.currentRule.peek();
chunks = ActionTranslator.translateAction(rf, ast.token, (ActionAST)ast);
chunks = ActionTranslator.translateAction(factory,rf, ast.token, (ActionAST)ast);
System.out.println("actions="+chunks);
}

View File

@ -8,23 +8,26 @@ import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.tool.GrammarAST;
import org.antlr.v4.tool.Rule;
import java.util.ArrayList;
import java.util.List;
/** */
public class InvokeRule extends SrcOp implements LabeledOp {
public String name;
public String label;
public List<String> labels = new ArrayList<String>();
public String argExprs;
public BitSetDecl follow;
public String ctxName;
public InvokeRule(OutputModelFactory factory, GrammarAST ast, GrammarAST labelAST) {
this.factory = factory;
this.ast = ast;
super(factory, ast);
this.name = ast.getText();
Rule r = factory.g.getRule(name);
ctxName = factory.gen.target.getRuleFunctionContextStructName(r);
if ( labelAST!=null ) {
label = labelAST.getText();
String label = labelAST.getText();
labels.add(label);
RuleContextDecl d = new RuleContextDecl(factory,label,ctxName);
factory.currentRule.peek().addDecl(d);
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
@ -36,6 +39,14 @@ public class InvokeRule extends SrcOp implements LabeledOp {
argExprs = ast.getChild(0).getText();
}
// If action refs as rulename not label, we need to define implicit label
if ( factory.currentAlt.ruleRefsInActions.containsKey(ast.getText()) ) {
String label = factory.gen.target.getImplicitRuleLabel(ast.getText());
labels.add(label);
RuleContextDecl d = new RuleContextDecl(factory,label,ctxName);
factory.currentRule.peek().addDecl(d);
}
// compute follow
LinearApproximator approx = new LinearApproximator(factory.g, -1);
IntervalSet fset = approx.LOOK(ast.nfaState.transition(0).target);
@ -44,7 +55,7 @@ public class InvokeRule extends SrcOp implements LabeledOp {
factory.defineBitSet(follow);
}
public String getLabel() {
return label;
public List<String> getLabels() {
return labels;
}
}

View File

@ -1,6 +1,8 @@
package org.antlr.v4.codegen.src;
import java.util.List;
/** */
public interface LabeledOp {
public String getLabel();
public List<String> getLabels();
}

View File

@ -7,18 +7,22 @@ import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.tool.GrammarAST;
import org.antlr.v4.tool.TerminalAST;
import java.util.ArrayList;
import java.util.List;
/** */
public class MatchToken extends SrcOp implements LabeledOp {
public String name;
public BitSetDecl follow;
public String label;
public List<String> labels = new ArrayList<String>();
public MatchToken(OutputModelFactory factory, TerminalAST ast, GrammarAST labelAST) {
this.factory = factory;
super(factory, ast);
int ttype = factory.g.getTokenType(ast.getText());
name = factory.gen.target.getTokenTypeAsTargetLabel(factory.g, ttype);
if ( labelAST!=null ) {
label = labelAST.getText();
String label = labelAST.getText();
labels.add(label);
TokenDecl d = new TokenDecl(factory, label);
factory.currentRule.peek().addDecl(d);
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
@ -27,6 +31,14 @@ public class MatchToken extends SrcOp implements LabeledOp {
}
}
// If action refs as token not label, we need to define implicit label
if ( factory.currentAlt.tokenRefsInActions.containsKey(ast.getText()) ) {
String label = factory.gen.target.getImplicitTokenLabel(ast.getText());
labels.add(label);
TokenDecl d = new TokenDecl(factory, label);
factory.currentRule.peek().addDecl(d);
}
LinearApproximator approx = new LinearApproximator(factory.g, -1);
IntervalSet fset = approx.LOOK(ast.nfaState.transition(0).target);
System.out.println("follow="+fset);
@ -34,7 +46,5 @@ public class MatchToken extends SrcOp implements LabeledOp {
factory.defineBitSet(follow);
}
public String getLabel() {
return label;
}
public List<String> getLabels() { return labels; }
}

View File

@ -0,0 +1,10 @@
package org.antlr.v4.codegen.src.actions;
/** */
public class TokenRef extends ActionChunk {
public String name;
public TokenRef(String name) {
this.name = name;
}
}

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} ANTLRLexer.g 2010-05-16 13:12:30
// $ANTLR ${project.version} ${buildNumber} ANTLRLexer.g 2010-05-19 15:07:23
/*
[The "BSD licence"]
@ -264,7 +264,7 @@ public class ANTLRLexer extends Lexer {
if ( (( input.LA(2) != '/')) ) {
alt3=1;
}
else if ( (((( true )&&( !(input.LA(1) == '*' && input.LA(2) == '/') ))||( true ))) ) {
else if ( ((( true )||(( true )&&( !(input.LA(1) == '*' && input.LA(2) == '/') )))) ) {
alt3=2;
}
else {

View File

@ -549,15 +549,15 @@ alternative
@init { paraphrases.push("matching alternative"); }
@after { paraphrases.pop(); }
: elements
( rewrite -> ^(ALT_REWRITE elements rewrite)
( rewrite -> ^(ALT_REWRITE<AltAST> elements rewrite)
| -> elements
)
| rewrite -> ^(ALT_REWRITE ^(ALT EPSILON) rewrite) // empty alt with rewrite
| -> ^(ALT EPSILON) // empty alt
| rewrite -> ^(ALT_REWRITE<AltAST> ^(ALT<AltAST> EPSILON) rewrite) // empty alt with rewrite
| -> ^(ALT<AltAST> EPSILON) // empty alt
;
elements
: e+=element+ -> ^(ALT $e+)
: e+=element+ -> ^(ALT<AltAST> $e+)
;
element

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} ASTVerifier.g 2010-05-16 13:12:34
// $ANTLR ${project.version} ${buildNumber} ASTVerifier.g 2010-05-19 15:07:27
/*
[The "BSD license"]

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} ActionSplitter.g 2010-05-18 16:11:58
// $ANTLR ${project.version} ${buildNumber} ActionSplitter.g 2010-05-19 15:07:26
package org.antlr.v4.parse;
@ -2175,6 +2175,20 @@ public class ActionSplitter extends Lexer {
state.failed=false;
return success;
}
public final boolean synpred12_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred12_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
boolean success = !state.failed;
input.rewind(start);
state.backtracking--;
state.failed=false;
return success;
}
public final boolean synpred17_ActionSplitter() {
state.backtracking++;
int start = input.mark();
@ -2203,20 +2217,6 @@ public class ActionSplitter extends Lexer {
state.failed=false;
return success;
}
public final boolean synpred12_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred12_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
boolean success = !state.failed;
input.rewind(start);
state.backtracking--;
state.failed=false;
return success;
}
public final boolean synpred9_ActionSplitter() {
state.backtracking++;
int start = input.mark();
@ -2329,11 +2329,11 @@ public class ActionSplitter extends Lexer {
state.failed=false;
return success;
}
public final boolean synpred2_ActionSplitter() {
public final boolean synpred8_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred2_ActionSplitter_fragment(); // can never throw exception
synpred8_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
@ -2343,11 +2343,11 @@ public class ActionSplitter extends Lexer {
state.failed=false;
return success;
}
public final boolean synpred8_ActionSplitter() {
public final boolean synpred2_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred8_ActionSplitter_fragment(); // can never throw exception
synpred2_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
@ -2399,11 +2399,11 @@ public class ActionSplitter extends Lexer {
state.failed=false;
return success;
}
public final boolean synpred3_ActionSplitter() {
public final boolean synpred15_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred3_ActionSplitter_fragment(); // can never throw exception
synpred15_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
@ -2413,11 +2413,11 @@ public class ActionSplitter extends Lexer {
state.failed=false;
return success;
}
public final boolean synpred15_ActionSplitter() {
public final boolean synpred3_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred15_ActionSplitter_fragment(); // can never throw exception
synpred3_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
@ -2491,21 +2491,30 @@ public class ActionSplitter extends Lexer {
}
}
static final String DFA29_eotS =
"\31\uffff";
"\32\uffff";
static final String DFA29_eofS =
"\31\uffff";
"\32\uffff";
static final String DFA29_minS =
"\1\0\1\uffff\1\0\2\uffff\1\0\12\uffff\1\0\6\uffff\1\0\1\uffff";
"\2\0\6\uffff\1\0\2\uffff\1\0\2\uffff\1\0\13\uffff";
static final String DFA29_maxS =
"\1\uffff\1\uffff\1\0\2\uffff\1\0\12\uffff\1\0\6\uffff\1\0\1\uffff";
"\1\uffff\1\0\6\uffff\1\0\2\uffff\1\0\2\uffff\1\0\13\uffff";
static final String DFA29_acceptS =
"\1\uffff\1\24\1\uffff\1\1\1\2\1\uffff\1\4\1\5\1\6\1\7\1\10\1\11"+
"\1\12\1\13\1\14\1\15\1\uffff\1\16\1\17\1\20\1\21\1\22\1\23\1\uffff"+
"\1\3";
"\2\uffff\1\16\1\17\1\20\1\21\1\22\1\23\1\uffff\1\3\1\24\1\uffff"+
"\1\1\1\2\1\uffff\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1"+
"\24";
static final String DFA29_specialS =
"\1\0\1\uffff\1\1\2\uffff\1\2\12\uffff\1\3\6\uffff\1\4\1\uffff}>";
"\1\0\1\1\6\uffff\1\2\2\uffff\1\3\2\uffff\1\4\13\uffff}>";
static final String[] DFA29_transitionS = {
"\44\1\1\5\1\20\11\1\1\2\54\1\1\27\uffa3\1",
"\44\31\1\16\1\1\11\31\1\13\54\31\1\10\uffa3\31",
"\1\uffff",
"",
"",
"",
"",
"",
"",
"\1\uffff",
"",
"",
"\1\uffff",
"",
@ -2521,14 +2530,6 @@ public class ActionSplitter extends Lexer {
"",
"",
"",
"\1\uffff",
"",
"",
"",
"",
"",
"",
"\1\uffff",
""
};
@ -2572,102 +2573,102 @@ public class ActionSplitter extends Lexer {
int LA29_0 = input.LA(1);
s = -1;
if ( ((LA29_0>='\u0000' && LA29_0<='#')||(LA29_0>='&' && LA29_0<='.')||(LA29_0>='0' && LA29_0<='[')||(LA29_0>=']' && LA29_0<='\uFFFF')) ) {s = 1;}
if ( (LA29_0=='%') ) {s = 1;}
else if ( (LA29_0=='/') ) {s = 2;}
else if ( (LA29_0=='\\') ) {s = 8;}
else if ( (LA29_0=='$') ) {s = 5;}
else if ( (LA29_0=='/') ) {s = 11;}
else if ( (LA29_0=='%') ) {s = 16;}
else if ( (LA29_0=='$') ) {s = 14;}
else if ( (LA29_0=='\\') ) {s = 23;}
else if ( ((LA29_0>='\u0000' && LA29_0<='#')||(LA29_0>='&' && LA29_0<='.')||(LA29_0>='0' && LA29_0<='[')||(LA29_0>=']' && LA29_0<='\uFFFF')) ) {s = 25;}
if ( s>=0 ) return s;
break;
case 1 :
int LA29_2 = input.LA(1);
int LA29_1 = input.LA(1);
int index29_2 = input.index();
int index29_1 = input.index();
input.rewind();
s = -1;
if ( (synpred1_ActionSplitter()) ) {s = 3;}
if ( (synpred14_ActionSplitter()) ) {s = 2;}
else if ( (synpred2_ActionSplitter()) ) {s = 4;}
else if ( (synpred15_ActionSplitter()) ) {s = 3;}
else if ( (true) ) {s = 1;}
else if ( (synpred16_ActionSplitter()) ) {s = 4;}
else if ( (synpred17_ActionSplitter()) ) {s = 5;}
else if ( (synpred18_ActionSplitter()) ) {s = 6;}
else if ( (synpred19_ActionSplitter()) ) {s = 7;}
input.seek(index29_2);
input.seek(index29_1);
if ( s>=0 ) return s;
break;
case 2 :
int LA29_5 = input.LA(1);
int LA29_8 = input.LA(1);
int index29_5 = input.index();
int index29_8 = input.index();
input.rewind();
s = -1;
if ( (synpred4_ActionSplitter()) ) {s = 6;}
if ( (synpred3_ActionSplitter()) ) {s = 9;}
else if ( (synpred5_ActionSplitter()) ) {s = 7;}
else if ( (synpred6_ActionSplitter()) ) {s = 8;}
else if ( (synpred7_ActionSplitter()) ) {s = 9;}
else if ( (synpred8_ActionSplitter()) ) {s = 10;}
else if ( (synpred9_ActionSplitter()) ) {s = 11;}
else if ( (synpred10_ActionSplitter()) ) {s = 12;}
else if ( (synpred11_ActionSplitter()) ) {s = 13;}
else if ( (synpred12_ActionSplitter()) ) {s = 14;}
else if ( (synpred13_ActionSplitter()) ) {s = 15;}
else if ( (true) ) {s = 10;}
input.seek(index29_5);
input.seek(index29_8);
if ( s>=0 ) return s;
break;
case 3 :
int LA29_16 = input.LA(1);
int LA29_11 = input.LA(1);
int index29_16 = input.index();
int index29_11 = input.index();
input.rewind();
s = -1;
if ( (synpred14_ActionSplitter()) ) {s = 17;}
if ( (synpred1_ActionSplitter()) ) {s = 12;}
else if ( (synpred15_ActionSplitter()) ) {s = 18;}
else if ( (synpred2_ActionSplitter()) ) {s = 13;}
else if ( (synpred16_ActionSplitter()) ) {s = 19;}
else if ( (synpred17_ActionSplitter()) ) {s = 20;}
else if ( (synpred18_ActionSplitter()) ) {s = 21;}
else if ( (synpred19_ActionSplitter()) ) {s = 22;}
else if ( (true) ) {s = 10;}
input.seek(index29_16);
input.seek(index29_11);
if ( s>=0 ) return s;
break;
case 4 :
int LA29_23 = input.LA(1);
int LA29_14 = input.LA(1);
int index29_23 = input.index();
int index29_14 = input.index();
input.rewind();
s = -1;
if ( (synpred3_ActionSplitter()) ) {s = 24;}
if ( (synpred4_ActionSplitter()) ) {s = 15;}
else if ( (true) ) {s = 1;}
else if ( (synpred5_ActionSplitter()) ) {s = 16;}
else if ( (synpred6_ActionSplitter()) ) {s = 17;}
else if ( (synpred7_ActionSplitter()) ) {s = 18;}
else if ( (synpred8_ActionSplitter()) ) {s = 19;}
else if ( (synpred9_ActionSplitter()) ) {s = 20;}
else if ( (synpred10_ActionSplitter()) ) {s = 21;}
else if ( (synpred11_ActionSplitter()) ) {s = 22;}
else if ( (synpred12_ActionSplitter()) ) {s = 23;}
else if ( (synpred13_ActionSplitter()) ) {s = 24;}
input.seek(index29_23);
input.seek(index29_14);
if ( s>=0 ) return s;
break;
}

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} NFABuilder.g 2010-05-16 13:12:33
// $ANTLR ${project.version} ${buildNumber} NFABuilder.g 2010-05-19 15:07:26
/*
[The "BSD license"]

View File

@ -0,0 +1,53 @@
package org.antlr.v4.semantics;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.Token;
import org.antlr.v4.parse.ActionSplitter;
import org.antlr.v4.tool.*;
import java.util.List;
/** Find token and rule refs, side-effect: update Alternatives */
public class ActionSniffer extends BlankActionSplitterListener {
public Grammar g;
public Rule r; // null if action outside of rule
public Alternative alt; // null if action outside of alt; could be in rule
public ActionAST node;
public Token actionToken; // token within action
public ErrorManager errMgr;
public ActionSniffer(Grammar g, Rule r, Alternative alt, ActionAST node, Token actionToken) {
this.g = g;
this.r = r;
this.alt = alt;
this.node = node;
this.actionToken = actionToken;
this.errMgr = g.tool.errMgr;
}
public void examineAction() {
//System.out.println("examine "+actionToken);
ANTLRStringStream in = new ANTLRStringStream(actionToken.getText());
in.setLine(actionToken.getLine());
in.setCharPositionInLine(actionToken.getCharPositionInLine());
ActionSplitter splitter = new ActionSplitter(in, this);
// forces eval, triggers listener methods
node.chunks = splitter.getActionTokens();
System.out.println(node.chunks);
}
public void attr(String expr, Token x) {
List<TerminalAST> xRefs = alt.tokenRefs.get(x.getText());
if ( alt!=null && xRefs!=null ) {
alt.tokenRefsInActions.map(x.getText(), node);
}
List<GrammarAST> rRefs = alt.ruleRefs.get(x.getText());
if ( alt!=null && rRefs!=null ) {
alt.ruleRefsInActions.map(x.getText(), node);
}
}
public void qualifiedAttr(String expr, Token x, Token y) {
attr(expr, x);
}
}

View File

@ -8,7 +8,9 @@ import org.antlr.v4.tool.*;
import java.util.List;
/** Trigger checks for various kinds of attribute expressions. no side-effects */
/** Trigger checks for various kinds of attribute expressions.
* no side-effects.
*/
public class AttributeChecks implements ActionSplitterListener {
public Grammar g;
public Rule r; // null if action outside of rule
@ -89,7 +91,7 @@ public class AttributeChecks implements ActionSplitterListener {
g.fileName, y, y.getText(), rref.name, expr);
}
}
else if ( !resolvesToAttributeDict(x.getText()) ) {
else if ( !node.resolver.resolvesToAttributeDict(x.getText(), node) ) {
errMgr.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
g.fileName, x, x.getText(), expr);
}
@ -113,7 +115,7 @@ public class AttributeChecks implements ActionSplitterListener {
if ( node.resolver.resolveToDynamicScope(x.getText(), node)!=null ) {
return; // $S for scope S is ok
}
if ( resolvesToToken(x.getText()) ) {
if ( node.resolver.resolvesToToken(x.getText(), node) ) {
return; // $ID for token ref or label of token
}
if ( node.resolver.resolvesToListLabel(x.getText(), node) ) {
@ -215,37 +217,4 @@ public class AttributeChecks implements ActionSplitterListener {
return null;
}
public boolean resolvesToAttributeDict(String x) {
if ( resolvesToToken(x) ) return true;
if ( node.resolver instanceof Grammar ) return g.scopes.get(x)!=null;
if ( x.equals(r.name) ) return true; // $r for action in rule r, $r is a dict
Rule r = g.getRule(x);
if ( r!=null && r.scope!=null ) return true;
if ( g.scopes.get(x)!=null ) return true;
return false;
}
public boolean resolvesToToken(String x) {
if ( node.resolver instanceof Grammar ) return false;
if ( node.resolver instanceof Alternative &&
((Alternative)node.resolver).tokenRefs.get(x)!=null )
{
return true;
}
List<LabelElementPair> labels = null;
if ( node.resolver instanceof Rule ) {
labels = r.getLabelDefs().get(x);
}
else if ( node.resolver instanceof Alternative ) {
labels = ((Alternative)node.resolver).labelDefs.get(x);
}
if ( labels!=null ) { // it's a label ref. is it a token label?
LabelElementPair anyLabelDef = labels.get(0);
if ( anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
}
return false;
}
}

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} BasicSemanticTriggers.g 2010-05-06 12:54:52
// $ANTLR ${project.version} ${buildNumber} BasicSemanticTriggers.g 2010-05-19 15:07:28
/*
[The "BSD license"]

View File

@ -1,4 +1,4 @@
package org.antlr.v4.test;
package org.antlr.v4.semantics;
import org.antlr.runtime.Token;
import org.antlr.v4.parse.ActionSplitterListener;

View File

@ -25,7 +25,7 @@
*/
/** Collects rules, terminals, strings, actions, scopes etc... from AST
* Side-effects: None
* No side-effects
*/
tree grammar CollectSymbols;
options {
@ -167,7 +167,10 @@ rule
setAlt
: {inContext("RULE BLOCK")}? ( ALT | ALT_REWRITE )
{currentAlt = $start.getChildIndex()+1;}
{
currentAlt = $start.getChildIndex()+1;
currentRule.alt[currentAlt].ast = (AltAST)$start;
}
;
finishRule
@ -264,7 +267,7 @@ terminal
terminals.add($start);
strings.add($STRING_LITERAL.text);
if ( currentRule!=null ) {
currentRule.alt[currentAlt].tokenRefs.map($STRING_LITERAL.text, $STRING_LITERAL);
currentRule.alt[currentAlt].tokenRefs.map($STRING_LITERAL.text, (TerminalAST)$STRING_LITERAL);
}
}
| TOKEN_REF
@ -272,7 +275,7 @@ terminal
terminals.add($TOKEN_REF);
tokenIDRefs.add($TOKEN_REF);
if ( currentRule!=null ) {
currentRule.alt[currentAlt].tokenRefs.map($TOKEN_REF.text, $TOKEN_REF);
currentRule.alt[currentAlt].tokenRefs.map($TOKEN_REF.text, (TerminalAST)$TOKEN_REF);
}
}
;

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} CollectSymbols.g 2010-05-18 17:55:53
// $ANTLR ${project.version} ${buildNumber} CollectSymbols.g 2010-05-19 15:10:21
/*
[The "BSD license"]
@ -38,7 +38,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
/** Collects rules, terminals, strings, actions, scopes etc... from AST
* Side-effects: None
* No side-effects
*/
public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final String[] tokenNames = new String[] {
@ -914,7 +914,10 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
if ( state.backtracking==1 ) {
currentAlt = ((GrammarAST)retval.start).getChildIndex()+1;
currentAlt = ((GrammarAST)retval.start).getChildIndex()+1;
currentRule.alt[currentAlt].ast = (AltAST)((GrammarAST)retval.start);
}
}
@ -932,11 +935,11 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "finishRule"
// CollectSymbols.g:173:1: finishRule : RULE ;
// CollectSymbols.g:176:1: finishRule : RULE ;
public final void finishRule() throws RecognitionException {
try {
// CollectSymbols.g:174:2: ( RULE )
// CollectSymbols.g:174:4: RULE
// CollectSymbols.g:177:2: ( RULE )
// CollectSymbols.g:177:4: RULE
{
match(input,RULE,FOLLOW_RULE_in_finishRule527); if (state.failed) return ;
if ( state.backtracking==1 ) {
@ -958,14 +961,14 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleNamedAction"
// CollectSymbols.g:177:1: ruleNamedAction : {...}? ^( AT ID ACTION ) ;
// CollectSymbols.g:180:1: ruleNamedAction : {...}? ^( AT ID ACTION ) ;
public final void ruleNamedAction() throws RecognitionException {
GrammarAST ID9=null;
GrammarAST ACTION10=null;
try {
// CollectSymbols.g:178:2: ({...}? ^( AT ID ACTION ) )
// CollectSymbols.g:178:4: {...}? ^( AT ID ACTION )
// CollectSymbols.g:181:2: ({...}? ^( AT ID ACTION ) )
// CollectSymbols.g:181:4: {...}? ^( AT ID ACTION )
{
if ( !((inContext("RULE"))) ) {
if (state.backtracking>0) {state.failed=true; return ;}
@ -1000,13 +1003,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleAction"
// CollectSymbols.g:185:1: ruleAction : {...}? ACTION ;
// CollectSymbols.g:188:1: ruleAction : {...}? ACTION ;
public final void ruleAction() throws RecognitionException {
GrammarAST ACTION11=null;
try {
// CollectSymbols.g:186:2: ({...}? ACTION )
// CollectSymbols.g:186:4: {...}? ACTION
// CollectSymbols.g:189:2: ({...}? ACTION )
// CollectSymbols.g:189:4: {...}? ACTION
{
if ( !((inContext("RULE ...")&&!inContext("SCOPE")&&
!inContext("CATCH")&&!inContext("FINALLY")&&!inContext("AT"))) ) {
@ -1036,13 +1039,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "exceptionHandler"
// CollectSymbols.g:195:1: exceptionHandler : ^( CATCH ARG_ACTION ACTION ) ;
// CollectSymbols.g:198:1: exceptionHandler : ^( CATCH ARG_ACTION ACTION ) ;
public final void exceptionHandler() throws RecognitionException {
GrammarAST ACTION12=null;
try {
// CollectSymbols.g:196:2: ( ^( CATCH ARG_ACTION ACTION ) )
// CollectSymbols.g:196:4: ^( CATCH ARG_ACTION ACTION )
// CollectSymbols.g:199:2: ( ^( CATCH ARG_ACTION ACTION ) )
// CollectSymbols.g:199:4: ^( CATCH ARG_ACTION ACTION )
{
match(input,CATCH,FOLLOW_CATCH_in_exceptionHandler583); if (state.failed) return ;
@ -1073,13 +1076,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "finallyClause"
// CollectSymbols.g:203:1: finallyClause : ^( FINALLY ACTION ) ;
// CollectSymbols.g:206:1: finallyClause : ^( FINALLY ACTION ) ;
public final void finallyClause() throws RecognitionException {
GrammarAST ACTION13=null;
try {
// CollectSymbols.g:204:2: ( ^( FINALLY ACTION ) )
// CollectSymbols.g:204:4: ^( FINALLY ACTION )
// CollectSymbols.g:207:2: ( ^( FINALLY ACTION ) )
// CollectSymbols.g:207:4: ^( FINALLY ACTION )
{
match(input,FINALLY,FOLLOW_FINALLY_in_finallyClause604); if (state.failed) return ;
@ -1109,13 +1112,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleArg"
// CollectSymbols.g:211:1: ruleArg : {...}? ARG_ACTION ;
// CollectSymbols.g:214:1: ruleArg : {...}? ARG_ACTION ;
public final void ruleArg() throws RecognitionException {
GrammarAST ARG_ACTION14=null;
try {
// CollectSymbols.g:212:2: ({...}? ARG_ACTION )
// CollectSymbols.g:212:4: {...}? ARG_ACTION
// CollectSymbols.g:215:2: ({...}? ARG_ACTION )
// CollectSymbols.g:215:4: {...}? ARG_ACTION
{
if ( !((inContext("RULE"))) ) {
if (state.backtracking>0) {state.failed=true; return ;}
@ -1145,13 +1148,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleReturns"
// CollectSymbols.g:220:1: ruleReturns : ^( RETURNS ARG_ACTION ) ;
// CollectSymbols.g:223:1: ruleReturns : ^( RETURNS ARG_ACTION ) ;
public final void ruleReturns() throws RecognitionException {
GrammarAST ARG_ACTION15=null;
try {
// CollectSymbols.g:221:2: ( ^( RETURNS ARG_ACTION ) )
// CollectSymbols.g:221:4: ^( RETURNS ARG_ACTION )
// CollectSymbols.g:224:2: ( ^( RETURNS ARG_ACTION ) )
// CollectSymbols.g:224:4: ^( RETURNS ARG_ACTION )
{
match(input,RETURNS,FOLLOW_RETURNS_in_ruleReturns643); if (state.failed) return ;
@ -1182,21 +1185,21 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleScopeSpec"
// CollectSymbols.g:229:1: ruleScopeSpec : {...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) ) ;
// CollectSymbols.g:232:1: ruleScopeSpec : {...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) ) ;
public final void ruleScopeSpec() throws RecognitionException {
GrammarAST ACTION16=null;
GrammarAST ids=null;
List list_ids=null;
try {
// CollectSymbols.g:230:2: ({...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) ) )
// CollectSymbols.g:230:4: {...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) )
// CollectSymbols.g:233:2: ({...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) ) )
// CollectSymbols.g:233:4: {...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) )
{
if ( !((inContext("RULE"))) ) {
if (state.backtracking>0) {state.failed=true; return ;}
throw new FailedPredicateException(input, "ruleScopeSpec", "inContext(\"RULE\")");
}
// CollectSymbols.g:231:3: ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) )
// CollectSymbols.g:234:3: ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) )
int alt12=2;
int LA12_0 = input.LA(1);
@ -1237,7 +1240,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt12) {
case 1 :
// CollectSymbols.g:231:5: ^( SCOPE ACTION )
// CollectSymbols.g:234:5: ^( SCOPE ACTION )
{
match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec668); if (state.failed) return ;
@ -1257,12 +1260,12 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 2 :
// CollectSymbols.g:238:5: ^( SCOPE (ids+= ID )+ )
// CollectSymbols.g:241:5: ^( SCOPE (ids+= ID )+ )
{
match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec683); if (state.failed) return ;
match(input, Token.DOWN, null); if (state.failed) return ;
// CollectSymbols.g:238:16: (ids+= ID )+
// CollectSymbols.g:241:16: (ids+= ID )+
int cnt11=0;
loop11:
do {
@ -1276,7 +1279,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
switch (alt11) {
case 1 :
// CollectSymbols.g:238:16: ids+= ID
// CollectSymbols.g:241:16: ids+= ID
{
ids=(GrammarAST)match(input,ID,FOLLOW_ID_in_ruleScopeSpec687); if (state.failed) return ;
if (list_ids==null) list_ids=new ArrayList();
@ -1325,14 +1328,14 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
};
// $ANTLR start "rewriteElement"
// CollectSymbols.g:242:1: rewriteElement : {...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL ) ;
// CollectSymbols.g:245:1: rewriteElement : {...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL ) ;
public final CollectSymbols.rewriteElement_return rewriteElement() throws RecognitionException {
CollectSymbols.rewriteElement_return retval = new CollectSymbols.rewriteElement_return();
retval.start = input.LT(1);
try {
// CollectSymbols.g:244:2: ({...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL ) )
// CollectSymbols.g:245:6: {...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL )
// CollectSymbols.g:247:2: ({...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL ) )
// CollectSymbols.g:248:6: {...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL )
{
if ( !((inContext("RESULT ..."))) ) {
if (state.backtracking>0) {state.failed=true; return retval;}
@ -1369,7 +1372,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
};
// $ANTLR start "labeledElement"
// CollectSymbols.g:249:1: labeledElement : {...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) ) ;
// CollectSymbols.g:252:1: labeledElement : {...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) ) ;
public final CollectSymbols.labeledElement_return labeledElement() throws RecognitionException {
CollectSymbols.labeledElement_return retval = new CollectSymbols.labeledElement_return();
retval.start = input.LT(1);
@ -1378,14 +1381,14 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
GrammarAST e=null;
try {
// CollectSymbols.g:255:2: ({...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) ) )
// CollectSymbols.g:255:4: {...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) )
// CollectSymbols.g:258:2: ({...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) ) )
// CollectSymbols.g:258:4: {...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) )
{
if ( !((inContext("RULE ..."))) ) {
if (state.backtracking>0) {state.failed=true; return retval;}
throw new FailedPredicateException(input, "labeledElement", "inContext(\"RULE ...\")");
}
// CollectSymbols.g:256:3: ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) )
// CollectSymbols.g:259:3: ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) )
int alt13=2;
int LA13_0 = input.LA(1);
@ -1404,7 +1407,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt13) {
case 1 :
// CollectSymbols.g:256:5: ^( ASSIGN id= ID e= . )
// CollectSymbols.g:259:5: ^( ASSIGN id= ID e= . )
{
match(input,ASSIGN,FOLLOW_ASSIGN_in_labeledElement751); if (state.failed) return retval;
@ -1418,7 +1421,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 2 :
// CollectSymbols.g:257:5: ^( PLUS_ASSIGN id= ID e= . )
// CollectSymbols.g:260:5: ^( PLUS_ASSIGN id= ID e= . )
{
match(input,PLUS_ASSIGN,FOLLOW_PLUS_ASSIGN_in_labeledElement767); if (state.failed) return retval;
@ -1459,7 +1462,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
};
// $ANTLR start "terminal"
// CollectSymbols.g:261:1: terminal : ({...}? STRING_LITERAL | TOKEN_REF );
// CollectSymbols.g:264:1: terminal : ({...}? STRING_LITERAL | TOKEN_REF );
public final CollectSymbols.terminal_return terminal() throws RecognitionException {
CollectSymbols.terminal_return retval = new CollectSymbols.terminal_return();
retval.start = input.LT(1);
@ -1468,7 +1471,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
GrammarAST TOKEN_REF18=null;
try {
// CollectSymbols.g:262:5: ({...}? STRING_LITERAL | TOKEN_REF )
// CollectSymbols.g:265:5: ({...}? STRING_LITERAL | TOKEN_REF )
int alt14=2;
int LA14_0 = input.LA(1);
@ -1487,7 +1490,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt14) {
case 1 :
// CollectSymbols.g:262:7: {...}? STRING_LITERAL
// CollectSymbols.g:265:7: {...}? STRING_LITERAL
{
if ( !((!inContext("TOKENS ASSIGN"))) ) {
if (state.backtracking>0) {state.failed=true; return retval;}
@ -1499,7 +1502,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
terminals.add(((GrammarAST)retval.start));
strings.add((STRING_LITERAL17!=null?STRING_LITERAL17.getText():null));
if ( currentRule!=null ) {
currentRule.alt[currentAlt].tokenRefs.map((STRING_LITERAL17!=null?STRING_LITERAL17.getText():null), STRING_LITERAL17);
currentRule.alt[currentAlt].tokenRefs.map((STRING_LITERAL17!=null?STRING_LITERAL17.getText():null), (TerminalAST)STRING_LITERAL17);
}
}
@ -1507,7 +1510,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 2 :
// CollectSymbols.g:270:7: TOKEN_REF
// CollectSymbols.g:273:7: TOKEN_REF
{
TOKEN_REF18=(GrammarAST)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal812); if (state.failed) return retval;
if ( state.backtracking==1 ) {
@ -1515,7 +1518,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
terminals.add(TOKEN_REF18);
tokenIDRefs.add(TOKEN_REF18);
if ( currentRule!=null ) {
currentRule.alt[currentAlt].tokenRefs.map((TOKEN_REF18!=null?TOKEN_REF18.getText():null), TOKEN_REF18);
currentRule.alt[currentAlt].tokenRefs.map((TOKEN_REF18!=null?TOKEN_REF18.getText():null), (TerminalAST)TOKEN_REF18);
}
}
@ -1537,15 +1540,15 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
// $ANTLR start "ruleref"
// CollectSymbols.g:280:1: ruleref : ({...}?r= RULE_REF | r= RULE_REF ) ;
// CollectSymbols.g:283:1: ruleref : ({...}?r= RULE_REF | r= RULE_REF ) ;
public final void ruleref() throws RecognitionException {
GrammarAST r=null;
try {
// CollectSymbols.g:282:5: ( ({...}?r= RULE_REF | r= RULE_REF ) )
// CollectSymbols.g:282:7: ({...}?r= RULE_REF | r= RULE_REF )
// CollectSymbols.g:285:5: ( ({...}?r= RULE_REF | r= RULE_REF ) )
// CollectSymbols.g:285:7: ({...}?r= RULE_REF | r= RULE_REF )
{
// CollectSymbols.g:282:7: ({...}?r= RULE_REF | r= RULE_REF )
// CollectSymbols.g:285:7: ({...}?r= RULE_REF | r= RULE_REF )
int alt15=2;
int LA15_0 = input.LA(1);
@ -1575,7 +1578,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
switch (alt15) {
case 1 :
// CollectSymbols.g:282:9: {...}?r= RULE_REF
// CollectSymbols.g:285:9: {...}?r= RULE_REF
{
if ( !((inContext("DOT ..."))) ) {
if (state.backtracking>0) {state.failed=true; return ;}
@ -1589,7 +1592,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
}
break;
case 2 :
// CollectSymbols.g:284:8: r= RULE_REF
// CollectSymbols.g:287:8: r= RULE_REF
{
r=(GrammarAST)match(input,RULE_REF,FOLLOW_RULE_REF_in_ruleref862); if (state.failed) return ;

View File

@ -74,6 +74,13 @@ public class SemanticPipeline {
for (AttributeDict s : collector.scopes) g.defineScope(s);
for (GrammarAST a : collector.actions) g.defineAction(a);
// LINK ALT NODES WITH Alternatives
for (Rule r : g.rules.values()) {
for (int i=1; i<=r.numberOfAlts; i++) {
r.alt[i].ast.alt = r.alt[i];
}
}
// CHECK RULE REFS NOW (that we've defined rules in grammar)
symcheck.checkRuleArgs(g, collector.rulerefs);
identifyStartRules(collector);
@ -101,6 +108,7 @@ public class SemanticPipeline {
UseDefAnalyzer usedef = new UseDefAnalyzer();
usedef.checkRewriteElementsPresentOnLeftSide(g, collector.rules);
usedef.trackTokenRuleRefsInActions(g);
}
void identifyStartRules(CollectSymbols collector) {

View File

@ -23,5 +23,19 @@ public class UseDefAnalyzer {
}
}
}
}
}
// side-effect: updates Alternative with refs in actions
public void trackTokenRuleRefsInActions(Grammar g) {
for (Rule r : g.rules.values()) {
for (int i=1; i<=r.numberOfAlts; i++) {
Alternative alt = r.alt[i];
for (ActionAST a : alt.actions) {
ActionSniffer sniffer = new ActionSniffer(g, r, alt, a, a.token);
sniffer.examineAction();
}
}
}
}
}

View File

@ -8,6 +8,8 @@ public class ActionAST extends GrammarAST {
// Alt, rule, grammar space
public AttributeResolver resolver;
public List<Token> chunks; // useful for ANTLR IDE developers
/** In which alt does this node live? */
// public Alternative alt;
public ActionAST(Token t) { super(t); }
public ActionAST(int type) { super(type); }

View File

@ -0,0 +1,12 @@
package org.antlr.v4.tool;
import org.antlr.runtime.Token;
/** An ALT or ALT_REWRITE node (left of ->) */
public class AltAST extends GrammarAST {
public Alternative alt;
public AltAST(Token t) { super(t); }
public AltAST(int type) { super(type); }
public AltAST(int type, Token t) { super(type, t); }
}

View File

@ -12,12 +12,20 @@ import java.util.List;
public class Alternative implements AttributeResolver {
Rule rule;
public AltAST ast;
// token IDs, string literals in this alt
public MultiMap<String, GrammarAST> tokenRefs = new MultiMap<String, GrammarAST>();
public MultiMap<String, TerminalAST> tokenRefs = new MultiMap<String, TerminalAST>();
// does not include labels
public MultiMap<String, GrammarAST> tokenRefsInActions = new MultiMap<String, GrammarAST>();
// all rule refs in this alt
public MultiMap<String, GrammarAST> ruleRefs = new MultiMap<String, GrammarAST>();
// does not include labels
public MultiMap<String, GrammarAST> ruleRefsInActions = new MultiMap<String, GrammarAST>();
/** A list of all LabelElementPair attached to tokens like id=ID, ids+=ID */
public MultiMap<String, LabelElementPair> labelDefs = new MultiMap<String, LabelElementPair>();
@ -33,15 +41,36 @@ public class Alternative implements AttributeResolver {
public Alternative(Rule r) { this.rule = r; }
public boolean resolvesToToken(String x, ActionAST node) {
if ( tokenRefs.get(x)!=null ) return true;
LabelElementPair anyLabelDef = getAnyLabelDef(x);
if ( anyLabelDef!=null && anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
return false;
}
// public String getTokenLabel(String x, ActionAST node) {
// LabelElementPair anyLabelDef = getAnyLabelDef(x);
// if ( anyLabelDef!=null ) return anyLabelDef.label.getText();
// if ( tokenRefs.get(x)!=null ) {
//
// }
// LabelElementPair anyLabelDef = getAnyLabelDef(x);
// if ( anyLabelDef!=null && anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
// return false;
// }
public boolean resolvesToAttributeDict(String x, ActionAST node) {
if ( resolvesToToken(x, node) ) return true;
if ( x.equals(rule.name) ) return true; // $r for action in rule r, $r is a dict
if ( rule!=null && rule.scope!=null ) return true;
if ( rule.g.scopes.get(x)!=null ) return true;
return false;
}
/** $x Attribute: rule arguments, return values, predefined rule prop.
*/
public Attribute resolveToAttribute(String x, ActionAST node) {
return rule.resolveToAttribute(x, node); // reuse that code
// if ( rule.args==null ) return null;
// Attribute a = rule.args.get(x); if ( a!=null ) return a;
// a = rule.retvals.get(x); if ( a!=null ) return a;
// AttributeDict properties = rule.getPredefinedScope(LabelType.RULE_LABEL);
// return properties.get(x);
}
/** $x.y, x can be surrounding rule, token/rule/label ref. y is visible
@ -75,6 +104,13 @@ public class Alternative implements AttributeResolver {
return rule.resolveToDynamicScope(x, node);
}
public boolean resolvesToLabel(String x, ActionAST node) {
LabelElementPair anyLabelDef = getAnyLabelDef(x);
return anyLabelDef!=null &&
(anyLabelDef.type==LabelType.TOKEN_LABEL ||
anyLabelDef.type==LabelType.RULE_LABEL);
}
public boolean resolvesToListLabel(String x, ActionAST node) {
LabelElementPair anyLabelDef = getAnyLabelDef(x);
return anyLabelDef!=null &&

View File

@ -31,6 +31,9 @@ package org.antlr.v4.tool;
*/
public interface AttributeResolver {
public boolean resolvesToListLabel(String x, ActionAST node);
public boolean resolvesToLabel(String x, ActionAST node);
public boolean resolvesToAttributeDict(String x, ActionAST node);
public boolean resolvesToToken(String x, ActionAST node);
public Attribute resolveToAttribute(String x, ActionAST node);
public Attribute resolveToAttribute(String x, String y, ActionAST node);
public AttributeDict resolveToDynamicScope(String x, ActionAST node);

View File

@ -121,7 +121,7 @@ public class Grammar implements AttributeResolver {
this("<string>", grammarText, listener);
}
/** For testing */
/** For testing; only builds trees; no sem anal */
public Grammar(String fileName, String grammarText, ANTLRToolListener listener)
throws RecognitionException
{
@ -496,9 +496,17 @@ public class Grammar implements AttributeResolver {
return scopes.get(x);
}
public boolean resolvesToLabel(String x, ActionAST node) { return false; }
public boolean resolvesToListLabel(String x, ActionAST node) { return false; }
/** Given a grammar type, what should be the default action scope?
public boolean resolvesToToken(String x, ActionAST node) { return false; }
public boolean resolvesToAttributeDict(String x, ActionAST node) {
return scopes.get(x)!=null;
}
/** Given a grammar type, what should be the default action scope?
* If I say @members in a COMBINED grammar, for example, the
* default scope should be "parser".
*/

View File

@ -50,6 +50,14 @@ public class GrammarAST extends CommonTree {
return nodes;
}
public AltAST getOutermostAltNode() {
if ( this instanceof AltAST && parent.parent instanceof RuleAST ) {
return (AltAST)this;
}
if ( parent!=null ) return ((GrammarAST)parent).getOutermostAltNode();
return null;
}
// @Override
// public boolean equals(Object obj) {
// return super.equals(obj);

View File

@ -118,7 +118,7 @@ public class Rule implements AttributeResolver {
public Attribute resolveRetvalOrProperty(String y) {
if ( retvals!=null ) {
Attribute a = retvals.get(y);
if ( a!=null ) return retvals.get(y);
if ( a!=null ) return a;
}
AttributeDict d = getPredefinedScope(LabelType.RULE_LABEL);
return d.get(y);
@ -163,8 +163,14 @@ public class Rule implements AttributeResolver {
return defs;
}
/** $x Attribute: rule arguments, return values, predefined rule prop,
* or a token/rule list label.
public AttributeDict getUniqueDictFor(String x, ActionAST node) {
if ( name.equals(x) ) { // x is this rule?
return getPredefinedScope(LabelType.RULE_LABEL);
}
return null;
}
/** $x Attribute: rule arguments, return values, predefined rule prop.
*/
public Attribute resolveToAttribute(String x, ActionAST node) {
if ( args!=null ) {
@ -202,6 +208,10 @@ public class Rule implements AttributeResolver {
return g.scopes.get(x);
}
public boolean resolvesToLabel(String x, ActionAST node) {
return false;
}
public boolean resolvesToListLabel(String x, ActionAST node) {
LabelElementPair anyLabelDef = getAnyLabelDef(x);
return anyLabelDef!=null &&
@ -209,6 +219,20 @@ public class Rule implements AttributeResolver {
anyLabelDef.type==LabelType.TOKEN_LIST_LABEL);
}
public boolean resolvesToToken(String x, ActionAST node) {
LabelElementPair anyLabelDef = getAnyLabelDef(x);
if ( anyLabelDef.type==LabelType.TOKEN_LABEL ) return true;
return false;
}
public boolean resolvesToAttributeDict(String x, ActionAST node) {
if ( resolvesToToken(x, node) ) return true;
if ( x.equals(name) ) return true; // $r for action in rule r, $r is a dict
if ( scope!=null ) return true;
if ( g.scopes.get(x)!=null ) return true;
return false;
}
public Rule resolveToRule(String x) {
if ( x.equals(this.name) ) return this;
LabelElementPair anyLabelDef = getAnyLabelDef(x);

View File

@ -37,6 +37,7 @@ import org.antlr.v4.analysis.DFAMinimizer;
import org.antlr.v4.analysis.LexerNFAToDFAConverter;
import org.antlr.v4.analysis.PredictionDFAFactory;
import org.antlr.v4.automata.*;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.semantics.SemanticPipeline;
import org.antlr.v4.tool.*;
import org.junit.After;
@ -545,10 +546,29 @@ public abstract class BaseTest {
msg = msg.replaceAll("\n","\\\\n");
msg = msg.replaceAll("\r","\\\\r");
msg = msg.replaceAll("\t","\\\\t");
// ignore error number
expect = stripErrorNum(expect);
actual = stripErrorNum(actual);
assertEquals("error in: "+msg,expect,actual);
}
}
// can be multi-line
//error(29): A.g:2:11: unknown attribute reference a in $a
//error(29): A.g:2:11: unknown attribute reference a in $a
String stripErrorNum(String errs) {
String[] lines = errs.split("\n");
for (int i=0; i<lines.length; i++) {
String s = lines[i];
int lp = s.indexOf('(');
int rp = s.indexOf(')', lp);
if ( lp<0 || rp<0 ) return s;
lines[i] = s.substring(0, lp) + s.substring(rp+1, s.length());
}
return Utils.join(lines, "\n");
}
public String getFilenameFromFirstLineOfGrammar(String line) {
String fileName = "<string>";
int grIndex = line.lastIndexOf("grammar");

View File

@ -3,6 +3,7 @@ package org.antlr.v4.test;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.Token;
import org.antlr.v4.parse.ActionSplitter;
import org.antlr.v4.semantics.BlankActionSplitterListener;
import org.junit.Test;
import java.util.ArrayList;

View File

@ -233,6 +233,15 @@ public class TestAttributeChecks extends BaseTest {
testActions("finally", dynFinallyChecks, scopeTemplate);
}
@Test public void testTokenRef() throws RecognitionException {
String grammar =
"parser grammar S;\n" +
"a : x=ID {Token t = $x; t = $ID;} ;\n";
String expected =
"";
testErrors(new String[] {grammar, expected}, false);
}
public void testActions(String location, String[] pairs, String template) {
for (int i = 0; i < pairs.length; i+=2) {
String action = pairs[i];