2012-06-24 41 views
0

我有非常簡單的XML(HTML)解析ANTLR語法:ANTLR中的空白有什麼問題?

wiki: ggg+; 

ggg: tag | text; 

tag: '<' tx=TEXT { System.out.println($tx.getText()); } '>'; 

text: tx=TEXT { System.out.println($tx.getText()); }; 

CHAR: ~('<'|'>'); 
TEXT: CHAR+; 

有了這樣輸入:"<ggg> fff"它工作正常。

但是當我開始處理空白時失敗。例如:

  • " <ggg> fff " - 失敗在beggining
  • "<ggg> <hhh> " - 工作正常
  • "<ggg> " - - <ggg>
  • "<ggg> fff "失敗後,未能在年底

我不知道是什麼錯誤。也許有一些特殊的語法選項來處理這個問題。 ANTLRWorks給我NoViableAltException

回答

3

ANTLR的詞法規則,儘可能地匹配。只有當兩個(或更多)規則匹配相同數量的字符時,首先定義的規則纔會「贏」。因此,除了'<''>'以外的單個字符被標記爲CHAR標記,而不是標記爲TEXT標記,無論分析器「需要」(詞法分析器獨立於分析器操作,請記住!)。除'<''>'之外,只有兩個或更多字符被標記爲(單個)TEXT令牌。

所以,爲此輸入" <ggg> fff "創建以下5個標記:

type | text 
--------+----------- 
CHAR | ' ' 
'<'  | '<' 
TEXT | 'ggg' 
'>'  | '>' 
TEXT | ' fff ' 

而且由於令牌CHAR在解析器規則(一個或多個)不佔,解析失敗。

只需刪除CHAR做:

TEXT : ~('<'|'>')+; 
1

你沒有處理這個空間的標記。詞法分析器的空間與可能遇到的任何其他字符沒有區別。

如果空白是不重要的,你可以簡單地使用:

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

如果空白是對你很重要:

WHITESPACE : ('\t' | ' ' | '\r' | '\n'| '\u000C')+ 
CHAR: ~('<'|'>'); 
TEXT: (CHAR|WHITESPACE)+; 
+0

空白字符對我很重要。 您寫道,詞法分析器的空間與其他任何字符沒有區別。 但在我的示例中,CHAR令牌應該匹配任何空格字符。所以它應該有效,但它不會。結論:詞法分析器的空白不同於其他字符! – pablo

+0

而你給的是錯誤的,因爲有多種選擇(WHITESPACE和CHAR)。 – pablo

+0

@pablo,你說得對,因爲你的詞法分析規則CHAR代表空格字符,但你的結論是錯誤的。我會在一個答案中很快解釋。 –