2010-01-31 94 views
5

我有我認爲是一個簡單的ANTLR問題。我有兩種令牌類型:identspecial_ident。我希望我的special_ident匹配一個字母后跟一個數字。我希望通用ident匹配一個字母,可選地跟隨任意數量的字母或數字。我(不正確)的語法如下:我的ANTLR詞法分析器如何匹配由另一種令牌子集的字符組成的令牌?

expr 
    : special_ident 
    | ident 
    ; 

special_ident : LETTER DIGIT; 
ident   : LETTER (LETTER | DIGIT)*; 

LETTER : 'A'..'Z'; 
DIGIT : '0'..'9'; 

當我嘗試檢查這個語法,我得到這樣的警告:

決策可以匹配輸入如「字母數字」使用多個備選方案:1, 2. 其結果是,可替代(S)2爲輸入

我明白,我的語法是不明確的,並且輸入禁用如A1兩者都可以匹配identspecial_ident。我真的只想在最狹窄的情況下使用special_ident

下面是一些示例輸入想什麼,我以匹配:

A  : ident 
A1  : special_ident 
A1A : ident 
A12 : ident 
AA1 : ident 

我怎樣才能形成我的語法,這樣我正確識別我的兩個標識類型?

回答

2

擴大對卡爾的想法,我就猜你有四種不同的情況:

  1. 一個
  2. AN
  3. AA(A | N)*
  4. AN(A | N)+

僅OP重刑2應該是標記special_ident和其他三個應該是身份。所有的令牌都可以通過語法來識別。這是一個我能夠在ANTLRWorks中測試的快速語法,它對我來說似乎正常工作。我認爲卡爾試圖檢查AA時可能會有一個錯誤,但讓你99%有很大的好處,所以這只是他敏捷思想的一個小修改。

prog 
    : (expr WS)+ EOF; 

expr 
    : special_ident {System.out.println("Found special_ident:" + $special_ident.text + "\n");} 
    | ident {System.out.println("Found ident:" + $ident.text + "\n");} 
    ; 

special_ident : LETTER DIGIT; 

ident   : LETTER 
    |LETTER DIGIT (LETTER|DIGIT)+ 
    |LETTER LETTER (LETTER|DIGIT)*; 

LETTER : 'A'..'Z'; 
DIGIT : '0'..'9'; 
WS 
    : (' '|'\t'|'\n'|'\r')+; 
+0

謝謝......我認爲這一切都更有意義。是'ident'多餘的最後一個選項? 「LETTER LETTER」不會使整個規則等同嗎?另外,對於整個規則來說,是否應該說'LETTER LETTER?'|字母數字(字母|數字)+'? – 2010-02-01 19:20:00

+0

有幾種不同的方法可以讓規則(我認爲),我只是確保字母數字有另一個字母或數字後,將其與special_ident規則分開。之後的LETTER LETTER選項不需要更多的令牌。這就是爲什麼有一個加號,另一個有星號。 – WayneH 2010-02-01 23:26:54

3

看來你有三種情況:

  • A
  • AN
  • A(A|N)(A|N)+

你可以中間一個爲special_ident,另兩個爲ident分類;似乎應該做的伎倆。

我對ANTLR有些生疏,我希望這個提示就夠了。我可以嘗試寫出來給你的表情,但他們可能是錯誤的:

long_ident : LETTER (LETTER | DIGIT) (LETTER | DIGIT)+ 
special_ident : LETTER DIGIT; 
ident   : LETTER | long_ident;