在 Xtext 中重载代码生成器



我有一个非常简单的DSL,它由一个包含比较器列表的验证器元素组成:

Validator:
'validator' name = ID '{'
comparisons+=Comparison*
'}'
;
Comparison:
LessThan | GreaterThan | EqualTo
;
LessThan:
'lt' value = INT
;

有了这个,我正在尝试生成 C 代码。 在我遍历每个验证器的地方,创建一个 C 文件(基于验证器的名称)并将比较器放入三元条件语句中。 当我遍历每个比较器时,它会调用输出if语句的类Comparison的定义。 一个削减示例(输出类似于 CPPUNIT 的内容):

int
main(int argc, char **argv)
{
// parse argv[1] if it exists -> place into i
printf("%c", i < (comparator_value_1) ? '.' : 'F');
printf("%c", i > (comparator_value_2) ? '.' : 'F');
printf("n");
return 0;
}

我可以很好地让所有这些工作;但是我遇到的问题是我似乎必须在我的Comparison生成器中选择条件。 我似乎无法通过为 LessThan 添加处理程序来覆盖生成器。

def compile(Comparison c) '''
printf("%c",
i «IF c.eClass.name.equals("LessThan")»...«ENDIF» «c.value»
? '.' : 'F');
'''

当我尝试重载它时:

def compile(LessThan lt) '''
printf("%c", i < «c.value» ? '.' : 'F');
...
'''

重载的例程不会被调用,这充其量是不幸的。

如果这有任何区别,则调用它:

«FOR c:v.comparisons»
«c.compile»
«ENDFOR»

其中"v"是验证器。

Xtext有这种能力吗?

Xtext可以使用多态调度(由@SpaceTrucker提供),其中:

函数或方法可以根据其多个参数的运行时(动态)类型动态调度。

为了使用此功能,我必须添加一个词dispatch

def dispatch expandComparator(GreaterThan gt) '''
printf("%c", i < «gt.value» ? '.' : 'F');
'''
def dispatch expandComparator(EqualTo eq) '''
printf("%c", i == «eq.value» ? '.' : 'F');
'''
def dispatch expandComparator(LessThan lt) '''
printf("%c", i < «lt.value» ? '.' : 'F');
'''

并使用以下内容生成它:

«FOR c:v.comparisons»
«c.expandComparator»
«ENDFOR»

函数的名称必须更改,因为compile是一个单一的调度函数。

以下链接包含有关此解决方案的更多详细信息。 http://dslmeinte.wordpress.com/2012/08/03/polymorphic-dispatch-in-xtend/

最新更新