4
grammar Test;

IDHEAD: ('a'..'z' | 'A'..'Z' | '_');
IDTAIL: (IDHEAD | '0'..'9');
ID:     (IDHEAD IDTAIL*);
fragment
TYPE:   ('text' | 'number' | 'bool');

define: 'define' ID 'as' TYPE;

问题是define规则匹配标记define, ID, as,但不匹配TYPE。我产生了 MissingTokenException。

如果我按如下方式内联 TYPE,它将按我的意图工作:

grammar Test;

IDHEAD: ('a'..'z' | 'A'..'Z' | '_');
IDTAIL: (IDHEAD | '0'..'9');
ID:     (IDHEAD IDTAIL*);
fragment
TYPE:   ('text' | 'number' | 'bool');

define: 'define' ID 'as' ('text' | 'number' | 'bool');

更新:fragment添加关键字是为了解决另一个冲突:The following token definitions can never be matched because prior tokens match the same input: TYPE.

4

4 回答 4

4

在组合语法中,将解析器规则置于词法分析器规则之上。另外,请记住,词法分析器首先运行,并且只有在解析器运行完成后才运行。在知道(解析器)规则需要它TYPE之前,必须匹配(词法分析器)令牌。define

片段词法分析器规则不创建标记,但它们可以组合成创建标记的非片段规则。在您的示例中,IDHEAD并且IDTAIL不是标记-它们仅用于描述ID. 因此,TYPEandID是您的非片段规则,IDHEADandIDTAIL是片段规则。

grammar Test;

define: 'define' ID 'as' TYPE;

/*
 * Lexer rules only below here
 */

TYPE:   ('text' | 'number' | 'bool');
ID:     (IDHEAD IDTAIL*);

fragment
IDHEAD: ('a'..'z' | 'A'..'Z' | '_');

fragment
IDTAIL: (IDHEAD | '0'..'9');
于 2009-11-12T03:51:30.643 回答
1

我认为词法分析器规则优先考虑它们的列出方式。因此,如果您希望实际创建令牌 TYPE,请将其移至所有其他词法分析器规则之上。

grammar Test;

fragment
TYPE:   ('text' | 'number' | 'bool');
IDHEAD: ('a'..'z' | 'A'..'Z' | '_');
IDTAIL: (IDHEAD | '0'..'9');
ID:     (IDHEAD IDTAIL*);

define: 'define' ID 'as' TYPE;
于 2009-11-12T03:41:53.300 回答
0

不是因为TYPE被定义为片段吗?

现在无法测试,但尝试删除片段,这应该可以解决问题,再加上给你一个启动令牌。

于 2009-11-07T22:00:21.107 回答
0

fragment该做什么?我认为如果您删除它,它应该可以按您的预期工作。

于 2009-11-07T22:58:39.257 回答