当前,我正在使用此ANTLR4语法(的一部分)来获取strings
和numbers
:
去图这个概括的语法:
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);
}
visitLiteral
和visitLiteralExpression()
有什么区别? 最佳答案
您的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
。尝试将其注释掉(//
),然后查看生成的代码更改。