using old ast op code from v3. works fine.

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8812]
This commit is contained in:
parrt 2011-06-30 12:11:32 -08:00
parent a421082008
commit b9daa3763c
8 changed files with 143 additions and 20 deletions

View File

@ -44,29 +44,71 @@ public abstract class BaseTreeAdaptor implements TreeAdaptor {
// BEGIN v4 stuff
/* Upon B^ in these cases:
A B^ add kids to newRoot B
return B
A^ B^ add any remaining kids to A
clear kids
add A as child of B
return B
r B^ add kids to B
clear kids
return B
r^ B^
Upon r^ in these cases:
A r^
A^ r^
s r^
s^ r^
A r^ B, r is (C D). result = (C D A B)
becomeRoot((C D), (nil A))
A r^ B, r is (nil C D). result = (A C D B)
becomeRoot((nil C D), (nil A))
todo: ref to r must chk if ^(nil list); can't just add to List<Tree>
*/
public Object becomeRoot(Object oldRoot, Object newRoot, List kids) {
return null;
// old root can be nil rooted if root set by r^ call like "r^ A"; implies a list
if ( ((Tree)oldRoot).isNil() ) {
addChildren(newRoot, getChildren(oldRoot)); // add old children to new root
addChildren(newRoot, kids); // add unattached kids also
kids.clear();
return oldRoot;
}
// must be from previous root match like "A^ B^" or single node
// result from r^ or rooted/non-nil root from r^ in "r^ A^".
addChildren(oldRoot, kids);
kids.clear();
addChild(newRoot, oldRoot); // newRoot becomes root of old root
return newRoot;
}
/** if oldRoot is nil then:
/** if oldRoot is nil then (oldRoot must be r^ result):
* create newRoot for rootToken
* add kids to newRoot
* clear kids
* return as new root
* if oldRoot not nil then:
* if oldRoot not nil then (must have created from A^):
* add kids to oldRoot
* clear kids
* create rootToken
* return as new root
*/
public Object becomeRoot(Object oldRoot, Token rootToken, List kids) {
// first flush all previous children onto old root
// old root can be nil rooted if root set by r^ call like "r^ A"; implies a list
if ( ((Tree)oldRoot).isNil() ) {
oldRoot = create(rootToken);
addChildren(oldRoot, kids);
Tree newRoot = (Tree)create(rootToken);
addChildren(newRoot, getChildren(oldRoot)); // add old children to new root
addChildren(newRoot, kids); // add unattached kids also
kids.clear();
return oldRoot;
}
// must be from previous root match like "A^ B^" or single node
// result from r^ or rooted/non-nil root from r^ in "r^ A^".
addChildren(oldRoot, kids);
kids.clear();
Object newRoot = create(rootToken);
@ -78,6 +120,31 @@ public abstract class BaseTreeAdaptor implements TreeAdaptor {
if ( root!=null ) ((Tree)root).addChildren(kids);
}
public List getChildren(Object root) { return ((Tree)root).getChildren(); }
/** Add remaining kids to non-null root. If null root, add kids to
* new nil root. If only one kid, make it the root. Return the
* root.
*/
public Object rulePostProcessing(Object root, List kids) {
if ( root!=null ) {
addChildren(root, kids);
}
else {
if ( kids.size()==1 ) {
root = kids.get(0);
// whoever invokes rule will set parent and child index
((Tree)root).setParent(null);
((Tree)root).setChildIndex(-1);
}
if ( kids.size()>1 ) {
root = nil();
addChildren(root, kids);
}
}
return root;
}
// END v4 stuff
public Object nil() {

View File

@ -49,6 +49,8 @@ public interface Tree {
// BEGIN v4
void addChildren(List t);
List getChildren();
// END v4
Tree getChild(int i);

View File

@ -63,6 +63,14 @@ public interface TreeAdaptor {
// If not null root, add kids to it
public void addChildren(Object root, List kids);
public List getChildren(Object root);
/** Add remaining kids to non-null root. If null root, add kids to
* new nil root. If only one kid, make it the root. Return the
* root.
*/
public Object rulePostProcessing(Object root, List kids);
// END new v4 stuff
// C o n s t r u c t i o n

View File

@ -1,6 +1,6 @@
grammar T;
options {output=AST;}
a : A^ C^ D ;
a : D^ b^ C D b;
b : B ;

View File

@ -103,8 +103,8 @@ public QStack\<<currentRule.ctxType>\> <currentRule.name>_stk = new QStack\<<cur
<locals; separator="\n">
try {
<code>
<postamble; separator="\n">
_localctx.stop = input.LT(-1);
<postamble; separator="\n">
<namedActions.after>
}
catch (RecognitionException re) {
@ -359,18 +359,18 @@ labelref(x) ::= "<if(!x.isLocal)>_localctx.<endif><x.name>"
// AST stuff (TODO: separate?)
KidsListDecl(d) ::= "List <d.name> = new ArrayList(5);"
RootDecl(d) ::= "Object <d.name> = null;"
RootDecl(d) ::= "Object <d.name> = _adaptor.nil();"
RootName(level) ::= "_root<level>"
KidsListName(level) ::= "_kids<level>"
AddTokenLeaf(a) ::= "_kids0.add(_adaptor.create(<labelref(a.label)>));"
AddRuleLeaf(a) ::= "_kids0.add(<labelref(a.label)>.tree);"
// TODO: need RuleBecomeRoot
BecomeRoot(r) ::= "_root0 = _root0==null ? _adaptor.create(<labelref(r.label)>) : _adaptor.becomeRoot(_root0, <labelref(r.label)>, _kids0);"
AddTokenLeaf(a) ::= "_adaptor.addChild(_root0, _adaptor.create(<labelref(a.label)>));"
AddRuleLeaf(a) ::= "_adaptor.addChild(_root0, <labelref(a.label)>.tree);"
RuleBecomeRoot(r) ::= "_root0 = _adaptor.becomeRoot(<labelref(r.label)>.tree, _root0);"
TokenBecomeRoot(t) ::= "_root0 = _adaptor.becomeRoot(_adaptor.create(<labelref(t.label)>), _root0);"
AssignTreeResult(a) ::= <<
if ( _root0==null && _kids0.size()>0 ) _root0 = _adaptor.nil();
_adaptor.addChildren(_root0, _kids0);
_root0 = _adaptor.rulePostProcessing(_root0);
_localctx.tree = _root0;
_adaptor.setTokenBoundaries(_localctx.tree, _localctx.start, _localctx.stop);
>>
/*

View File

@ -49,14 +49,14 @@ public class ParserASTExtension extends CodeGeneratorExtension {
@Override
public List<SrcOp> rootRule(List<SrcOp> ops) {
InvokeRule invokeOp = (InvokeRule)Utils.find(ops, InvokeRule.class);
SrcOp treeOp = new BecomeRoot(factory, invokeOp.ast, invokeOp);
SrcOp treeOp = new RuleBecomeRoot(factory, invokeOp.ast, invokeOp);
return DefaultOutputModelFactory.list(ops, treeOp);
}
@Override
public List<SrcOp> rootToken(List<SrcOp> ops) {
MatchToken matchOp = (MatchToken)Utils.find(ops, MatchToken.class);
SrcOp treeOp = new BecomeRoot(factory, matchOp.ast, matchOp);
SrcOp treeOp = new TokenBecomeRoot(factory, matchOp.ast, matchOp);
return DefaultOutputModelFactory.list(ops, treeOp);
}

View File

@ -34,12 +34,11 @@ import org.antlr.v4.codegen.model.*;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.GrammarAST;
/** */
public class BecomeRoot extends SrcOp {
public class RuleBecomeRoot extends SrcOp {
public LabeledOp opWithResultToAdd;
public Decl label;
public BecomeRoot(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
public RuleBecomeRoot(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
super(factory, ast);
this.opWithResultToAdd = opWithResultToAdd;
label = opWithResultToAdd.getLabels().get(0);

View File

@ -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.*;
import org.antlr.v4.codegen.model.decl.Decl;
import org.antlr.v4.tool.GrammarAST;
/** */
public class TokenBecomeRoot extends SrcOp {
public LabeledOp opWithResultToAdd;
public Decl label;
public TokenBecomeRoot(OutputModelFactory factory, GrammarAST ast, LabeledOp opWithResultToAdd) {
super(factory, ast);
this.opWithResultToAdd = opWithResultToAdd;
label = opWithResultToAdd.getLabels().get(0);
}
}