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(從不打印)。 –