ANTLR4 -> 检查文字是 STRING_LITERAL 还是 NUMBER_LITERAL
ANTLR4 -> Check a literal is STRING_LITERAL or a NUMBER_LITERAL
目前,我正在使用这个 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
产生式由两个可能的终端组成,即数字和字符串文字。解析后的输入是否包含一个或另一个,您可以在 visitLiteral
.
中使用 null
检查来确定
@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);
}
What's the difference between visitLiteral and visitLiteralExpression()?
前者代表你的literal
作品,后者代表你的expr
作品。请注意,#
符号在 ANTLR 4 语法中具有特殊含义,代表一个标签 - 产品内部备选方案的名称。这不是评论。因为你的expr
只有一个选择,所以变成了visitLiteralExpression
。尝试将其注释掉 (//
) 并查看生成的代码更改。
目前,我正在使用这个 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
产生式由两个可能的终端组成,即数字和字符串文字。解析后的输入是否包含一个或另一个,您可以在 visitLiteral
.
null
检查来确定
@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);
}
What's the difference between visitLiteral and visitLiteralExpression()?
前者代表你的literal
作品,后者代表你的expr
作品。请注意,#
符号在 ANTLR 4 语法中具有特殊含义,代表一个标签 - 产品内部备选方案的名称。这不是评论。因为你的expr
只有一个选择,所以变成了visitLiteralExpression
。尝试将其注释掉 (//
) 并查看生成的代码更改。