2

Antlr と式ツリーを使用して言語を書いています。

ツリー パーサーが加算を生成するときに使用する標準のファクトリ メソッドを定義しました。これは、組み込みの整数型に対して非常にうまく機能します。次に、より一般的な型に進みます。

現時点では信じられないほどナイーブで、これを行うだけです (進行中の TDD コードは、しばしばナイーブに見えます!?):

protected Expression GenerateAdd(Expression left, Expression right)
{
  if (left.Type.Equals(right.Type))
    return Expression.Add(left, right);
  if (left.Type.IsValueType && right.Type.IsValueType)
    Promote7_2_6_2(ref left, ref right);
  return Expression.Add(left, right);
}

WherePromote7_2_6_2は、C# 仕様 7.2.6.2 で定められた統合昇格の規則に従う Convert 式を生成します (言語は C# に似ていますが、JScript とクロスオーバーし、他のまったく新しいキーワードがあります)。

当然のことながら、文字列の追加のテストに移りました。つまり"a" + "b";、次のエラーが表示されます。

System.InvalidOperationException: The binary operator Add is not defined for the types 'System.String' and 'System.String'.

十分に公平です-私はSystem.Stringを反映しており、演算子が実際に定義されていないことを十分に確認しています。次のようなテスト メソッドで式ツリーを生成します。

Expression<Func<string, string, string>> e = (s1, s2) => s1 + s2;

Add BinaryExpression が実際に作成されているが、実装メソッドがいずれかのメソッドに設定されていることを示していstring.Concatます。

場合によっては、このようなことを検討する必要があることは承知していましたが、このように足し算を定義する型が他にいくつあるでしょうか? それはただstringですか?

それは C# コンパイラに埋め込まれたルールですか?それとも、他の型でそのようなメソッドを自動検出するために使用できるある種の検出可能なメタ データはありますか?

前もって感謝します!

4

1 に答える 1

1

私は自分自身の質問に答えるのに素晴らしいラインをしているようです!

申し訳ありませんが、この回答はより適切にフォーマットされている可能性がありますが、私は HTC の欲求に基づいており、そのキーボードはすべての記号をサポートしていません!

実行時にこれらのルールを「発見」する方法はないようです。文字列の追加などを実装する方法を決定するのはホスト言語の責任です。C# は加算の連続する項の数に適応し、それに最も適切に一致する .Concat メソッドを呼び出します。

したがって、たとえば、自分の言語で演算子が定義されていないクラス インスタンスの追加をサポートしたい場合は、それを行うための静的メソッドを記述または検索するだけで (もちろん正しいシグネチャで!)、その場合に使用する言語。ここでの典型的な例は、静的な Array メソッドを通じて array1 + array2 をサポートするかどうかです。

演算子の発見に関しては、 Expression.Add メソッドがそれを処理しますが、自動的に変換を実行するわけではないため、質問で参照する整数/浮動小数点昇格メソッドと同様に、言語のルールを使用して、式を作成する前に他の変換が必要かどうかを判断します。

そのため、最初に演算子を反映し、2 つの型に対して演算子が定義されているかどうかを確認してから、存在する場合は変換を検討するのがおそらく最善です。

于 2010-09-17T20:34:10.463 に答える