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);
|
return Trees.toStringTree(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void discover(ParseTreeListener listener) { }
|
||||||
|
public void finish(ParseTreeListener listener) { }
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return toString(null);
|
return toString(null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,4 +79,8 @@ public interface ParseTree extends SyntaxTree {
|
||||||
return toString();
|
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;
|
grammar T;
|
||||||
s : i=ifstat {System.out.println(_input.toString(0,_input.index()-1));} ;
|
s : i=ifstat {System.out.println(_input.toString(0,_input.index()-1));} ;
|
||||||
ifstat : 'if' '(' INT ')' ID '=' ID ';' ;
|
ifstat : 'if' '(' INT ')' ID '=' ID ';' ;
|
||||||
|
|
||||||
|
r[int x] returns [int y]
|
||||||
|
locals [int z]
|
||||||
|
: name=ID
|
||||||
|
;
|
||||||
|
|
||||||
EQ : '=' ;
|
EQ : '=' ;
|
||||||
INT : '0'..'9'+ ;
|
INT : '0'..'9'+ ;
|
||||||
ID : 'a'..'z'+ ;
|
ID : 'a'..'z'+ ;
|
||||||
|
|
|
@ -415,6 +415,10 @@ public static class <s.name> extends ParserRuleContext {
|
||||||
super(parent, state);
|
super(parent, state);
|
||||||
<s.ctorAttrs:{a | this.<a.name> = <a.name>;}; separator="\n">
|
<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();
|
popCurrentRule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,12 +199,16 @@ public class Target {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRuleFunctionContextStructName(Rule r) {
|
public String getRuleFunctionContextStructName(Rule r) {
|
||||||
boolean hasNoExternallyVisibleElements =
|
if ( r.g.isLexer() ) {
|
||||||
r.args==null && r.retvals==null && r.scope==null && r.getLabelNames()==null;
|
|
||||||
if ( hasNoExternallyVisibleElements ) {
|
|
||||||
return gen.templates.getInstanceOf("ParserRuleContext").render();
|
return gen.templates.getInstanceOf("ParserRuleContext").render();
|
||||||
}
|
}
|
||||||
return r.name+"_ctx";
|
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.
|
/** 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) {
|
public String getRuleFunctionContextStructName(RuleFunction function) {
|
||||||
Rule r = function.rule;
|
Rule r = function.rule;
|
||||||
boolean hasNoExternallyVisibleElements =
|
if ( r.g.isLexer() ) {
|
||||||
r.args==null && r.retvals==null && r.scope==null && r.getLabelNames()==null;
|
|
||||||
|
|
||||||
if ( hasNoExternallyVisibleElements && function.ruleCtx.isEmpty() ) {
|
|
||||||
return gen.templates.getInstanceOf("ParserRuleContext").render();
|
return gen.templates.getInstanceOf("ParserRuleContext").render();
|
||||||
}
|
}
|
||||||
return r.name+"_ctx";
|
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
|
// should be same for all refs to same token like $ID within single rule function
|
||||||
|
|
Loading…
Reference in New Issue