解析A
して命令のツリーを構築し、リーフから開始して実行することができます (最も内側の括弧の内容を最初に実行したいと思うと思います)。この解析タスクでは、正規表現またはその他の必要なものを使用できます。頭のてっぺんから、最初に括弧と演算子記号を探してツリー構造を把握し、次に各リーフに実際の初等命令を入力し、各ジャンクションに演算子を入力することができると思います。
データ構造の格納は、インターフェイスを実装するA
オブジェクト (それらを と呼びます) で構成できます。それぞれに 3 つのフィールドが必要です。Expression
IOperand
Expression
Operator
のインスタンスであるフィールドenum Operations {Union, Intersection, SetDiff}
、または好みに応じて単なる文字列です。
- 2 つのフィールド
Operand1
とOperand2
は、「Ah」(カードのセットを定義する) のようなものか、別の のいずれかExpression
です。したがって、これらは のインスタンスとして宣言する必要がありますIOperand
。
"Ah" のように 1 組のカードを保持するクラスも、これを実装する必要がありますIOperand
。インターフェイスIOperand
自体は、実際には何もする必要はありません。
与えられた各命令を操作に一致させるには、単純なスイッチを使用するか、代わりにDictionary
of string
(またはenum
) to を使用してから、 with (匿名) 関数 ( の命令を含む) をdelegate IOperand SetOp(IOperand, IOperand);
入力します。Dictionary
B
このDictionary
場合、単純に実行できinstructionList[thisExpression.Operation](thisExpression);
(これはおそらく、2 回の参照を避けるためにもう少しエレガントに行うことができますthisExpression
)、文字列入力の適切な C# 変換が実行されます。
コンセプトの証明
ここで使用方法を示すために、基本的な実装とコンソール アプリを作成しました: https://bitbucket.org/Superbest/lexer
正気を保ったまま演習全体を進めることに成功した場合 (コンピューターはあなたを代理解析および操作ライブラリとして使用するので、頑張ってください)、最後のステップで、等しい式を評価し、C
何を出力するかを尋ねられるはずです。あなたはちょうどあなたに戻ってきました。(初めて実行するときは、プログラムの指示に従う必要があるかもしれません。コードを壊して多くの例外を取得するのは非常に簡単だと思います。無効なプログラムに何が起こったのかを考えようとすると、非常に混乱します。入力。)
コードをそのまま実行している場合は、次の一連の回答を試してください (, = Enter)。
n, y, 2, n, n, n, y, 2, n, n, y, n, y, 2, n, n, n, n, alpha, beta, gamma
出力は次のようになります。
gamma
廃止されたとマークされたメソッドの本体を簡単に更新して、動作するプログラムを作成できるはずです。
さらに二項演算を追加したい場合は、 の本文の TODO を参照してくださいSimplification.Simplification()
。適切な構文は、既に行った 3 つの操作を見れば明らかです。現状では、コードはバイナリ操作のみをサポートしています。メソッドが文字列を使用する場合は、SimplifiedOperand.Symbol
フィールドを使用できます。