2014-02-05 76 views
2

使用ANTLR 4.2,我想這個測試數據的一個非常簡單的解析:ANTLR4詞法語法爲了不解決歧義

RRV0#ABC 

使用最小的語法:

grammar Tiny; 

thing : RRV N HASH ID ; 

RRV : 'RRV' ; 
N : [0-9]+ ; 
HASH : '#' ; 
ID : [a-zA-Z0-9]+ ; 
WS : [\t\r\n]+ -> skip ; // match 1-or-more whitespace but discard 

我期待詞法分析器RRV到ID匹配之前,基於從特倫斯帕爾的權威ANTLR 4參考下面的摘錄:

BEGIN : 'begin' ; // match b-e-g-i-n sequence; ambiguity resolves to BEGIN 
ID : [a-z]+ ; // match one or more of any lowercase letter 

潤寧的ANTLR4試驗檯上面的測試數據,則輸出是

[@0,0:3='RRV0',<4>,1:0] 
[@1,4:4='#',<3>,1:4] 
[@2,5:7='ABC',<4>,1:5] 
[@3,10:9='<EOF>',<-1>,2:0] 
line 1:0 mismatched input 'RRV0' expecting 'RRV' 

我可以看到所述第一令牌是< 4> ID,其值爲「RRV0」

我試圖重新排列詞法分析器項目順序。我也嘗試通過在語法規則中顯式匹配來使用隱式詞法分析器項目(而不是通過明確的詞法分析器項目)。我嘗試讓比賽不貪心。那些對我來說並不成功。

如果我將lexed ID項目更改爲不匹配大寫,那麼RRV項目會匹配,並且解析將進一步進行。

我從ANTLR 4.1開始就有同樣的問題。

我檢查了ANTLRWorks和命令行,結果都是一樣的。

如何更改語法以匹配詞法分析器項目RRV優先於ID?

回答

5

語法順序解析策略僅適用於兩個不同詞法分析器規則匹配相同長度的標記時。當長度不同時,最長的一個總會贏。在你的情況下,ID規則匹配長度爲4的令牌,該令牌比只有3個字符的RRV令牌長。

這種策略在像Java這樣的語言中特別重要。考慮下面的輸入:

String className = ""; 

隨着以下兩個語法規則(略微簡化的):

CLASS : 'class'; 
ID : [a-zA-Z_] [a-zA-Z0-9_]*; 

如果我們只考慮語法順序,則輸入className將產生一個關鍵字之後是標識符Name。重新排列規則不會解決問題,因爲那樣就不可能創建CLASS令牌,即使對於輸入class也是如此。

+0

這是非常有意義的。可以寫成明確匹配'RRV'作爲標記的語法?我猜想我需要選擇匹配ID,然後使用更多代碼來檢查ID是「RRV」 – Colin