0
我试图在词法分析器中使用语义谓词来展望一个标记,但不知何故我无法正确理解它。下面是我有:ANRLR4词法分析器语义谓词问题
词法语法
lexer grammar TLLexer;
DirStart
: { getCharPositionInLine() == 0 }? '#dir'
;
DirEnd
: { getCharPositionInLine() == 0 }? '#end'
;
Cont
: 'contents' [ \t]* -> mode(CNT)
;
WS
: [ \t]+ -> channel(HIDDEN)
;
NL
: '\r'? '\n'
;
mode CNT;
CNT_DirEnd
: '#end' [ \t]* '\n'?
{ System.out.println("--matched end--"); }
;
CNT_LastLine
: ~ '\n'* '\n'
{ _input.LA(1) == CNT_DirEnd }? -> mode(DEFAULT_MODE)
;
CNT_Line
: ~ '\n'* '\n'
;
解析器语法
parser grammar TLParser;
options { tokenVocab = TLLexer; }
dirs
: (dir
| NL
)*
;
dir
: DirStart Cont
contents
DirEnd
;
contents
: CNT_Line* CNT_LastLine
;
基本上在CNT模式的东西,每一行是免费的形式,但它从来没有开始#end后跟可选空白。基本上我希望在默认词法分析器模式下保持匹配#结束标记。
我的测试输入如下:
#dir contents
..line..
#end
如果我在GRUN运行此我得到以下
$ grun TL dirs test.txt
--matched end--
line 3:0 extraneous input '#end\n' expecting {CNT_LastLine, CNT_Line}
所以很明显CNT_DirEnd得到匹配,但不知何故谓词没有检测到。
我知道这个特定任务不需要语义谓词,但这只是不起作用的部分。实际的解析器,虽然它可能没有谓词,但如果我简单地将标签的匹配移动到模式CNT中,将会不那么干净。
谢谢,
Kesha。
看来CNT_Line定义是优雅不匹配'..线..' –
@ThomasG它匹配它,你可以用-gui选项看到它,或者如果你添加打印动作到CNT_Line(然后grun打印它3次,因为它永远不会逃脱CNT模式)和CNT_LastLine(从不打印)。 –