【问题标题】:Antlr Lexer rulesAntlr 词法分析器规则
【发布时间】:2011-08-15 01:16:22
【问题描述】:

我有一个规则来匹配一个看起来像这样的字符串:

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

我不希望引号成为标记文本的一部分。在 Antlr2 中,我只需将 '!' 放在引号之后,告诉 Antlr 不要将它们添加到文本中。

注意下面的 '!'。

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

但是在 Antlr3 中我不能再这样做了,因为我得到了错误:

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

我不知道我是否可以在这里使用重写规则,因为我不知道如何编写匹配所有令牌'。'

我唯一的另一个想法是获取匹配的文本并在不带引号的情况下返回它,但我不确定如何执行此操作,因为尚未创建令牌。

我正在使用 C Antlr 运行时。 我怎样才能做到这一点?

【问题讨论】:

    标签: antlr3 lexer


    【解决方案1】:

    为了后人,我会提到我最终是如何解决这个问题的。

    我使用了@after 块来去除引号

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

    【讨论】:

    • 在这种情况下,您需要删除感叹号。此外,您现在只删除引号,但留下可能在其中转义其他字符的反斜杠:我希望在从令牌中删除引号时将它们删除。
    • @Bart 谢谢!你是对的。事实上,最初的问题是 ANTLR 3 不允许使用感叹号:) 我从记忆中重新输入了答案。我已经更新了我的答案。
    • 没有比添加这样耗时的操作更好的解决方案吗?
    • @Nicolas 可能就像我说的那样,我提出了我最终使用的解决方案。由于没有其他解决方案,这个最终成为公认的解决方案。您还有其他解决方案吗?
    • @chollida 我发布了我的解决方案,不知道哪个是最好的。我想我会回滚到您的解决方案,因为我不喜欢 c=CHAR 的实现方式。
    【解决方案2】:

    这是我最终使用的解决方案:

    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 语言,这就是为什么会有 \$ 你知道哪个更快吗?

    【讨论】:

    • 我看到的最大区别是我的解决方案使用了通配符 '.'匹配任何符号。您必须在列表中指定每个符号。例如,您的字符串 cant' 当前包含许多常见的标点符号元素,例如分号 ':',尽管您可以解决此问题。你确实有一个很好的解决方案,我希望我早点想到它。
    猜你喜欢
    • 1970-01-01
    • 2014-06-29
    • 1970-01-01
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-20
    • 1970-01-01
    相关资源
    最近更新 更多