From 646b22b9ec25ee5c0c763f850dd055bdab17dc85 Mon Sep 17 00:00:00 2001 From: Terence Parr Date: Thu, 16 Feb 2012 13:36:07 -0800 Subject: [PATCH] snapshot --- .../v4/runtime/tree/ParseTreeVisitor.java | 7 +++- tool/playground/ABaseVisitor.java | 15 ++++--- tool/playground/AVisitor.java | 3 ++ tool/playground/TestVisitor.java | 2 +- .../v4/tool/templates/codegen/Java/Java.stg | 10 +++++ .../org/antlr/v4/codegen/CodeGenPipeline.java | 3 +- .../org/antlr/v4/codegen/CodeGenerator.java | 41 +++++++++++++++---- .../v4/codegen/OutputModelController.java | 9 +++- .../v4/codegen/model/BaseVisitorFile.java | 9 ++++ .../antlr/v4/codegen/model/ListenerFile.java | 1 - 10 files changed, 79 insertions(+), 21 deletions(-) create mode 100644 tool/src/org/antlr/v4/codegen/model/BaseVisitorFile.java diff --git a/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeVisitor.java b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeVisitor.java index c77131a47..5dd260312 100644 --- a/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeVisitor.java +++ b/runtime/Java/src/org/antlr/v4/runtime/tree/ParseTreeVisitor.java @@ -8,7 +8,12 @@ public class ParseTreeVisitor { return ctx.accept(this); } - /** Visit all rule, nonleaf children */ + /** Visit all rule, nonleaf children. Not useful if you are using T as + * non-Void. This returns nothing, losing all computations from below. + * But handy if you are just walking the tree with a visitor and only + * care about some nodes. The ParserRuleContext.accept() method + * walks all children by default; i.e., calls this method. + */ public void visitChildren(ParserRuleContext ctx) { for (ParseTree c : ctx.children) { if ( c instanceof ParseTree.RuleNode) { diff --git a/tool/playground/ABaseVisitor.java b/tool/playground/ABaseVisitor.java index b20971e54..aa3159fbc 100644 --- a/tool/playground/ABaseVisitor.java +++ b/tool/playground/ABaseVisitor.java @@ -1,11 +1,10 @@ +import org.antlr.v4.runtime.tree.*; 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; } -} + public T visit(AParser.MultContext ctx) { visitChildren(ctx); return null; } + public T visit(AParser.ParensContext ctx) { visitChildren(ctx); return null; } + public T visit(AParser.sContext ctx) { visitChildren(ctx); return null; } + public T visit(AParser.AddContext ctx) { visitChildren(ctx); return null; } + public T visit(AParser.IntContext ctx) { visitChildren(ctx); return null; } +} \ No newline at end of file diff --git a/tool/playground/AVisitor.java b/tool/playground/AVisitor.java index 5badbd275..5730fa2d6 100644 --- a/tool/playground/AVisitor.java +++ b/tool/playground/AVisitor.java @@ -1,3 +1,6 @@ +import org.antlr.v4.runtime.tree.*; +import org.antlr.v4.runtime.Token; + public interface AVisitor { T visit(AParser.MultContext ctx); T visit(AParser.ParensContext ctx); diff --git a/tool/playground/TestVisitor.java b/tool/playground/TestVisitor.java index 734e6bc6a..6d7e240cb 100644 --- a/tool/playground/TestVisitor.java +++ b/tool/playground/TestVisitor.java @@ -31,7 +31,7 @@ import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.ParseTreeVisitor; public class TestVisitor { - public static class MyVisitor extends ParseTreeVisitor implements AVisitor { + public static class MyVisitor extends ABaseVisitor implements AVisitor { @Override public Integer visit(AParser.AddContext ctx) { return ctx.e(0).accept(this) + ctx.e(1).accept(this); 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 545a72227..6fd56d759 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 @@ -67,6 +67,16 @@ T visit(.Context ctx);}; separator="\n"> } >> +BaseVisitorFile(file, header) ::= << +
+import org.antlr.v4.runtime.tree.*; +import org.antlr.v4.runtime.Token; + +public class BaseVisitor\ extends ParseTreeVisitor\ implements Visitor\ { + .Context ctx) { visitChildren(ctx); return null; \}}; separator="\n"> +} +>> Parser(parser, funcs, atn, sempredFuncs, superclass) ::= << diff --git a/tool/src/org/antlr/v4/codegen/CodeGenPipeline.java b/tool/src/org/antlr/v4/codegen/CodeGenPipeline.java index fd08c81c9..d89443fcd 100644 --- a/tool/src/org/antlr/v4/codegen/CodeGenPipeline.java +++ b/tool/src/org/antlr/v4/codegen/CodeGenPipeline.java @@ -48,8 +48,9 @@ public class CodeGenPipeline { gen.writeRecognizer(gen.generateParser()); if ( g.tool.gen_listener) { gen.writeListener(gen.generateListener()); + gen.writeBaseListener(gen.generateBaseListener()); gen.writeVisitor(gen.generateVisitor()); - gen.writeBlankListener(gen.generateBlankListener()); + gen.writeBaseVisitor(gen.generateBaseVisitor()); } gen.writeHeaderFile(); } diff --git a/tool/src/org/antlr/v4/codegen/CodeGenerator.java b/tool/src/org/antlr/v4/codegen/CodeGenerator.java index 22ff0d310..eaf9cba06 100644 --- a/tool/src/org/antlr/v4/codegen/CodeGenerator.java +++ b/tool/src/org/antlr/v4/codegen/CodeGenerator.java @@ -182,16 +182,29 @@ public class CodeGenerator { return st; } - public ST generateBlankListener() { + public ST generateBaseListener() { OutputModelFactory factory = new ParserFactory(this); OutputModelController controller = new OutputModelController(factory); factory.setController(controller); - OutputModelObject blankModel = controller.buildBlankListenerOutputModel(); + OutputModelObject baseModel = controller.buildBaseListenerOutputModel(); OutputModelWalker walker = new OutputModelWalker(tool, templates); - ST st = walker.walk(blankModel); + ST st = walker.walk(baseModel); + return st; + } + + public ST generateBaseVisitor() { + OutputModelFactory factory = new ParserFactory(this); + + OutputModelController controller = new OutputModelController(factory); + factory.setController(controller); + + OutputModelObject baseModel = controller.buildBaseVisitorOutputModel(); + + OutputModelWalker walker = new OutputModelWalker(tool, templates); + ST st = walker.walk(baseModel); return st; } @@ -235,14 +248,18 @@ public class CodeGenerator { target.genFile(g,outputFileST, getListenerFileName()); } - public void writeBlankListener(ST outputFileST) { - target.genFile(g,outputFileST, getBlankListenerFileName()); + public void writeBaseListener(ST outputFileST) { + target.genFile(g,outputFileST, getBaseListenerFileName()); } public void writeVisitor(ST outputFileST) { target.genFile(g,outputFileST, getVisitorFileName()); } + public void writeBaseVisitor(ST outputFileST) { + target.genFile(g,outputFileST, getBaseVisitorFileName()); + } + public void writeHeaderFile() { String fileName = getHeaderFileName(); if ( fileName==null ) return; @@ -333,15 +350,25 @@ public class CodeGenerator { } /** A given grammar T, return a blank listener implementation - * such as BlankTListener.java, if we're using the Java target. + * such as TBaseListener.java, if we're using the Java target. */ - public String getBlankListenerFileName() { + public String getBaseListenerFileName() { assert g.name != null; ST extST = templates.getInstanceOf("codeFileExtension"); String listenerName = g.name + "BaseListener"; return listenerName+extST.render(); } + /** A given grammar T, return a blank listener implementation + * such as TBaseListener.java, if we're using the Java target. + */ + public String getBaseVisitorFileName() { + assert g.name != null; + ST extST = templates.getInstanceOf("codeFileExtension"); + String listenerName = g.name + "BaseVisitor"; + return listenerName+extST.render(); + } + /** What is the name of the vocab file generated for this grammar? * Returns null if no .tokens file should be generated. */ diff --git a/tool/src/org/antlr/v4/codegen/OutputModelController.java b/tool/src/org/antlr/v4/codegen/OutputModelController.java index c68613f31..9827eaf85 100644 --- a/tool/src/org/antlr/v4/codegen/OutputModelController.java +++ b/tool/src/org/antlr/v4/codegen/OutputModelController.java @@ -108,9 +108,9 @@ public class OutputModelController { return new ListenerFile(delegate, gen.getListenerFileName()); } - public OutputModelObject buildBlankListenerOutputModel() { + public OutputModelObject buildBaseListenerOutputModel() { CodeGenerator gen = delegate.getGenerator(); - return new BaseListenerFile(delegate, gen.getBlankListenerFileName()); + return new BaseListenerFile(delegate, gen.getBaseListenerFileName()); } public OutputModelObject buildVisitorOutputModel() { @@ -118,6 +118,11 @@ public class OutputModelController { return new VisitorFile(delegate, gen.getVisitorFileName()); } + public OutputModelObject buildBaseVisitorOutputModel() { + CodeGenerator gen = delegate.getGenerator(); + return new BaseVisitorFile(delegate, gen.getBaseVisitorFileName()); + } + public ParserFile parserFile(String fileName) { ParserFile f = delegate.parserFile(fileName); for (CodeGeneratorExtension ext : extensions) f = ext.parserFile(f); diff --git a/tool/src/org/antlr/v4/codegen/model/BaseVisitorFile.java b/tool/src/org/antlr/v4/codegen/model/BaseVisitorFile.java new file mode 100644 index 000000000..0d8d1ab28 --- /dev/null +++ b/tool/src/org/antlr/v4/codegen/model/BaseVisitorFile.java @@ -0,0 +1,9 @@ +package org.antlr.v4.codegen.model; + +import org.antlr.v4.codegen.OutputModelFactory; + +public class BaseVisitorFile extends VisitorFile { + public BaseVisitorFile(OutputModelFactory factory, String fileName) { + super(factory, fileName); + } +} diff --git a/tool/src/org/antlr/v4/codegen/model/ListenerFile.java b/tool/src/org/antlr/v4/codegen/model/ListenerFile.java index 5461d26fa..dda76c16b 100644 --- a/tool/src/org/antlr/v4/codegen/model/ListenerFile.java +++ b/tool/src/org/antlr/v4/codegen/model/ListenerFile.java @@ -14,7 +14,6 @@ public class ListenerFile extends OutputFile { public String grammarName; public String parserName; public Set listenerNames = new HashSet(); -// public List ruleNames = new ArrayList(); @ModelElement public Action header;