根据ANTLR3中解析器规则的可选部分重写规则

时间:2012-04-16 10:48:41

标签: antlr antlr3

我正在尝试根据其上下文修改规则,尽可能少复制/粘贴。我最好从我想要实现的伪代码变体开始:

module[boolean isParam]: 'module' id=identity?
        declaration+ 
        update+
        'endmodule' -> ^(MODULE ({if (isParam)} IS_PARAMETER {else} $id) declaration+ update+);

如果设置了isParam,我希望模块与identity规则不匹配,但在其位置创建IS_PARAMETER令牌。我确信我可以使用两个单独的module规则来执行此操作,但是有更简洁的方法可以减少代码重复,或者不将module规则拆分为许多较小的规则吗?

2 个答案:

答案 0 :(得分:1)

我相信这样的事情有效:

module[boolean isParam]: 'module' id=identity?
        declaration+ 
        update+
        'endmodule' -> {isParam}? ^(MODULE IS_PARAMETER declaration+ update+)
                    ->            ^(MODULE $id declaration+ update+);

答案 1 :(得分:1)

如前所述,这可行:

module[boolean isParam]
 : 'module' id=identity? declaration+ update+ 'endmodule' 
   -> {isParam}? ^(MODULE IS_PARAMETER declaration+ update+)
   ->            ^(MODULE $id? declaration+ update+)
 ;

(请注意可选的$id!)

但是通过查看您的规则,我得到的印象是,只要identity 存在,您就希望AST中有IS_PARAMETER个节点。如果是这种情况,您可以在没有参数和谓词的情况下处理此问题,这是IMO的首选:

module
 : 'module' ( identity declaration+ update+ 'endmodule' -> ^(MODULE identity declaration+ update+)
            | declaration+ update+ 'endmodule'          -> ^(MODULE IS_PARAMETER declaration+ update+)
            )
 ;