2011-08-15 90 views
3

我有一個規則匹配的字符串,看起來像這樣:ANTLR的詞法分析規則

STRING 
    : '"' (~('"' | '\\') | '\\' .)* '"' 
    ; 

我不想引號是標記文本的一部分。在Antlr2中,我會在引號後面加上'!',告訴Antlr不要將它們添加到文本中。

注意'!'下面是

STRING 
    : '"'! (~('"' | '\\') | '\\' .)* '"'! 
    ; 

然而,在Antlr3我再也不能這樣做,因爲我得到的錯誤:

warning(149): Crv__.g:0:0: rewrite syntax or operator with no output option; setting output=AST 

我不知道我是否可以使用一個重寫規則這裏我不知道該怎麼寫匹配所有標記'。'

我唯一的想法是抓住匹配的文本並且不用引號就可以返回它,但我不確定如何做到這一點,因爲令牌尚未創建。

我正在使用C Antlr運行時。 我該如何做到這一點?

回答

1

對於後代我會提到我是如何解決這個問題的。

我使用的@after塊剝去引號

STRING 
@after 
{ 
    SETTEXT(GETTEXT()->substring(GETTEXT(),1,GETTEXT()->len-1)) 
} 
: '"' (~('"' | '\\') | '\\' .)* '"' 
; 
+0

在這種情況下,您將要刪除感嘆號。此外,您現在只刪除引號,但留下可能在其中跳出其他字符的反斜槓:我希望它們在引號時被刪除從標記中剝離 –

+0

@感謝!你是對的事實上,最初的問題是ANTLR 3不允許感嘆號: )我從記憶中重新輸入了我的答案。我已經更新了我的答案。 – chollida

+0

沒有比添加這種耗時的操作更好的解決方案嗎? –

0

這是我最終使用的溶液:

STRING   :  '"'   { \$s = ""; } 
       ( '"' '"'   { \$s .= '"';} 
       | c=CHAR   { \$s .= \$c->gettext();} 
       | ' '    { \$s .= ' ';} 
       )* 
       '"'     { \$this->setText(\$s); } 
    ; 



fragment CHAR  : (ACCENT|SPECIAL|ALPHA|DIGIT); 
fragment ACCENT  : '\u00C0'..'\u00D6' | '\u00D9'..'\u00DD' | '\u00E0'..'\u00F6' |'\u00F9'..'\u00FD'; 
fragment SPECIAL : '.' | '!' | '-'| '?'; 
fragment ALPHA  : 'a'..'z' | 'A'..'Z'; 
fragment DIGIT  : '0'..'9' ; 

有一個微小的差別,這是我有字符的白名單出於安全原因。

但主要的區別是,我建立結果字符串遞增,折騰了「字符。

我在PHP語言就是,這就是爲什麼有\ $ 你知道哪一個是更快?

+0

我看到的最大區別是我的解決方案使用通配符'。'匹配任何符號。您必須在列表中指定每個符號。例如,你的字符串'cant'目前包含很多常見的標點符號,比如一個分號':',儘管你可以修復它。你有一個很好的解決方案,我希望我早點想到它。 – chollida

相關問題