2013-07-18 107 views
3

我想匹配形式的輸入::ANTLR4:不匹配的輸入

commit a1b2c3 
Author: Michael <[email protected]> 

commit d3g4 
Author: David <[email protected]> 

這是我寫的語法:

grammar commit; 

file : commitinfo+; 

commitinfo : commitdesc authordesc; 
commitdesc : 'commit' COMMITHASH NEWLINE; 
authordesc : 'Author:' AUTHORNAME '<' EMAIL '>' NEWLINE; 

COMMITHASH : [a-z0-9]+; 
AUTHORNAME : [a-zA-Z]+; 
EMAIL  : [[email protected]]+; 
NEWLINE : '\r'?'\n'; 
WHITESPACE : [ \t]->skip; 

上述解析器的問題是,對於上面的輸入它完美匹配。但是,當輸入變爲:

commit c1d2 
Author: michael <[email protected]> 

它引發等的錯誤:期待AUTHORNAME 8不匹配的輸入 '邁克爾':

線2。

當我打印的標記,似乎字符串「邁克爾」獲取令牌COMMITHASH而不是AUTHORNAME匹配。

如何解決上述情況?

回答

4

ANTLR4根據它們被寫入的順序匹配詞法分析規則。

'michael'獲得匹配的規則COMMITHASH : [a-z0-9]+ ;出現在規則AUTHORNAME之前,因此你有錯誤。

我能想到的下列選項來解決你所面臨的問題:

  • 可以使用'mode'功能在ANTLR:在ANTLR 4,一個詞法分析器模式是活動的時間,該模式規則中的最長non-fragment lexer rule將確定創建哪個令牌。您的語法僅包含默認模式,因此所有詞法分析規則都處於活動狀態,因此「michael」匹配爲COMMITHASH,因爲匹配的標記長度與COMMITHASHAUTHORNAME相同,但COMMITHASH在語法中出現在AUTHORNAME之前。

  • 您可以通過交換它們出現在語法的方法改變你的詞法規則。假設你的COMMITHASH規則總是有一個與它匹配的數字。把AUTHORNAMECOMMITHASH之前通過以下方式:

    grammar commit; 
    ... 
    
    AUTHORNAME : [a-zA-Z]+; 
    COMMITHASH : [a-z0-9]+; 
    ... 
    

注:我強烈地感覺到你的詞法規則不脆寫入。你確定你的COMMITHASH規則應該是[a-z0-9]+;這意味着像'abhdks'令牌也會被你COMMITHASH規則匹配。但這完全是一個不同的問題。

+0

RISHABH您好,感謝。我使用詞法模式解決它。 – Ramg