【问题标题】:What is wrong with whitespaces in ANTLR?ANTLR 中的空格有什么问题?
【发布时间】:2012-06-26 00:37:05
【问题描述】:

我有非常简单的 XML (HTML) 解析 ANTLR 语法:

wiki: ggg+;

ggg: tag | text;

tag: '<' tx=TEXT { System.out.println($tx.getText()); } '>';

text: tx=TEXT { System.out.println($tx.getText()); };

CHAR: ~('<'|'>');
TEXT: CHAR+;

有了这样的输入:"&lt;ggg&gt; fff" 它工作正常。

但是当我开始处理空格时它失败了。例如:

  • " &lt;ggg&gt; fff " - 开始失败
  • "&lt;ggg&gt; &lt;hhh&gt; " - 在&lt;ggg&gt; 之后失败
  • "&lt;ggg&gt; fff " - 工作正常
  • "&lt;ggg&gt; " - 最后失败

我不知道出了什么问题。也许有一些特殊的语法选项来处理这个问题。 ANTLRWorks 给了我NoViableAltException

【问题讨论】:

    标签: xml xml-parsing html-parsing antlr antlr3


    【解决方案1】:

    ANTLR 的词法分析器规则尽可能匹配。只有当 2 个(或更多)规则匹配相同数量的字符时,首先定义的规则才会“获胜”。因此,除了'&lt;''&gt;' 之外的单个字符被标记为CHAR 标记,而不是TEXT 标记,无论解析器“需要”什么(词法分析器独立于解析器运行,记住这一点!)。除了'&lt;''&gt;' 之外,只有两个或更多字符被标记为(单个)TEXT 标记。

    因此,输入 " &lt;ggg&gt; fff " 创建以下 5 个标记:

    type    | text
    --------+-----------
    CHAR    |   ' '
    '<'     |   '<'
    TEXT    |   'ggg'
    '>'     |   '>'
    TEXT    |   ' fff '
    

    并且由于令牌CHAR 未在您的解析器规则中考虑,因此解析失败。

    只需删除 CHAR 并执行以下操作:

    TEXT : ~('<'|'>')+;
    

    【讨论】:

      【解决方案2】:

      你没有令牌来处理这个空间。词法分析器的空格与它可能遇到的任何其他字符没有什么不同。

      如果空格不重要,您可以简单地使用:

      WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;
      

      如果空格对您很重要:

      WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+
      CHAR: ~('<'|'>');
      TEXT: (CHAR|WHITESPACE)+;
      

      【讨论】:

      • 空格对我来说很重要。您写道,词法分析器的空格与任何其他字符没有什么不同。但在我的示例中,CHAR 标记应匹配任何空白字符。所以它应该有效,但它没有。结论:词法分析器的空格与其他字符不同!
      • 您给出的答案是错误的,因为有多种选择(WHITESPACE 和 CHAR)。
      • @pablo,您的词法分析规则CHAR 考虑了空格字符这一事实是正确的,但您的结论是错误的。我会在一个答案中很快解释。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-11
      • 1970-01-01
      • 1970-01-01
      • 2013-07-21
      • 1970-01-01
      相关资源
      最近更新 更多