我試圖匹配英文輸入文本中的測量,使用Antlr 3.2和Java1.6。我有詞法規則如下所示:Antlr3匹配lexeme變體
fragment
MILLIMETRE
: 'millimetre' | 'millimetres'
| 'millimeter' | 'millimeters'
| 'mm'
;
MEASUREMENT
: MILLIMETRE | CENTIMETRE | ... ;
我希望能接受大寫和小寫輸入的任意組合 - 更重要的是 - 只返回一個單一的詞彙令牌的所有變種毫米。但目前,我的AST包含「毫米」,「毫米」,「毫米」等,就像在輸入文本中一樣。
閱讀http://www.antlr.org/wiki/pages/viewpage.action?pageId=1802308後,我想我需要做類似如下:
tokens {
T_MILLIMETRE;
}
fragment
MILLIMETRE
: ('millimetre' | 'millimetres'
| 'millimeter' | 'millimeters'
| 'mm') { $type = T_MILLIMETRE; }
;
然而,當我這樣做,我得到了ANTLR的生成的Java代碼以下編譯器錯誤:
cannot find symbol
_type = T_MILLIMETRE;
我嘗試以下代替:
MEASUREMENT
: MILLIMETRE { $type = T_MILLIMETRE; }
| ...
但之後MEASUREMENT不再匹配。
與重寫規則更明顯的解決方案:
MEASUREMENT
: MILLIMETRE -> ^(T_MILLIMETRE MILLIMETRE)
| ...
導致NPE:
java.lang.NullPointerException at org.antlr.grammar.v2.DefineGrammarItemsWalker.alternative(DefineGrammarItemsWalker.java:1555).
使測量到解析器規則給了我可怕的「下面的標記定義不能匹配因爲之前的令牌匹配相同的輸入「錯誤。
通過創建一個解析器規則
measurement : T_MILLIMETRE | ...
我得到警告「對應令牌的詞法規則:T_MILLIMETRE」。雖然Antlr運行,但它仍然給我在AST中的輸入文本,而不是T_MILLIMETRE。
我顯然還沒有像Antlr那樣看世界。任何人都可以給我任何提示或建議嗎?
史蒂夫
感謝您的迴應,Bart。我意識到這種可能性。不同之處在於我試圖在詞彙層面解決問題,而您提出了一個語法規則。你的方式可能是正確的Antlr方式。我對這個問題的經驗是重寫規則只適用於句法規則,而不適用於詞法規則。我現在通過在Java代碼中對結果進行後處理來解決問題,但是我應該重新考慮我在詞彙層面所做的工作以及我在語法層面所做的工作。 – 2010-09-30 14:09:33
@Stephen,好吧,我明白你的意思了。但在我的例子中,類型(毫米)總是「MilliMeter」(參見我的**編輯**)。所以我不完全確定你在做什麼。 – 2010-09-30 14:20:19
你讓我覺得,巴特。我以錯誤的方式接近了這個問題。我試圖通過對詞法分析進行上下文敏感來有效地進行自下而上的認識。這意味着我很快達到了Antlr能夠做到的極限,因爲它是一種自上而下的工具。現在我已經將很多分析轉移到了語法中(比如在你的例子中),並且一切都變得更加容易。我認爲人們必須非常清楚Antlr中的詞法規則和語法規則之間的差別,即使它們看起來非常相似。並非所有句法規則都可以用詞彙表達。 – 2010-10-01 15:12:34