我正在尝试根据其上下文修改规则,尽可能少复制/粘贴。我最好从我想要实现的伪代码变体开始:
module[boolean isParam]: 'module' id=identity?
declaration+
update+
'endmodule' -> ^(MODULE ({if (isParam)} IS_PARAMETER {else} $id) declaration+ update+);
如果设置了isParam
,我希望模块与identity
规则不匹配,但在其位置创建IS_PARAMETER
令牌。我确信我可以使用两个单独的module
规则来执行此操作,但是有更简洁的方法可以减少代码重复,或者不将module
规则拆分为许多较小的规则吗?
答案 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+)
)
;