ANTLR4 - >检查文字是STRING_LITERAL还是NUMBER_LITERAL

时间:2016-05-05 06:13:21

标签: java antlr

目前,我使用此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()之间的区别是什么?

1 个答案:

答案 0 :(得分:1)

您的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。尝试对其进行评论(//)并查看生成的代码更改。