構文解析!part2.2

ポテチ先生に色々教えてもらいました。

問題点1が最もなおすべきなので、考えました。。
けどよくわからないからあとに回して、他を改善しました。
exitとquitをコマンドとしてそれ以外はSyntaxErrorを吐くようにしました。
問題点3ですが、先日もイテレータ使うって言ってましたが、変数に一回代入するほどかっこ悪いものはないのでクラスにまとめたいと思いますはい。
問題点4の命名ですが、ネーミングセンス?じゃないけど、どうにかしたい。
ちなみに、time関数をmulにして、number関数をfactorにしました。

自分でも機能を使いかを試みました。
1.改行できる
2.空白があっても無視する。
3.%剰余算も使えるようにしました。

だけ。

Source Code:

def factor(begin):
  global SyntaxFlag
  global i
  val = 0

  if begin[i] == "(":
    i+=1
    val = expression(begin)
    i+=1

  while begin[i].isdigit():
    SyntaxFlag=0
    val *= 10
    val += int(begin[i])
    i+=1
  return val

def mul(begin):
  
  global i
  val = factor(begin)

  while True:
    if begin[i] is "*":
      if begin[i+1] is "*":
        i += 2
        val **= mul(begin)#factor(begin)
      else:
        return val
    else:
      break
  return val 

def term(begin):
  
  global i
  val = mul(begin) #factor(begin)

  while True:
    if begin[i] is "*":
      i += 1
      val *= mul(begin)
    elif begin[i] is "/":
      i += 1
      val2 = mul(begin)
      if val < 0 or val2 < 0:
        val = func1(str(abs2(val,val2)))
      else:
        val /= 1.0*val2
        val = func1(str(val))
    elif begin[i] is "%":
      i += 1
      val %= mul(begin)
    else:
      break

  return val

def expression(begin):

  global i
  val = term(begin)

  while True:
    if begin[i] is "+":
      i += 1
      val += expression(begin)
    elif begin[i] is "-":
      i += 1
      val -= expression(begin)
    else:
      break
  return val

#-3/2 == -2
abs2 = lambda x,y: int(x*1.0/y)
func1 = lambda x: float(x[0:x.index('.')+3])
def main():
  while True:
    try:
      ex=""
      global SyntaxFlag
      SyntaxFlag=1
      tmp = (raw_input(">>")+"=").split()
      for j in tmp: ex+=j
      if True in [ex == x for x in ['exit=','quit=']]:
        print "End..." 
        exit(0)
      elif ex=="=": continue
      global i
      i = 0
      #print expression(ex)
      result= expression(ex)
      if SyntaxFlag:
        raise SyntaxError,'WTF are u "d"oin!!?'
      else:
        print(result) 
    except EOFError:
      break

if __name__ == '__main__':
  main()

Test Case:

1+1
123+321
100-50
100-123
123*3
8/2
100/3
(10+5)*2
(5-10)*3
(100/2)+(100/3)-(11*3)
2**3
(10**3)/1000
10**3/10**3
2**3**3
(2**3)**3
(  2 **     3) ** 3
1    + 3
3  ** 3
16%16
16%15
HOGEHOGEWORLD

Response:

>>2
>>444
>>50
>>-23
>>369
>>4.0
>>33.33
>>30
>>-15
>>50.33
>>8
>>1.0
>>1.0
>>134217728
>>512
>>512
>>4
>>27
>>0
>>1
>>Traceback (most recent call last):
  File "expression.py", line 99, in <module>
    main()
  File "expression.py", line 92, in main
    raise SyntaxError,'WTF are u "d"oin!!?'
SyntaxError: WTF are u "d"oin!!?

まとめ:
1.ポテチ先生の洞察力やヴぁい
2.raiseとか初めて使ったけど何も見ずに書けてテンション上がった
3.構文解析たのしい。