我在ANTLR4做了一个简单的语法解析器与词法分析器和使用Java对象。 然后我做了一个监听器子类,并与我的自定义监听器调用ParseTreeWalker。 它看起来像监听对象的只有基本方法 - enterEveryRule,exitEveryRule,visitTerminalNode,visitErrorNode - 越来越调用。 我的语法有其他规则,其进入/退出功能显然没有得到调用。 我在做什么错在这里? 这里是我的代码:
import java.lang.StringBuffer;
import java.util.Map;
import java.util.HashMap;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
public class GameLangCompiler {
public static String Compile(String fileName) {
ANTLRInputStream input = null;
try {
input = new ANTLRFileStream(fileName);
} catch (Exception ex) {
ex.printStackTrace();
}
GameLangLexer lexer = new GameLangLexer(input);
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
GameLangParser parser = new GameLangParser(tokenStream);
AwesomeListener listener = new AwesomeListener(parser);
GameLangParser.ProgramContext tree = parser.program();
ParseTreeWalker.DEFAULT.walk(listener, tree);
return listener.getSourceCode();
}
public static void main(String[] args) {
if (args.length < 1) {
System.err.println("Give a filename\n");
System.exit(1);
}
String out = Compile(args[0]);
System.out.println("-------- Compiler output --------\n" + out);
}
/**
* Code generating listener for GameLang
*/
public static class AwesomeListener extends GameLangBaseListener {
private GameLangParser parser;
private StringBuffer source;
private Map<String, String> scriptBlocks;
private static final String UPDATE = "update", RENDER = "render", SETUP = "setup";
public AwesomeListener(GameLangParser parser) {
this.parser = parser;
this.source = new StringBuffer();
this.scriptBlocks = new HashMap<String, String>();
}
public String getSourceCode() {
return source.toString();
}
@Override public void enterProgram(GameLang.ProgramContext ctx) {
source.append("program\n");
}
@Override public void exitProgram(GameLang.ProgramContext ctx) {
source.append("Entering program!\n");
}
@Override public void enterBlock(GameLang.BlockContext ctx) {
source.append("block\n");
}
@Override public void exitBlock(GameLang.BlockContext ctx) { }
@Override public void enterEveryRule(ParserRuleContext ctx) {
source.append("Entering a rule:\n");
source.append(ctx.getText() + "\n\n");
}
}
}
那就是越来越解析树走去,编译器的输出:
(program (block setup ( ) (body {\n x = 5\n})) <EOF>)
-------- Compiler output --------
Entering a rule:
setup(){
x = 5
}<EOF>
Entering a rule:
setup(){
x = 5
}
Entering a rule:
{
x = 5
}
正如你所看到的,只有“enterEveryRule”监听方法获取调用。