def p_term_2op(p): ''' term_2op : term TIMES factor | term DIVIDE factor | term POW factor | term PERC factor | term EQUAL factor | term NEQ factor | term GEQ factor | term LEQ factor | term GT factor | term LT factor | term IS factor ''' p[0] = p[1] + p[3] if p[2] == '*': p[0] += ['MUL'] elif p[2] == '/': p[0] += ['DIV'] elif p[2] == '**': p[0] += ['POW'] elif p[2] == '%': p[0] += ['LD', 'mod', 'CALL', 2] elif p[2] == '==': p[0] += ['EQ'] elif p[2] == '!=': p[0] += ['NEQ'] elif p[2] == '>=': p[0] += ['GEQ'] elif p[2] == '<=': p[0] += ['LEQ'] elif p[2] == '>': p[0] += ['GT'] elif p[2] == '<': p[0] += ['LT'] elif p[2] == 'is': p[0] += ['IS'] if len(p[1]) == 2 and len( p[3]) == 2 and p[1][0] == 'LDC' and p[3][0] == 'LDC': v = eval([], [G], p[0] + ['STOP'], 0, [], []) p[0] = ['LDC', v[-1]]
def p_expression_2op(p): ''' expression_2op : expression PLUS expression | expression MINUS expression | expression ID expression ''' #print(p) p[0] = p[1] + p[3] if p[2] == '+': p[0] += ['ADD'] elif p[2] == '-': p[0] += ['SUB'] elif p[2] in G: #2項演算子系のマクロを展開する c = G[p[2]] #print(c) if isinstance(c, list) and c[0] == 'MACRO_CL': p[0] = macrofunction_expand(c, [p[1], p[3]]) return p[0] += ['LD', p[2], 'CALL', 2] else: p[0] += ['LD', p[2], 'CALL', 2] if len(p[1]) == 2 and len( p[3]) == 2 and p[1][0] == 'LDC' and p[3][0] == 'LDC': v = eval([], [G], p[0] + ['STOP'], 0, [], []) p[0] = ['LDC', v[-1]] return if len(p[3]) == 2 and p[3][0] == 'LDC' and p[3][1] == 1: if p[2] == '+': p[0] = p[1] + ['INC'] elif p[2] == '-': p[0] = p[1] + ['DEC']
def p_term_1op(p): ''' term_1op : MINUS factor | NOT factor ''' if p[1] == '-': p[0] = p[2] + ['MINUS'] elif p[1] == '!': p[0] = p[2] + ['NOT'] # 定数の畳み込み if len(p[2]) == 2 and p[2][0] == 'LDC': v = eval([], [G], p[0] + ['STOP'], 0, [], []) p[0] = ['LDC', v[-1]]
def load(file_name): f = open(file_name) s = f.read() print(s) result = parser.parse(s) #c_time = time.time() v = eval([], [G], result + ['STOP'], 0, [], []) #e_time = time.time() if type(v) == list and v != [] and v[0] == 'CL':print('Usser Function') elif type(v) == list and v != [] and v[0] == 'MACRO_CL':print ('User Macro') elif type(v) == list and v != [] and v[0] == 'CONT':print ('User Continueation') else:print(v) #print('c_time : ', int((1000000 * (c_time - s_time))) / 1000000) #print('e_time : ', int((1000000 * (e_time - c_time))) / 1000000) G['_'] = v
def add_expr(p): ''' add_expr : mul_expr | add_expr ADD mul_expr | add_expr SUB mul_expr ''' if len(p) == 2: p[0] = p[1] return p[0] = p[1] + p[3] if p[2] == '+': p[0] += ['ADD'] elif p[2] == '-': p[0] += ['SUB'] # 定数畳み込み if len(p[1]) == 2 and len(p[3]) == 2 and p[1][0] == 'LDC' and p[3][0] == 'LDC': v = eval([], [G], p[0] + ['STOP'],0, [], []) p[0] = ['LDC', v]
def eq_expression(p): ''' eq_expr : rel_expr | eq_expr IS rel_expr | eq_expr EQUAL rel_expr | eq_expr NEQ rel_expr ''' if len(p) == 2: p[0] = p[1] return p[0] = p[1] + p[3] if p[2] == 'is': p[0] += ['IS'] elif p[2] == '==': p[0] += ['EQ'] elif p[2] == '!=': p[0] += ['NEQ'] # 定数畳み込み if len(p[1]) == 2 and len(p[3]) == 2 and p[1][0] == 'LDC' and p[3][0] == 'LDC': v = eval([], [G], p[0] + ['STOP'],0, [], []) p[0] = ['LDC', v]
def p_factor_var(p): ''' var : ID ''' #p[0] = ['LD', p[1]] # マクロの処置をしないならここまででOK if p[1] in G: c = G[p[1]] if isinstance(c, list) and c != [] and c[0] == 'MACRO': #p[0] = c[1] # 解釈しないでそのまま出力すのも仕様としてあり try: # 定数として解釈可能ならそれを返す v = eval([], [G], c[1] + ['STOP'], 0, [], []) p[0] = ['LDC', v[-1]] except: # 定数として解釈できなければコードを残す p[0] = c[1] #p[0] = ['LDC', v] else: p[0] = ['LD', p[1]] # else: p[0] = ['LD', p[1]]
def rel_expression(p): ''' rel_expr : add_expr | rel_expr GT add_expr | rel_expr GEQ add_e]pr | rel_expr LT add_expr | rel_expr LEQ add_expr ''' if len(p) == 2: p[0] = p[1] return p[0] = p[1] + p[3] if p[2] == '>': p[0] += ['GT'] elif p[2] == '>=': p[0] += ['GEQ'] elif p[2] == '<': p[0] += ['LT'] elif p[2] == '<=': p[0] += ['LEQ'] # 定数畳み込み if len(p[1]) == 2 and len(p[3]) == 2 and p[1][0] == 'LDC' and p[3][0] == 'LDC': v = eval([], [G], p[0] + ['STOP'],0, [], []) p[0] = ['LDC', v]
def mul_expr(p): ''' mul_exp : uni_exper | mul_expr MUL uni_expr | mul_expr DIV uni_expr | mul_expr MOD uni_expr | mul_expr POW uni_expr | mul_expr IDIV uni_expr ''' if len(p) == 2: p[0] = p[1] return p[0] = p[1] + p[3] if p[2] == '*': p[0] += ['MUL'] elif p[2] == '/': p[0] += ['DIV'] elif p[2] == '%': p[0] += ['MOD'] elif p[2] == '**': p[0] += ['POW'] elif p[2] == '//': p[0] += ['IDIV'] # 定数畳み込み if len(p[1]) == 2 and len(p[3]) == 2 and p[1][0] == 'LDC' and p[3][0] == 'LDC': v = eval([], [G], p[0] + ['STOP'],0, [], []) p[0] = ['LDC', v]
def Eval(s): return eval([], [G], Compile(s), 0, [], [])
# call_ccの処理 # q = result + ['STOP'] qq = q cc = search_nr(qq, '__CODE__') if cc != []: for (ccc, j) in cc: ccc[j] = ccc[j + 6:] # __DCL__を元に戻す replace(qq, ['__DCL__'], ['DCL']) if G['_code']: print(qq) c_time = time.time() #print( result) try: #v = eval([], [G], result + ['STOP'], 0, [], []) V = eval([], [G], qq, 0, [], []) e_time = time.time() for v in V: if type(v) == list and v != [] and v[0] == 'CL': print('User Function') elif type(v) == list and v != [] and v[0] == 'MACRO_CL': print('User Macro') elif type(v) == list and v != [] and v[0] == 'CONT': print('User Continueation') elif type(v) == str: print(repr(v)) else: print(v) if G['_time']: print('c_time : ', int((1000000 * (c_time - s_time))) / 1000000,
def uni_expr(p): ''' uni_expr : pfix_expr | MINUS uni_expr | NOT uni_expr | CALLCC LPAREN expr RPAREN ''' if len(p) == 2: # 単純式または後置式 p[0] = compile_pfix_expr(p[1]) return if len(p) == 5: # call_cc p[0] = ['LDICT', '__CODE__'] + p[3] + ['CALL', 1] return # 単項演算子 '-'または'!'の場合 p[0] = p[2] if p[1] == '-':p[0] += ['MINUS'] elif p[1] == '!':p[0] += ['NOT'] else # 定数の畳み込み if len(p[2]) == 2 and p[2][0] == 'LDC' : v = eval([], [G], p[0] + ['STOP'],0, [], []) p[0] = ['LDC', v] NON_TYPE, INC_TYPE, DEC_TYPE, CALL_TYPE, APLY_TYPE = 0, 1, 2, 3, 4 def pfix_expr(p): ''' pfix_expr : prm_expr | pfix_expr LBRAK expr RBRAK | pfix_expr LPAREN args DOTS RPAREN | pfix_expr LPAREN args RPAREN | pfix_expr LPAREN RPAREN | pfix_expr INC | pfix_expr DEC ''' if len(p) == 2: p[0] = p[1] # 後置表記なし return # 長さが2でないならp[1]がpfix_exprなのでまずそれをコンパイル p[1] = compile_pfix_expr(p[1]) # 右辺式のコードを生成しp[0]に入れる if p[2] == '++': p[0] = ['_PF_', INC_TYPE, p[1]] # ++ の後置表記 elif p[2] == '--': p[0] = ['_PF_', DEC_TYPE, p[1]] # -- の後置表記 elif p[2] == '(' : # 関数呼び出し if len(p) == 4: # 引数なしの関数呼び出し表記 p[0] = ['_PF_', CALL_TYPE,[], p[1] ] elif len(p) == 5: p[0] = ['_PF_', CALL_TYPE, p[3], p[1]] elif len(p) == 6: p[0] = ['_PF_', APLY_TYPE, p[3], p[1]] elif p[2] == '[': p[0] = ['_PF_', REF_TYPE, p[3], p[1]] # Vector参照表記 def prm_exp(p): # primitive expression ''' prm_expr : atm | LPAREN expr RPAREN | var | vector | closure | macro_expr ''' if len(p) == 2: p[0] = p[1] else: p[0] = p[2] def atm(p): # basic factor ''' atm : INT | FLOAT | E_FLOAT |FLOAT2 | FACT | TRUE | FALSE | STR ''' p[0] = ['LDC', p[1]] def var(p): ''' var : ID ''' p[0] = ['LD', p[1]] # マクロ処理を追加すること def vector(p): ''' vector : LBRAK args RBRAK | LBRAK RBRAK ''' if len(p) == 2: p[0] = ['LDC', []] # NULL vector else: n = len(p[1]) C = [] for c in p[1]: C = C + c p[0] = C + ['VEC', n] # closure (LAMBDA式) def closure(p): ''' closure : LAMBDA LPAREN id_list DOTS RPAREN expr | LAMBDA LPAREN id_list RPAREN expr | LAMBDA LPAREN RPAREN expr ''' if len(p) == 5: p[0] = ['LDF', tail(p[4] + ['RTN']), []] if len(p) == 6: p[0] = ['LDF', tail(p[5] + ['RTN']), p[3]] if len(p) == 7: p[0] = ['LDF', tail(p[6] + ['RTN']), p[3], '..'] # 関数マクロ def macro_expr(p): ''' macro_expr : MACRO LPAREN args DOTS RPAREN expression | MACRO LPAREN args RPAREN expression | MACRO LPAREN RPAREN expression | MACRO expression ''' if len(p) == 7:p[0] = ['LDM_CL', p[6], p[3], ['..']] elif len(p) == 6:p[0] = ['LDM_CL', p[5], p[3]] elif len(p) == 5:p[0] = ['LDM_CL', p[4], []] elif len(p) == 3:p[0] = ['LDM', p[2]] def args(p): ''' args : expr | args CAMMA expr ''' if len(p) == 2: p[0] = [p[1]] elif len(p) == 4: p[0] = p[1] + [p[3]] def id_list(p): ''' id_list : ID | id_list CAMMA ID ''' if len(p) == 2: p[0] = [p[1]] elif len(p) == 4: p[0] = p[1] + [p[3]] # # 構文エラー # def p_error(p): #print( "Syntax error in input") raise SyntaxError("SyntaxError: " + str(p)) # 構文解析器の構築 parser = yacc.yacc() from eval_test import eval import time if __name__ == '__main__': load("lib.py") while True: try: s = input('pure> ') except EOFError: break if not s: continue s_time = time.time() try: result = parser.parse(s) #print(result) except (SyntaxError, ZeroDivisionError) as e: print(e) continue # # call_ccの処理 # q = result + ['STOP'] qq = q cc = search_nr(qq, '__CODE__') if cc != []: for (ccc, j) in cc: ccc[j] = ccc[j + 6:] # __DCL__を元に戻す replace(qq, ['__DCL__'], ['DCL']) if G['_code']:print(qq) c_time = time.time() #print( result) try: #v = eval([], [G], result + ['STOP'], 0, [], []) v = eval([], [G], qq, 0, [], []) e_time = time.time() if type(v) == list and v != [] and v[0] == 'CL':print('Usser Function') elif type(v) == list and v != [] and v[0] == 'MACRO_CL':print ('User Macro') elif type(v) == list and v != [] and v[0] == 'CONT':print ('User Continueation') else:print(v) if G['_time']:print('c_time : ', int((1000000 * (c_time - s_time))) / 1000000, '\te_time : ', int((1000000 * (e_time - c_time))) / 1000000) G['_'] = v except (KeyError, IndexError, SyntaxError, TypeError, ZeroDivisionError) as e: print(e) continue