rewrite is now block of code; can have nested

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8822]
This commit is contained in:
parrt 2011-07-02 17:27:54 -08:00
parent 07161bffe7
commit 411e1bb210
20 changed files with 190 additions and 41 deletions

View File

@ -28,6 +28,7 @@ import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.*;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
<parser>
@ -376,12 +377,18 @@ ElementListName(elemName) ::= "_track_<elemName>"
TrackRuleElement(e) ::= "<e.name>.add(<labelref(e.label)>);"
TrackTokenElement(e) ::= "<e.name>.add(_adaptor.create(<labelref(e.label)>));"
TreeRewrite(tr, ops) ::= <<
TreeRewrite(tr, locals, preamble, ops) ::= <<
// rewrite: ...
<locals; separator="\n">
<preamble; separator="\n">
<ops; separator="\n">
>>
RewriteTokenRef(t) ::= "/* tokenref */"
RewriteIteratorDecl(d) ::= "Iterator <d.name>;"
RewriteIteratorInit(i) ::= "<i.decl.name> = <i.decl.listName>.iterator();"
RewriteIteratorName(elemName,level) ::= "it<level>_<elemName>"
RewriteTokenRef(t) ::= "_adaptor.addChild(<t.decl.name>.next());"
RewriteRuleRef(r) ::= "/* ruleref */"
/*

View File

@ -149,7 +149,7 @@ public class ActionTranslator implements ActionSplitterListener {
switch ( a.dict.type ) {
case ARG: chunks.add(new ArgRef(y.getText())); break; // has to be current rule
case RET:
if ( factory.getCurrentRule()!=null && factory.getCurrentRule().name.equals(x.getText()) ) {
if ( factory.getCurrentRuleFunction()!=null && factory.getCurrentRuleFunction().name.equals(x.getText()) ) {
chunks.add(new RetValueRef(y.getText())); break;
}
else {

View File

@ -77,7 +77,7 @@ public abstract class BlankOutputModelFactory implements OutputModelFactory {
// AST REWRITES
public TreeRewrite treeRewrite(List<SrcOp> ops) { return null; }
public TreeRewrite treeRewrite(GrammarAST ast) { return null; }
public List<SrcOp> rewrite_ruleRef(GrammarAST ID) { return null; }

View File

@ -87,7 +87,7 @@ public class CodeGeneratorExtension {
// AST REWRITEs
public TreeRewrite treeRewrite(TreeRewrite code) { return code; }
public TreeRewrite treeRewrite(TreeRewrite r) { return r; }
public List<SrcOp> rewrite_ruleRef(List<SrcOp> ops) { return ops; }

View File

@ -49,6 +49,7 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory
public OutputModelObject root; // normally ParserFile, LexerFile, ...
public Stack<RuleFunction> currentRule = new Stack<RuleFunction>();
public Alternative currentAlt;
public Rewrite currentRewrite;
protected DefaultOutputModelFactory(CodeGenerator gen) {
this.gen = gen;
@ -63,7 +64,7 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory
public void setRoot(OutputModelObject root) { this.root = root; }
public RuleFunction getCurrentRule() {
public RuleFunction getCurrentRuleFunction() {
if ( currentRule.size()>0 ) return currentRule.peek();
return null;
}
@ -83,6 +84,14 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory
this.controller = controller;
}
public void setCurrentRewriteBlock(Rewrite rew) {
currentRewrite = rew;
}
public Rewrite getCurrentRewriteBlock() {
return currentRewrite;
}
// MISC
public static List<SrcOp> list(Object... values) {

View File

@ -271,8 +271,8 @@ public class OutputModelController implements OutputModelFactory {
// REWRITES
public TreeRewrite treeRewrite(List<SrcOp> ops) {
TreeRewrite r = delegate.treeRewrite(ops);
public TreeRewrite treeRewrite(GrammarAST ast) {
TreeRewrite r = delegate.treeRewrite(ast);
for (CodeGeneratorExtension ext : extensions) r = ext.treeRewrite(r);
return r;
}
@ -295,7 +295,7 @@ public class OutputModelController implements OutputModelFactory {
public void setRoot(OutputModelObject root) { delegate.setRoot(root); }
public RuleFunction getCurrentRule() { return delegate.getCurrentRule(); }
public RuleFunction getCurrentRuleFunction() { return delegate.getCurrentRuleFunction(); }
public void pushCurrentRule(RuleFunction r) { delegate.pushCurrentRule(r); }
@ -306,4 +306,8 @@ public class OutputModelController implements OutputModelFactory {
public void setCurrentAlt(Alternative alt) { delegate.setCurrentAlt(alt); }
public void setController(OutputModelController controller) { } // nop; we are controller
public void setCurrentRewriteBlock(Rewrite rew) { delegate.setCurrentRewriteBlock(rew); }
public Rewrite getCurrentRewriteBlock() { return delegate.getCurrentRewriteBlock(); }
}

View File

@ -92,8 +92,10 @@ public interface OutputModelFactory {
boolean needsImplicitLabel(GrammarAST ID, LabeledOp op);
// AST REWRITE TRIGGERS
// Though dealing with ASTs, we must deal with here since these are
// triggered from elements in ANTLR's internal GrammarAST
TreeRewrite treeRewrite(List<SrcOp> ops);
TreeRewrite treeRewrite(GrammarAST ast);
List<SrcOp> rewrite_ruleRef(GrammarAST ID);
@ -107,7 +109,7 @@ public interface OutputModelFactory {
void setRoot(OutputModelObject root);
RuleFunction getCurrentRule();
RuleFunction getCurrentRuleFunction();
void pushCurrentRule(RuleFunction r);
@ -118,4 +120,8 @@ public interface OutputModelFactory {
void setCurrentAlt(Alternative currentAlt);
void setController(OutputModelController controller);
void setCurrentRewriteBlock(Rewrite rew);
Rewrite getCurrentRewriteBlock();
}

View File

@ -85,7 +85,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
InvokeRule invokeOp = (InvokeRule)Utils.find(ops, InvokeRule.class);
Alternative alt = factory.getCurrentAlt();
if ( alt.hasRewrite() ) {
RuleFunction rf = factory.getCurrentRule();
RuleFunction rf = factory.getCurrentRuleFunction();
rf.addLocalDecl(new ElementListDecl(factory, invokeOp.ast));
TrackRuleElement t = new TrackRuleElement(factory, invokeOp.ast, invokeOp);
return DefaultOutputModelFactory.list(ops, t);
@ -101,7 +101,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
MatchToken matchOp = (MatchToken)Utils.find(ops, MatchToken.class);
Alternative alt = factory.getCurrentAlt();
if ( alt.hasRewrite() ) {
RuleFunction rf = factory.getCurrentRule();
RuleFunction rf = factory.getCurrentRuleFunction();
rf.addLocalDecl(new ElementListDecl(factory, matchOp.ast));
TrackTokenElement t = new TrackTokenElement(factory, matchOp.ast, matchOp);
return DefaultOutputModelFactory.list(ops, t);
@ -122,7 +122,6 @@ public class ParserASTExtension extends CodeGeneratorExtension {
// REWRITES
@Override
public List<SrcOp> rewrite_ruleRef(List<SrcOp> ops) {
return super.rewrite_ruleRef(ops);

View File

@ -172,16 +172,22 @@ public class ParserFactory extends DefaultOutputModelFactory {
@Override
public TreeRewrite treeRewrite(List<SrcOp> ops) {
return new TreeRewrite(this, ops);
public TreeRewrite treeRewrite(GrammarAST ast) {
return new TreeRewrite(this);
}
public List<SrcOp> rewrite_ruleRef(GrammarAST ID) {
Decl d = new RewriteIteratorDecl(this, ID, 0);
getCurrentRewriteBlock().addLocalDecl(d);
return list(new RewriteRuleRef(this, ID));
}
public List<SrcOp> rewrite_tokenRef(GrammarAST ID) {
return list(new RewriteTokenRef(this, ID));
RewriteIteratorDecl d = new RewriteIteratorDecl(this, ID, 0);
getCurrentRewriteBlock().addLocalDecl(d);
RewriteIteratorInit init = new RewriteIteratorInit(this, d);
getCurrentRewriteBlock().addPreambleOp(init);
return list(new RewriteTokenRef(this, ID, d));
}
// support
@ -199,7 +205,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
d = new TokenDecl(this, implLabel);
}
op.getLabels().add(d);
getCurrentRule().addLocalDecl(d);
getCurrentRuleFunction().addLocalDecl(d);
}
public AddToLabelList getListLabel(LabeledOp op, GrammarAST label) {

View File

@ -149,7 +149,12 @@ elementOption
// R E W R I T E S T U F F
rewrite returns [Rewrite code]
: predicatedRewrite* nakedRewrite {$code = factory.treeRewrite($nakedRewrite.omos);}
: {
$code = factory.treeRewrite($start);
factory.setCurrentRewriteBlock($code);
}
predicatedRewrite* nakedRewrite
{$code.ops = $nakedRewrite.omos;}
;
predicatedRewrite returns [List<SrcOp> omos]

View File

@ -228,15 +228,26 @@ public class Target {
return st.render();
}
public String getRewriteIteratorName(GrammarAST elem, int level) {
ST st = gen.templates.getInstanceOf("RewriteIteratorName");
st.add("elemName", getElementName(elem));
st.add("level", level);
return st.render();
}
public String getElementListName(GrammarAST elem) {
ST st = gen.templates.getInstanceOf("ElementListName");
String text = elem.getText();
if ( gen.g.getRule(text)!=null ) st.add("elemName", text);
else {
int ttype = gen.g.getTokenType(text);
text = getTokenTypeAsTargetLabel(gen.g, ttype);
st.add("elemName", text);
}
st.add("elemName", getElementName(elem));
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;
}
}

View File

@ -41,7 +41,7 @@ public class Action extends RuleElement {
public Action(OutputModelFactory factory, GrammarAST ast) {
super(factory,ast);
RuleFunction rf = factory.getCurrentRule();
RuleFunction rf = factory.getCurrentRuleFunction();
chunks = ActionTranslator.translateAction(factory, rf, ast.token, (ActionAST)ast);
//System.out.println("actions="+chunks);
}

View File

@ -81,7 +81,7 @@ public abstract class Choice extends RuleElement {
if ( expr instanceof TestSetInline) {
TestSetInline e = (TestSetInline)expr;
Decl d = new TokenTypeDecl(factory, e.varName);
factory.getCurrentRule().addLocalDecl(d);
factory.getCurrentRuleFunction().addLocalDecl(d);
CaptureNextTokenType nextType = new CaptureNextTokenType(e.varName);
addPreambleOp(nextType);
}

View File

@ -61,11 +61,11 @@ public class InvokeRule extends RuleElement implements LabeledOp {
String label = labelAST.getText();
RuleContextDecl d = new RuleContextDecl(factory,label,ctxName);
labels.add(d);
factory.getCurrentRule().addContextDecl(d);
factory.getCurrentRuleFunction().addContextDecl(d);
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
String listLabel = gen.target.getListLabel(label);
RuleContextListDecl l = new RuleContextListDecl(factory, listLabel, d);
factory.getCurrentRule().addContextDecl(l);
factory.getCurrentRuleFunction().addContextDecl(l);
}
}
if ( ast.getChildCount()>0 ) {
@ -77,7 +77,7 @@ public class InvokeRule extends RuleElement implements LabeledOp {
String label = gen.target.getImplicitRuleLabel(ast.getText());
RuleContextDecl d = new RuleContextDecl(factory,label,ctxName);
labels.add(d);
factory.getCurrentRule().addContextDecl(d);
factory.getCurrentRuleFunction().addContextDecl(d);
}
// LinearApproximator approx = new LinearApproximator(factory.g, ATN.INVALID_DECISION_NUMBER);

View File

@ -51,10 +51,10 @@ public class MatchToken extends RuleElement implements LabeledOp {
String label = labelAST.getText();
TokenDecl d = new TokenDecl(factory, label);
labels.add(d);
factory.getCurrentRule().addContextDecl(d);
factory.getCurrentRuleFunction().addContextDecl(d);
if ( labelAST.parent.getType() == ANTLRParser.PLUS_ASSIGN ) {
TokenListDecl l = new TokenListDecl(factory, gen.target.getListLabel(label));
factory.getCurrentRule().addContextDecl(l);
factory.getCurrentRuleFunction().addContextDecl(l);
}
}
}

View File

@ -30,14 +30,29 @@
package org.antlr.v4.codegen.model;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.runtime.misc.OrderedHashSet;
import java.util.List;
import java.util.*;
public class Rewrite extends SrcOp {
@ModelElement public OrderedHashSet<Decl> locals;
@ModelElement public List<SrcOp> preamble;
@ModelElement public List<? extends SrcOp> ops;
public Rewrite(OutputModelFactory factory, List<SrcOp> ops) {
public Rewrite(OutputModelFactory factory) {
super(factory);
this.ops = ops;
}
/** Add local var decl */
public void addLocalDecl(Decl d) {
if ( locals==null ) locals = new OrderedHashSet<Decl>();
locals.add(d);
d.isLocal = true;
}
public void addPreambleOp(SrcOp op) {
if ( preamble==null ) preamble = new ArrayList<SrcOp>();
preamble.add(op);
}
}

