visitLiteralExpression

visitLiteralExpression

当前,我正在使用此ANTLR4语法(的一部分)来获取stringsnumbers

去图这个概括的语法:

gramm
 : expr SCOL
 ;

expr
 : literal          #LiteralExpression
 ;

literal
 : NUMERIC_LITERAL
 | STRING_LITERAL
 ;

NUMERIC_LITERAL
 : DIGIT+ ( '.' DIGIT* )? ( E [-+]? DIGIT+ )?
 | '.' DIGIT+ ( E [-+]? DIGIT+ )?
 ;

STRING_LITERAL
 : '\'' ( ~'\'' | '\'\'' )* '\''
 ;

SPACES
 : [ \u000B\t\r\n] -> channel(HIDDEN)
 ;

fragment DIGIT : [0-9];


因此,我正在实现GrammBaseVisitor<Void>

我不太想知道如何检查文字是NUMERIC_LITERAL还是STRING_LITERAL

到目前为止,我已经覆盖了visitLiteral()visitLiteralExpression()

@Override
public Void visitLiteral(LiteralContext ctx) {
    // TODO What should I do here in order to check whether
    // ctx contains an STRING_LITERAL or a NUMBER_LITERAL?
    return super.visitLiteral(ctx);
}

@Override
public Void visitLiteralExpression(LiteralExpressionContext ctx) {
    return super.visitLiteralExpression(ctx);
}


visitLiteralvisitLiteralExpression()有什么区别?

最佳答案

您的literal生产包括两个可能的终端,即数字和字符串文字。解析的输入是否包含一个或另一个,您可以使用null检查visitLiteral中的内容来确定。

@Override
public Object visitLiteral(LiteralContext ctx) {
    TerminalNode numeric = ctx.NUMERIC_LITERAL();
    TerminalNode string = ctx.STRING_LITERAL();
    if (numeric != null) {
        System.out.println(numeric.getSymbol().getType());
    } else if (string != null) {
        System.out.println(string.getSymbol().getType());
    }
    return super.visitLiteral(ctx);
}


您可以通过覆盖visitTerminal来访问所有终端。

@Override
public Object visitTerminal(TerminalNode node) {
    int type = node.getSymbol().getType(); // matches a constant in your parser

    switch (type) {
        case GrammParser.NUMERIC_LITERAL:
            System.out.println("numeric literal");
            break;
        case GrammParser.STRING_LITERAL:
            System.out.println("string literal");
            break;
    }

    System.out.println(node.getSymbol().getText());
    return super.visitTerminal(node);
}



  visitLiteral和visitLiteralExpression()有什么区别?


前者代表您的literal生产,后者代表您的expr生产。请注意,#符号在ANTLR 4语法中具有特殊含义,表示标签-生产中替代品的名称。这不是评论。由于您的expr只有一种选择,因此它将变为visitLiteralExpression。尝试将其注释掉(//),然后查看生成的代码更改。

10-07 13:34