fixed outer most vs inner alt issue

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8853]
This commit is contained in:
parrt 2011-07-12 10:21:34 -08:00
parent 59178d9959
commit 39fe27dd1f
9 changed files with 51 additions and 47 deletions

View File

@ -1,7 +1,7 @@
grammar T; grammar T;
options {output=AST;} options {output=AST;}
a: b {int x = $b.i;} ; a : (ID INT) ;
b returns [int i] : ID; b returns [int i] : ID;
ID : 'a'..'z'+ ; ID : 'a'..'z'+ ;
INT : '0'..'9'+; INT : '0'..'9'+;

View File

@ -56,9 +56,9 @@ public class CodeGeneratorExtension {
public List<SrcOp> rulePostamble(List<SrcOp> ops) { return ops; } public List<SrcOp> rulePostamble(List<SrcOp> 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; } public CodeBlockForAlt epsilon(CodeBlockForAlt blk) { return blk; }

View File

@ -65,11 +65,11 @@ public abstract class DefaultOutputModelFactory extends BlankOutputModelFactory
public RuleFunction getCurrentRuleFunction() { return controller.getCurrentRuleFunction(); } 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 getCurrentBlock() { return controller.getCurrentBlock(); }
public CodeBlock getCurrentAlternativeBlock() { return controller.getCurrentAlternativeBlock(); } public CodeBlock getCurrentOuterMostAlternativeBlock() { return controller.getCurrentOuterMostAlternativeBlock(); }
public int getCodeBlockLevel() { return controller.codeBlockLevel; } public int getCodeBlockLevel() { return controller.codeBlockLevel; }

View File

@ -58,9 +58,9 @@ public class OutputModelController {
public int treeLevel = -1; public int treeLevel = -1;
public OutputModelObject root; // normally ParserFile, LexerFile, ... public OutputModelObject root; // normally ParserFile, LexerFile, ...
public Stack<RuleFunction> currentRule = new Stack<RuleFunction>(); public Stack<RuleFunction> currentRule = new Stack<RuleFunction>();
public Alternative currentAlt; public Alternative currentOuterMostAlt;
public CodeBlock currentBlock; public CodeBlock currentBlock;
public CodeBlock currentAlternativeBlock; public CodeBlock currentOuterMostAlternativeBlock;
public OutputModelController(OutputModelFactory factory) { public OutputModelController(OutputModelFactory factory) {
@ -154,15 +154,18 @@ public class OutputModelController {
public CodeGenerator getGenerator() { return delegate.getGenerator(); } public CodeGenerator getGenerator() { return delegate.getGenerator(); }
public CodeBlockForAlt alternative(Alternative alt) { public CodeBlockForAlt alternative(Alternative alt, boolean outerMost) {
CodeBlockForAlt blk = delegate.alternative(alt); 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; return blk;
} }
public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, List<SrcOp> ops) { public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, List<SrcOp> ops,
boolean outerMost)
{
blk = delegate.finishAlternative(blk, ops); blk = delegate.finishAlternative(blk, ops);
for (CodeGeneratorExtension ext : extensions) blk = ext.finishAlternative(blk); for (CodeGeneratorExtension ext : extensions) blk = ext.finishAlternative(blk, outerMost);
return blk; return blk;
} }
@ -356,9 +359,9 @@ public class OutputModelController {
return null; 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) { public void setCurrentBlock(CodeBlock blk) {
currentBlock = blk; currentBlock = blk;
@ -368,12 +371,12 @@ public class OutputModelController {
return currentBlock; return currentBlock;
} }
public void setCurrentAlternativeBlock(CodeBlock currentAlternativeBlock) { public void setCurrentOuterMostAlternativeBlock(CodeBlock currentOuterMostAlternativeBlock) {
this.currentAlternativeBlock = currentAlternativeBlock; this.currentOuterMostAlternativeBlock = currentOuterMostAlternativeBlock;
} }
public CodeBlock getCurrentAlternativeBlock() { public CodeBlock getCurrentOuterMostAlternativeBlock() {
return currentAlternativeBlock; return currentOuterMostAlternativeBlock;
} }
public int getCodeBlockLevel() { return codeBlockLevel; } public int getCodeBlockLevel() { return codeBlockLevel; }

View File

@ -130,11 +130,11 @@ public interface OutputModelFactory {
RuleFunction getCurrentRuleFunction(); RuleFunction getCurrentRuleFunction();
Alternative getCurrentAlt(); Alternative getCurrentOuterMostAlt();
CodeBlock getCurrentBlock(); CodeBlock getCurrentBlock();
CodeBlock getCurrentAlternativeBlock(); CodeBlock getCurrentOuterMostAlternativeBlock();
int getCodeBlockLevel(); int getCodeBlockLevel();

View File

@ -47,7 +47,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
@Override @Override
public List<SrcOp> getChoiceBlock(List<SrcOp> ops) { public List<SrcOp> getChoiceBlock(List<SrcOp> ops) {
Choice choice = (Choice)Utils.find(ops, Choice.class); Choice choice = (Choice)Utils.find(ops, Choice.class);
Alternative alt = factory.getCurrentAlt(); Alternative alt = factory.getCurrentOuterMostAlt();
if ( alt.hasRewrite() && choice.label!=null ) { if ( alt.hasRewrite() && choice.label!=null ) {
trackExplicitLabel(choice.preamble, choice.label, choice); trackExplicitLabel(choice.preamble, choice.label, choice);
} }
@ -55,15 +55,17 @@ public class ParserASTExtension extends CodeGeneratorExtension {
} }
@Override @Override
public CodeBlockForAlt alternative(CodeBlockForAlt blk) { public CodeBlockForAlt alternative(CodeBlockForAlt blk, boolean outerMost) {
Alternative alt = factory.getCurrentAlt(); Alternative alt = factory.getCurrentOuterMostAlt();
if ( !alt.hasRewrite() ) factory.getCurrentRuleFunction().addLocalDecl( new RootDecl(factory, 0) ); if ( outerMost && !alt.hasRewrite() ) {
blk.addLocalDecl(new RootDecl(factory, 0));
}
return blk; return blk;
} }
@Override @Override
public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk) { public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, boolean outerMost) {
Alternative alt = factory.getCurrentAlt(); Alternative alt = factory.getCurrentOuterMostAlt();
if ( !alt.hasRewrite() ) blk.addOp(new AssignTreeResult(factory)); if ( !alt.hasRewrite() ) blk.addOp(new AssignTreeResult(factory));
return blk; return blk;
} }
@ -76,7 +78,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
@Override @Override
public List<SrcOp> rootRule(List<SrcOp> ops) { public List<SrcOp> rootRule(List<SrcOp> ops) {
Alternative alt = factory.getCurrentAlt(); Alternative alt = factory.getCurrentOuterMostAlt();
if ( alt.hasRewrite() ) { if ( alt.hasRewrite() ) {
return ops; return ops;
} }
@ -92,7 +94,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
@Override @Override
public List<SrcOp> leafRule(List<SrcOp> ops) { public List<SrcOp> leafRule(List<SrcOp> ops) {
InvokeRule invokeOp = (InvokeRule)Utils.find(ops, InvokeRule.class); InvokeRule invokeOp = (InvokeRule)Utils.find(ops, InvokeRule.class);
Alternative alt = factory.getCurrentAlt(); Alternative alt = factory.getCurrentOuterMostAlt();
if ( alt.hasRewrite() ) { if ( alt.hasRewrite() ) {
return leafRuleInRewriteAlt(invokeOp, ops); return leafRuleInRewriteAlt(invokeOp, ops);
} }
@ -108,7 +110,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
@Override @Override
public List<SrcOp> rootToken(List<SrcOp> ops) { public List<SrcOp> rootToken(List<SrcOp> ops) {
Alternative alt = factory.getCurrentAlt(); Alternative alt = factory.getCurrentOuterMostAlt();
if ( alt.hasRewrite() ) { if ( alt.hasRewrite() ) {
return ops; return ops;
} }
@ -124,7 +126,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
@Override @Override
public List<SrcOp> leafToken(List<SrcOp> ops) { public List<SrcOp> leafToken(List<SrcOp> ops) {
MatchToken matchOp = (MatchToken)Utils.find(ops, MatchToken.class); MatchToken matchOp = (MatchToken)Utils.find(ops, MatchToken.class);
Alternative alt = factory.getCurrentAlt(); Alternative alt = factory.getCurrentOuterMostAlt();
if ( alt.hasRewrite() ) { if ( alt.hasRewrite() ) {
return leafTokenInRewriteAlt(matchOp, ops); return leafTokenInRewriteAlt(matchOp, ops);
} }
@ -146,7 +148,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
public List<SrcOp> leafRuleInRewriteAlt(InvokeRule invokeOp, List<SrcOp> ops) { public List<SrcOp> leafRuleInRewriteAlt(InvokeRule invokeOp, List<SrcOp> ops) {
RuleContextDecl label = (RuleContextDecl)invokeOp.getLabels().get(0); RuleContextDecl label = (RuleContextDecl)invokeOp.getLabels().get(0);
CodeBlock blk = factory.getCurrentAlternativeBlock(); CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock();
String elemListName = factory.getGenerator().target.getElementListName(invokeOp.ast.getText()); String elemListName = factory.getGenerator().target.getElementListName(invokeOp.ast.getText());
blk.addLocalDecl(new ElementListDecl(factory, elemListName)); blk.addLocalDecl(new ElementListDecl(factory, elemListName));
@ -162,7 +164,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
} }
public List<SrcOp> leafTokenInRewriteAlt(SrcOp matchOp, List<SrcOp> ops) { public List<SrcOp> leafTokenInRewriteAlt(SrcOp matchOp, List<SrcOp> ops) {
CodeBlock blk = factory.getCurrentAlternativeBlock(); CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock();
TokenDecl label = (TokenDecl)((LabeledOp)matchOp).getLabels().get(0); TokenDecl label = (TokenDecl)((LabeledOp)matchOp).getLabels().get(0);
// First declare tracking lists for elements, labels // First declare tracking lists for elements, labels
// track the named element like _track_A // track the named element like _track_A
@ -181,7 +183,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
@Override @Override
public List<SrcOp> wildcard(List<SrcOp> ops) { public List<SrcOp> wildcard(List<SrcOp> ops) {
Wildcard wild = (Wildcard)Utils.find(ops, Wildcard.class); Wildcard wild = (Wildcard)Utils.find(ops, Wildcard.class);
Alternative alt = factory.getCurrentAlt(); Alternative alt = factory.getCurrentOuterMostAlt();
if ( alt.hasRewrite() ) { if ( alt.hasRewrite() ) {
TokenDecl label = (TokenDecl)((LabeledOp)wild).getLabels().get(0); TokenDecl label = (TokenDecl)((LabeledOp)wild).getLabels().get(0);
if ( !label.isImplicit ) trackExplicitLabel(ops, label, wild); if ( !label.isImplicit ) trackExplicitLabel(ops, label, wild);
@ -198,7 +200,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
} }
public void trackExplicitLabel(List<SrcOp> ops, Decl label, SrcOp opWithLabel) { public void trackExplicitLabel(List<SrcOp> ops, Decl label, SrcOp opWithLabel) {
CodeBlock blk = factory.getCurrentAlternativeBlock(); CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock();
// declare _track_label // declare _track_label
String labelListName = String labelListName =
factory.getGenerator().target.getElementListName(label.name); factory.getGenerator().target.getElementListName(label.name);

View File

@ -218,8 +218,8 @@ public class ParserFactory extends DefaultOutputModelFactory {
public boolean needsImplicitLabel(GrammarAST ID, LabeledOp op) { public boolean needsImplicitLabel(GrammarAST ID, LabeledOp op) {
return op.getLabels().size()==0 && return op.getLabels().size()==0 &&
(getCurrentAlt().tokenRefsInActions.containsKey(ID.getText()) || (getCurrentOuterMostAlt().tokenRefsInActions.containsKey(ID.getText()) ||
getCurrentAlt().ruleRefsInActions.containsKey(ID.getText())); getCurrentOuterMostAlt().ruleRefsInActions.containsKey(ID.getText()));
} }
// AST REWRITE // AST REWRITE
@ -231,7 +231,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
tr.addLocalDecl(new RootDecl(this, 0)); tr.addLocalDecl(new RootDecl(this, 0));
List<GrammarAST> refs = List<GrammarAST> refs =
UseDefAnalyzer.getElementReferencesShallowInOuterAlt(getGrammar(), ast); UseDefAnalyzer.getElementReferencesShallowInOuterAlt(getGrammar(), ast);
refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentAlt(), refs); refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentOuterMostAlt(), refs);
if ( refs!=null ) { if ( refs!=null ) {
for (GrammarAST ref : refs) { for (GrammarAST ref : refs) {
RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel()); RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel());
@ -258,7 +258,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
List<GrammarAST> refs = UseDefAnalyzer.getElementReferencesInEBNF(getGrammar(), List<GrammarAST> refs = UseDefAnalyzer.getElementReferencesInEBNF(getGrammar(),
ast, ast,
true); true);
refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentAlt(), refs); refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentOuterMostAlt(), refs);
if ( refs!=null ) { if ( refs!=null ) {
for (GrammarAST ref : refs) { for (GrammarAST ref : refs) {
RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel()); RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel());
@ -278,7 +278,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
List<GrammarAST> refs = UseDefAnalyzer.getElementReferencesInEBNF(getGrammar(), List<GrammarAST> refs = UseDefAnalyzer.getElementReferencesInEBNF(getGrammar(),
ast, ast,
false); false);
refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentAlt(), refs); refs = UseDefAnalyzer.filterForRuleAndTokenRefs(getCurrentOuterMostAlt(), refs);
if ( refs!=null ) { if ( refs!=null ) {
for (GrammarAST ref : refs) { for (GrammarAST ref : refs) {
RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel()); RewriteIteratorDecl d = new RewriteIteratorDecl(this, ref, getCodeBlockLevel());
@ -305,7 +305,7 @@ public class ParserFactory extends DefaultOutputModelFactory {
} }
public List<SrcOp> rewrite_tokenRef(GrammarAST ID, boolean isRoot, ActionAST argAST) { public List<SrcOp> rewrite_tokenRef(GrammarAST ID, boolean isRoot, ActionAST argAST) {
Alternative alt = getCurrentAlt(); Alternative alt = getCurrentOuterMostAlt();
String iterName = gen.target.getRewriteIteratorName(ID, getCodeBlockLevel()); 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"] // not ref'd on left hand side or it is but we have an argument like ID["x"]
// implies create new node // implies create new node

View File

@ -32,7 +32,8 @@ block[GrammarAST label, GrammarAST ebnfRoot, GrammarAST astOp] returns [List<? e
{List<CodeBlockForAlt> alts = new ArrayList<CodeBlockForAlt>();} {List<CodeBlockForAlt> alts = new ArrayList<CodeBlockForAlt>();}
( alternative ( 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); alts.add($alternative.altCodeBlock);
} }
)+ )+
@ -52,7 +53,7 @@ alternative returns [CodeBlockForAlt altCodeBlock, List<SrcOp> ops]
@init { @init {
// set alt if outer ALT only // set alt if outer ALT only
if ( inContext("RULE BLOCK") && ((AltAST)$start).alt!=null ) { if ( inContext("RULE BLOCK") && ((AltAST)$start).alt!=null ) {
controller.setCurrentAlt(((AltAST)$start).alt); controller.setCurrentOuterMostAlt(((AltAST)$start).alt);
} }
} }
: ^(ALT_REWRITE : ^(ALT_REWRITE
@ -67,12 +68,10 @@ alternative returns [CodeBlockForAlt altCodeBlock, List<SrcOp> ops]
| { | {
List<SrcOp> elems = new ArrayList<SrcOp>(); List<SrcOp> elems = new ArrayList<SrcOp>();
$altCodeBlock = controller.alternative(controller.getCurrentAlt()); boolean outerMost = inContext("RULE BLOCK") || inContext("RULE BLOCK ALT_REWRITE");
$ops = elems; $altCodeBlock = controller.alternative(controller.getCurrentOuterMostAlt(), outerMost);
$altCodeBlock.ops = $ops = elems;
controller.setCurrentBlock($altCodeBlock); 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);} )+ ) ^( ALT ( element {if ($element.omos!=null) elems.addAll($element.omos);} )+ )
; ;

View File

@ -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 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()); String label = gen.target.getImplicitRuleLabel(ast.getText());
RuleContextDecl d = new RuleContextDecl(factory,label,ctxName); RuleContextDecl d = new RuleContextDecl(factory,label,ctxName);
labels.add(d); labels.add(d);