为什么语义谓词在 ANTLR4 中不起作用

Why are Semantic Predicates not working in ANTLR4

我有一个非常简单的语法,如下所示:

grammar Testing;

a :  d | b;
b : {_input.LT(1).equals("b")}? C;
d : {!_input.LT(1).equals("b")}? C;
C : .;

它从输入中解析一个字符并检查它是否等于字符 b。如果是,则使用规则b,如果不是,则使用规则d。

然而,解析树没有达到预期并使用第一条规则(规则 d)解析所有内容。

$ antlr Testing.g4
$ javac *.java
$ grun Testing a -trace                                                                                                                                                                                                                                     (base) 
c
enter   a, LT(1)=c
enter   d, LT(1)=c
consume [@0,0:0='c',<1>,1:0] rule d
exit    d, LT(1)=

exit    a, LT(1)=

$ grun Testing a -trace                                                                                                                                                                                                                                     (base) 
b
enter   a, LT(1)=b
enter   d, LT(1)=b
consume [@0,0:0='b',<1>,1:0] rule d
exit    d, LT(1)=

exit    a, LT(1)=

在这两种情况下,都使用规则 d。但是,由于规则 d 上有守卫,我希望当第一个字符恰好是 'b'.

时规则 d 会失败

我是不是在使用语义谓词时做错了什么?

(我需要使用语义谓词,因为我需要解析一种可以使用关键字作为标识符的语言)。

参考:https://github.com/antlr/antlr4/blob/master/doc/predicates.md

_input.LT(int) return 一个 TokenToken.equals(String) 将始终 return false。您要做的是在 Token:

上调用 getText()
b : {_input.LT(1).getText().equals("b")}? C;
d : {!_input.LT(1).getText().equals("b")}? C;

但是,通常以这种方式处理关键字作为标识符会更容易:

rule
 : KEYWORD_1 identifier
 ;

identifier
 : IDENTIFIER
 | KEYWORD_1
 | KEYWORD_2
 | KEYWORD_3
 ;

KEYWORD_1 : 'k1';
KEYWORD_2 : 'k2';
KEYWORD_3 : 'k3';

IDENTIFIER : [a-zA-Z_] [a-zA-Z_0-9]*;