構文解析!part2.2
ポテチ先生に色々教えてもらいました。
@ashigirl96 1個目:2**3**3が512に評価されるのはおかしい。 2個目:"it=quit"などでも終了してしまうので終了条件変えよう 3個目:iがglobal変数なのキモいので、iterator使うなどしよう 4個目:全体的に命名規則どうにかしよう
— 准将 (@potetisensei) October 12, 2013
問題点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.構文解析たのしい。