From 8013bb868c5270a135f1701c49903d9e516e50fc Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Wed, 15 Feb 2012 18:28:34 -0800 Subject: [PATCH 1/9] stash; got lost of visitor stuff working --- .../antlr/v4/runtime/ParserRuleContext.java | 4 +- .../v4/runtime/tree/ParseTreeVisitor.java | 27 +++++++ tool/playground/ABaseVisitor.java | 11 +++ tool/playground/AVisitor.java | 11 +++ tool/playground/TestVisitor.java | 79 +++++++++++++++++++ .../v4/tool/templates/codegen/Java/Java.stg | 2 + 6 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeVisitor.java create mode 100644 tool/playground/ABaseVisitor.java create mode 100644 tool/playground/AVisitor.java create mode 100644 tool/playground/TestVisitor.java diff --git a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java index 70dac3a32e..ec112740eb 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java @@ -34,6 +34,7 @@ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT import org.antlr.v4.runtime.misc.Nullable; import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTreeListener; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; import java.util.ArrayList; import java.util.Collections; @@ -131,10 +132,11 @@ public ParserRuleContext(@Nullable ParserRuleContext parent, int stateNu this(parent, parent!=null ? parent.s : -1 /* invoking state */, stateNumber); } - // Double dispatch methods + // Double dispatch methods for listeners and visitors public void enterRule(ParseTreeListener listener) { } public void exitRule(ParseTreeListener listener) { } + public > T dispatch(V visitor) { visitor.visitChildren(this); return null; } /** Does not set parent link; other add methods do */ public void addChild(TerminalNode t) { diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeVisitor.java b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeVisitor.java new file mode 100644 index 0000000000..9ad8eabaee --- /dev/null +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeVisitor.java @@ -0,0 +1,27 @@ +package org.antlr.v4.runtime.tree; + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; + +/** T is return type of visit methods. Use T=Void for no return type. */ +public class ParseTreeVisitor { + public T visit(ParserRuleContext ctx) { + return ctx.dispatch(this); + } + + /** Visit all rule, nonleaf children */ + public void visitChildren(ParserRuleContext ctx) { + for (ParseTree c : ctx.children) { + if ( c instanceof ParseTree.RuleNode) { + ParseTree.RuleNode r = (ParseTree.RuleNode)c; + ParserRuleContext rctx = (ParserRuleContext)r.getRuleContext(); + rctx.dispatch(this); + } + } + } + +// Don't need to visit tokens. each visit() method deals with it's leaf children +// public T visit(Token t) { +// return null; +// } +} diff --git a/tool/playground/ABaseVisitor.java b/tool/playground/ABaseVisitor.java new file mode 100644 index 0000000000..b20971e549 --- /dev/null +++ b/tool/playground/ABaseVisitor.java @@ -0,0 +1,11 @@ +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; + +public class ABaseVisitor extends ParseTreeVisitor implements AVisitor { + public T visit(AParser.MultContext ctx) { return null; } + public T visit(AParser.ParensContext ctx) { return null; } + public T visit(AParser.eContext ctx) { return null; } + public T visit(AParser.sContext ctx) { return null; } + public T visit(AParser.AddContext ctx) { return null; } + public T visit(AParser.IntContext ctx) { return null; } +} diff --git a/tool/playground/AVisitor.java b/tool/playground/AVisitor.java new file mode 100644 index 0000000000..5f0af723d7 --- /dev/null +++ b/tool/playground/AVisitor.java @@ -0,0 +1,11 @@ +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; + +public interface AVisitor { + T visit(AParser.MultContext ctx); + T visit(AParser.ParensContext ctx); + T visit(AParser.sContext ctx); + T visit(AParser.AddContext ctx); + T visit(AParser.IntContext ctx); +// T visit(Token t); +} diff --git a/tool/playground/TestVisitor.java b/tool/playground/TestVisitor.java new file mode 100644 index 0000000000..31fbabfd8d --- /dev/null +++ b/tool/playground/TestVisitor.java @@ -0,0 +1,79 @@ +/* + [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. + */ + +import org.antlr.v4.runtime.ANTLRFileStream; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.tree.ParseTreeVisitor; +import org.antlr.v4.runtime.tree.ParseTreeWalker; + +public class TestVisitor { + public static class MyVisitor extends ParseTreeVisitor implements AVisitor { + @Override + public Integer visit(AParser.AddContext ctx) { + return ctx.e(0).dispatch(this) + ctx.e(1).dispatch(this); + } + + @Override + public Integer visit(AParser.IntContext ctx) { + return Integer.valueOf(ctx.INT().getText()); + } + + @Override + public Integer visit(AParser.MultContext ctx) { + return ctx.e(0).dispatch(this) * ctx.e(1).dispatch(this); + } + + @Override + public Integer visit(AParser.ParensContext ctx) { + return ctx.e().dispatch(this); + } + + @Override + public Integer visit(AParser.sContext ctx) { + return ctx.e().dispatch(this); + } + } + + public static void main(String[] args) throws Exception { + ALexer lexer = new ALexer(new ANTLRFileStream(args[0])); + CommonTokenStream tokens = new CommonTokenStream(lexer); + AParser p = new AParser(tokens); + p.setBuildParseTree(true); + ParserRuleContext t = p.s(); + System.out.println("tree = "+t.toStringTree(p)); + + MyVisitor visitor = new MyVisitor(); + Integer result = visitor.visit(t); +// Integer result = t.dispatch(visitor); + System.out.println("result from tree walk = " + result); + } +} + diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index 5c0d27bba6..c7719732ad 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -551,6 +551,7 @@ public static class extends implements + public \Visitor\\> T dispatch(V visitor) { return visitor.visit(this); } } >> @@ -561,6 +562,7 @@ public static class extends Context { }; separator="\n"> public (Context ctx) { copyFrom(ctx); } + public \Visitor\\> T dispatch(V visitor) { return visitor.visit(this); } } >> From baf62685ab1ade1bec904b53c5195ace9e30ded3 Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Thu, 16 Feb 2012 10:27:56 -0800 Subject: [PATCH 2/9] snapshot --- .../antlr/v4/runtime/ParserRuleContext.java | 2 +- tool/playground/AVisitor.java | 1 - tool/playground/TestVisitor.java | 4 ++-- .../v4/tool/templates/codegen/Java/Java.stg | 20 ++++++++++++------- .../codegen/model/ListenerDispatchMethod.java | 20 +++++++++++++++++++ .../v4/codegen/model/decl/StructDecl.java | 10 +++++----- 6 files changed, 41 insertions(+), 16 deletions(-) create mode 100644 tool/src/org/antlr/v4/codegen/model/ListenerDispatchMethod.java diff --git a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java index ec112740eb..531956edeb 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java +++ b/runtime/Java/src/org/antlr/v4/runtime/ParserRuleContext.java @@ -136,7 +136,7 @@ public ParserRuleContext(@Nullable ParserRuleContext parent, int stateNu public void enterRule(ParseTreeListener listener) { } public void exitRule(ParseTreeListener listener) { } - public > T dispatch(V visitor) { visitor.visitChildren(this); return null; } + public T dispatch(ParseTreeVisitor visitor) { visitor.visitChildren(this); return null; } /** Does not set parent link; other add methods do */ public void addChild(TerminalNode t) { diff --git a/tool/playground/AVisitor.java b/tool/playground/AVisitor.java index 5f0af723d7..358bc5a0f0 100644 --- a/tool/playground/AVisitor.java +++ b/tool/playground/AVisitor.java @@ -7,5 +7,4 @@ public interface AVisitor { T visit(AParser.sContext ctx); T visit(AParser.AddContext ctx); T visit(AParser.IntContext ctx); -// T visit(Token t); } diff --git a/tool/playground/TestVisitor.java b/tool/playground/TestVisitor.java index 31fbabfd8d..8d39973de8 100644 --- a/tool/playground/TestVisitor.java +++ b/tool/playground/TestVisitor.java @@ -48,7 +48,8 @@ public Integer visit(AParser.IntContext ctx) { @Override 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 @@ -76,4 +77,3 @@ public static void main(String[] args) throws Exception { System.out.println("result from tree walk = " + result); } } - diff --git a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg index c7719732ad..32fa834b36 100644 --- a/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg +++ b/tool/resources/org/antlr/v4/tool/templates/codegen/Java/Java.stg @@ -533,7 +533,7 @@ ListLabelName(label) ::= "