为什么语义谓词在 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 一个 Token
,Token.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]*;
我有一个非常简单的语法,如下所示:
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 一个 Token
,Token.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]*;