ANTLR中的空格有什么问题?

时间:2012-06-24 13:16:24

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

我有非常简单的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+;

使用这样的输入:"<ggg> fff"它可以正常工作。

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

  • " <ggg> fff " - 在beggining失败
  • "<ggg> <hhh> " - 在<ggg>
  • 之后失败
  • "<ggg> fff " - 工作正常
  • "<ggg> " - 最后失败

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

2 个答案:

答案 0 :(得分:3)

ANTLR的词法分析规则尽可能匹配。仅当2(或更多)规则匹配相同数量的字符时,首先定义的规则将“赢”。因此,'<''>'以外的单个字符被标记为CHAR标记,而不是TEXT标记,无论解析器“需要”什么(词法分析器独立于解析器运行,请记住!)。只有'<''>'以外的两个或多个字符被标记为(单个)TEXT令牌。

因此,输入" <ggg> fff "会创建以下5个标记:

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

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

只需删除CHAR并执行:

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

答案 1 :(得分:1)

你没有处理空间的令牌。词法分析器的空间与它可能遇到的任何其他角色没有区别。

如果空格不重要,您只需使用:

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

如果空白对您很重要:

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