1

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

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

如果isParam设置了,我希望模块不匹配identity规则,但在其位置创建一个IS_PARAMETER令牌。我确信我可以使用两个单独module的规则来做到这一点,但是有没有一种更简洁的方法,代码重复更少,或者没有将module规则拆分为多个较小的规则?

4

2 回答 2

1

我相信这样的事情是有效的:

module[boolean isParam]: 'module' id=identity?
        declaration+ 
        update+
        'endmodule' -> {isParam}? ^(MODULE IS_PARAMETER declaration+ update+)
                    ->            ^(MODULE $id declaration+ update+);
于 2012-04-16T12:30:20.700 回答
1

正如已经建议的那样,这将起作用:

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

(但请注意可选$id!)

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

module
 : 'module' ( identity declaration+ update+ 'endmodule' -> ^(MODULE identity declaration+ update+)
            | declaration+ update+ 'endmodule'          -> ^(MODULE IS_PARAMETER declaration+ update+)
            )
 ;
于 2012-04-16T15:15:01.270 回答