我目前正在开发一个项目,要求我动态生成ANTLR语法,因为生成的语言取决于用户输入。因此,我在代码中生成ANTLR语法,并从中生成词法分析器和解析器。
我的目标是让一个输入程序用生成的语法语言编写(它实际上是通过遗传算法创建的,但这里不相关),最终有一个AST代表程序。但是,目前我只能生成一个ParseTree对象,这对我的程序来说还不够。
有人知道如何使用ANTLR API生成代表AST的对象吗? (例如antlr.collections.AST对象)。我会在这里添加一段代码,但测试它的最佳方法是运行驻留在https://snowdrop.googlecode.com/svn/trunk/src/ANTLRTest/
中的Eclipse项目public class GEQuorra extends GEModel {
Grammar grammar;
private org.antlr.tool.Grammar lexer;
private org.antlr.tool.Grammar parser;
private String startRule;
private String ignoreTokens;
public GEQuorra(IntegrationTest.Grammar g) {
grammar = new Grammar(g.getBnfGrammar());
setGrammar(grammar);
try {
ignoreTokens = "WS";
startRule = "agentProgram";
parser = new org.antlr.tool.Grammar(g.getAntlrGrammar());
@SuppressWarnings("rawtypes")
List leftRecursiveRules = parser.checkAllRulesForLeftRecursion();
if (leftRecursiveRules.size() > 0) {
throw new Exception("Grammar is left recursive");
}
String lexerGrammarText = parser.getLexerGrammar();
lexer = new org.antlr.tool.Grammar();
lexer.importTokenVocabulary(parser);
lexer.setFileName(parser.getFileName());
lexer.setGrammarContent(lexerGrammarText);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public double getFitness(CandidateProgram program) {
try {
GECandidateProgram gecp = (GECandidateProgram) program;
System.out.println("Parsing:" + gecp.getSourceCode());
CharStream input = new ANTLRStringStream(gecp.getSourceCode());
Interpreter lexEngine = new Interpreter(lexer, input);
FilteringTokenStream tokens = new FilteringTokenStream(lexEngine);
StringTokenizer tk = new StringTokenizer(ignoreTokens, " ");
while (tk.hasMoreTokens()) {
String tokenName = tk.nextToken();
tokens.setTokenTypeChannel(lexer.getTokenType(tokenName), 99);
}
Interpreter parseEngine = new Interpreter(parser, tokens);
ParseTree t;
t = parseEngine.parse(startRule);
return 1.0 / t.toStringTree().length();
} catch (Exception e) {
// Something failed, return very big fitness, making it unfavorable
return Double.MAX_VALUE;
}
}
其中t.toStringTree()包含ParseTree。