This commit is contained in:
Terence Parr 2012-02-16 10:27:56 -08:00
parent 8013bb868c
commit baf62685ab
6 changed files with 41 additions and 16 deletions

View File

@ -136,7 +136,7 @@ public class ParserRuleContext<Symbol> extends RuleContext {
public void enterRule(ParseTreeListener<Symbol> listener) { } public void enterRule(ParseTreeListener<Symbol> listener) { }
public void exitRule(ParseTreeListener<Symbol> listener) { } public void exitRule(ParseTreeListener<Symbol> listener) { }
public <T,V extends ParseTreeVisitor<T>> T dispatch(V visitor) { visitor.visitChildren(this); return null; } public <T> T dispatch(ParseTreeVisitor<? extends T> visitor) { visitor.visitChildren(this); return null; }
/** Does not set parent link; other add methods do */ /** Does not set parent link; other add methods do */
public void addChild(TerminalNode<Symbol> t) { public void addChild(TerminalNode<Symbol> t) {

View File

@ -7,5 +7,4 @@ public interface AVisitor<T> {
T visit(AParser.sContext ctx); T visit(AParser.sContext ctx);
T visit(AParser.AddContext ctx); T visit(AParser.AddContext ctx);
T visit(AParser.IntContext ctx); T visit(AParser.IntContext ctx);
// T visit(Token t);
} }

View File

@ -48,7 +48,8 @@ public class TestVisitor {
@Override @Override
public Integer visit(AParser.MultContext ctx) { public Integer visit(AParser.MultContext ctx) {
return ctx.e(0).dispatch(this) * ctx.e(1).dispatch(this); // return ctx.e(0).dispatch(this) * ctx.e(1).dispatch(this);
return visit(ctx.e(0)) * visit(ctx.e(1));
} }
@Override @Override
@ -76,4 +77,3 @@ public class TestVisitor {
System.out.println("result from tree walk = " + result); System.out.println("result from tree walk = " + result);
} }
} }

View File

@ -533,7 +533,7 @@ ListLabelName(label) ::= "<label>"
CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);" CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);"
CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);" CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);"
StructDecl(s,attrs,getters,visitorDispatchMethods,interfaces,extensionMembers, StructDecl(s,attrs,getters,dispatchMethods,interfaces,extensionMembers,
superClass={ParserRuleContext\<<InputSymbolType()>>}) ::= << superClass={ParserRuleContext\<<InputSymbolType()>>}) ::= <<
public static class <s.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> { public static class <s.name> extends <superClass><if(interfaces)> implements <interfaces; separator=", "><endif> {
<attrs:{a | <a>}; separator="\n"> <attrs:{a | <a>}; separator="\n">
@ -550,29 +550,35 @@ public static class <s.name> extends <superClass><if(interfaces)> implements <in
<s.attrs:{a | this.<a.name> = ctx.<a.name>;}; separator="\n"> <s.attrs:{a | this.<a.name> = ctx.<a.name>;}; separator="\n">
} }
<endif> <endif>
<visitorDispatchMethods; separator="\n"> <dispatchMethods; separator="\n">
public \<T, V extends <parser.grammarName>Visitor\<T>\> T dispatch(V visitor) { return visitor.visit(this); }
<extensionMembers; separator="\n"> <extensionMembers; separator="\n">
} }
>> >>
AltLabelStructDecl(s,attrs,getters,visitorDispatchMethods) ::= << AltLabelStructDecl(s,attrs,getters,dispatchMethods) ::= <<
public static class <s.name> extends <currentRule.name>Context { public static class <s.name> extends <currentRule.name>Context {
<attrs:{a | <a>}; separator="\n"> <attrs:{a | <a>}; separator="\n">
<getters:{g | <g>}; separator="\n"> <getters:{g | <g>}; separator="\n">
public <s.name>(<currentRule.name>Context ctx) { copyFrom(ctx); } public <s.name>(<currentRule.name>Context ctx) { copyFrom(ctx); }
<visitorDispatchMethods; separator="\n"> <dispatchMethods; separator="\n">
public \<T, V extends <parser.grammarName>Visitor\<T>\> T dispatch(V visitor) { return visitor.visit(this); }
} }
>> >>
VisitorDispatchMethod(method) ::= << ListenerDispatchMethod(method) ::= <<
@Override @Override
public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener\<<InputSymbolType()>\> listener) { public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener\<<InputSymbolType()>\> listener) {
if ( listener instanceof <parser.grammarName>Listener ) ((<parser.grammarName>Listener)listener).<if(method.isEnter)>enter<else>exit<endif>(this); if ( listener instanceof <parser.grammarName>Listener ) ((<parser.grammarName>Listener)listener).<if(method.isEnter)>enter<else>exit<endif>(this);
} }
>> >>
VisitorDispatchMethod() ::= <<
@Override
public \<T> T dispatch(ParseTreeVisitor\<? extends T> visitor) {
if ( listener instanceof <parser.grammarName>Visitor ) return ((<parser.grammarName>Visitor\<T>)visitor).visit(this);
else return null;
}
>>
AttributeDecl(d) ::= "public <d.decl>;" AttributeDecl(d) ::= "public <d.decl>;"
/** If we don't know location of label def x, use this template */ /** If we don't know location of label def x, use this template */

