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;
options {output=AST;}
a: b {int x = $b.i;} ;
a : (ID INT) ;
b returns [int i] : ID;
ID : 'a'..'z'+ ;
INT : '0'..'9'+;

View File

@ -56,9 +56,9 @@ public class CodeGeneratorExtension {
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; }

View File

@ -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; }

View File

@ -58,9 +58,9 @@ public class OutputModelController {
public int treeLevel = -1;
public OutputModelObject root; // normally ParserFile, LexerFile, ...
public Stack<RuleFunction> currentRule = new Stack<RuleFunction>();
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<SrcOp> ops) {
public CodeBlockForAlt finishAlternative(CodeBlockForAlt blk, List<SrcOp> 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; }

View File

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

View File

@ -47,7 +47,7 @@ public class ParserASTExtension extends CodeGeneratorExtension {
@Override
public List<SrcOp> getChoiceBlock(List<SrcOp> 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<SrcOp> rootRule(List<SrcOp> 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<SrcOp> leafRule(List<SrcOp> 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<SrcOp> rootToken(List<SrcOp> 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<SrcOp> leafToken(List<SrcOp> 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<SrcOp> leafRuleInRewriteAlt(InvokeRule invokeOp, List<SrcOp> 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<SrcOp> leafTokenInRewriteAlt(SrcOp matchOp, List<SrcOp> 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<SrcOp> wildcard(List<SrcOp> 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<SrcOp> ops, Decl label, SrcOp opWithLabel) {
CodeBlock blk = factory.getCurrentAlternativeBlock();
CodeBlock blk = factory.getCurrentOuterMostAlternativeBlock();
// declare _track_label
String labelListName =
factory.getGenerator().target.getElementListName(label.name);

View File

@ -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<GrammarAST> 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<GrammarAST> 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<GrammarAST> 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<SrcOp> 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

View File

@ -32,7 +32,8 @@ block[GrammarAST label, GrammarAST ebnfRoot, GrammarAST astOp] returns [List<? e
{List<CodeBlockForAlt> alts = new ArrayList<CodeBlockForAlt>();}
( 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<SrcOp> 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<SrcOp> ops]
| {
List<SrcOp> elems = new ArrayList<SrcOp>();
$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);} )+ )
;

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 ( 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);