View File

@ -0,0 +1,42 @@
/*
[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.codegen.model.decl.RewriteIteratorDecl;
public class RewriteIteratorInit extends SrcOp {
public RewriteIteratorDecl decl;
public RewriteIteratorInit(OutputModelFactory factory, RewriteIteratorDecl decl) {
super(factory);
this.decl = decl;
}
}

View File

@ -31,10 +31,14 @@ package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.SrcOp;
import org.antlr.v4.codegen.model.decl.RewriteIteratorDecl;
import org.antlr.v4.tool.GrammarAST;
public class RewriteTokenRef extends SrcOp {
public RewriteTokenRef(OutputModelFactory factory, GrammarAST ast) {
/** Which iterator decl are we associated with? */
public RewriteIteratorDecl decl;
public RewriteTokenRef(OutputModelFactory factory, GrammarAST ast, RewriteIteratorDecl decl) {
super(factory, ast);
this.decl = decl;
}
}

View File

@ -30,12 +30,10 @@
package org.antlr.v4.codegen.model.ast;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.*;
import java.util.List;
import org.antlr.v4.codegen.model.Rewrite;
public class TreeRewrite extends Rewrite {
public TreeRewrite(OutputModelFactory factory, List<SrcOp> ops) {
super(factory, ops);
public TreeRewrite(OutputModelFactory factory) {
super(factory);
}
}

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.decl;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.tool.GrammarAST;
public class RewriteIteratorDecl extends Decl {
public int level;
public String listName;
public RewriteIteratorDecl(OutputModelFactory factory, GrammarAST elem, int level) {
super(factory, factory.getGenerator().target.getRewriteIteratorName(elem, level));
listName = factory.getGenerator().target.getElementListName(elem);
this.level = level;
}
}