我有一个非常简单的DSL,它包含一个包含比较器列表的验证器元素:
Validator:
'validator' name = ID '{'
comparisons+=Comparison*
'}'
;
Comparison:
LessThan | GreaterThan | EqualTo
;
LessThan:
'lt' value = INT
;
有了这个我试图生成C代码。在我遍历每个验证器的地方,创建一个C文件(基于验证器的名称)并将比较器放入三元条件语句中。当我遍历每个比较器时,它调用类Comparison
的定义,该类输出if
语句。一个减少的例子(输出类似于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是否具备此功能?
答案 0 :(得分:1)
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/