antlr4 - вызов функции парсинга - PullRequest
1 голос
/ 07 февраля 2020

У меня есть следующие правила:

functionInv
    : NAME paramInvList #functionInvStmt
    ;
paramInvList
    : BRO BRC
    | BRO expression (',' expression )* BRC
    ;

и соответствующий класс Ast:

public class FunctionInvocationExpr implements Ast {
    private final String target;
    private final List<Ast> arguments;

    public FunctionInvocationExpr(String target, List<Ast> arguments) {
        this.target = target;
        this.arguments = arguments;
    }

    @Override
    public <T> T accept(AstVisitor<T> visitor) {
        return visitor.visitFunctionInvocationExpr(this);
    }
}

Вопрос в том, как мне go перейти от одного к другому. Поиск в Google не помог. Может ли кто-нибудь указать мне правильное направление? Я использую генерацию кода посетителя.

1 Ответ

1 голос
/ 08 февраля 2020

Когда вы генерируете свои классы лексеров и анализаторов, вам нужно добавить параметр -visitor, чтобы ANTLR сгенерировал для вас посетителей по умолчанию:

java -jar antlr-4.8-complete.jar -visitor Test.g4

это создаст класс TestBaseVisitor<T> для Вы:

public class TestBaseVisitor<T> extends AbstractParseTreeVisitor<T> implements TestVisitor<T> {

    @Override
    public T visitFunctionInvStmt(TestParser.FunctionInvStmtContext ctx) { return visitChildren(ctx); }

    @Override
    public T visitParamInvList(TestParser.ParamInvListContext ctx) { return visitChildren(ctx); }

    @Override
    public T visitExpression(TestParser.ExpressionContext ctx) { return visitChildren(ctx); }

    // ...
}

, который вы можете расширить и заставить его возвращать свои собственные Ast узлы:

class AstVisitorBuilder extends TestBaseVisitor<Ast> {

    @Override
    public Ast visitFunctionInvStmt(TestParser.FunctionInvStmtContext ctx) {

        final String functionName = ctx.NAME().getText();
        final List<Ast> arguments = new ArrayList<>();

        if (ctx.paramInvList().expression() != null) {
            for (TestParser.ExpressionContext expression : ctx.paramInvList().expression()) {
                arguments.add(this.visitExpression(expression));
            }
        }

        return new FunctionInvocationExpr(functionName, arguments);
    }

    @Override
    public Ast visitExpression(TestParser.ExpressionContext ctx) {
        return null; // TODO return your expression AST node here
    }

    // ...
}

Вызов этого можно выполнить следующим образом:

TestLexer lexer = new TestLexer(new ANTLRInputStream("your source code"));
TestParser parser = new TestParser(new CommonTokenStream(lexer));
Ast ast = new AstVisitorBuilder().visit(parser.functionInv());
// ...
...