ANTLR文法中语法规则是在词法规则基础上建立的。但不一定每个词法规则都会被语法规则直接使用。这就象一个类的公有成员和私有成员,公有成员是对外公开的会被外界直接调用。而私有成员不对外公开是由公有成员间接调用的。在词法规则中那些不会被语法规则直接调用的词法规则可以用一个fragment关键字来标识,fragment标识的规则只能为其它词法规则提供基础。
grammar TestFragment;
options {
language=CSharp;
output=AST;
}
a : INT;
INT : DIGIT+;
fragment DIGIT : '0' .. '9';
此示例中词法符号INT定义了整型数,而DIGIT定义了一位数字。语法规则a对DIGIT规则的使用是间接的,这时使用fragment来标识DIGIT规则,DIGIT规则将不能被语法规则直接调用。如果如下例语法规则a直接调用DIGIT规则,运行时语法分析器会死循环。
a : DIGIT;
INT : DIGIT+;
fragment DIGIT : '0' .. '9';
在不使用fragment关键字的时候,有时语法规则也不能直接使用某些词法规则。请看下面的示例。
a : DIGIT;
INT : DIGIT+;
DIGIT : '0' .. '9';
运行后输入“9”分析器生成的语法树为空,使用java命令行运行时提示“line 1:0 mismatched input '0'expecting DIGIT ”。这是因为DIGIT规则匹配的内容对INT规则来说也是匹配的,INT规则干扰了DIGIT规则的匹配,造成DIGIT规则没有匹配的内容。
a : DIGIT;
fragment INT : DIGIT+;
DIGIT : '0' .. '9';
如果在INT前加入fragment则分析器可以生成有一个节点“9” 的语法树,不过在实际中不应该这样定义。在第五章我们会学到fragment词法规则是可以带参数的,这样可以在词法分析的过程中灵活的控制,fragment词法规则具有更大的意义。