diff --git a/tool/playground/TestA.java b/tool/playground/TestA.java index da3d96087..ff9b9c8fa 100644 --- a/tool/playground/TestA.java +++ b/tool/playground/TestA.java @@ -155,13 +155,63 @@ public class TestA { printMethodName(ctx); } - public void printMethodName(ParserRuleContext ctx) { - Throwable t = new Throwable(); - StackTraceElement[] stack = t.getStackTrace(); - String m = stack[1].getMethodName(); - System.out.println(m+"("+ctx.getClass().getSimpleName()+")"); + } + + public static class TraceDuringParse extends ABaseParseListener { + @Override + public void enterNonLRRule(ParserRuleContext ctx) { + printMethodName(ctx); + } + + @Override + public void enterS(ParserRuleContext ctx) { + printMethodName(ctx); + } + + @Override + public void exitAdd(AParser.AddContext ctx) { + printMethodName(ctx); + } + + @Override + public void exitEveryRule(ParserRuleContext ctx) { + printMethodName(ctx); + } + + @Override + public void exitMult(AParser.MultContext ctx) { + printMethodName(ctx); + } + + @Override + public void exitParens(AParser.ParensContext ctx) { + printMethodName(ctx); + } + + @Override + public void exitPrimary(AParser.PrimaryContext ctx) { + printMethodName(ctx); + } + + @Override + public void exitS(AParser.SContext ctx) { + printMethodName(ctx); + } + + @Override + public void visitTerminal(ParserRuleContext ctx, Token symbol) { + printMethodName(ctx); + System.out.println("visiting "+symbol); } } + + public static void printMethodName(ParserRuleContext ctx) { + Throwable t = new Throwable(); + StackTraceElement[] stack = t.getStackTrace(); + String m = stack[1].getMethodName(); + System.out.println(m+"("+ctx.getClass().getSimpleName()+")"); + } + public static void main(String[] args) throws Exception { InputStream is = System.in; if ( args.length>0 && args[0]!=null ) { @@ -171,7 +221,7 @@ public class TestA { CommonTokenStream tokens = new CommonTokenStream(lexer); AParser p = new AParser(tokens); p.setBuildParseTree(true); -// p.addParseListener(new Tracer()); + p.addParseListener(new TraceDuringParse()); ParserRuleContext t = p.s(); System.out.println("tree = "+t.toStringTree(p)); 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 7f7efaff6..6805d5820 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 @@ -63,7 +63,7 @@ import org.antlr.v4.runtime.*; public interface ParseListener extends ParseListener\<\> { (ParseListener\<\> ctx);}; separator="\n"> +void enter(ParserRuleContext\<\> ctx);}; separator="\n"> (.Context ctx);}; separator="\n"> } @@ -76,7 +76,7 @@ import org.antlr.v4.runtime.*; public class BaseParseListener implements ParseListener { (ParseListener\<\> ctx) { \}}; separator="\n"> +public void enter(ParserRuleContext\<\> ctx) { \}}; separator="\n"> (.Context ctx) { \}}; separator="\n"> @@ -629,6 +629,12 @@ public \ T accept(ParseTreeVisitor\ visitor) { } >> +ParseListenerDispatchMethod(method) ::= << +public void enterexitRule(ParseListener\<\> listener) { + if ( listener instanceof ParseListener ) ((ParseListener)listener).enterexit(this); +} +>> + AttributeDecl(d) ::= "public ;" /** If we don't know location of label def x, use this template */ diff --git a/tool/src/org/antlr/v4/codegen/model/ParseListenerDispatchMethod.java b/tool/src/org/antlr/v4/codegen/model/ParseListenerDispatchMethod.java new file mode 100644 index 000000000..ba0392716 --- /dev/null +++ b/tool/src/org/antlr/v4/codegen/model/ParseListenerDispatchMethod.java @@ -0,0 +1,13 @@ +package org.antlr.v4.codegen.model; + +import org.antlr.v4.codegen.OutputModelFactory; + +public class ParseListenerDispatchMethod extends DispatchMethod { + public boolean isEnter; + + public ParseListenerDispatchMethod(OutputModelFactory factory, boolean isEnter) { + super(factory); + this.isEnter = isEnter; + } + +} diff --git a/tool/src/org/antlr/v4/codegen/model/decl/AltLabelStructDecl.java b/tool/src/org/antlr/v4/codegen/model/decl/AltLabelStructDecl.java index 35bc77dcb..07a650690 100644 --- a/tool/src/org/antlr/v4/codegen/model/decl/AltLabelStructDecl.java +++ b/tool/src/org/antlr/v4/codegen/model/decl/AltLabelStructDecl.java @@ -31,7 +31,7 @@ package org.antlr.v4.codegen.model.decl; import org.antlr.v4.codegen.OutputModelFactory; import org.antlr.v4.codegen.model.*; -import org.antlr.v4.tool.Rule; +import org.antlr.v4.tool.*; import java.util.ArrayList; @@ -44,18 +44,27 @@ public class AltLabelStructDecl extends StructDecl { super(factory, r); this.altNum = altNum; this.name = // override name set in super to the label ctx - factory.getGenerator().target.getAltLabelContextStructName(label); + factory.getGenerator().target.getAltLabelContextStructName(label); derivedFromName = label; } @Override public void addDispatchMethods(Rule r) { dispatchMethods = new ArrayList(); - dispatchMethods.add(new ListenerDispatchMethod(factory, true)); - dispatchMethods.add(new ListenerDispatchMethod(factory, false)); + if ( factory.getGrammar().tool.gen_listener ) { + dispatchMethods.add(new ListenerDispatchMethod(factory, true)); + dispatchMethods.add(new ListenerDispatchMethod(factory, false)); + } if ( factory.getGrammar().tool.gen_visitor ) { dispatchMethods.add(new VisitorDispatchMethod(factory)); } + if ( factory.getGrammar().tool.gen_parse_listener ) { + if ( !(r instanceof LeftRecursiveRule) ) { + dispatchMethods.add(new ParseListenerDispatchMethod(factory, true)); + } + dispatchMethods.add(new ParseListenerDispatchMethod(factory, false)); + } + } @Override diff --git a/tool/src/org/antlr/v4/codegen/model/decl/StructDecl.java b/tool/src/org/antlr/v4/codegen/model/decl/StructDecl.java index c0a62e13b..c24352e00 100644 --- a/tool/src/org/antlr/v4/codegen/model/decl/StructDecl.java +++ b/tool/src/org/antlr/v4/codegen/model/decl/StructDecl.java @@ -65,6 +65,12 @@ public class StructDecl extends Decl { if ( factory.getGrammar().tool.gen_visitor ) { dispatchMethods.add(new VisitorDispatchMethod(factory)); } + if ( factory.getGrammar().tool.gen_parse_listener ) { + if ( !(r instanceof LeftRecursiveRule) ) { + dispatchMethods.add(new ParseListenerDispatchMethod(factory, true)); + } + dispatchMethods.add(new ParseListenerDispatchMethod(factory, false)); + } } }