デジタル忍者ブログ

デジタル忍者ブログ

2019/05/16

pythonでパーサを作る(#3:四則演算)


今回は四則演算に対応してみます。


四則演算とは、和、差、積、商の4つの記号が混在している数式を指します。


ここで気を付けるべき点として、


積と商は、和、差より先に計算をします。




そのため、


1+2*3


のケースであっても、


2*3を先に計算する処理が必要となります。




<数式>:=<数値><記号><数式>|<数値>


<数値>:=<数字><数値>|<数字>


<数字>:=0|1|2|3|4|5|6|7|8|9


<記号>:=+|-|*|/




本来、積と商、和と差は分けて定義するのですが、


ここでは積と商、和と差の構文解析は行わず、


解析後の処理で、先に積と商を処理してから、


和と差の処理を行います。


parser3.py

units = []
symbols = []

def calc():
  global symbols
  global units
  idx = 0
  while True:
    p = -1
    for i in range(len(symbols)):
      if symbols[i] == '*' or symbols[i] == '/':
        p = i
        break
    if p == -1:
      break
    
    if symbols[p] == '*':
      units[p] = units[p] * units[p + 1]
    if symbols[p] == '/':
      units[p] = units[p] / units[p + 1]
    del units[p + 1]
    del symbols[p]

  result = units[0]
  for i in range(len(symbols)):
    if symbols[i] == '+':
      result = result + units[i + 1]
    if symbols[i] == '-':
      result = result - units[i + 1]
  return result


def solve():
  global symbols
  global units
  expression = input()
  num = ''
  for c in expression:
    if c.isdigit():
      num = num + c
    else:
      units.append(int(num))
      num = ''
      symbols.append(c)
  units.append(int(num))
  print(calc())


if __name__ == '__main__':
  solve()

solve()メソッドの段階で、

数値と記号をそれぞれunits、symbolsのリストに入れます。

解析後の処理calc()メソッドで、

先に積と商の記号があればそのインデックスをpとして、

units[p]とunits[p+1]の計算を行い、

units[p+1],symbol[p]の要素を削除します。

この処理の繰り返しで、積と商の記号が無くなったら、

和と差の算出を繰り返し行います。



実行結果は以下の通りです。

$ python parser3.py
3*4+5*6
42

$ python parser3.py
1+2*3+4*5+6*7+8*9
141

$ python parser3.py
180/10-3*3
9.0

$



Comment Form

コメント内容(必須)

Comment

2023年1月12日1:36  Hatexceed@onemailtop.xyz

管理者がコメントの内容を確認中・・・