2012-03-13 73 views
2

特定號碼在我的語法我有這樣的事情:匹配到一個非貪婪的方式重複在ANTLR

line : startWord (matchPhrase| 
        anyWord matchPhrase| 
        anyWord anyWord matchPhrase| 
        anyWord anyWord anyWord matchPhrase| 
        anyWord anyWord anyWord anyWord matchPhrase) 
     -> ^(TreeParent startWord anyWord* matchPhrase); 

所以我想匹配的matchPhrase第一次出現,但我會允許在它之前達到一定數量的anyWord。組成matchPhrase的令牌也與anyWord匹配。

有沒有更好的方法來做到這一點?

我認爲它可能是由語義謂詞in this answer與非貪婪選項結合成爲可能:

(options {greedy=false;} : anyWord)* 

,但我無法弄清楚究竟是如何做到這一點。

編輯:下面是一個例子。我想從下面的句子中提取信息:

Picture of a red flower. 

Picture of the following: A red flower. 

我輸入實際被標記的英語句子,和詞法規則相匹配的標籤,而不是單詞。所以輸入到ANTLR是:

NN-PICTURE Picture IN-OF of DT a JJ-COLOR red NN-FLOWER flower 

NN-PICTURE Picture IN-OF of DT the VBG following COLON : DT a JJ-COLOR red NN-FLOWER flower 

我有詞法規則,這樣每個標籤:

WS : (' ')+ {skip();}; 
TOKEN : (~' ')+; 

nnpicture:'NN-PICTURE' TOKEN -> ^('NN-PICTURE' TOKEN); 
vbg:'VBG' TOKEN -> ^('VBG' TOKEN); 

我的語法規則是這樣的:

sentence : nnpicture inof matchFlower; 

matchFlower : (dtTHE|dt)? jjcolor? nnflower; 

當然,但這將在第二句話中失敗。所以我想通過在花比賽之前允許多達N個令牌來允許一點靈活性。我有一個匹配任何一個anyWord令牌,以及以下工作:

sentence : nnpicture inof (matchFlower | 
          anyWord matchFlower | 
          anyWord anyWord matchFlower | etc. 

,但它是不是很優雅,並且不與大N.很好地工作

+0

@BartKiers:對不起,我沒有解釋它是那麼好 - ' matchPhrase'是'anyWord'的一個子集,所以可能會有一些單詞不在'matchPhrase'之前的'matchPhrase'中,並且它們會被'anyWord'匹配。但是因爲它是一個子集,所以'anyWord'匹配需要非貪婪,否則'matchPhrase'字將與'anyWord'匹配。因此,爲什麼我不能做'任何語言?任何單詞?任何單詞? matchPhrase'。 – 2012-03-14 10:13:23

+0

@Matt,我明白你的意思了。如果有人在我面前不這樣做,我會在今天晚上回答你(我在ATM工作)。 – 2012-03-14 10:47:48

回答

2

您可以先檢查做使用syntactic predicatematchFlower規則裏面如果存在真的dt? jjcolor? nnflower在它的令牌流中。如果這樣的令牌可以看到,只需匹配它們,如果不匹配,則匹配任何令牌,並遞歸匹配matchFlower。這看起來像:

matchFlower 
: (dt? jjcolor? nnflower)=> dt? jjcolor? nnflower -> ^(FLOWER dt? jjcolor? nnflower) 
|       . matchFlower   -> matchFlower 
; 

注意,.(點)語法分析規則中確實匹配任何字符,但任何標記。

這裏有一個快速演示:

grammar T; 

options { 
    output=AST; 
} 

tokens { 
    TEXT; 
    SENTENCE; 
    FLOWER; 
} 

parse 
: sentence+ EOF -> ^(TEXT sentence+) 
; 

sentence 
: nnpicture inof matchFlower -> ^(SENTENCE nnpicture inof matchFlower) 
; 

nnpicture 
: NN_PICTURE TOKEN -> ^(NN_PICTURE TOKEN) 
; 

matchFlower 
: (dt? jjcolor? nnflower)=> dt? jjcolor? nnflower -> ^(FLOWER dt? jjcolor? nnflower) 
|       . matchFlower   -> matchFlower 
; 

inof 
: IN_OF (t=IN | t=OF) -> ^(IN_OF $t) 
; 

dt 
: DT (t=THE | t=A) -> ^(DT $t) 
; 

jjcolor 
: JJ_COLOR TOKEN -> ^(JJ_COLOR TOKEN) 
; 

nnflower 
: NN_FLOWER TOKEN -> ^(NN_FLOWER TOKEN) 
; 

IN_OF  : 'IN-OF'; 
NN_FLOWER : 'NN-FLOWER'; 
DT   : 'DT'; 
A   : 'a'; 
THE  : 'the'; 
IN   : 'in'; 
OF   : 'of'; 
VBG  : 'VBG'; 
NN_PICTURE : 'NN-PICTURE'; 
JJ_COLOR : 'JJ-COLOR'; 
TOKEN  : ~' '+; 
WS   : ' '+ {skip();}; 

從語法生成上面會分析你輸入解析器:如下

NN-PICTURE Picture IN-OF of DT the VBG following COLON : DT a JJ-COLOR red NN-FLOWER flower 

enter image description here

,你可以看,在樹的花被省略之前的一切。如果你想守在那裏這些令牌,做這樣的事情:

grammar T; 

// ... 

tokens { 
    // ... 
    NOISE; 
} 

// ... 

matchFlower 
: (dt? jjcolor? nnflower)=> dt? jjcolor? nnflower -> ^(FLOWER dt? jjcolor? nnflower) 
|       t=. matchFlower  -> ^(NOISE $t) matchFlower 
; 

// ... 

導致以下AST:

enter image description here

+0

感謝您的詳細解答。這是完美的,正是我需要的。 – 2012-03-14 21:39:27

+0

不客氣,@Matt。 – 2012-03-14 21:57:24