0

我有非常简单的 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 "- 开始失败
  • "<ggg> <hhh> "- 失败后<ggg>
  • "<ggg> fff "- 工作正常
  • "<ggg> "- 最终失败

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

4

2 回答 2

3

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

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

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

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

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

TEXT : ~('<'|'>')+;
于 2012-06-24T14:04:28.803 回答
1

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

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

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

如果空格对您很重要:

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+
CHAR: ~('<'|'>');
TEXT: (CHAR|WHITESPACE)+;
于 2012-06-24T13:20:37.730 回答