2012-06-25 97 views
1

我想創建應分析下列文件非常簡單ANTLR語法文件:我的簡單antlr語法有什麼問題?

Report (MyReport) 
Begin 
End 

或者不報告名稱:

Report 
Begin 
End 

這裏是我的語法文件:

grammar RL; 

options { 
    language = Java; 
} 

report: 
    REPORT ('(' SPACE* STRING_LITERAL SPACE* ')')? 
    BEGIN 
    END 
    ; 

REPORT 
    : 'Report' 
    ;  

BEGIN 
    : 'Begin' 
    ; 

END : 'End'; 

NAME: LETTER (LETTER | DIGIT | '_')*; 

STRING_LITERAL : NAME SPACE*; 

fragment LETTER: LOWER | UPPER; 

fragment LOWER: 'a'..'z'; 

fragment UPPER: 'A'..'Z'; 

fragment DIGIT: '0'..'9'; 

fragment SPACE: ' ' | '\t'; 

WHITESPACE: SPACE+ { $channel = HIDDEN; }; 

rule: ; 

但是,當我在ANTLRWorks調試時,我總是得到以下錯誤:

root -> report -> MismatchedTokenException(0!=0) 

我的語法文件有什麼問題?

感謝, 綠色

回答

3

一對夫婦的言論:

  • Java是默認的語言,所以你可以省略language=Java;;
  • 您在解析器規則中使用SPACE,而此SPACE令牌爲fragment:這會導致詞法分析器永遠不會創建此令牌:將其從解析器規則中移除;
  • 輸入"Report "(「報告」後跟單個空格)被標記爲STRING_LITERAL,而不是REPORT!只有當兩個或更多規則匹配相同數量的字符時,ANTLR的詞法分析器纔會貪婪地使用字符,首先定義的規則將優先。詞法分析器而不是產生解析器試圖匹配的標記(解析和標記化是獨立執行的!)。

嘗試,而不是執行以下操作:

grammar RL; 

report 
: REPORT ('(' NAME ')')? BEGIN END 
; 

REPORT : 'Report';  
BEGIN : 'Begin'; 
END : 'End'; 
NAME : LETTER (LETTER | DIGIT | '_')*; 

fragment LETTER : LOWER | UPPER; 
fragment LOWER : 'a'..'z'; 
fragment UPPER : 'A'..'Z'; 
fragment DIGIT : '0'..'9'; 

SPACE : (' ' | '\t' | '\r' | '\n')+ { $channel = HIDDEN; }; 

green wrote:

What if I want to allow "SPACE" inside Report NAME?

我仍然會跳過的詞法空間。接受名稱之間的空格但忽略其他上下文中的空格會導致一些笨拙的規則。相反,佔報告的名稱之間的空間,我會做這樣的事情:

report 
: REPORT ('(' report_name ')')? BEGIN END 
; 

report_name 
: NAME+ 
; 

導致以下分析樹:

enter image description here

爲輸入:

Report (a name with spaces) 
Begin 
End

green wrote:

so is it possible to allow me use reserved words like 'Report' in the name?

當然,明確地將它們添加到report_name規則:

report_name 
: (NAME | REPORT | BEGIN | END)+ 
; 
+0

非常感謝。如果我想讓報告名稱中包含「SPACE」,該怎麼辦? –

+0

@green,不客氣。看到我編輯的答案。 –

+0

我遵循「report_name」方法,並得到此錯誤:「T:\ tmp \ RL \ RL.g:11:1:以下標記定義永遠無法匹配,因爲之前的標記匹配相同的輸入:REPORT_NAME」。源代碼在https://gist.github.com/2991022 –