Antlr lexer语义谓词的替代方案

时间:2013-10-09 21:33:11

标签: antlr antlr4

鉴于语法:

grammar Test;
words: (WORD|SPACE|DOT)+;
WORD : (
       LD
       |DOT       {_input.LA(1)!='.'}?
       ) +        ;
DOT: '.';
SPACE: ' ';
fragment LD: ~[.\n\r ];

使用Antlr4生成Lexer,输入:

test. test.test test..test

令牌序列如下:

[@0,0:4='test.',<1>,1:0]
[@1,5:5=' ',<3>,1:5]
[@2,6:14='test.test',<1>,1:6]
[@3,15:15=' ',<3>,1:15]
[@4,16:19='test',<1>,1:16]
[@5,20:20='.',<2>,1:20]
[@6,21:25='.test',<1>,1:21]
[@7,26:25='<EOF>',<-1>,1:26]

令人困惑的是为什么最后一段文字test..test被标记为test ..test,而我应该看到test. {{1 }}

更令我困惑的是输入:

.test

令牌序列是:

test..test test. test.test

此处[@0,0:3='test',<1>,1:0] [@1,4:4='.',<2>,1:4] [@2,5:9='.test',<1>,1:5] [@3,10:10=' ',<3>,1:10] [@4,11:14='test',<1>,1:11] [@5,15:15='.',<1>,1:15] [@6,16:16=' ',<3>,1:16] [@7,17:20='test',<1>,1:17] [@8,21:25='.test',<1>,1:21] [@9,26:25='<EOF>',<-1>,1:26] 分为两个标记,而在上方则为一个。 调用_input.LA(1)是否会产生一些副作用?有人可以解释一下吗?

我正在使用Antlr4。

1 个答案:

答案 0 :(得分:0)

快速解决方法是检查上一个LA(-1)令牌是否不等.并添加前导可选DOT

结果语法是:

grammar Test;
words: (WORD|SPACE|DOT)+;
WORD : DOT? (
       LD
       |{_input.LA(-1)!='.'}? DOT       
       ) +        ;
DOT: '.';
SPACE: ' ';
fragment LD: ~[.\n\r ];

玩得开心,享受ANTLR,这是一个很好的工具。