无需修改EMF模型,如何复用语法规则中的重复片段?
复用Xtext语法规则且不修改EMF模型的解决方案
问题背景
我正在开发一款可转换为EMF模型的语法,该模型包含带有大量属性的类型,导致语法可读性较差。此外,部分规则存在完全相同的内容,我希望将这些重复部分提取出来以实现复用,但需要找到一种无需修改EMF模型的解决方案。
原始简化示例:
Function1 returns Function: 'function' name=ID '{' (statements=Statement)* '}'; Function2 returns Function: 'function2' name=ID '{' (statements=Statement)* '}';
我尝试提取重复部分但遇到了单个未分配规则的限制,而使用赋值的方式(如body=Body)需要修改EMF模型添加新类型和特征,因此寻求无需修改模型的替代方案。
解决方案
方法1:利用上下文赋值的无返回值规则
将重复的Body部分定义为无返回类型的规则,直接在规则中对目标EMF对象的特征进行赋值,Xtext会自动将赋值应用到当前上下文的对象(即上层规则返回的Function实例):
Function1 returns Function: 'function' name=ID Body; Function2 returns Function: 'function2' name=ID Body; // 无返回类型,直接为上下文的Function实例赋值statements特征 Body: '{' (statements+=Statement)* '}';
这里的statements+=Statement会直接把收集到的Statement实例添加到当前Function对象的statements集合中,完全不需要修改现有的EMF模型。
方法2:结合抽象规则进一步提升复用性
如果有更多类似的Function规则,可以定义抽象规则来统一公共部分,进一步减少重复代码:
// 抽象规则,定义Function的公共结构 abstract FunctionCore returns Function: name=ID Body; Function1 returns Function: 'function' FunctionCore; Function2 returns Function: 'function2' FunctionCore; Body: '{' (statements+=Statement)* '}';
这种方式既保留了语法的可读性,又最大化了代码复用,同时完全不依赖EMF模型的修改。
关键原理
Xtext的语法规则中,当未指定赋值的接收者时,会默认将赋值操作应用到当前上下文的语义对象(即上层规则正在构建的实例)。利用这一特性,我们可以将重复的语法片段提取为独立规则,直接操作目标对象的已有特征,无需新增任何EMF模型元素。
内容的提问来源于stack exchange,提问作者kapex
相关产品推荐
相关产品推荐

