From df80cb762203701eb764ae40c999d4907e0fc232 Mon Sep 17 00:00:00 2001 From: parrt Date: Mon, 4 Jul 2011 17:47:44 -0800 Subject: [PATCH] good start on * and ? in rewrites [git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8826] --- tool/playground/T.g | 4 + tool/playground/TestT.java | 5 +- .../v4/tool/templates/codegen/Java/Java.stg | 34 ++++-- .../v4/codegen/BlankOutputModelFactory.java | 8 +- .../v4/codegen/CodeGeneratorExtension.java | 4 + .../v4/codegen/DefaultOutputModelFactory.java | 14 ++- .../v4/codegen/OutputModelController.java | 102 ++++++++++++++++-- .../antlr/v4/codegen/OutputModelFactory.java | 14 ++- .../antlr/v4/codegen/ParserASTExtension.java | 2 +- .../org/antlr/v4/codegen/ParserFactory.java | 53 ++++++--- .../org/antlr/v4/codegen/SourceGenTriggers.g | 35 ++++-- .../org/antlr/v4/codegen/model/Rewrite.java | 4 +- .../antlr/v4/codegen/model/RuleFunction.java | 6 +- .../v4/codegen/model/ast/RewriteTokenRef.java | 6 +- .../model/ast/RewriteTokenRefIsRoot.java | 6 +- .../codegen/model/ast/RewriteTreeClosure.java | 47 ++++++++ .../RewriteTreeOptional.java} | 16 +-- .../model/ast/RewriteTreeStructure.java | 8 +- .../v4/codegen/model/ast/TreeRewrite.java | 8 +- .../v4/codegen/model/decl/CodeBlock.java | 14 +++ .../model/decl/RewriteIteratorDecl.java | 9 +- .../antlr/v4/codegen/model/decl/RootDecl.java | 7 +- tool/src/org/antlr/v4/tool/Rule.java | 1 - 23 files changed, 331 insertions(+), 76 deletions(-) create mode 100644 tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeClosure.java rename tool/src/org/antlr/v4/codegen/model/{decl/NestedDecl.java => ast/RewriteTreeOptional.java} (80%) diff --git a/tool/playground/T.g b/tool/playground/T.g index 7ab8a3425..62e0318d1 100644 --- a/tool/playground/T.g +++ b/tool/playground/T.g @@ -1,11 +1,15 @@ grammar T; options {output=AST;} tokens {I;} +/* a : A b C -> ^(A ^(b C)) | B ; b : B | C ; +*/ + +c : A B C -> (A B C*)* ; A : 'a'; B : 'b'; diff --git a/tool/playground/TestT.java b/tool/playground/TestT.java index 94301b49b..73a905eaa 100644 --- a/tool/playground/TestT.java +++ b/tool/playground/TestT.java @@ -2,7 +2,6 @@ import org.antlr.v4.Tool; import org.antlr.v4.automata.ParserATNFactory; import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.atn.ATN; -import org.antlr.v4.runtime.tree.Tree; import org.antlr.v4.semantics.SemanticPipeline; import org.antlr.v4.tool.*; @@ -13,8 +12,8 @@ public class TestT { TLexer t = new TLexer(new ANTLRFileStream(args[0])); CommonTokenStream tokens = new CommonTokenStream(t); TParser p = new TParser(tokens); - ParserRuleContext ret = p.a(); - System.out.println(((Tree)ret.tree).toStringTree()); +// ParserRuleContext ret = p.a(); +// System.out.println(((Tree)ret.tree).toStringTree()); } public static void dump() throws Exception { diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index 69c608218..a55e84c06 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -389,6 +389,28 @@ TreeRewrite(tr, locals, preamble, ops) ::= << _localctx.tree = _root0; >> +RewriteIteratorDecl(d) ::= "Iterator ;" +RewriteIteratorInit(i) ::= " = .iterator();" +RewriteIteratorName(elemName,level) ::= "it_" + +RewriteTreeOptional(o, locals, preamble, ops) ::= << +// ? + + +//if ( true ) { + +//} +>> + +RewriteTreeClosure(c, locals, preamble, ops) ::= << +// * + + +//while ( .hasNext()}; separator=" || "> ) { + +//} +>> + RewriteTreeStructure(t, locals, preamble, ops) ::= << { @@ -397,15 +419,11 @@ RewriteTreeStructure(t, locals, preamble, ops) ::= << _adaptor.addChild(, ); } >> -RewriteIteratorDecl(d) ::= "Iterator ;" -RewriteIteratorInit(i) ::= " = .iterator();" -RewriteIteratorName(elemName,level) ::= "it_" -RewriteTokenRef(t) ::= "_adaptor.addChild(, .next());" -RewriteTokenRefIsRoot(t) ::= <% - = - _adaptor.becomeRoot(.next(), ); -%> +RewriteTokenRef(t) ::= "_adaptor.addChild(, .next());" +RewriteTokenRefIsRoot(t) ::= << + = _adaptor.becomeRoot(.next(), ); +>> RewriteRuleRef(r) ::= "_adaptor.addChild(, .next());" RewriteRuleRefIsRoot(r) ::= <% = diff --git a/tool/src/org/antlr/v4/codegen/BlankOutputModelFactory.java b/tool/src/org/antlr/v4/codegen/BlankOutputModelFactory.java index 982d9869e..b37bf3057 100644 --- a/tool/src/org/antlr/v4/codegen/BlankOutputModelFactory.java +++ b/tool/src/org/antlr/v4/codegen/BlankOutputModelFactory.java @@ -79,9 +79,13 @@ public abstract class BlankOutputModelFactory implements OutputModelFactory { // AST REWRITES - public TreeRewrite treeRewrite(GrammarAST ast, int rewriteLevel) { return null; } + public TreeRewrite treeRewrite(GrammarAST ast) { return null; } - public RewriteTreeStructure rewrite_tree(GrammarAST root, int rewriteLevel) { return null; } + public RewriteTreeOptional rewrite_optional(GrammarAST ast) { return null; } + + public RewriteTreeClosure rewrite_closure(GrammarAST ast) { return null; } + + public RewriteTreeStructure rewrite_tree(GrammarAST root) { return null; } public List rewrite_ruleRef(GrammarAST ID, boolean isRoot) { return null; } diff --git a/tool/src/org/antlr/v4/codegen/CodeGeneratorExtension.java b/tool/src/org/antlr/v4/codegen/CodeGeneratorExtension.java index 823521137..b230a50f4 100644 --- a/tool/src/org/antlr/v4/codegen/CodeGeneratorExtension.java +++ b/tool/src/org/antlr/v4/codegen/CodeGeneratorExtension.java @@ -91,6 +91,10 @@ public class CodeGeneratorExtension { public TreeRewrite treeRewrite(TreeRewrite r) { return r; } + public RewriteTreeOptional rewrite_optional(RewriteTreeOptional o) { return o; } + + public RewriteTreeClosure rewrite_closure(RewriteTreeClosure c) { return c; } + public RewriteTreeStructure rewrite_tree(RewriteTreeStructure t) { return t; } public List rewrite_ruleRef(List ops) { return ops; } diff --git a/tool/src/org/antlr/v4/codegen/DefaultOutputModelFactory.java b/tool/src/org/antlr/v4/codegen/DefaultOutputModelFactory.java index 02a59f789..fedb4ea7e 100644 --- a/tool/src/org/antlr/v4/codegen/DefaultOutputModelFactory.java +++ b/tool/src/org/antlr/v4/codegen/DefaultOutputModelFactory.java @@ -30,7 +30,7 @@ package org.antlr.v4.codegen; import org.antlr.v4.codegen.model.*; -import org.antlr.v4.codegen.model.decl.CodeBlock; +import org.antlr.v4.codegen.model.decl.*; import org.antlr.v4.tool.*; import java.util.*; @@ -93,6 +93,10 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory return currentBlock; } + public int getCodeBlockLevel() { return controller.walker.codeBlockLevel; } + + public int getTreeLevel() { return controller.walker.treeLevel; } + // MISC public static List list(Object... values) { @@ -105,5 +109,13 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory } return x; } + + public Decl getCurrentDeclForName(String name) { + for (Decl d : getCurrentBlock().locals.elements()) { + if ( d.name.equals(name) ) return d; + } + return null; + } + } diff --git a/tool/src/org/antlr/v4/codegen/OutputModelController.java b/tool/src/org/antlr/v4/codegen/OutputModelController.java index 835dd218a..c2eee8272 100644 --- a/tool/src/org/antlr/v4/codegen/OutputModelController.java +++ b/tool/src/org/antlr/v4/codegen/OutputModelController.java @@ -49,6 +49,11 @@ public class OutputModelController implements OutputModelFactory { /** Post-processing CodeGeneratorExtension objects; done in order given. */ public List extensions = new ArrayList(); + /** While walking code in rules, this is set to the tree walker that + * triggers actions. + */ + public SourceGenTriggers walker; + public OutputModelController(OutputModelFactory factory) { this.delegate = factory; } @@ -76,9 +81,9 @@ public class OutputModelController implements OutputModelFactory { GrammarASTAdaptor adaptor = new GrammarASTAdaptor(r.ast.token.getInputStream()); GrammarAST blk = (GrammarAST)r.ast.getFirstChildWithType(ANTLRParser.BLOCK); CommonTreeNodeStream nodes = new CommonTreeNodeStream(adaptor,blk); - SourceGenTriggers genTriggers = new SourceGenTriggers(nodes, this); + walker = new SourceGenTriggers(nodes, this); try { - function.code = DefaultOutputModelFactory.list(genTriggers.block(null, null)); // walk AST of rule alts/elements + function.code = DefaultOutputModelFactory.list(walker.block(null, null)); // walk AST of rule alts/elements } catch (Exception e){ e.printStackTrace(System.err); @@ -278,14 +283,27 @@ public class OutputModelController implements OutputModelFactory { // REWRITES - public TreeRewrite treeRewrite(GrammarAST ast, int rewriteLevel) { - TreeRewrite r = delegate.treeRewrite(ast, rewriteLevel); + public TreeRewrite treeRewrite(GrammarAST ast) { + TreeRewrite r = delegate.treeRewrite(ast); for (CodeGeneratorExtension ext : extensions) r = ext.treeRewrite(r); return r; } - public RewriteTreeStructure rewrite_tree(GrammarAST root, int rewriteLevel) { - RewriteTreeStructure t = delegate.rewrite_tree(root, rewriteLevel); + public RewriteTreeOptional rewrite_optional(GrammarAST ast) { + RewriteTreeOptional o = delegate.rewrite_optional(ast); + for (CodeGeneratorExtension ext : extensions) o = ext.rewrite_optional(o); + return o; + } + + public RewriteTreeClosure rewrite_closure(GrammarAST ast) { + List refs = getElementReferencesShallow(ast); + RewriteTreeClosure c = delegate.rewrite_closure(ast); + for (CodeGeneratorExtension ext : extensions) c = ext.rewrite_closure(c); + return c; + } + + public RewriteTreeStructure rewrite_tree(GrammarAST root) { + RewriteTreeStructure t = delegate.rewrite_tree(root); for (CodeGeneratorExtension ext : extensions) t = ext.rewrite_tree(t); return t; } @@ -323,4 +341,76 @@ public class OutputModelController implements OutputModelFactory { public void setCurrentBlock(CodeBlock blk) { delegate.setCurrentBlock(blk); } public CodeBlock getCurrentBlock() { return delegate.getCurrentBlock(); } + + public int getCodeBlockLevel() { return delegate.getCodeBlockLevel(); } + + public int getTreeLevel() { return delegate.getTreeLevel(); } + + // SUPPORT + + /** Given (('?'|'*') (REWRITE_BLOCK (ALT ...))) return list of element refs at + * top level of REWRITE_BLOCK. + */ + public List getElementReferencesShallow(GrammarAST ebnfRoot) { + if ( ebnfRoot.getType()!=ANTLRParser.CLOSURE && + ebnfRoot.getType()!=ANTLRParser.OPTIONAL ) + { + return null; + } + GrammarAST blkAST = (GrammarAST)ebnfRoot.getChild(0); + if ( blkAST.getType()!=ANTLRParser.REWRITE_BLOCK ) return null; + GrammarAST altAST = (GrammarAST)blkAST.getChild(0); + if ( altAST.getType()!=ANTLRParser.ALT ) return null; + + IntervalSet elementTokenTypes = getRewriteElementTokenTypeSet(); + Alternative alt = getCurrentAlt(); + List elems = new ArrayList(); + for (Object o : altAST.getChildren()) { + GrammarAST ref = (GrammarAST)o; + if ( elementTokenTypes.member(ref.getType()) ) { + boolean imaginary = ref.getType()==ANTLRParser.TOKEN_REF && + !alt.tokenRefs.containsKey(ref.getText()); + if ( !imaginary ) elems.add(ref); + } + } + + return elems; + } + + /** Given (('?'|'*') (REWRITE_BLOCK (ALT ...))) return list of element refs at + * or below toplevel REWRITE_BLOCK. + */ + public List getElementReferencesDeep(GrammarAST ebnfRoot) { + if ( ebnfRoot.getType()!=ANTLRParser.CLOSURE && + ebnfRoot.getType()!=ANTLRParser.OPTIONAL ) + { + return null; + } + GrammarAST blkAST = (GrammarAST)ebnfRoot.getChild(0); + if ( blkAST.getType()!=ANTLRParser.REWRITE_BLOCK ) return null; + GrammarAST altAST = (GrammarAST)blkAST.getChild(0); + if ( altAST.getType()!=ANTLRParser.ALT ) return null; + + List elems = new ArrayList(); + Alternative alt = getCurrentAlt(); + IntervalSet elementTokenTypes = getRewriteElementTokenTypeSet(); + List refs = altAST.getNodesWithType(elementTokenTypes); + if ( refs!=null ) { + for (GrammarAST ref : refs) { + boolean imaginary = ref.getType()==ANTLRParser.TOKEN_REF && + !alt.tokenRefs.containsKey(ref.getText()); + if ( !imaginary ) elems.add(ref); + } + } + return elems; + } + + public IntervalSet getRewriteElementTokenTypeSet() { + IntervalSet elementTokenTypes = new IntervalSet(); + elementTokenTypes.add(ANTLRParser.TOKEN_REF); // might be imaginary + elementTokenTypes.add(ANTLRParser.RULE_REF); + elementTokenTypes.add(ANTLRParser.STRING_LITERAL); + elementTokenTypes.add(ANTLRParser.LABEL); + return elementTokenTypes; + } } diff --git a/tool/src/org/antlr/v4/codegen/OutputModelFactory.java b/tool/src/org/antlr/v4/codegen/OutputModelFactory.java index b94123c5d..487b897f8 100644 --- a/tool/src/org/antlr/v4/codegen/OutputModelFactory.java +++ b/tool/src/org/antlr/v4/codegen/OutputModelFactory.java @@ -98,9 +98,13 @@ public interface OutputModelFactory { // Though dealing with ASTs, we must deal with here since these are // triggered from elements in ANTLR's internal GrammarAST - TreeRewrite treeRewrite(GrammarAST ast, int rewriteLevel); + TreeRewrite treeRewrite(GrammarAST ast); - RewriteTreeStructure rewrite_tree(GrammarAST root, int rewriteLevel); + RewriteTreeOptional rewrite_optional(GrammarAST ast); + + RewriteTreeClosure rewrite_closure(GrammarAST ast); + + RewriteTreeStructure rewrite_tree(GrammarAST root); List rewrite_ruleRef(GrammarAST ID, boolean isRoot); @@ -110,6 +114,8 @@ public interface OutputModelFactory { // CONTEXT MANIPULATION + // TODO: move to controller? + OutputModelObject getRoot(); void setRoot(OutputModelObject root); @@ -129,4 +135,8 @@ public interface OutputModelFactory { void setCurrentBlock(CodeBlock blk); CodeBlock getCurrentBlock(); + + int getCodeBlockLevel(); + + int getTreeLevel(); } diff --git a/tool/src/org/antlr/v4/codegen/ParserASTExtension.java b/tool/src/org/antlr/v4/codegen/ParserASTExtension.java index ca4cde3af..9843c1ad9 100644 --- a/tool/src/org/antlr/v4/codegen/ParserASTExtension.java +++ b/tool/src/org/antlr/v4/codegen/ParserASTExtension.java @@ -45,7 +45,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { @Override public CodeBlockForAlt alternative(CodeBlockForAlt blk) { Alternative alt = factory.getCurrentAlt(); - if ( !alt.hasRewrite() ) blk.addLocalDecl( new RootDecl(factory, 0) ); + if ( !alt.hasRewrite() ) blk.addLocalDecl( new RootDecl(factory) ); return blk; } diff --git a/tool/src/org/antlr/v4/codegen/ParserFactory.java b/tool/src/org/antlr/v4/codegen/ParserFactory.java index e3bdfce84..ba926ac48 100644 --- a/tool/src/org/antlr/v4/codegen/ParserFactory.java +++ b/tool/src/org/antlr/v4/codegen/ParserFactory.java @@ -169,29 +169,49 @@ public class ParserFactory extends DefaultOutputModelFactory { } public boolean needsImplicitLabel(GrammarAST ID, LabeledOp op) { - return op.getLabels().size()==0 && - (getCurrentAlt().tokenRefsInActions.containsKey(ID.getText()) || - getCurrentAlt().ruleRefsInActions.containsKey(ID.getText())); + return op.getLabels().size()==0 && + (getCurrentAlt().tokenRefsInActions.containsKey(ID.getText()) || + getCurrentAlt().ruleRefsInActions.containsKey(ID.getText())); } // AST REWRITE @Override - public TreeRewrite treeRewrite(GrammarAST ast, int rewriteLevel) { - return new TreeRewrite(this, rewriteLevel); + public TreeRewrite treeRewrite(GrammarAST ast) { + return new TreeRewrite(this, getTreeLevel(), getCodeBlockLevel()); } @Override - public RewriteTreeStructure rewrite_tree(GrammarAST root, int rewriteLevel) { - return new RewriteTreeStructure(this, root, rewriteLevel); + public RewriteTreeOptional rewrite_optional(GrammarAST ast) { + List refs = controller.getElementReferencesDeep(ast); + return new RewriteTreeOptional(this, ast); + } + + @Override + public RewriteTreeClosure rewrite_closure(GrammarAST ast) { + RewriteTreeClosure c = + new RewriteTreeClosure(this, ast, getTreeLevel(), getCodeBlockLevel()); + List refs = controller.getElementReferencesShallow(ast); + if ( refs!=null ) { + for (GrammarAST ref : refs) { + RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref); + c.addLocalDecl(d); + c.iteratorDecls.add(d); + RewriteIteratorInit init = new RewriteIteratorInit(this, d); + c.addPreambleOp(init); + } + } + return c; + } + + @Override + public RewriteTreeStructure rewrite_tree(GrammarAST root) { + return new RewriteTreeStructure(this, root, getTreeLevel(), getCodeBlockLevel()); } public List rewrite_ruleRef(GrammarAST ID, boolean isRoot) { - RewriteIteratorDecl d = new RewriteIteratorDecl(this, ID, 0); - getCurrentBlock().addLocalDecl(d); - RewriteIteratorInit init = new RewriteIteratorInit(this, d); - getCurrentBlock().addPreambleOp(init); + RewriteIteratorDecl d = new RewriteIteratorDecl(this, ID); RewriteRuleRef ruleRef; if ( isRoot ) ruleRef = new RewriteRuleRefIsRoot(this, ID, d); else ruleRef = new RewriteRuleRef(this, ID, d); @@ -199,13 +219,12 @@ public class ParserFactory extends DefaultOutputModelFactory { } public List rewrite_tokenRef(GrammarAST ID, boolean isRoot) { - RewriteIteratorDecl d = new RewriteIteratorDecl(this, ID, 0); - getCurrentBlock().addLocalDecl(d); - RewriteIteratorInit init = new RewriteIteratorInit(this, d); - getCurrentBlock().addPreambleOp(init); + String itName = gen.target.getRewriteIteratorName(ID, getCodeBlockLevel()); + String rootName = gen.target.getRootName(getTreeLevel()); + RewriteIteratorDecl d = (RewriteIteratorDecl)getCurrentDeclForName(itName); RewriteTokenRef tokenRef; - if ( isRoot ) tokenRef = new RewriteTokenRefIsRoot(this, ID, d); - else tokenRef = new RewriteTokenRef(this, ID, d); + if ( isRoot ) tokenRef = new RewriteTokenRefIsRoot(this, ID, rootName, d); + else tokenRef = new RewriteTokenRef(this, ID, rootName, d); return list(tokenRef); } diff --git a/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g b/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g index 6a6f05522..254cba465 100644 --- a/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g +++ b/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g @@ -18,7 +18,8 @@ import java.util.HashMap; } @members { - public int codeBlockLevel = 0; + public int codeBlockLevel = -1; + public int treeLevel = -1; public OutputModelFactory factory; public SourceGenTriggers(TreeNodeStream input, OutputModelFactory factory) { this(input); @@ -194,7 +195,9 @@ elementOption rewrite returns [Rewrite code] : { - $code = factory.treeRewrite($start, codeBlockLevel++); + treeLevel = 0; + codeBlockLevel++; + $code = factory.treeRewrite($start); CodeBlock save = factory.getCurrentBlock(); factory.setCurrentBlock($code); } @@ -229,7 +232,7 @@ rewriteTreeAlt returns [List omos] rewriteTreeElement returns [List omos] : rewriteTreeAtom[false] {$omos = $rewriteTreeAtom.omos;} | rewriteTree {$omos = $rewriteTree.omos;} - | rewriteTreeEbnf {$omos = $rewriteTreeEbnf.omos;} + | rewriteTreeEbnf {$omos = DefaultOutputModelFactory.list($rewriteTreeEbnf.op);} ; rewriteTreeAtom[boolean isRoot] returns [List omos] @@ -244,15 +247,32 @@ rewriteTreeAtom[boolean isRoot] returns [List omos] | ACTION ; -rewriteTreeEbnf returns [List omos] - : ^('?' ^(REWRITE_BLOCK rewriteTreeAlt)) - | ^('*' ^(REWRITE_BLOCK rewriteTreeAlt)) +rewriteTreeEbnf returns [CodeBlock op] + : ^( (a=OPTIONAL|a=CLOSURE) + ^( REWRITE_BLOCK + { + codeBlockLevel++; + if ( $a.getType()==OPTIONAL ) $op = factory.rewrite_optional($start); + else $op = factory.rewrite_closure($start); + CodeBlock save = factory.getCurrentBlock(); + factory.setCurrentBlock($op); + } + alt=rewriteTreeAlt + ) + ) + { + $op.addOps($alt.omos); + factory.setCurrentBlock(save); + codeBlockLevel--; + } ; rewriteTree returns [List omos] : { + codeBlockLevel++; + treeLevel++; List elems = new ArrayList(); - RewriteTreeStructure t = factory.rewrite_tree($start, codeBlockLevel++); + RewriteTreeStructure t = factory.rewrite_tree($start); CodeBlock save = factory.getCurrentBlock(); factory.setCurrentBlock(t); } @@ -264,6 +284,7 @@ rewriteTree returns [List omos] t.ops = elems; $omos = DefaultOutputModelFactory.list(t); factory.setCurrentBlock(save); + treeLevel--; codeBlockLevel--; } ; diff --git a/tool/src/org/antlr/v4/codegen/model/Rewrite.java b/tool/src/org/antlr/v4/codegen/model/Rewrite.java index 7de74abe8..5124bcc5c 100644 --- a/tool/src/org/antlr/v4/codegen/model/Rewrite.java +++ b/tool/src/org/antlr/v4/codegen/model/Rewrite.java @@ -33,7 +33,7 @@ import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.model.decl.CodeBlock; public class Rewrite extends CodeBlock { - public Rewrite(OutputModelFactory factory) { - super(factory); + public Rewrite(OutputModelFactory factory, int treeLevel, int codeBlockLevel) { + super(factory, treeLevel, codeBlockLevel); } } diff --git a/tool/src/org/antlr/v4/codegen/model/RuleFunction.java b/tool/src/org/antlr/v4/codegen/model/RuleFunction.java index 9ddff6ff5..ee38d28bd 100644 --- a/tool/src/org/antlr/v4/codegen/model/RuleFunction.java +++ b/tool/src/org/antlr/v4/codegen/model/RuleFunction.java @@ -51,6 +51,7 @@ public class RuleFunction extends OutputModelObject { public ATNState startState; public int index; public Collection args = null; + public Rule rule; @ModelElement public List code; @ModelElement public OrderedHashSet locals; // TODO: move into ctx? @@ -59,13 +60,10 @@ public class RuleFunction extends OutputModelObject { @ModelElement public Action finallyAction; @ModelElement public List postamble; - public RuleFunction(OutputModelFactory factory) { - super(factory); - } - public RuleFunction(OutputModelFactory factory, Rule r) { super(factory); this.name = r.name; + this.rule = r; if ( r.modifiers!=null && r.modifiers.size()>0 ) { this.modifiers = new ArrayList(); for (GrammarAST t : r.modifiers) modifiers.add(t.getText()); diff --git a/tool/src/org/antlr/v4/codegen/model/ast/RewriteTokenRef.java b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTokenRef.java index bce671e78..751e908d0 100644 --- a/tool/src/org/antlr/v4/codegen/model/ast/RewriteTokenRef.java +++ b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTokenRef.java @@ -37,8 +37,12 @@ import org.antlr.v4.tool.GrammarAST; public class RewriteTokenRef extends SrcOp { /** Which iterator decl are we associated with? */ public RewriteIteratorDecl decl; - public RewriteTokenRef(OutputModelFactory factory, GrammarAST ast, RewriteIteratorDecl decl) { + public String rootName; + public RewriteTokenRef(OutputModelFactory factory, GrammarAST ast, + String rootName, RewriteIteratorDecl decl) + { super(factory, ast); + this.rootName = rootName; this.decl = decl; } } diff --git a/tool/src/org/antlr/v4/codegen/model/ast/RewriteTokenRefIsRoot.java b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTokenRefIsRoot.java index f02bb5aef..f2e2f315c 100644 --- a/tool/src/org/antlr/v4/codegen/model/ast/RewriteTokenRefIsRoot.java +++ b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTokenRefIsRoot.java @@ -34,7 +34,9 @@ import org.antlr.v4.codegen.model.decl.RewriteIteratorDecl; import org.antlr.v4.tool.GrammarAST; public class RewriteTokenRefIsRoot extends RewriteTokenRef { - public RewriteTokenRefIsRoot(OutputModelFactory factory, GrammarAST ast, RewriteIteratorDecl decl) { - super(factory, ast, decl); + public RewriteTokenRefIsRoot(OutputModelFactory factory, GrammarAST ast, + String rootName, RewriteIteratorDecl decl) + { + super(factory, ast, rootName, decl); } } diff --git a/tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeClosure.java b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeClosure.java new file mode 100644 index 000000000..bc8252186 --- /dev/null +++ b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeClosure.java @@ -0,0 +1,47 @@ +/* + [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.decl.*; +import org.antlr.v4.tool.GrammarAST; + +import java.util.*; + +public class RewriteTreeClosure extends CodeBlock { + public List iteratorDecls = new ArrayList(); + + public RewriteTreeClosure(OutputModelFactory factory, GrammarAST ast, + int treeLevel, int codeBlockLevel) + { + super(factory, treeLevel, codeBlockLevel); + this.ast = ast; + } +} diff --git a/tool/src/org/antlr/v4/codegen/model/decl/NestedDecl.java b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeOptional.java similarity index 80% rename from tool/src/org/antlr/v4/codegen/model/decl/NestedDecl.java rename to tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeOptional.java index 7c50babe6..fd53095d4 100644 --- a/tool/src/org/antlr/v4/codegen/model/decl/NestedDecl.java +++ b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeOptional.java @@ -27,15 +27,19 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.antlr.v4.codegen.model.decl; +package org.antlr.v4.codegen.model.ast; import org.antlr.v4.codegen.OutputModelFactory; +import org.antlr.v4.codegen.model.decl.*; +import org.antlr.v4.tool.GrammarAST; -public class NestedDecl extends Decl { - public int level; +import java.util.*; - public NestedDecl(OutputModelFactory factory, String name, int level) { - super(factory, name); - this.level = level; +public class RewriteTreeOptional extends CodeBlock { + public List iteratorDecls = new ArrayList(); + + public RewriteTreeOptional(OutputModelFactory factory, GrammarAST ast) { + super(factory); + this.ast = ast; } } diff --git a/tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeStructure.java b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeStructure.java index 71d7bc82c..7a27fdd81 100644 --- a/tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeStructure.java +++ b/tool/src/org/antlr/v4/codegen/model/ast/RewriteTreeStructure.java @@ -34,10 +34,14 @@ import org.antlr.v4.tool.GrammarAST; /** ^(A B C) */ public class RewriteTreeStructure extends TreeRewrite { + public int treeLevel; + public RewriteTreeStructure(OutputModelFactory factory, GrammarAST ast, - int level) + int treeLevel, + int codeBlockLevel) { - super(factory, level); + super(factory, treeLevel, codeBlockLevel); + this.treeLevel = treeLevel; } } diff --git a/tool/src/org/antlr/v4/codegen/model/ast/TreeRewrite.java b/tool/src/org/antlr/v4/codegen/model/ast/TreeRewrite.java index e7302d77e..b77cabd37 100644 --- a/tool/src/org/antlr/v4/codegen/model/ast/TreeRewrite.java +++ b/tool/src/org/antlr/v4/codegen/model/ast/TreeRewrite.java @@ -34,13 +34,11 @@ import org.antlr.v4.codegen.model.Rewrite; import org.antlr.v4.codegen.model.decl.RootDecl; public class TreeRewrite extends Rewrite { - public int level; public RootDecl rootDecl; - public TreeRewrite(OutputModelFactory factory, int level) { - super(factory); - this.level = level; - rootDecl = new RootDecl(factory, level); // track here too for easy access in template + public TreeRewrite(OutputModelFactory factory, int treeLevel, int codeBlockLevel) { + super(factory, treeLevel, codeBlockLevel); + rootDecl = new RootDecl(factory); addLocalDecl(rootDecl); } } diff --git a/tool/src/org/antlr/v4/codegen/model/decl/CodeBlock.java b/tool/src/org/antlr/v4/codegen/model/decl/CodeBlock.java index eaa30b213..e19933191 100644 --- a/tool/src/org/antlr/v4/codegen/model/decl/CodeBlock.java +++ b/tool/src/org/antlr/v4/codegen/model/decl/CodeBlock.java @@ -36,6 +36,9 @@ import org.antlr.v4.runtime.misc.OrderedHashSet; import java.util.*; public class CodeBlock extends SrcOp { + public int codeBlockLevel; + public int treeLevel; + @ModelElement public OrderedHashSet locals; @ModelElement public List preamble; @ModelElement public List ops; @@ -44,6 +47,12 @@ public class CodeBlock extends SrcOp { super(factory); } + public CodeBlock(OutputModelFactory factory, int treeLevel, int codeBlockLevel) { + super(factory); + this.treeLevel = treeLevel; + this.codeBlockLevel = codeBlockLevel; + } + /** Add local var decl */ public void addLocalDecl(Decl d) { if ( locals==null ) locals = new OrderedHashSet(); @@ -60,4 +69,9 @@ public class CodeBlock extends SrcOp { if ( ops==null ) ops = new ArrayList(); ops.add(op); } + + public void addOps(List ops) { + if ( this.ops==null ) this.ops = new ArrayList(); + this.ops.addAll(ops); + } } diff --git a/tool/src/org/antlr/v4/codegen/model/decl/RewriteIteratorDecl.java b/tool/src/org/antlr/v4/codegen/model/decl/RewriteIteratorDecl.java index 34dc5dd42..6f987b913 100644 --- a/tool/src/org/antlr/v4/codegen/model/decl/RewriteIteratorDecl.java +++ b/tool/src/org/antlr/v4/codegen/model/decl/RewriteIteratorDecl.java @@ -32,10 +32,13 @@ package org.antlr.v4.codegen.model.decl; import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.tool.GrammarAST; -public class RewriteIteratorDecl extends NestedDecl { +public class RewriteIteratorDecl extends Decl { public String listName; - public RewriteIteratorDecl(OutputModelFactory factory, GrammarAST elem, int level) { - super(factory, factory.getGenerator().target.getRewriteIteratorName(elem, level), level); + public RewriteIteratorDecl(OutputModelFactory factory, + GrammarAST elem) + { + super(factory, factory.getGenerator().target + .getRewriteIteratorName(elem, factory.getCodeBlockLevel())); listName = factory.getGenerator().target.getElementListName(elem); } } diff --git a/tool/src/org/antlr/v4/codegen/model/decl/RootDecl.java b/tool/src/org/antlr/v4/codegen/model/decl/RootDecl.java index fd4f51dc9..9c234437e 100644 --- a/tool/src/org/antlr/v4/codegen/model/decl/RootDecl.java +++ b/tool/src/org/antlr/v4/codegen/model/decl/RootDecl.java @@ -31,8 +31,9 @@ package org.antlr.v4.codegen.model.decl; import org.antlr.v4.codegen.OutputModelFactory; -public class RootDecl extends NestedDecl { - public RootDecl(OutputModelFactory factory, int level) { - super(factory, factory.getGenerator().target.getRootName(level), level); +public class RootDecl extends Decl { + public RootDecl(OutputModelFactory factory) { + super(factory, + factory.getGenerator().target.getRootName(factory.getCodeBlockLevel())); } } diff --git a/tool/src/org/antlr/v4/tool/Rule.java b/tool/src/org/antlr/v4/tool/Rule.java index 546c9447f..adf20f9f8 100644 --- a/tool/src/org/antlr/v4/tool/Rule.java +++ b/tool/src/org/antlr/v4/tool/Rule.java @@ -159,7 +159,6 @@ public class Rule implements AttributeResolver { return refs; } - // TODO: called frequently; make it more efficient public MultiMap getLabelDefs() { MultiMap defs = new MultiMap();