这个语法有什么关系?

时间:2009-11-07 21:36:26

标签: antlr grammar

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规则与令牌defineIDas匹配,但不匹配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 个答案:

答案 0 :(得分:4)

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

片段词法分析器规则不会创建令牌,但可以将它们组合成创建令牌的非片段规则。在您的示例中,IDHEADIDTAIL不是令牌 - 它们仅用于描述ID的部分。因此,TYPEID是您的非片段规则,IDHEADIDTAIL是片段规则。

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');

答案 1 :(得分: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;

答案 2 :(得分:0)

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

现在无法测试,但尝试删除片段,这应该可以解决问题,并提供一个令牌来启动。

答案 3 :(得分:0)

fragment应该做什么行?我认为如果你删除它,它应该像你期望的那样工作。