fixed outer most vs inner alt issue
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8853]
This commit is contained in:
parent
59178d9959
commit
39fe27dd1f
|
@ -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'+;
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -130,11 +130,11 @@ public interface OutputModelFactory {
|
|||
|
||||
RuleFunction getCurrentRuleFunction();
|
||||
|
||||
Alternative getCurrentAlt();
|
||||
Alternative getCurrentOuterMostAlt();
|
||||
|
||||
CodeBlock getCurrentBlock();
|
||||
|
||||
CodeBlock getCurrentAlternativeBlock();
|
||||
CodeBlock getCurrentOuterMostAlternativeBlock();
|
||||
|
||||
int getCodeBlockLevel();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);} )+ )
|
||||
;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue