記事一覧
逆ポーランド記法を利用した数式の計算(1) 逆ポーランド記法の計算
逆ポーランド記法を利用した数式の計算(2) 数式をトークンに分割する
逆ポーランド記法を利用した数式の計算(3) ReversePolishNotationクラスを改良する
逆ポーランド記法を利用した数式の計算(4) Contextクラスを定義する ← 当記事
逆ポーランド記法を利用した数式の計算(5) Interpreterパターンで数式を解析する
逆ポーランド記法を利用した数式の計算(6) 最後の仕上げ
これまで、以下の3つのクラスを定義しました。
ReversePolishNotation : 逆ポーランド記法を表すクラス
RpnCalculator : 逆ポーランド記法で表された式を計算するクラス
Tokenizer : 式をトークンに分解するクラス
今回は、このなかの、ReversePolishNotationとTokenizerの2つのオブジェクトをまとめて管理するContextクラスを定義します。
Contextクラス
Contextクラスは、たぶん必須のクラスではないと思います。しかし、数式を解析する際は、Tokenizerクラスでトークンを取り出しつつReversePolishNotationオブジェクトを組み立てていくことになるはずです。そのため、この2つのオブジェクトをContextクラスとして纏めてしまったほうが、取り扱いが楽になると思います。
実は、初めて作成したときは、このContextクラスは存在しなかったのですが、次回で説明する予定の数式を解析するコードがちょっとごちゃごちゃした感じになったので、途中でこのContextクラスを追加したという経緯があります。
ということで、そのクラスを以下に示します。
public class Context {
private Tokenizer _tokenizer;
// 逆ポーランド記法を表すオブジェクト
public ReversePolishNotation Notation { get; } = new ReversePolishNotation();
// トークンの取得が終わったかどうかを示す。
// MoveNextを呼び出した後でも、このプロパティを見れば、次があるかどうかがわかる。
public bool IsTerminate { get; private set; } = false;
// コンストラクタ 加減乗除を行う数式を引数で受け取る
public Context(string exp) {
_tokenizer = new Tokenizer(exp);
_tokenizer.MoveNext();
}
// 次のトークンを取り出すためにカレントを移動する
// 最初のトークンを取り出すには、まず、MoveNextを呼び出す必要がある。
public bool MoveNext() {
if (_tokenizer.MoveNext())
return true;
IsTerminate = true;
return false;
}
// 現在のトークン
public string CurrentToken {
get { return _tokenizer.Current; }
}
}
Tokenizerオブジェクトをpublicにして、MoveNextメソッド、CurrentTokenプロパティは定義しなくてもよかったかなと思いますが、IsTerminateというプロパティを定義したかったので、だたら、MoveNextとCurrentTokenもこのクラスのあった方がいいかなと思い、このような形にしています。
ReversePolishNotationは、そのままプロパティとして公開しています。
このクラスの実装詳細の説明は省略します。コードとコメントを読んでください。
これで、RpnCalculator, Tokenizer, ReversePolishNotation, Context という4つのクラスを定義しました。
次は、いよいよ、数式の解析を行うクラスを定義します。インタープリター・パターンを使う予定です。
(続く)...
この記事は、Gushwell's C# Programming Pageで公開したものを大幅に加筆・修正したものです。