parse tree visiting; now, we ALWAYS generate a return struct definition: rule_ctx.
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9049]
This commit is contained in:
parent
d3dc566a69
commit
730794128e
|
@ -281,6 +281,9 @@ public class RuleContext implements ParseTree.RuleNode {
|
|||
return Trees.toStringTree(this);
|
||||
}
|
||||
|
||||
public void discover(ParseTreeListener listener) { }
|
||||
public void finish(ParseTreeListener listener) { }
|
||||
|
||||
public String toString() {
|
||||
return toString(null);
|
||||
}
|
||||
|
|
|
@ -79,4 +79,8 @@ public interface ParseTree extends SyntaxTree {
|
|||
return toString();
|
||||
}
|
||||
}
|
||||
|
||||
// the following methods narrow the return type; they are not additional methods
|
||||
ParseTree getParent();
|
||||
ParseTree getChild(int i);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
[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.runtime.tree;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
public interface ParseTreeListener {
|
||||
void visitToken(Token token);
|
||||
void discoverRule(ParserRuleContext ctx);
|
||||
void finishRule(ParserRuleContext ctx);
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
[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.runtime.tree;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
|
||||
public class ParseTreeVisitor {
|
||||
public void visit(ParseTreeListener listener, ParseTree t) {
|
||||
if ( t instanceof ParseTree.TokenNode) {
|
||||
visitToken(listener, (ParseTree.TokenNode) t);
|
||||
return;
|
||||
}
|
||||
ParseTree.RuleNode r = (ParseTree.RuleNode)t;
|
||||
discoverRule(listener, r);
|
||||
int n = r.getChildCount();
|
||||
for (int i = 0; i<n; i++) {
|
||||
visit(listener, r.getChild(i));
|
||||
}
|
||||
finishRule(listener, r);
|
||||
}
|
||||
|
||||
protected void visitToken(ParseTreeListener listener, ParseTree.TokenNode t) {
|
||||
listener.visitToken(t.getToken());
|
||||
}
|
||||
|
||||
/** The discovery of a rule node, involves sending two events:
|
||||
* the generic discoverRule and a RuleContext-specific event.
|
||||
* First we trigger the generic and then the rule specific.
|
||||
* We to them in reverse order upon finishing the node.
|
||||
*/
|
||||
protected void discoverRule(ParseTreeListener listener, ParseTree.RuleNode r) {
|
||||
ParserRuleContext ctx = (ParserRuleContext)r.getRuleContext();
|
||||
listener.discoverRule((ParserRuleContext)r.getRuleContext());
|
||||
ctx.discover(listener);
|
||||
}
|
||||
|
||||
protected void finishRule(ParseTreeListener listener, ParseTree.RuleNode r) {
|
||||
ParserRuleContext ctx = (ParserRuleContext)r.getRuleContext();
|
||||
ctx.finish(listener);
|
||||
listener.finishRule(ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
public static void main(String[] args) {
|
||||
TListener listener = new TListener() {
|
||||
public void discover_s(s_ctx ctx) {
|
||||
}
|
||||
public void finish_s(s_ctx ctx) {
|
||||
}
|
||||
public void discover_ifstat(ParserRuleContext ctx) {
|
||||
}
|
||||
public void finish_ifstat(ParserRuleContext ctx) {
|
||||
}
|
||||
public void visitToken(Token token) {
|
||||
}
|
||||
public void discoverRule(ParserRuleContext ctx) {
|
||||
}
|
||||
public void finishRule(ParserRuleContext ctx) {
|
||||
}
|
||||
};
|
||||
ParserRuleContext ctx = new ParserRuleContext();
|
||||
ParseTreeVisitor visitor = new ParseTreeVisitor();
|
||||
visitor.visit(listener, ctx);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
interface TListener extends ParseTreeListener {
|
||||
void discover_s(s_ctx ctx);
|
||||
void finish_s(s_ctx ctx);
|
||||
void discover_ifstat(ParserRuleContext ctx); // no labels
|
||||
void finish_ifstat(ParserRuleContext ctx); // no labels
|
||||
}
|
||||
|
||||
class s_ctx extends ParserRuleContext {
|
||||
public ParserRuleContext i;
|
||||
public s_ctx(RuleContext parent, int state) {
|
||||
super(parent, state);
|
||||
}
|
||||
public void discover(TListener listener) { listener.discover_s(this); }
|
||||
public void finish(TListener listener) { listener.discover_s(this); }
|
||||
}
|
||||
*/
|
|
@ -1,6 +1,12 @@
|
|||
grammar T;
|
||||
s : i=ifstat {System.out.println(_input.toString(0,_input.index()-1));} ;
|
||||
ifstat : 'if' '(' INT ')' ID '=' ID ';' ;
|
||||
|
||||
r[int x] returns [int y]
|
||||
locals [int z]
|
||||
: name=ID
|
||||
;
|
||||
|
||||
EQ : '=' ;
|
||||
INT : '0'..'9'+ ;
|
||||
ID : 'a'..'z'+ ;
|
||||
|
|
|
@ -415,6 +415,10 @@ public static class <s.name> extends ParserRuleContext {
|
|||
super(parent, state);
|
||||
<s.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n">
|
||||
}
|
||||
/*
|
||||
public void discover(TListener listener) { listener.discover_<s.name>(this); }
|
||||
public void finish(TListener listener) { listener.finish_<s.name>(this); }
|
||||
*/
|
||||
}
|
||||
>>
|
||||
|
||||
|
|
|
@ -161,7 +161,12 @@ public class OutputModelController {
|
|||
}
|
||||
}
|
||||
|
||||
if ( function.ruleCtx.isEmpty() ) function.ruleCtx = null;
|
||||
// we will usually have to build one of these because of labels
|
||||
// and it will come in very handy for visitors on the parse tree.
|
||||
// I think I will just always generate this structure now.
|
||||
// It makes it easier for code generation as well because every
|
||||
// rule context has a real name.
|
||||
//if ( function.ruleCtx.isEmpty() ) function.ruleCtx = null;
|
||||
popCurrentRule();
|
||||
}
|
||||
|
||||
|
|
|
@ -199,12 +199,16 @@ public class Target {
|
|||
}
|
||||
|
||||
public String getRuleFunctionContextStructName(Rule r) {
|
||||
boolean hasNoExternallyVisibleElements =
|
||||
r.args==null && r.retvals==null && r.scope==null && r.getLabelNames()==null;
|
||||
if ( hasNoExternallyVisibleElements ) {
|
||||
if ( r.g.isLexer() ) {
|
||||
return gen.templates.getInstanceOf("ParserRuleContext").render();
|
||||
}
|
||||
return r.name+"_ctx";
|
||||
// boolean hasNoExternallyVisibleElements =
|
||||
// r.args==null && r.retvals==null && r.scope==null && r.getLabelNames()==null;
|
||||
// if ( hasNoExternallyVisibleElements ) {
|
||||
// return gen.templates.getInstanceOf("ParserRuleContext").render();
|
||||
// }
|
||||
// return r.name+"_ctx";
|
||||
}
|
||||
|
||||
/** If we know which actual function, we can provide the actual ctx type.
|
||||
|
@ -214,13 +218,17 @@ public class Target {
|
|||
*/
|
||||
public String getRuleFunctionContextStructName(RuleFunction function) {
|
||||
Rule r = function.rule;
|
||||
boolean hasNoExternallyVisibleElements =
|
||||
r.args==null && r.retvals==null && r.scope==null && r.getLabelNames()==null;
|
||||
|
||||
if ( hasNoExternallyVisibleElements && function.ruleCtx.isEmpty() ) {
|
||||
if ( r.g.isLexer() ) {
|
||||
return gen.templates.getInstanceOf("ParserRuleContext").render();
|
||||
}
|
||||
return r.name+"_ctx";
|
||||
// boolean hasNoExternallyVisibleElements =
|
||||
// r.args==null && r.retvals==null && r.scope==null && r.getLabelNames()==null;
|
||||
//
|
||||
// if ( hasNoExternallyVisibleElements && function.ruleCtx.isEmpty() ) {
|
||||
// return gen.templates.getInstanceOf("ParserRuleContext").render();
|
||||
// }
|
||||
// return r.name+"_ctx";
|
||||
}
|
||||
|
||||
// should be same for all refs to same token like $ID within single rule function
|
||||
|
|
Loading…
Reference in New Issue