在Xtext中重载代码生成器

时间:2012-10-05 12:55:21

标签: java dsl xtext

我有一个非常简单的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是否具备此功能?

1 个答案:

答案 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/