目前,我使用此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()
之间的区别是什么?
答案 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
。尝试对其进行评论(//
)并查看生成的代码更改。