forked from jasder/antlr
snapshot
This commit is contained in:
parent
4a374dab60
commit
646b22b9ec
|
@ -8,7 +8,12 @@ public class ParseTreeVisitor<T> {
|
||||||
return ctx.accept(this);
|
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 <Symbol> void visitChildren(ParserRuleContext<Symbol> ctx) {
|
public <Symbol> void visitChildren(ParserRuleContext<Symbol> ctx) {
|
||||||
for (ParseTree c : ctx.children) {
|
for (ParseTree c : ctx.children) {
|
||||||
if ( c instanceof ParseTree.RuleNode) {
|
if ( c instanceof ParseTree.RuleNode) {
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
|
import org.antlr.v4.runtime.tree.*;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
|
||||||
|
|
||||||
public class ABaseVisitor<T> extends ParseTreeVisitor<T> implements AVisitor<T> {
|
public class ABaseVisitor<T> extends ParseTreeVisitor<T> implements AVisitor<T> {
|
||||||
public T visit(AParser.MultContext ctx) { return null; }
|
public T visit(AParser.MultContext ctx) { visitChildren(ctx); return null; }
|
||||||
public T visit(AParser.ParensContext ctx) { return null; }
|
public T visit(AParser.ParensContext ctx) { visitChildren(ctx); return null; }
|
||||||
public T visit(AParser.eContext ctx) { return null; }
|
public T visit(AParser.sContext ctx) { visitChildren(ctx); return null; }
|
||||||
public T visit(AParser.sContext ctx) { return null; }
|
public T visit(AParser.AddContext ctx) { visitChildren(ctx); return null; }
|
||||||
public T visit(AParser.AddContext ctx) { return null; }
|
public T visit(AParser.IntContext ctx) { visitChildren(ctx); return null; }
|
||||||
public T visit(AParser.IntContext ctx) { return null; }
|
|
||||||
}
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
|
import org.antlr.v4.runtime.tree.*;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
public interface AVisitor<T> {
|
public interface AVisitor<T> {
|
||||||
T visit(AParser.MultContext ctx);
|
T visit(AParser.MultContext ctx);
|
||||||
T visit(AParser.ParensContext ctx);
|
T visit(AParser.ParensContext ctx);
|
||||||
|
|
|
@ -31,7 +31,7 @@ import org.antlr.v4.runtime.*;
|
||||||
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
|
||||||
|
|
||||||
public class TestVisitor {
|
public class TestVisitor {
|
||||||
public static class MyVisitor extends ParseTreeVisitor<Integer> implements AVisitor<Integer> {
|
public static class MyVisitor extends ABaseVisitor<Integer> implements AVisitor<Integer> {
|
||||||
@Override
|
@Override
|
||||||
public Integer visit(AParser.AddContext ctx) {
|
public Integer visit(AParser.AddContext ctx) {
|
||||||
return ctx.e(0).accept(this) + ctx.e(1).accept(this);
|
return ctx.e(0).accept(this) + ctx.e(1).accept(this);
|
||||||
|
|
|
@ -67,6 +67,16 @@ T visit(<file.parserName>.<lname>Context ctx);}; separator="\n">
|
||||||
}
|
}
|
||||||
>>
|
>>
|
||||||
|
|
||||||
|
BaseVisitorFile(file, header) ::= <<
|
||||||
|
<header>
|
||||||
|
import org.antlr.v4.runtime.tree.*;
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
|
public class <file.grammarName>BaseVisitor\<T> extends ParseTreeVisitor\<T> implements <file.grammarName>Visitor\<T> {
|
||||||
|
<file.visitorNames:{lname |
|
||||||
|
public T visit(<file.parserName>.<lname>Context ctx) { visitChildren(ctx); return null; \}}; separator="\n">
|
||||||
|
}
|
||||||
|
>>
|
||||||
|
|
||||||
Parser(parser, funcs, atn, sempredFuncs, superclass) ::= <<
|
Parser(parser, funcs, atn, sempredFuncs, superclass) ::= <<
|
||||||
<Parser_(ctor="parser_ctor", ...)>
|
<Parser_(ctor="parser_ctor", ...)>
|
||||||
|
|
|
@ -48,8 +48,9 @@ public class CodeGenPipeline {
|
||||||
gen.writeRecognizer(gen.generateParser());
|
gen.writeRecognizer(gen.generateParser());
|
||||||
if ( g.tool.gen_listener) {
|
if ( g.tool.gen_listener) {
|
||||||
gen.writeListener(gen.generateListener());
|
gen.writeListener(gen.generateListener());
|
||||||
|
gen.writeBaseListener(gen.generateBaseListener());
|
||||||
gen.writeVisitor(gen.generateVisitor());
|
gen.writeVisitor(gen.generateVisitor());
|
||||||
gen.writeBlankListener(gen.generateBlankListener());
|
gen.writeBaseVisitor(gen.generateBaseVisitor());
|
||||||
}
|
}
|
||||||
gen.writeHeaderFile();
|
gen.writeHeaderFile();
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,16 +182,29 @@ public class CodeGenerator {
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ST generateBlankListener() {
|
public ST generateBaseListener() {
|
||||||
OutputModelFactory factory = new ParserFactory(this);
|
OutputModelFactory factory = new ParserFactory(this);
|
||||||
|
|
||||||
OutputModelController controller = new OutputModelController(factory);
|
OutputModelController controller = new OutputModelController(factory);
|
||||||
factory.setController(controller);
|
factory.setController(controller);
|
||||||
|
|
||||||
OutputModelObject blankModel = controller.buildBlankListenerOutputModel();
|
OutputModelObject baseModel = controller.buildBaseListenerOutputModel();
|
||||||
|
|
||||||
OutputModelWalker walker = new OutputModelWalker(tool, templates);
|
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;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,14 +248,18 @@ public class CodeGenerator {
|
||||||
target.genFile(g,outputFileST, getListenerFileName());
|
target.genFile(g,outputFileST, getListenerFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeBlankListener(ST outputFileST) {
|
public void writeBaseListener(ST outputFileST) {
|
||||||
target.genFile(g,outputFileST, getBlankListenerFileName());
|
target.genFile(g,outputFileST, getBaseListenerFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeVisitor(ST outputFileST) {
|
public void writeVisitor(ST outputFileST) {
|
||||||
target.genFile(g,outputFileST, getVisitorFileName());
|
target.genFile(g,outputFileST, getVisitorFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeBaseVisitor(ST outputFileST) {
|
||||||
|
target.genFile(g,outputFileST, getBaseVisitorFileName());
|
||||||
|
}
|
||||||
|
|
||||||
public void writeHeaderFile() {
|
public void writeHeaderFile() {
|
||||||
String fileName = getHeaderFileName();
|
String fileName = getHeaderFileName();
|
||||||
if ( fileName==null ) return;
|
if ( fileName==null ) return;
|
||||||
|
@ -333,15 +350,25 @@ public class CodeGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A given grammar T, return a blank listener implementation
|
/** 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;
|
assert g.name != null;
|
||||||
ST extST = templates.getInstanceOf("codeFileExtension");
|
ST extST = templates.getInstanceOf("codeFileExtension");
|
||||||
String listenerName = g.name + "BaseListener";
|
String listenerName = g.name + "BaseListener";
|
||||||
return listenerName+extST.render();
|
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?
|
/** What is the name of the vocab file generated for this grammar?
|
||||||
* Returns null if no .tokens file should be generated.
|
* Returns null if no .tokens file should be generated.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -108,9 +108,9 @@ public class OutputModelController {
|
||||||
return new ListenerFile(delegate, gen.getListenerFileName());
|
return new ListenerFile(delegate, gen.getListenerFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputModelObject buildBlankListenerOutputModel() {
|
public OutputModelObject buildBaseListenerOutputModel() {
|
||||||
CodeGenerator gen = delegate.getGenerator();
|
CodeGenerator gen = delegate.getGenerator();
|
||||||
return new BaseListenerFile(delegate, gen.getBlankListenerFileName());
|
return new BaseListenerFile(delegate, gen.getBaseListenerFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputModelObject buildVisitorOutputModel() {
|
public OutputModelObject buildVisitorOutputModel() {
|
||||||
|
@ -118,6 +118,11 @@ public class OutputModelController {
|
||||||
return new VisitorFile(delegate, gen.getVisitorFileName());
|
return new VisitorFile(delegate, gen.getVisitorFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OutputModelObject buildBaseVisitorOutputModel() {
|
||||||
|
CodeGenerator gen = delegate.getGenerator();
|
||||||
|
return new BaseVisitorFile(delegate, gen.getBaseVisitorFileName());
|
||||||
|
}
|
||||||
|
|
||||||
public ParserFile parserFile(String fileName) {
|
public ParserFile parserFile(String fileName) {
|
||||||
ParserFile f = delegate.parserFile(fileName);
|
ParserFile f = delegate.parserFile(fileName);
|
||||||
for (CodeGeneratorExtension ext : extensions) f = ext.parserFile(f);
|
for (CodeGeneratorExtension ext : extensions) f = ext.parserFile(f);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,6 @@ public class ListenerFile extends OutputFile {
|
||||||
public String grammarName;
|
public String grammarName;
|
||||||
public String parserName;
|
public String parserName;
|
||||||
public Set<String> listenerNames = new HashSet<String>();
|
public Set<String> listenerNames = new HashSet<String>();
|
||||||
// public List<String> ruleNames = new ArrayList<String>();
|
|
||||||
|
|
||||||
@ModelElement public Action header;
|
@ModelElement public Action header;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue