Создание AST через API ANTLR в Java - PullRequest
1 голос
/ 02 ноября 2011

В настоящее время я работаю над проектом, который требует от меня создания грамматики 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.

...