[Go言語]Interpreterパターンを学ぼう!

こんにちは、KOUKIです。

この記事では、デザインパターンの一つであるInterpreterパターンについて紹介します。

デザインパターンまとめ

シチュエーション

Interpreter とは、解釈者や説明者を意味する単語です。Interpreterパターンは、なんらかの文法規則で記述された文字を解析し、その結果、得られた手順に基づき処理を実行していくパターンです。

例えば、「(4+3) – (1+2)」という文字列(文法規則)があったとします。

これをいい感じに変換して、計算結果を出力できるプログラムを実装したいと思います。

サンプルコードの実装

サンプルコードを実装しつつ、Interpreterパターンを理解しましょう。

文字列の変換について

最初に「”(4+3) – (1+2)”」の文字列をどうやって変換させるかについて考えてみましょう。

この文字列は、「(」「)」「+」「-」+ 「数値」から成り立っており、プログラムに落とし込むと以下のように表せます。

Convert関数の実装

Convert関数は、Interpreterパターンの「なんらかの文法規則で記述された文字を解析し」を実装します。

入力したinputをループで回し、+、-、(、)、数値のいずれかに該当した場合は、resultに格納します。

defaultの「input[i]」には、byte型が入ります。それを数値判定したいので、「unicode.IsDigit」メソッドを使用しました。このメソッドの引数はrune型なので、runeで型変換する必要があります。

プログラムを実行すると以下の結果を得られます。

対象の文字列を仕分けして、Charインスタンス化できましたね。

Parse関数の実装

Parse関数は、Interpreterパターンの「その結果、得られた手順に基づき処理を実行していく」を実現します。

最初に考えるべきことは、仕分けした文字列(Charインスタンス)をどう処理していくか、です。

以下のコードを実装しましょう。

引数には、Charインスタンスのスライスを渡しました。そして、戻り値は、Valueメソッドを持つElementインターフェースを指定しています。

これで、何らかの処理をCharインスタンスに加え、最終結果をValueメソッドから取り出せる流れを作りました。

次に考えることは、数値の計算処理です。今回は、可算、減算処理のみをターゲットとしているので、それをプログラムで表してみましょう。

このValueメソッド内で呼び出される「r.Left.Value()/r.Right.Value()」は、RuneOperation構造体のValueメソッドを指しません
※少し混乱するかもしれません!

Left/Rightプロパティに格納する数値構造体を実装します。

RuneOperationをインスタンス化する -> RuneOperationのValueメソッドを呼び出す ->IntegerのValueメソッド を呼び出す、みたいな感じになりますね。

Parse関数の実装を完成させましょう。

ここでやりたいことは、「(4+3) – (1+2)」式の計算です。
この計算式は、以下の順で計算されます。

  1. (4+3) -> 7
  2. (1+2) -> 3
  3. 7 – 3 -> 4が得られる

具体的には、「case Lparen」内の処理で、(4+3)の計算結果がLeft、(1+2)の計算結果がRightに入り、Typeには、「-」が入ります。

使ってみよう

実装したプログラムを使ってみましょう。

OKですね。

まとめ

Interpreterパターンは、結構難しく感じますね。

今回は、簡単なフォーマット「(4+3) – (1+2)」だったので、なんとか実装できましたが、もっと複雑なものになっていくとめんどくさそうです^^;

しかし、ログのパースツールなどを作る時に、活躍してくれそうな感じもするので、習熟しておきたいですね。

それでは、また!

Go言語まとめ

ソースコード

コメントを残す