From 39fe27dd1f8b714f4c7ad6cedf938b793e43f01c Mon Sep 17 00:00:00 2001 From: parrt Date: Tue, 12 Jul 2011 10:21:34 -0800 Subject: [PATCH] fixed outer most vs inner alt issue [git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8853] --- tool/playground/T.g | 2 +- .../v4/codegen/CodeGeneratorExtension.java | 4 +-- .../v4/codegen/DefaultOutputModelFactory.java | 4 +-- .../v4/codegen/OutputModelController.java | 27 +++++++++-------- .../antlr/v4/codegen/OutputModelFactory.java | 4 +-- .../antlr/v4/codegen/ParserASTExtension.java | 30 ++++++++++--------- .../org/antlr/v4/codegen/ParserFactory.java | 12 ++++---- .../org/antlr/v4/codegen/SourceGenTriggers.g | 13 ++++---- .../antlr/v4/codegen/model/InvokeRule.java | 2 +- 9 files changed, 51 insertions(+), 47 deletions(-) diff --git a/tool/playground/T.g b/tool/playground/T.g index 58ac53707..3dc7442f0 100644 --- a/tool/playground/T.g +++ b/tool/playground/T.g @@ -1,7 +1,7 @@ grammar T; options {output=AST;} -a: b {int x = $b.i;} ; +a : (ID INT) ; b returns [int i] : ID; ID : 'a'..'z'+ ; INT : '0'..'9'+; diff --git a/tool/src/org/antlr/v4/codegen/CodeGeneratorExtension.java b/tool/src/org/antlr/v4/codegen/CodeGeneratorExtension.java index 65ce3b7e2..ae20b7ac5 100644 --- a/tool/src/org/antlr/v4/codegen/CodeGeneratorExtension.java +++ b/tool/src/org/antlr/v4/codegen/CodeGeneratorExtension.java @@ -56,9 +56,9 @@ public class CodeGeneratorExtension { public List rulePostamble(List ops) { return ops; } - public CodeBlockForAlt alternative(CodeBlockForAlt blk) { return blk; } + public CodeBlockForAlt alternative(CodeBlockForAlt blk, boolean outerMost) { return blk; } - public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk) { return blk; } + public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, boolean outerMost) { return blk; } public CodeBlockForAlt epsilon(CodeBlockForAlt blk) { return blk; } diff --git a/tool/src/org/antlr/v4/codegen/DefaultOutputModelFactory.java b/tool/src/org/antlr/v4/codegen/DefaultOutputModelFactory.java index 30b2551bf..e798d0941 100644 --- a/tool/src/org/antlr/v4/codegen/DefaultOutputModelFactory.java +++ b/tool/src/org/antlr/v4/codegen/DefaultOutputModelFactory.java @@ -65,11 +65,11 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory public RuleFunction getCurrentRuleFunction() { return controller.getCurrentRuleFunction(); } - public Alternative getCurrentAlt() { return controller.getCurrentAlt(); } + public Alternative getCurrentOuterMostAlt() { return controller.getCurrentOuterMostAlt(); } public CodeBlock getCurrentBlock() { return controller.getCurrentBlock(); } - public CodeBlock getCurrentAlternativeBlock() { return controller.getCurrentAlternativeBlock(); } + public CodeBlock getCurrentOuterMostAlternativeBlock() { return controller.getCurrentOuterMostAlternativeBlock(); } public int getCodeBlockLevel() { return controller.codeBlockLevel; } diff --git a/tool/src/org/antlr/v4/codegen/OutputModelController.java b/tool/src/org/antlr/v4/codegen/OutputModelController.java index e60d608a0..069912100 100644 --- a/tool/src/org/antlr/v4/codegen/OutputModelController.java +++ b/tool/src/org/antlr/v4/codegen/OutputModelController.java @@ -58,9 +58,9 @@ public class OutputModelController { public int treeLevel = -1; public OutputModelObject root; // normally ParserFile, LexerFile, ... public Stack currentRule = new Stack(); - public Alternative currentAlt; + public Alternative currentOuterMostAlt; public CodeBlock currentBlock; - public CodeBlock currentAlternativeBlock; + public CodeBlock currentOuterMostAlternativeBlock; public OutputModelController(OutputModelFactory factory) { @@ -154,15 +154,18 @@ public class OutputModelController { public CodeGenerator getGenerator() { return delegate.getGenerator(); } - public CodeBlockForAlt alternative(Alternative alt) { + public CodeBlockForAlt alternative(Alternative alt, boolean outerMost) { CodeBlockForAlt blk = delegate.alternative(alt); - for (CodeGeneratorExtension ext : extensions) blk = ext.alternative(blk); + if ( outerMost ) currentOuterMostAlternativeBlock = blk; + for (CodeGeneratorExtension ext : extensions) blk = ext.alternative(blk, outerMost); return blk; } - public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, List ops) { + public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, List ops, + boolean outerMost) + { blk = delegate.finishAlternative(blk, ops); - for (CodeGeneratorExtension ext : extensions) blk = ext.finishAlternative(blk); + for (CodeGeneratorExtension ext : extensions) blk = ext.finishAlternative(blk, outerMost); return blk; } @@ -356,9 +359,9 @@ public class OutputModelController { return null; } - public Alternative getCurrentAlt() { return currentAlt; } + public Alternative getCurrentOuterMostAlt() { return currentOuterMostAlt; } - public void setCurrentAlt(Alternative currentAlt) { this.currentAlt = currentAlt; } + public void setCurrentOuterMostAlt(Alternative currentOuterMostAlt) { this.currentOuterMostAlt = currentOuterMostAlt; } public void setCurrentBlock(CodeBlock blk) { currentBlock = blk; @@ -368,12 +371,12 @@ public class OutputModelController { return currentBlock; } - public void setCurrentAlternativeBlock(CodeBlock currentAlternativeBlock) { - this.currentAlternativeBlock = currentAlternativeBlock; + public void setCurrentOuterMostAlternativeBlock(CodeBlock currentOuterMostAlternativeBlock) { + this.currentOuterMostAlternativeBlock = currentOuterMostAlternativeBlock; } - public CodeBlock getCurrentAlternativeBlock() { - return currentAlternativeBlock; + public CodeBlock getCurrentOuterMostAlternativeBlock() { + return currentOuterMostAlternativeBlock; } public int getCodeBlockLevel() { return codeBlockLevel; } diff --git a/tool/src/org/antlr/v4/codegen/OutputModelFactory.java b/tool/src/org/antlr/v4/codegen/OutputModelFactory.java index aef343527..d4d7dc2e7 100644 --- a/tool/src/org/antlr/v4/codegen/OutputModelFactory.java +++ b/tool/src/org/antlr/v4/codegen/OutputModelFactory.java @@ -130,11 +130,11 @@ public interface OutputModelFactory { RuleFunction getCurrentRuleFunction(); - Alternative getCurrentAlt(); + Alternative getCurrentOuterMostAlt(); CodeBlock getCurrentBlock(); - CodeBlock getCurrentAlternativeBlock(); + CodeBlock getCurrentOuterMostAlternativeBlock(); int getCodeBlockLevel(); diff --git a/tool/src/org/antlr/v4/codegen/ParserASTExtension.java b/tool/src/org/antlr/v4/codegen/ParserASTExtension.java index 880f783db..d74e48800 100644 --- a/tool/src/org/antlr/v4/codegen/ParserASTExtension.java +++ b/tool/src/org/antlr/v4/codegen/ParserASTExtension.java @@ -47,7 +47,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { @Override public List getChoiceBlock(List ops) { Choice choice = (Choice)Utils.find(ops, Choice.class); - Alternative alt = factory.getCurrentAlt(); + Alternative alt = factory.getCurrentOuterMostAlt(); if ( alt.hasRewrite() && choice.label!=null ) { trackExplicitLabel(choice.preamble, choice.label, choice); } @@ -55,15 +55,17 @@ public class ParserASTExtension extends CodeGeneratorExtension { } @Override - public CodeBlockForAlt alternative(CodeBlockForAlt blk) { - Alternative alt = factory.getCurrentAlt(); - if ( !alt.hasRewrite() ) factory.getCurrentRuleFunction().addLocalDecl( new RootDecl(factory, 0) ); + public CodeBlockForAlt alternative(CodeBlockForAlt blk, boolean outerMost) { + Alternative alt = factory.getCurrentOuterMostAlt(); + if ( outerMost && !alt.hasRewrite() ) { + blk.addLocalDecl(new RootDecl(factory, 0)); + } return blk; } @Override - public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk) { - Alternative alt = factory.getCurrentAlt(); + public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, boolean outerMost) { + Alternative alt = factory.getCurrentOuterMostAlt(); if ( !alt.hasRewrite() ) blk.addOp(new AssignTreeResult(factory)); return blk; } @@ -76,7 +78,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { @Override public List rootRule(List ops) { - Alternative alt = factory.getCurrentAlt(); + Alternative alt = factory.getCurrentOuterMostAlt(); if ( alt.hasRewrite() ) { return ops; } @@ -92,7 +94,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { @Override public List leafRule(List ops) { InvokeRule invokeOp = (InvokeRule)Utils.find(ops, InvokeRule.class); - Alternative alt = factory.getCurrentAlt(); + Alternative alt = factory.getCurrentOuterMostAlt(); if ( alt.hasRewrite() ) { return leafRuleInRewriteAlt(invokeOp, ops); } @@ -108,7 +110,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { @Override public List rootToken(List ops) { - Alternative alt = factory.getCurrentAlt(); + Alternative alt = factory.getCurrentOuterMostAlt(); if ( alt.hasRewrite() ) { return ops; } @@ -124,7 +126,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { @Override public List leafToken(List ops) { MatchToken matchOp = (MatchToken)Utils.find(ops, MatchToken.class); - Alternative alt = factory.getCurrentAlt(); + Alternative alt = factory.getCurrentOuterMostAlt(); if ( alt.hasRewrite() ) { return leafTokenInRewriteAlt(matchOp, ops); } @@ -146,7 +148,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { public List leafRuleInRewriteAlt(InvokeRule invokeOp, List ops) { RuleContextDecl label = (RuleContextDecl)invokeOp.getLabels().get(0); - CodeBlock blk = factory.getCurrentAlternativeBlock(); + CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock(); String elemListName = factory.getGenerator().target.getElementListName(invokeOp.ast.getText()); blk.addLocalDecl(new ElementListDecl(factory, elemListName)); @@ -162,7 +164,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { } public List leafTokenInRewriteAlt(SrcOp matchOp, List ops) { - CodeBlock blk = factory.getCurrentAlternativeBlock(); + CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock(); TokenDecl label = (TokenDecl)((LabeledOp)matchOp).getLabels().get(0); // First declare tracking lists for elements, labels // track the named element like _track_A @@ -181,7 +183,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { @Override public List wildcard(List ops) { Wildcard wild = (Wildcard)Utils.find(ops, Wildcard.class); - Alternative alt = factory.getCurrentAlt(); + Alternative alt = factory.getCurrentOuterMostAlt(); if ( alt.hasRewrite() ) { TokenDecl label = (TokenDecl)((LabeledOp)wild).getLabels().get(0); if ( !label.isImplicit ) trackExplicitLabel(ops, label, wild); @@ -198,7 +200,7 @@ public class ParserASTExtension extends CodeGeneratorExtension { } public void trackExplicitLabel(List ops, Decl label, SrcOp opWithLabel) { - CodeBlock blk = factory.getCurrentAlternativeBlock(); + CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock(); // declare _track_label String labelListName = factory.getGenerator().target.getElementListName(label.name); diff --git a/tool/src/org/antlr/v4/codegen/ParserFactory.java b/tool/src/org/antlr/v4/codegen/ParserFactory.java index 694301fc8..23961631c 100644 --- a/tool/src/org/antlr/v4/codegen/ParserFactory.java +++ b/tool/src/org/antlr/v4/codegen/ParserFactory.java @@ -218,8 +218,8 @@ 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())); + (getCurrentOuterMostAlt().tokenRefsInActions.containsKey(ID.getText()) || + getCurrentOuterMostAlt().ruleRefsInActions.containsKey(ID.getText())); } // AST REWRITE @@ -231,7 +231,7 @@ public class ParserFactory extends DefaultOutputModelFactory { tr.addLocalDecl(new RootDecl(this, 0)); List refs = UseDefAnalyzer.getElementReferencesShallowInOuterAlt(getGrammar(), ast); - refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentAlt(), refs); + refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentOuterMostAlt(), refs); if ( refs!=null ) { for (GrammarAST ref : refs) { RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel()); @@ -258,7 +258,7 @@ public class ParserFactory extends DefaultOutputModelFactory { List refs = UseDefAnalyzer.getElementReferencesInEBNF(getGrammar(), ast, true); - refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentAlt(), refs); + refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentOuterMostAlt(), refs); if ( refs!=null ) { for (GrammarAST ref : refs) { RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel()); @@ -278,7 +278,7 @@ public class ParserFactory extends DefaultOutputModelFactory { List refs = UseDefAnalyzer.getElementReferencesInEBNF(getGrammar(), ast, false); - refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentAlt(), refs); + refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentOuterMostAlt(), refs); if ( refs!=null ) { for (GrammarAST ref : refs) { RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel()); @@ -305,7 +305,7 @@ public class ParserFactory extends DefaultOutputModelFactory { } public List rewrite_tokenRef(GrammarAST ID, boolean isRoot, ActionAST argAST) { - Alternative alt = getCurrentAlt(); + Alternative alt = getCurrentOuterMostAlt(); String iterName = gen.target.getRewriteIteratorName(ID, getCodeBlockLevel()); // not ref'd on left hand side or it is but we have an argument like ID["x"] // implies create new node diff --git a/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g b/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g index f6aeb4b1d..2e3042c37 100644 --- a/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g +++ b/tool/src/org/antlr/v4/codegen/SourceGenTriggers.g @@ -32,7 +32,8 @@ block[GrammarAST label, GrammarAST ebnfRoot, GrammarAST astOp] returns [List alts = new ArrayList();} ( alternative { - controller.finishAlternative($alternative.altCodeBlock, $alternative.ops); + boolean outerMost = inContext("RULE BLOCK") || inContext("RULE BLOCK ALT_REWRITE"); + controller.finishAlternative($alternative.altCodeBlock, $alternative.ops, outerMost); alts.add($alternative.altCodeBlock); } )+ @@ -52,7 +53,7 @@ alternative returns [CodeBlockForAlt altCodeBlock, List ops] @init { // set alt if outer ALT only if ( inContext("RULE BLOCK") && ((AltAST)$start).alt!=null ) { - controller.setCurrentAlt(((AltAST)$start).alt); + controller.setCurrentOuterMostAlt(((AltAST)$start).alt); } } : ^(ALT_REWRITE @@ -67,12 +68,10 @@ alternative returns [CodeBlockForAlt altCodeBlock, List ops] | { List elems = new ArrayList(); - $altCodeBlock = controller.alternative(controller.getCurrentAlt()); - $ops = elems; + boolean outerMost = inContext("RULE BLOCK") || inContext("RULE BLOCK ALT_REWRITE"); + $altCodeBlock = controller.alternative(controller.getCurrentOuterMostAlt(), outerMost); + $altCodeBlock.ops = $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);} )+ ) ; diff --git a/tool/src/org/antlr/v4/codegen/model/InvokeRule.java b/tool/src/org/antlr/v4/codegen/model/InvokeRule.java index de2215d3b..0da869b0a 100644 --- a/tool/src/org/antlr/v4/codegen/model/InvokeRule.java +++ b/tool/src/org/antlr/v4/codegen/model/InvokeRule.java @@ -75,7 +75,7 @@ public class InvokeRule extends RuleElement implements LabeledOp { } // If action refs rule as rulename not label, we need to define implicit label - if ( factory.getCurrentAlt().ruleRefsInActions.containsKey(ast.getText()) ) { + if ( factory.getCurrentOuterMostAlt().ruleRefsInActions.containsKey(ast.getText()) ) { String label = gen.target.getImplicitRuleLabel(ast.getText()); RuleContextDecl d = new RuleContextDecl(factory,label,ctxName); labels.add(d);