В настоящее время я работаю над проектом, который требует от меня создания грамматики ANTLR на лету, потому что сгенерированный язык зависит от пользовательского ввода. Следовательно, я генерирую грамматику ANTLR в коде и генерирую из нее лексер и парсер.
Моя цель состоит в том, чтобы иметь программу ввода, написанную на языке сгенерированной грамматики (на самом деле она создается с помощью генетических алгоритмов, но здесь это не актуально), и в конечном итоге иметь AST, представляющий программу. Однако в настоящее время я могу генерировать только объект ParseTree, и этого недостаточно для моей программы.
Кто-нибудь знает, как использовать API ANTLR для генерации объекта, представляющего AST? (Например, объект antlr.collections.AST). Я добавлю фрагмент кода здесь, но лучший способ проверить это - запустить проект Eclipse, который находится в https://snowdrop.googlecode.com/svn/trunk/src/ANTLRTest/
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.