数式を解くプログラム その5 - 構文解析2
id:yone-ken:20090220:p1 の続きです。再度、拡張BNFによる構文定義を確認します。
::= ('+' )* | ('-' )* ::= ('*' )* | ('/' )* ::= '(' ')' | '+' | '-' |
構文解析を実装するに当たり、どんなクラスが必要でしょうか?また、そのクラスにはどんなメンバが必要でしょうか?私の考えた方針は次の通りです。
この方針により、Expressionクラス、Termクラス、Factorクラスを作成することにします。また、これらが解析+計算を行うメソッドをEvaluateメソッドとし、戻り値はなしで、引数には字句解析処理を渡すことにします。計算結果はValueプロパティを用意してそこから取得することにします。(今考えるとValueプロパティは不要で、単純にEvaluateメソッドの戻り値で返すので十分な気もします。)これら3つのクラスは共通のインタフェースを持つのでこれらの抽象クラスとしてNodeクラスを用意します。
また、与えられる数式は正しい式ばかりとは限りませんし、問題なく計算できるとは限りませんので、Evaluateメソッドで解析エラー、もしくは、計算エラーがあった場合には、EvaluateExceptionを発生させることにします。
NodeクラスとEvaluateExceptionクラスを以下に掲載します。
abstract class Node { public decimal Value { get; protected set; } public abstract void Evaluate(Context<Token> context); } class EvaluateException : Exception { private Token token; public Token Token { get { return this.token; } } public EvaluateException(string messgae, Token token) : base(messgae) { this.token = token; } }
次回はExpressionクラス、Termクラス、Factorクラスと外向きのインターフェースとしてのExpressionEvaluatorクラスを紹介します。