View File

@ -0,0 +1,20 @@
package org.antlr.v4.codegen.model;
import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.misc.Triple;
import org.antlr.v4.tool.Rule;
import org.antlr.v4.tool.ast.AltAST;
import java.util.List;
public class ListenerDispatchMethod extends OutputModelObject {
public String listenerName = "Rule";
public boolean isEnter;
public ListenerDispatchMethod(OutputModelFactory factory, Rule r, boolean isEnter) {
super(factory);
this.isEnter = isEnter;
List<Triple<Integer,AltAST,String>> label = r.getAltLabels();
if ( label!=null ) listenerName = label.get(0).c;
}
}

View File

@ -32,7 +32,7 @@ package org.antlr.v4.codegen.model.decl;
import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.OutputModelFactory;
import org.antlr.v4.codegen.model.ModelElement; import org.antlr.v4.codegen.model.ModelElement;
import org.antlr.v4.codegen.model.OutputModelObject; import org.antlr.v4.codegen.model.OutputModelObject;
import org.antlr.v4.codegen.model.VisitorDispatchMethod; import org.antlr.v4.codegen.model.ListenerDispatchMethod;
import org.antlr.v4.runtime.misc.OrderedHashSet; import org.antlr.v4.runtime.misc.OrderedHashSet;
import org.antlr.v4.tool.Attribute; import org.antlr.v4.tool.Attribute;
import org.antlr.v4.tool.Rule; import org.antlr.v4.tool.Rule;
@ -50,7 +50,7 @@ public class StructDecl extends Decl {
@ModelElement public OrderedHashSet<Decl> attrs = new OrderedHashSet<Decl>(); @ModelElement public OrderedHashSet<Decl> attrs = new OrderedHashSet<Decl>();
@ModelElement public OrderedHashSet<Decl> getters = new OrderedHashSet<Decl>(); @ModelElement public OrderedHashSet<Decl> getters = new OrderedHashSet<Decl>();
@ModelElement public Collection<Attribute> ctorAttrs; @ModelElement public Collection<Attribute> ctorAttrs;
@ModelElement public List<VisitorDispatchMethod> visitorDispatchMethods; @ModelElement public List<ListenerDispatchMethod> dispatchMethods;
@ModelElement public List<OutputModelObject> interfaces; @ModelElement public List<OutputModelObject> interfaces;
@ModelElement public List<OutputModelObject> extensionMembers; @ModelElement public List<OutputModelObject> extensionMembers;
@ -61,9 +61,9 @@ public class StructDecl extends Decl {
} }
public void addVisitorDispatchMethods(Rule r) { public void addVisitorDispatchMethods(Rule r) {
visitorDispatchMethods = new ArrayList<VisitorDispatchMethod>(); dispatchMethods = new ArrayList<ListenerDispatchMethod>();
visitorDispatchMethods.add(new VisitorDispatchMethod(factory, r, true)); dispatchMethods.add(new ListenerDispatchMethod(factory, r, true));
visitorDispatchMethods.add(new VisitorDispatchMethod(factory, r, false)); dispatchMethods.add(new ListenerDispatchMethod(factory, r, false));
} }
public void addDecl(Decl d) { public void addDecl(Decl d) {