got 61/81 rewrite ast tests working

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8846]
This commit is contained in:
parrt 2011-07-08 17:50:25 -08:00
parent 671a7f9038
commit 557e3a8389
40 changed files with 578 additions and 134 deletions

View File

@ -2,7 +2,9 @@ grammar T;
options {output=AST;}
tokens {I;}
a : x=A -> $a ;
a : x+=b x+=b -> {new CommonTree()} ;
atom : A ;
b : B | C ;

View File

@ -27,6 +27,7 @@ import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.*;
import org.antlr.v4.runtime.tree.*;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
@ -328,13 +329,13 @@ SetDynScopeAttr_negIndex(s, indexChunks, rhsChunks) ::=
SetDynScopeAttr_index(s, indexChunks, rhsChunks) ::=
"<s.scope>.get(<indexChunks>).<s.attr> =<rhsChunks>;"
AddToLabelList(a) ::= "_localctx.<a.listName>.add(<labelref(first(a.opWithResultToAdd.labels))>);"
AddToLabelList(a) ::= "_localctx.<a.listName>.add(<labelref(a.label)>);"
TokenDecl(t) ::= "Token <t.name>;"
TokenTypeDecl(t) ::= "int <t.name>;"
TokenListDecl(t) ::= "List\<Token> <t.name> = new ArrayList\<Token>();"
RuleContextDecl(r) ::= "<r.ctxName> <r.name>;"
RuleContextListDecl(rdecl) ::= "List\<<rdecl.decl.ctxName>> <rdecl.name> = new ArrayList\<<rdecl.decl.ctxName>>();"
RuleContextListDecl(rdecl) ::= "List\<<rdecl.ctxName>> <rdecl.name> = new ArrayList\<<rdecl.ctxName>>();"
/** Default RuleContext type name for a Parser rule */
ParserRuleContext() ::= "ParserRuleContext"
@ -378,6 +379,7 @@ _adaptor.setTokenBoundaries(_localctx.tree, _localctx.start, _localctx.stop);
ElementListDecl(d) ::= "List\<Object> <d.name> = _adaptor.createElementList();"
ElementListName(elemName) ::= "_track_<elemName>"
ClearElementList(c) ::= "<c.name>.clear();"
TrackRuleElement(e) ::= "<e.name>.add(<labelref(e.label)>.tree);"
TrackTokenElement(e) ::= "<e.name>.add(_adaptor.create(<labelref(e.label)>));"
@ -450,6 +452,22 @@ RewriteRuleRef(r) ::= "_adaptor.addChild(<r.rootName>, <r.iterName>.next());"
RewriteRuleRefIsRoot(r) ::=
"<r.rootName> = _adaptor.becomeRoot(<r.iterName>.next(), <r.rootName>);"
RewriteLabelRef(t) ::= "<RewriteAddChild(t.rootName, {<t.iterName>.next()})>"
RewriteLabelRefIsRoot(t) ::= "<RewriteBecomeRoot({<t.iterName>.next()}, t.rootName)>"
// -> $e in rule e
RewriteSelfRuleLabelRef(s) ::= "<RewriteAddChild(s.rootName, {_localctx.tree})>"
RewriteSelfRuleLabelRefIsRoot(s) ::= "<RewriteBecomeRoot({_localctx.tree}, s.rootName)>"
RewriteAction(a, chunks) ::= "<RewriteAddChild(a.rootName, chunks)>"
RewriteActionIsRoot(a, chunks) ::= "<RewriteBecomeRoot(chunks, a.rootName)>"
// how to add child, make root
RewriteAddChild(rootName, child) ::= "_adaptor.addChild(<rootName>, <child>);"
RewriteBecomeRoot(newRoot, rootName) ::=
"<rootName> = _adaptor.becomeRoot(<newRoot>, <rootName>);"
/*
BitSetDecl(b) ::= <<
public static final LABitSet <b.name>=new LABitSet(new long[]{<b.hexWords:{it|<it>L};separator=",">}<if(b.fset.EOF)>, true<endif>);

View File

@ -95,6 +95,10 @@ public abstract class BlankOutputModelFactory implements OutputModelFactory {
return rewrite_tokenRef(ID, isRoot, null);
}
public List<SrcOp> rewrite_labelRef(GrammarAST ID, boolean isRoot) { return null; }
public List<SrcOp> rewrite_action(ActionAST action, boolean isRoot) { return null; }
// BLOCKS
public Choice getChoiceBlock(BlockAST blkAST, List<CodeBlockForAlt> alts) { return null; }

View File

@ -103,6 +103,10 @@ public class CodeGeneratorExtension {
public List<SrcOp> rewrite_stringRef(List<SrcOp> ops) { return ops; }
public List<SrcOp> rewrite_labelRef(List<SrcOp> ops) { return ops; }
public List<SrcOp> rewrite_action(List<SrcOp> ops) { return ops; }
// BLOCKS
public List<SrcOp> getChoiceBlock(List<SrcOp> ops) { return ops; }

View File

@ -51,6 +51,7 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory
public Stack<RuleFunction> currentRule = new Stack<RuleFunction>();
public Alternative currentAlt;
public CodeBlock currentBlock;
public CodeBlock currentAlternativeBlock;
protected DefaultOutputModelFactory(CodeGenerator gen) {
this.gen = gen;
@ -93,6 +94,14 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory
return currentBlock;
}
public void setCurrentAlternativeBlock(CodeBlock currentAlternativeBlock) {
this.currentAlternativeBlock = currentAlternativeBlock;
}
public CodeBlock getCurrentAlternativeBlock() {
return currentAlternativeBlock;
}
public int getCodeBlockLevel() { return controller.walker.codeBlockLevel; }
public int getTreeLevel() { return controller.walker.treeLevel; }

View File

@ -323,6 +323,18 @@ public class OutputModelController {
return rewrite_tokenRef(ID, isRoot, null);
}
public List<SrcOp> rewrite_labelRef(GrammarAST ID, boolean isRoot) {
List<SrcOp> ops = delegate.rewrite_labelRef(ID, isRoot);
for (CodeGeneratorExtension ext : extensions) ops = ext.rewrite_labelRef(ops);
return ops;
}
public List<SrcOp> rewrite_action(ActionAST action, boolean isRoot) {
List<SrcOp> ops = delegate.rewrite_action(action, isRoot);
for (CodeGeneratorExtension ext : extensions) ops = ext.rewrite_action(ops);
return ops;
}
public OutputModelObject getRoot() { return delegate.getRoot(); }
public void setRoot(OutputModelObject root) { delegate.setRoot(root); }
@ -343,6 +355,12 @@ public class OutputModelController {
public CodeBlock getCurrentBlock() { return delegate.getCurrentBlock(); }
public void setCurrentAlternativeBlock(CodeBlock currentAlternativeBlock) {
delegate.setCurrentAlternativeBlock(currentAlternativeBlock);
}
public CodeBlock getCurrentAlternativeBlock() { return delegate.getCurrentAlternativeBlock(); }
public int getCodeBlockLevel() { return delegate.getCodeBlockLevel(); }
public int getTreeLevel() { return delegate.getTreeLevel(); }

View File

@ -112,6 +112,10 @@ public interface OutputModelFactory {
List<SrcOp> rewrite_stringRef(GrammarAST ID, boolean isRoot);
List<SrcOp> rewrite_labelRef(GrammarAST ID, boolean isRoot);
List<SrcOp> rewrite_action(ActionAST action, boolean isRoot);
// CONTEXT MANIPULATION
// TODO: move to controller?
@ -136,6 +140,10 @@ public interface OutputModelFactory {
CodeBlock getCurrentBlock();
void setCurrentAlternativeBlock(CodeBlock currentAlternativeBlock);
CodeBlock getCurrentAlternativeBlock();
int getCodeBlockLevel();
int getTreeLevel();

View File

@ -33,6 +33,7 @@ import org.antlr.v4.codegen.model.*;
import org.antlr.v4.codegen.model.ast.*;
import org.antlr.v4.codegen.model.decl.*;
import org.antlr.v4.misc.Utils;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.tool.*;
import java.util.List;
@ -70,7 +71,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
}
else {
InvokeRule invokeOp = (InvokeRule)Utils.find(ops, InvokeRule.class);
SrcOp treeOp = new RuleBecomeRoot(factory, invokeOp.ast, invokeOp);
SrcOp treeOp = new RuleBecomeRoot(factory, invokeOp.ast, invokeOp.getLabels().get(0));
return DefaultOutputModelFactory.list(ops, treeOp);
}
}
@ -83,7 +84,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
}
else {
MatchToken matchOp = (MatchToken)Utils.find(ops, MatchToken.class);
SrcOp treeOp = new TokenBecomeRoot(factory, matchOp.ast, matchOp);
SrcOp treeOp = new TokenBecomeRoot(factory, matchOp.ast, matchOp.getLabels().get(0));
return DefaultOutputModelFactory.list(ops, treeOp);
}
}
@ -92,32 +93,79 @@ public class ParserASTExtension extends CodeGeneratorExtension {
public List<SrcOp> leafRule(List<SrcOp> ops) {
InvokeRule invokeOp = (InvokeRule)Utils.find(ops, InvokeRule.class);
Alternative alt = factory.getCurrentAlt();
RuleContextDecl label = (RuleContextDecl)invokeOp.getLabels().get(0);
if ( alt.hasRewrite() ) {
RuleFunction rf = factory.getCurrentRuleFunction();
rf.addLocalDecl(new ElementListDecl(factory, invokeOp.ast));
TrackRuleElement t = new TrackRuleElement(factory, invokeOp.ast, invokeOp);
return DefaultOutputModelFactory.list(ops, t);
CodeBlock blk = factory.getCurrentAlternativeBlock();
String elemListName = factory.getGenerator().target.getElementListName(invokeOp.ast.getText());
blk.addLocalDecl(new ElementListDecl(factory, elemListName));
// track any explicit label like _track_label but not implicit label
if ( !label.isImplicit ) {
String labelListName =
factory.getGenerator().target.getElementListName(label.name);
blk.addLocalDecl(new ElementListDecl(factory, labelListName));
}
String trackName = factory.getGenerator().target.getElementListName(invokeOp.ast.getText());
TrackRuleElement t = new TrackRuleElement(factory, invokeOp.ast, trackName, label);
ops.add(t);
if ( !label.isImplicit ) {
trackName = factory.getGenerator().target.getElementListName(label.name);
TrackRuleElement t2 = new TrackRuleElement(factory, invokeOp.ast, trackName,
label);
if ( invokeOp.ast.parent.getType() == ANTLRParser.ASSIGN ) {
// if x=A must keep it a single-element list; clear before add
ClearElementList c = new ClearElementList(factory, invokeOp.ast, trackName);
ops.add(c);
}
ops.add(t2);
}
}
else {
SrcOp treeOp = new AddRuleLeaf(factory, invokeOp.ast, invokeOp);
return DefaultOutputModelFactory.list(ops, treeOp);
SrcOp treeOp = new AddRuleLeaf(factory, invokeOp.ast, label);
ops.add(treeOp);
}
return ops;
}
@Override
public List<SrcOp> leafToken(List<SrcOp> ops) {
MatchToken matchOp = (MatchToken)Utils.find(ops, MatchToken.class);
TokenDecl label = (TokenDecl)matchOp.getLabels().get(0);
Alternative alt = factory.getCurrentAlt();
if ( alt.hasRewrite() ) {
RuleFunction rf = factory.getCurrentRuleFunction();
rf.addLocalDecl(new ElementListDecl(factory, matchOp.ast));
TrackTokenElement t = new TrackTokenElement(factory, matchOp.ast, matchOp);
return DefaultOutputModelFactory.list(ops, t);
CodeBlock blk = factory.getCurrentAlternativeBlock();
// First declare tracking lists for elements, labels
// track the named element like _track_A
String elemListName = factory.getGenerator().target.getElementListName(matchOp.ast.getText());
blk.addLocalDecl(new ElementListDecl(factory, elemListName));
// track any explicit label like _track_label but not implicit label
if ( !label.isImplicit ) {
String labelListName =
factory.getGenerator().target.getElementListName(label.name);
blk.addLocalDecl(new ElementListDecl(factory, labelListName));
}
// Now, generate track instructions for element and any labels
// do element
String trackName = factory.getGenerator().target.getElementListName(matchOp.ast.getText());
TrackTokenElement t = new TrackTokenElement(factory, matchOp.ast, trackName,
label);
ops.add(t);
if ( !label.isImplicit ) { // track all explicit labels
trackName = factory.getGenerator().target.getElementListName(label.name);
TrackTokenElement t2 = new TrackTokenElement(factory, matchOp.ast, trackName,
label);
if ( matchOp.ast.parent.getType() == ANTLRParser.ASSIGN ) {
// if x=A must keep it a single-element list; clear before add
ClearElementList c = new ClearElementList(factory, matchOp.ast, trackName);
ops.add(c);
}
ops.add(t2);
}
}
else {
SrcOp treeOp = new AddTokenLeaf(factory, matchOp.ast, matchOp);
return DefaultOutputModelFactory.list(ops, treeOp);
SrcOp treeOp = new AddTokenLeaf(factory, matchOp.ast, label);
ops.add(treeOp);
}
return ops;
}
@Override

View File

@ -78,14 +78,14 @@ public class ParserFactory extends DefaultOutputModelFactory {
// If no manual label and action refs as token/rule not label or
// we're adding to trees, we need to define implicit label
if ( controller.needsImplicitLabel(ID, invokeOp) ) defineImplicitLabel(ID, invokeOp);
AddToLabelList listLabelOp = getListLabel(invokeOp, label);
AddToLabelList listLabelOp = getListLabelIfPresent(invokeOp, label);
return list(invokeOp, listLabelOp);
}
public List<SrcOp> tokenRef(GrammarAST ID, GrammarAST label, GrammarAST args) {
LabeledOp matchOp = new MatchToken(this, (TerminalAST) ID, label);
if ( controller.needsImplicitLabel(ID, matchOp) ) defineImplicitLabel(ID, matchOp);
AddToLabelList listLabelOp = getListLabel(matchOp, label);
AddToLabelList listLabelOp = getListLabelIfPresent(matchOp, label);
return list(matchOp, listLabelOp);
}
@ -277,6 +277,33 @@ public class ParserFactory extends DefaultOutputModelFactory {
return list(tokenRef);
}
@Override
public List<SrcOp> rewrite_labelRef(GrammarAST ID, boolean isRoot) {
String rootName = gen.target.getRootName(getTreeLevel());
String iterName = gen.target.getRewriteIteratorName(ID, getCodeBlockLevel());
if ( ID.getText().equals(getCurrentRuleFunction().rule.name) ) { // $e in rule e
RewriteSelfRuleLabelRef labelRef;
if ( isRoot ) labelRef = new RewriteSelfRuleLabelRef(this, ID, rootName);
else labelRef = new RewriteSelfRuleLabelRef(this, ID, rootName);
return list(labelRef);
}
else { // normal element label
RewriteLabelRef labelRef;
if ( isRoot ) labelRef = new RewriteLabelRefIsRoot(this, ID, rootName, iterName);
else labelRef = new RewriteLabelRef(this, ID, rootName, iterName);
return list(labelRef);
}
}
@Override
public List<SrcOp> rewrite_action(ActionAST actionAST, boolean isRoot) {
String rootName = gen.target.getRootName(getTreeLevel());
RewriteAction action;
if ( isRoot ) action = new RewriteActionIsRoot(this, actionAST, rootName);
else action = new RewriteAction(this, actionAST, rootName);
return list(action);
}
// support
public void defineImplicitLabel(GrammarAST ID, LabeledOp op) {
@ -286,20 +313,22 @@ public class ParserFactory extends DefaultOutputModelFactory {
String implLabel = gen.target.getImplicitRuleLabel(ID.getText());
String ctxName = gen.target.getRuleFunctionContextStructName(r);
d = new RuleContextDecl(this, implLabel, ctxName);
((RuleContextDecl)d).isImplicit = true;
}
else {
String implLabel = gen.target.getImplicitTokenLabel(ID.getText());
d = new TokenDecl(this, implLabel);
((TokenDecl)d).isImplicit = true;
}
op.getLabels().add(d);
getCurrentRuleFunction().addLocalDecl(d);
}
public AddToLabelList getListLabel(LabeledOp op, GrammarAST label) {
public AddToLabelList getListLabelIfPresent(LabeledOp op, GrammarAST label) {
AddToLabelList labelOp = null;
if ( label!=null && label.parent.getType()==ANTLRParser.PLUS_ASSIGN ) {
String listLabel = gen.target.getListLabel(label.getText());
labelOp = new AddToLabelList(this, listLabel, op);
labelOp = new AddToLabelList(this, listLabel, op.getLabels().get(0));
}
return labelOp;
}

View File

@ -83,7 +83,9 @@ alternative_with_rewrite returns [CodeBlockForAlt altCodeBlock]
alternative returns [CodeBlockForAlt altCodeBlock, List<SrcOp> ops]
@init {
// set alt if outer ALT only
if ( inContext("RULE BLOCK") && ((AltAST)$start).alt!=null ) controller.setCurrentAlt(((AltAST)$start).alt);
if ( inContext("RULE BLOCK") && ((AltAST)$start).alt!=null ) {
controller.setCurrentAlt(((AltAST)$start).alt);
}
}
: ^(ALT_REWRITE
a=alternative
@ -100,6 +102,9 @@ alternative returns [CodeBlockForAlt altCodeBlock, List<SrcOp> ops]
$altCodeBlock = controller.alternative(controller.getCurrentAlt());
$ops = elems;
controller.setCurrentBlock($altCodeBlock);
if ( inContext("RULE BLOCK") || inContext("RULE BLOCK ALT_REWRITE") ) { // outer block
controller.setCurrentAlternativeBlock($altCodeBlock);
}
}
^( ALT ( element {if ($element.omos!=null) elems.addAll($element.omos);} )+ )
;
@ -243,8 +248,8 @@ rewriteTreeAtom[boolean isRoot] returns [List<SrcOp> omos]
| RULE_REF {$omos = controller.rewrite_ruleRef($RULE_REF, $isRoot);}
| ^(STRING_LITERAL elementOptions) {$omos = controller.rewrite_stringRef($STRING_LITERAL, $isRoot);}
| STRING_LITERAL {$omos = controller.rewrite_stringRef($STRING_LITERAL, $isRoot);}
| LABEL
| ACTION
| LABEL {$omos = controller.rewrite_labelRef($LABEL, $isRoot);}
| ACTION {$omos = controller.rewrite_action((ActionAST)$ACTION, $isRoot);}
;
rewriteTreeEbnf returns [CodeBlock op]

View File

@ -30,7 +30,7 @@
package org.antlr.v4.codegen;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.*;
import org.antlr.v4.tool.*;
import org.stringtemplate.v4.ST;
@ -230,23 +230,21 @@ public class Target {
public String getRewriteIteratorName(GrammarAST elem, int level) {
ST st = gen.templates.getInstanceOf("RewriteIteratorName");
st.add("elemName", getElementName(elem));
st.add("elemName", getElementName(elem.getText()));
st.add("level", level);
return st.render();
}
public String getElementListName(GrammarAST elem) {
public String getElementListName(String name) {
ST st = gen.templates.getInstanceOf("ElementListName");
st.add("elemName", getElementName(elem));
st.add("elemName", getElementName(name));
return st.render();
}
public String getElementName(GrammarAST elem) {
String text = elem.getText();
if ( gen.g.getRule(text)==null ) {
int ttype = gen.g.getTokenType(text);
text = getTokenTypeAsTargetLabel(gen.g, ttype);
}
return text;
public String getElementName(String name) {
if ( gen.g.getRule(name)!=null ) return name;
int ttype = gen.g.getTokenType(name);
if ( ttype==Token.INVALID_TYPE ) return name;
return getTokenTypeAsTargetLabel(gen.g, ttype);
}
}

View File

@ -30,15 +30,15 @@
package org.antlr.v4.codegen.model;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.ast.ElementASTOp;
import org.antlr.v4.codegen.model.decl.Decl;
/** */
public class AddToLabelList extends SrcOp {
public class AddToLabelList extends ElementASTOp {
public String listName;
public LabeledOp opWithResultToAdd;
public AddToLabelList(OutputModelFactory factory, String listName, LabeledOp opWithResultToAdd) {
super(factory);
public AddToLabelList(OutputModelFactory factory, String listName, Decl label) {
super(factory, null, label);
this.listName = listName;
this.opWithResultToAdd = opWithResultToAdd;
}
}

View File

@ -33,14 +33,15 @@ import org.antlr.v4.codegen.*;
import org.antlr.v4.codegen.model.decl.*;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.runtime.atn.RuleTransition;
import org.antlr.v4.runtime.misc.OrderedHashSet;
import org.antlr.v4.tool.*;
import java.util.*;
import java.util.List;
/** */
public class InvokeRule extends RuleElement implements LabeledOp {
public String name;
public List<Decl> labels = new ArrayList<Decl>();
public OrderedHashSet<Decl> labels = new OrderedHashSet<Decl>(); // TODO: should need just 1
public String argExprs;
public String ctxName;
@ -64,7 +65,7 @@ public class InvokeRule extends RuleElement implements LabeledOp {
factory.getCurrentRuleFunction().addContextDecl(d);
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
String listLabel = gen.target.getListLabel(label);
RuleContextListDecl l = new RuleContextListDecl(factory, listLabel, d);
RuleContextListDecl l = new RuleContextListDecl(factory, listLabel, ctxName);
factory.getCurrentRuleFunction().addContextDecl(l);
}
}
@ -89,6 +90,6 @@ public class InvokeRule extends RuleElement implements LabeledOp {
}
public List<Decl> getLabels() {
return labels;
return labels.elements();
}
}

View File

@ -47,7 +47,7 @@ public class MatchToken extends RuleElement implements LabeledOp {
CodeGenerator gen = factory.getGenerator();
int ttype = g.getTokenType(ast.getText());
name = gen.target.getTokenTypeAsTargetLabel(g, ttype);
if ( labelAST!=null ) {
if ( labelAST!=null ) { // TODO: move to factory
String label = labelAST.getText();
TokenDecl d = new TokenDecl(factory, label);
labels.add(d);

View File

@ -30,11 +30,11 @@
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.LabeledOp;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.GrammarAST;
public class AddRuleLeaf extends ElementASTOp {
public AddRuleLeaf(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
super(factory, ast, opWithResultToAdd);
public AddRuleLeaf(OutputModelFactory factory, GrammarAST ast, Decl label) {
super(factory, ast, label);
}
}

View File

@ -30,12 +30,12 @@
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.LabeledOp;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.GrammarAST;
/** */
public class AddTokenLeaf extends ElementASTOp {
public AddTokenLeaf(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
super(factory, ast, opWithResultToAdd);
public AddTokenLeaf(OutputModelFactory factory, GrammarAST ast, Decl label) {
super(factory, ast, label);
}
}

View File

@ -0,0 +1,43 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.SrcOp;
import org.antlr.v4.tool.GrammarAST;
public class ClearElementList extends SrcOp {
public String name;
public ClearElementList(OutputModelFactory factory, GrammarAST ast, String name) {
super(factory, ast);
this.name = name;
}
}

View File

@ -30,17 +30,15 @@
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.*;
import org.antlr.v4.codegen.model.SrcOp;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.GrammarAST;
public class ElementASTOp extends SrcOp {
public LabeledOp opWithResultToAdd;
public Decl label;
public ElementASTOp(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
public ElementASTOp(OutputModelFactory factory, GrammarAST ast, Decl label) {
super(factory, ast);
this.opWithResultToAdd = opWithResultToAdd;
label = opWithResultToAdd.getLabels().get(0);
this.label = label;
}
}

View File

@ -0,0 +1,53 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.*;
import org.antlr.v4.codegen.model.*;
import org.antlr.v4.codegen.model.actions.ActionChunk;
import org.antlr.v4.tool.ActionAST;
import java.util.List;
public class RewriteAction extends SrcOp {
public String rootName;
@ModelElement public List<ActionChunk> chunks;
public RewriteAction(OutputModelFactory factory, ActionAST ast, String rootName) {
super(factory, ast);
this.rootName = rootName;
if ( ast!=null ) {
chunks = ActionTranslator.translateAction(factory,
factory.getCurrentRuleFunction(),
ast.token, ast);
}
}
}

View File

@ -0,0 +1,39 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.ActionAST;
public class RewriteActionIsRoot extends RewriteAction {
public RewriteActionIsRoot(OutputModelFactory factory, ActionAST ast, String rootName) {
super(factory, ast, rootName);
}
}

View File

@ -0,0 +1,46 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.SrcOp;
import org.antlr.v4.tool.GrammarAST;
public class RewriteLabelRef extends SrcOp {
public String rootName;
public String iterName;
public RewriteLabelRef(OutputModelFactory factory, GrammarAST ast,
String rootName, String iterName) {
super(factory, ast);
this.rootName = rootName;
this.iterName = iterName;
}
}

View File

@ -0,0 +1,40 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.GrammarAST;
public class RewriteLabelRefIsRoot extends RewriteLabelRef {
public RewriteLabelRefIsRoot(OutputModelFactory factory, GrammarAST ast,
String rootName, String iterName) {
super(factory, ast, rootName, iterName);
}
}

View File

@ -0,0 +1,43 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.SrcOp;
import org.antlr.v4.tool.GrammarAST;
public class RewriteSelfRuleLabelRef extends SrcOp {
public String rootName;
public RewriteSelfRuleLabelRef(OutputModelFactory factory, GrammarAST ast, String rootName) {
super(factory, ast);
this.rootName = rootName;
}
}

View File

@ -0,0 +1,39 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.GrammarAST;
public class RewriteSelfRuleLabelRefIsRoot extends RewriteSelfRuleLabelRef {
public RewriteSelfRuleLabelRefIsRoot(OutputModelFactory factory, GrammarAST ast, String rootName) {
super(factory, ast, rootName);
}
}

View File

@ -30,11 +30,11 @@
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.LabeledOp;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.GrammarAST;
public class RuleBecomeRoot extends ElementASTOp {
public RuleBecomeRoot(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
super(factory, ast, opWithResultToAdd);
public RuleBecomeRoot(OutputModelFactory factory, GrammarAST ast, Decl label) {
super(factory, ast, label);
}
}

View File

@ -30,12 +30,12 @@
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.LabeledOp;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.GrammarAST;
/** */
public class TokenBecomeRoot extends ElementASTOp {
public TokenBecomeRoot(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
super(factory, ast, opWithResultToAdd);
public TokenBecomeRoot(OutputModelFactory factory, GrammarAST ast, Decl label) {
super(factory, ast, label);
}
}

View File

@ -30,13 +30,13 @@
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.LabeledOp;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.GrammarAST;
public class TrackRuleElement extends ElementASTOp {
public String name;
public TrackRuleElement(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
super(factory, ast, opWithResultToAdd);
name = factory.getGenerator().target.getElementListName(ast);
public TrackRuleElement(OutputModelFactory factory, GrammarAST ast, String trackName, Decl label) {
super(factory, ast, label);
name = trackName;
}
}

View File

@ -30,13 +30,13 @@
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.LabeledOp;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.GrammarAST;
public class TrackTokenElement extends ElementASTOp {
public String name;
public TrackTokenElement(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
super(factory, ast, opWithResultToAdd);
name = factory.getGenerator().target.getElementListName(ast);
public TrackTokenElement(OutputModelFactory factory, GrammarAST ast, String trackName, Decl label) {
super(factory, ast, label);
name = trackName;
}
}

View File

@ -30,10 +30,9 @@
package org.antlr.v4.codegen.model.decl;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.GrammarAST;
public class ElementListDecl extends Decl {
public ElementListDecl(OutputModelFactory factory, GrammarAST elem) {
super(factory, factory.getGenerator().target.getElementListName(elem));
public ElementListDecl(OutputModelFactory factory, String name) {
super(factory, name);
}
}

View File

@ -40,6 +40,6 @@ public class RewriteIteratorDecl extends Decl {
{
super(factory, factory.getGenerator().target
.getRewriteIteratorName(elem, codeBlockLevel));
listName = factory.getGenerator().target.getElementListName(elem);
listName = factory.getGenerator().target.getElementListName(elem.getText());
}
}

View File

@ -34,6 +34,8 @@ import org.antlr.v4.codegen.OutputModelFactory;
/** */
public class RuleContextDecl extends Decl {
public String ctxName;
public boolean isImplicit;
public RuleContextDecl(OutputModelFactory factory, String name, String ctxName) {
super(factory, name);
this.ctxName = ctxName;

View File

@ -31,10 +31,9 @@ package org.antlr.v4.codegen.model.decl;
import org.antlr.v4.codegen.OutputModelFactory;
public class RuleContextListDecl extends Decl {
public RuleContextDecl decl;
public RuleContextListDecl(OutputModelFactory factory, String name, RuleContextDecl decl) {
super(factory, name);
this.decl = decl;
public class RuleContextListDecl extends RuleContextDecl {
public RuleContextListDecl(OutputModelFactory factory, String name, String ctxName) {
super(factory, name, ctxName);
isImplicit = false;
}
}

View File

@ -31,13 +31,14 @@ package org.antlr.v4.codegen.model.decl;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.ModelElement;
import org.antlr.v4.runtime.misc.OrderedHashSet;
import org.antlr.v4.tool.Attribute;
import java.util.*;
import java.util.Collection;
/** */
public class StructDecl extends Decl {
@ModelElement public List<Decl> attrs = new ArrayList<Decl>();
@ModelElement public OrderedHashSet<Decl> attrs = new OrderedHashSet<Decl>();
@ModelElement public Collection<Attribute> ctorAttrs;
public StructDecl(OutputModelFactory factory) {

View File

@ -33,6 +33,8 @@ import org.antlr.v4.codegen.OutputModelFactory;
/** */
public class TokenDecl extends Decl {
public boolean isImplicit;
public TokenDecl(OutputModelFactory factory, String varName) {
super(factory, varName);
}

View File

@ -32,7 +32,7 @@ package org.antlr.v4.codegen.model.decl;
import org.antlr.v4.codegen.OutputModelFactory;
/** */
public class TokenListDecl extends Decl {
public class TokenListDecl extends TokenDecl {
public TokenListDecl(OutputModelFactory factory, String varName) {
super(factory, varName);
}

View File

@ -700,12 +700,9 @@ blockSuffixe
;
ebnfSuffix
@init {
Token op = input.LT(1);
}
: QUESTION -> OPTIONAL[op]
| STAR -> CLOSURE[op]
| PLUS -> POSITIVE_CLOSURE[op]
: QUESTION -> OPTIONAL[$start]
| STAR -> CLOSURE[$start]
| PLUS -> POSITIVE_CLOSURE[$start]
;
atom: // Qualified reference delegate.rule. This must be
@ -839,15 +836,15 @@ nakedRewrite
// rule altAndRewrite makes REWRITE root. for ST, we use ST_REWRITE
rewriteAlt returns [boolean isTemplate]
options {backtrack=true;}
: // try to parse a template rewrite
rewriteTemplate {$isTemplate=true;}
| // If we are not building templates, then we must be
: // If we are not building templates, then we must be
// building ASTs or have rewrites in a grammar that does not
// have output=AST; options. If that is the case, we will issue
// errors/warnings in the next phase, so we just eat them here
rewriteTreeAlt
| // try to parse a template rewrite
rewriteTemplate {$isTemplate=true;} // must be 2nd so "ACTION ..." matches as tree rewrite
| ETC
| /* empty rewrite */ -> EPSILON
@ -888,8 +885,8 @@ rewriteTreeEbnf
;
rewriteEbnfSuffix
: OPTIONAL
| CLOSURE
: QUESTION -> OPTIONAL[$start]
| STAR -> CLOSURE[$start]
;
rewriteTree

View File

@ -232,6 +232,7 @@ ruleArg
currentRule.args = ScopeParser.parseTypeList($ARG_ACTION.text);
currentRule.args.type = AttributeDict.DictType.ARG;
currentRule.args.ast = $ARG_ACTION;
((ActionAST)$ARG_ACTION).resolver = currentRule.alt[currentAlt];
}
;
@ -260,8 +261,16 @@ ruleScopeSpec
rewriteElement
//@init {System.out.println("rewriteElement: "+((Tree)input.LT(1)).getText());}
:
{inContext("RESULT ...")}? (TOKEN_REF|RULE_REF|STRING_LITERAL|LABEL)
{currentRule.alt[currentAlt].rewriteElements.add($start);}
{inContext("RESULT ...")}? t=(TOKEN_REF|RULE_REF|STRING_LITERAL|LABEL)
{
currentRule.alt[currentAlt].rewriteElements.add($start);
if ( $t.getType()==TOKEN_REF && t.getChildCount()>0 ) {
GrammarAST arg = (GrammarAST)t.getChild(0);
if ( arg.getType()==ARG_ACTION ) {
((ActionAST)arg).resolver = currentRule.alt[currentAlt];
}
}
}
;
labeledElement
@ -285,12 +294,13 @@ terminal
currentRule.alt[currentAlt].tokenRefs.map($STRING_LITERAL.text, (TerminalAST)$STRING_LITERAL);
}
}
| TOKEN_REF
| (tref=TOKEN_REF | ^(tref=TOKEN_REF ARG_ACTION .?))
{
terminals.add($TOKEN_REF);
tokenIDRefs.add($TOKEN_REF);
terminals.add($tref);
tokenIDRefs.add($tref);
if ( currentRule!=null ) {
currentRule.alt[currentAlt].tokenRefs.map($TOKEN_REF.text, (TerminalAST)$TOKEN_REF);
currentRule.alt[currentAlt].tokenRefs.map($tref.text, (TerminalAST)$tref);
if ( $ARG_ACTION!=null ) ((ActionAST)$ARG_ACTION).resolver = currentRule.alt[currentAlt];
}
}
;

View File

@ -90,15 +90,22 @@ public class UseDefAnalyzer {
return UseDefAnalyzer.getRewriteElementRefs(g, ebnfRoot, 1, deep);
}
/** Get list of rule refs, token refs mentioned on left, and labels not
* referring to rule result like $e in rule e.
*/
public static List<GrammarAST> filterForRuleAndTokenRefs(Alternative alt,
List<GrammarAST> refs)
{
List<GrammarAST> elems = new ArrayList<GrammarAST>();
if ( refs!=null ) {
for (GrammarAST ref : refs) {
boolean imaginary = ref.getType()== ANTLRParser.TOKEN_REF &&
!alt.tokenRefs.containsKey(ref.getText());
if ( !imaginary ) elems.add(ref);
boolean imaginary =
ref.getType()== ANTLRParser.TOKEN_REF &&
!alt.tokenRefs.containsKey(ref.getText());
boolean selfLabel =
ref.getType()==ANTLRParser.LABEL &&
ref.getText().equals(alt.rule.name);
if ( !imaginary && !selfLabel ) elems.add(ref);
}
}
return elems;

View File

@ -39,7 +39,7 @@ import java.util.*;
* or rule of a grammar.
*/
public class Alternative implements AttributeResolver {
Rule rule;
public Rule rule;
public AltAST ast;
@ -72,7 +72,7 @@ public class Alternative implements AttributeResolver {
/** (ALT_REWRITE (ALT ...) (-> (ALT ...))) */
public boolean hasRewrite() {
return ast!=null && ast.getType()==ANTLRParser.ALT_REWRITE;
return ast.getNodesWithType(ANTLRParser.ALT_REWRITE).size()>0;
}
public boolean resolvesToToken(String x, ActionAST node) {

View File

@ -29,7 +29,7 @@
package org.antlr.v4.test;
import org.junit.*;
import org.junit.Test;
public class TestRewriteAST extends BaseTest {
protected boolean debug = false;
@ -288,20 +288,6 @@ public class TestRewriteAST extends BaseTest {
assertEquals("a\n", found);
}
@Test public void testPositiveClosureSingleRule() throws Exception {
String grammar =
"grammar T;\n" +
"options {output=AST;}\n" +
"a : b b -> b+;\n" +
"b : ID ;\n" +
"ID : 'a'..'z'+ ;\n" +
"INT : '0'..'9'+;\n" +
"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
String found = execParser("T.g", grammar, "TParser", "TLexer",
"a", "a b", debug);
assertEquals("a b\n", found);
}
@Test public void testSinglePredicateT() throws Exception {
String grammar =
"grammar T;\n" +
@ -501,7 +487,7 @@ public class TestRewriteAST extends BaseTest {
"options {output=AST;}\n" +
"tokens {BLOCK;}\n" +
"a : b b ;\n" +
"b : (ID INT -> INT ID | INT INT -> INT+ )\n" +
"b : (ID INT -> INT ID | INT INT -> INT* )\n" +
" ;\n" +
"ID : 'a'..'z'+ ;\n" +
"INT : '0'..'9'+;\n" +
@ -544,15 +530,15 @@ public class TestRewriteAST extends BaseTest {
"INT : '0'..'9'+;\n" +
"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
String found = execParser("T.g", grammar, "TParser", "TLexer",
"a", "a b c d; 42", debug);
assertEquals("d 42\n", found);
"a", "a b c; 42", debug);
assertEquals("c 42\n", found);
}
@Test public void testRewriteActions() throws Exception {
String grammar =
"grammar T;\n" +
"options {output=AST;}\n" +
"a : atom -> ^({adaptor.create(INT,\"9\")} atom) ;\n" +
"a : atom -> ^({_adaptor.create(INT,\"9\")} atom) ;\n" +
"atom : INT ;\n" +
"ID : 'a'..'z'+ ;\n" +
"INT : '0'..'9'+;\n" +
@ -566,7 +552,7 @@ public class TestRewriteAST extends BaseTest {
String grammar =
"grammar T;\n" +
"options {output=AST;}\n" +
"a : atom -> {adaptor.create(INT,\"9\")} atom ;\n" +
"a : atom -> {_adaptor.create(INT,\"9\")} atom ;\n" +
"atom : INT ;\n" +
"ID : 'a'..'z'+ ;\n" +
"INT : '0'..'9'+;\n" +
@ -786,7 +772,7 @@ public class TestRewriteAST extends BaseTest {
"grammar T;\n" +
"options {output=AST;}\n" +
"tokens {VAR;}\n"+
"a : first=ID others+=ID* -> $first VAR $others+ ;\n" +
"a : first=ID others+=ID* -> $first VAR $others* ;\n" +
"op : '+'|'-' ;\n" +
"ID : 'a'..'z'+ ;\n" +
"INT : '0'..'9'+;\n" +
@ -801,7 +787,7 @@ public class TestRewriteAST extends BaseTest {
"grammar T;\n" +
"options {output=AST;}\n" +
"tokens {BLOCK;}\n" +
"a : A A b=B B b=B c+=C C c+=C D {String s=$D.text;} -> A+ B+ C+ D ;\n" +
"a : A A b=B B b=B c+=C C c+=C D {String s=$D.text;} -> A* B* C* D ;\n" +
"type : 'int' | 'float' ;\n" +
"A : 'a' ;\n" +
"B : 'b' ;\n" +
@ -868,7 +854,7 @@ public class TestRewriteAST extends BaseTest {
"grammar T;\n" +
"options {output=AST;}\n" +
"tokens {BLOCK;}\n" +
"a : x+=b x+=b -> $x+;\n"+
"a : x+=b x+=b -> $x*;\n"+
"b : ID ;\n"+
"ID : 'a'..'z'+ ;\n" +
"WS : (' '|'\\n') {$channel=HIDDEN;} ;\n";
@ -1001,11 +987,7 @@ public class TestRewriteAST extends BaseTest {
assertEquals("2\n", found);
}
@Ignore
// TODO: FAILS. The should probably generate a warning from antlr
// See http://www.antlr.org:8888/browse/ANTLR-162
//
public void testSetWithLabel() throws Exception {
@Test public void testSetWithLabel() throws Exception {
String grammar =
"grammar T;\n" +
@ -1041,7 +1023,7 @@ public class TestRewriteAST extends BaseTest {
"tokens {PARMS;} \n" +
"\n" +
"modulo \n" +
" : 'modulo' ID ('(' parms+ ')')? -> ^('modulo' ID ^(PARMS parms+)?) \n" +
" : 'modulo' ID ('(' parms+ ')')? -> ^('modulo' ID ^(PARMS parms*)?) \n" +
" ; \n" +
"parms : '#'|ID; \n" +
"ID : ('a'..'z' | 'A'..'Z')+;\n" +