如何制定规则 "templates"

How to make rule "templates"

我有这样的语法:

start : topDef* EOF ;
topDef : topId '(' scopeDef* ')' ;
topId : UPPER_ID ;
scopeDef : scopeId '(' scopeDef* ')' ;
scopeId : LOWER_ID NUMBER? ;

UPPER_ID : [A-Z] [A-Za-z0-9_]* ;
LOWER_ID : [a-z] [A-Za-z0-9_]* ;
NUMBER : [0-9]+ ;
WS : [ \t\r\n]+ -> skip ;

可以看出,topDefscopeDef除了id子规则外是一样的。有没有办法将这些包装成一个定义?也许是一种模板规则的方法,比如

start : def<topId>* EOF ;
def<id> : id '(' def<scopeId>* ')' ;
topId : UPPER_ID ;
scopeId : LOWER_ID NUMBER? ;

或者类似

scopeDef : topDef except(topId : LOWER_ID NUMBER?) ;

不是没有谓词(其中包含目标特定代码,Java 在下面的示例中):

start : def[true]* EOF ;

def[boolean isTopDef]
 : ( {$isTopDef}? topId | scopeId ) '(' def[false]* ')'
 ;

topId : UPPER_ID ;
scopeId : LOWER_ID NUMBER? ;

所以答案是肯定的,你可以做到,但如果我是你就不会。