0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

意外と手間のかかる四則演算プログラム:2. 地道に字句解析と構文解析をする

Posted at

前回

プログラムで解析しやすくするため、入力の側において形式を変化させるという手法を採用しました。実際のシステム構築などでも、この方法が適用できる場合はあると思います。

今回は入力の形式を維持したまま、プログラム側で頑張って解析します。

字句解析

目的

次の式を文字列として入力するとします。

入力例
(-3*4+ 5) + (11 * 13 / 6 - 9) * (111 % 8)

これを、次のようなイメージで内部に持たせるようにするのが目的です。数値、演算子、括弧がそれぞれきちんと切り離されて保存されています。以後、これをトークン列と呼び、一つずつをトークンと呼びます。

["(", "-", "3", "*", "4", "+", "5", ")", "+", "(", "11", "*", "13", "/", "6", "-", "9", ")", "*", "(", "111", "%", "8", ")"]

状態の変化と文字列の蓄え

ここでは、状態と蓄えをそれぞれ Q, S と表すことにします。

  • Q は、通常 (P)、数値読み込み状態 (N) のどちらかをとる。初期状態は P である。
  • S は、 Q = N のとき、読んだ数字を追加することで蓄え、 Q = P になったときに空にする。初期状態は空文字列である。

この状況で、文字列を左から1文字ずつ読んでいき、その文字を c として次の処理を実行します。

  • c が数値であれば、 Q = N に変更し、 S に c を追加。
  • c が演算子であれば、 Q = P に変更する。 S の内容を数値としてトークン列に追加し、 S を空文字列にする。さらに、演算子をトークン列に追加する。
  • c が空白であれば、 Q = P に変更する。 S の内容を数値としてトークン列に追加し、 S を空文字列にする。

注意

演算子を読み込んだときに演算子をトークン列にすぐ突っ込めるのは、今回扱う演算子が全て1文字であるからです。

例えば ++ のような演算子が存在した場合、 + を読み込んだ時点で、その次が + なのかそれ以外なのかの分岐が発生します。 Q には N, P の他に + を1文字だけ読み込んだ新しい状態が追加され、処理もその分だけ分岐により増えます。

構文解析

今度は、字句解析によって生成されたトークン列を読み込んで、計算を行った結果を数値として返します。

さて、工夫すべきポイントがあります。

  • 乗算 (*)、除算 (/, %) は、加算 (+) 、減算 (-) より優先して計算する。
  • 括弧の中は先に計算する。

何らかのプログラムを書いたとき、多くの場合は文字列もリストも左から順番に処理していくので、上記の対応が難しくなります。

関数 evaluate は、トークン列を入力とし、計算結果の数値(あるいは入力ミスによる計算不能)を返すものとして定義します。

アルゴリズムの特徴

  1. トークン列を左から読んでいく。
  2. 右括弧がいきなり現れた場合はエラー。
  3. 左括弧が位置 L に現れた場合、対応する右括弧が現れるまで読み進める。左括弧が連続した場合、同じ個数の右括弧が出るまで。対応する右括弧が位置 R の場合、 L から R までのトークン列を新たに入力として evaluate を行う。
  4. トークン列に括弧がない場合、左から順番に読んでいき、乗算、除算があればそれを計算する。
  5. 加算、減算を計算する。

3 によって、括弧があればその中だけを見るという操作になるので、括弧の対応が複雑に入り込んでいても、一つずつ取り払われていき、最終的に4以降の処理に進むことになります。プログラム自体は再帰を用いることになるので、思考は複雑にはなります。

参照

自作コード: https://github.com/tfull/arithmetic_operations/tree/main/normal

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?