1

コンパレータのリストを含むバリデーター要素で構成される非常に単純なDSLがあります。

Validator:
  'validator' name = ID '{'
    comparisons+=Comparison*
  '}'
;

Comparison:
  LessThan | GreaterThan | EqualTo
;

LessThan:
  'lt' value = INT
;

これで私はCコードを生成しようとしています。各バリデーターをループする場所で、(バリデーターの名前に基づいて)Cファイルを作成し、コンパレーターを3項条件ステートメントに配置します。各コンパレータをループすると、ステートメント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にはこの機能がありますか?

4

1 に答える 1

1

Xtext は、ポリモーフィック ディスパッチ (@SpaceTrucker 提供) を使用できます。

関数またはメソッドは、複数の引数の実行時 (動的) 型に基づいて動的にディスパッチできます。

この機能を使用するには、単語を 1 つ追加する必要がありました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/

于 2012-10-05T19:36:58.490 に答える