2011-08-15 62 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

相关问题