Programming Calculator

3282 days ago by wubo87

# Final project #programming calculator with user defined function and control statement 
       
# Global token values addop = 0 subop = 1 multop = 2 divop = 3 power = 4 l_par = 5 r_par = 6 assign = 7 ident = 8 number = 9 fname = 10 uminus = 11 eol = 12 space = 14 other = 15 ''' This block defines a Stack class Each instance is initialized with an empty list. The class provides 5 methods: push, pop, peek, clear, and display. Daniel D. Warner October 4, 2011 ''' class Stack: def __init__(self): self._s = [] def push(self,x): self._s.append(x) def pop(self): if 0 < len(self._s): return self._s.pop() else: return None def peek(self): if 0 < len(self._s): return self._s[-1] else: return None def depth(self): return len(self._s) def clear(self): self._s = [] def display(self): print self._s import re # Global regular expression pattern matchers line_finder = re.compile(r'\S.*$',re.MULTILINE) self_function = {} self_function_parameter = {} tok_finder = re.compile(r"""(?P<addop> [+] ) | (?P<subop> [-] ) | (?P<multop>[*] ) | (?P<divop> [/] ) | (?P<power> \^ ) | (?P<l_par> \( ) | (?P<r_par> \) ) | (?P<assign>[=] ) | (?P<ident>[a-zA-Z_]\w*) | (?P<number>((\.\d+)|(\d+\.?\d*))([Ee][+-]?\d+)?) | (?P<space> \s+ ) | (?P<other> . ) """,re.VERBOSE) # The numeric field for this incarnation of the Algebraic Calculator MyFloat = RealField(53) functions = {'abs':0, 'sqrt':1, 'exp':2, 'ln':3, 'cos':4, 'sin':5, 'tan':6, 'acos':7, 'asin':8, 'atan':9} symbol_table = {} # Global Operator Precedence Function based on the 13 tokens addop through eol # addop multop power r_par ident fname eol # subop divop l_par assign number uminus OP_f = (('R', 'R', 'P', 'P', 'P', 'P', 'R', 'E', 'S', 'S', 'P', 'P', 'R'), # addop \ ('R', 'R', 'P', 'P', 'P', 'P', 'R', 'E', 'S', 'S', 'P', 'P', 'R'), # subop \ ('R', 'R', 'R', 'R', 'P', 'P', 'R', 'E', 'S', 'S', 'P', 'P', 'R'), # multop \ ('R', 'R', 'R', 'R', 'P', 'P', 'R', 'E', 'S', 'S', 'P', 'P', 'R'), # divop \ ('R', 'R', 'R', 'R', 'P', 'P', 'R', 'E', 'S', 'S', 'P', 'P', 'R'), # power \ ('P', 'P', 'P', 'P', 'P', 'P', 'D', 'E', 'S', 'S', 'P', 'P', 'E'), # l_par \ ('E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'), # r_par \ ('P', 'P', 'P', 'P', 'P', 'P', 'E', 'P', 'S', 'S', 'P', 'P', 'R'), # assign \ ('E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'), # ident \ ('E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E', 'E'), # number \ ('R', 'R', 'R', 'R', 'R', 'P', 'R', 'E', 'E', 'E', 'E', 'E', 'R'), # fname \ ('R', 'R', 'R', 'R', 'R', 'P', 'R', 'E', 'S', 'S', 'P', 'P', 'R'), # uminus \ ('P', 'P', 'P', 'P', 'P', 'P', 'E', 'P', 'S', 'S', 'P', 'P', 'F')) # eol header = ''' addop multop power r_par ident fname eol subop divop l_par assign number uminus''' def get_tok(s): pos = tok = 0 while 0<len(s): m = tok_finder.match(s) if m: categories = m.groups() # print categories for k in range(other+1): if categories[k]: tok = k break start,pos = m.span() val = s[start:pos] s = s[pos:] return (tok,val,s) else: print '***',s return (None,None,'') def lex(input): statement_list = [] pos = 0 while pos<len(input): m = line_finder.search(input,pos) if m: start,n = m.span() s = input[start:n] lex_list = [] while 0<len(s): tok,val,s = get_tok(s) if tok == space: pass elif tok == other: print "*** Illegal character:",val," ignored ***" elif tok == number: # val = RDF(val) # Hardware double precision val = MyFloat(val) lex_list.append((tok,val)) elif tok == ident: if val in functions.keys(): tok = fname val = functions[val] elif val in self_function.keys(): tok=fname else: if val not in symbol_table.keys(): symbol_table[val] = None lex_list.append((tok,val)) elif tok == addop: # Check for unary addops and delete if len(lex_list)==0: pass else: ptok = lex_list[-1][0] if (ptok!=r_par) and (ptok!=ident) and (ptok!=number): pass else: lex_list.append((tok,val)) elif tok == subop: # Check for unary minus and convert to uminus if len(lex_list)==0: tok = uminus else: ptok = lex_list[-1][0] if (ptok!=r_par) and (ptok!=ident) and (ptok!=number): tok = uminus lex_list.append((tok,val)) elif (tok == l_par) and (0<len(lex_list)): ptok,pval = lex_list[-1] if (ptok==r_par) or (ptok==ident) or (ptok==number): print "*** Illegal syntax:",pval,val," ***" lex_list.append((tok,val)) else: lex_list.append((tok,val)) statement_list.append(lex_list) pos = n else: #statement_list.append([]) break return statement_list # This block defines a Parser for standard algebraic formulas written with infix notation. # It converts the infix formula to an algebraic formula containing variables, numbers, # binary operators and unary operators written in Reverse Polish notation. # The binary operators include: '+', '-', '*', '/', '^', and '='. # The unary operators include the unary minus and the 10 elementary functions. def RPN_Parser(input_list): S = Stack() input_list.append((12,'\n')) S.push((12,'\n')) output_list = [] while 0 < len(input_list): keyi, itoken = input_list.pop(0) keys, stoken = S.pop() action = OP_f[keys][keyi] if action == 'P': # Push S.push((keys,stoken)) S.push((keyi,itoken)) elif action == 'R': # Reduce output_list.append((keys,stoken)) input_list.insert(0,(keyi,itoken)) elif action == 'S': # Keep the stack the same output_list.append((keyi,itoken)) S.push((keys,stoken)) elif action == 'D': # Discard the pair of parentheses pass elif action == 'F': # Finished #print "bingo\n" return output_list else: break # Error # Error exit return ['*** Error *** ',itoken, input_list] 
       
 
       


 
       
 
       
 
       
 
       
 
       
 
       

 
       

RPN Calculator Engine

# This block defines an extended RPN Calculator # # It evaluates an algebraic formula containing variables, numbers, # binary operators and unary operators written in Reverse Polish notation. # The binary operators include: '+', '-', '*', '/', '^', and '='. # The unary operators include the unary minus and the 10 elementary functions. # It also includes the commands 'SWAP' and 'DUP' where 'SWAP exchanges the # top two items on the stack, and 'DUP' duplicates the top of the stack. def Err(message,text): n = min(40,len(text)) if 0 < n: print ('*** Error: {0} at {1} \n'.format(message,text[:n])) else: print ('*** Error: {0} \n'.format(message)) def RPN_calc(input_list): global symbol_table S = Stack() ret=0 step = 0 while step < len(input_list): token = input_list[step] if token[0] == addop: y = S.pop() x = S.pop() S.push((number,x[1]+y[1])) elif token[0] == subop: y = S.pop() x = S.pop() S.push((number,x[1]-y[1])) elif token[0] == multop: y = S.pop() x = S.pop() S.push((number,x[1]*y[1])) elif token[0] == divop: y = S.pop() x = S.pop() S.push((number,x[1]/y[1])) elif token[0] == power: y = S.pop() x = S.pop() S.push((number,x[1]^y[1])) elif token[0] == assign: y = S.pop() x = S.pop() if x[0] != ident or y[0] != number: Err('The assign does not have ident on the left or a value on the right', str(x[1])) return None else: symbol_table[x[1]] = y[1] S.push(y) elif token[0] == ident: if input_list[len(input_list)-step-1][0] == assign: S.push(token) else: if symbol_table.get(token[1]) != None: S.push((number,symbol_table[token[1]])) else: Err('The ident has not be assigned yet', str(token[1])) return None elif token[0] == number: value = MyFloat(token[1]) S.push((number,value)) elif token[0] == fname: x = S.pop() if token[1] == 0: S.push((number,abs(x[1]))) elif token[1] == 1: if step + 2 < len(input_list) and input_list[step+1][0]==number and input_list[step+1][1]==2 and input_list[step+2][0]==power: S.push(x) step += 2 else: S.push((number,math.sqrt(x[1]))) elif token[1] == 2: S.push((number,math.exp(x[1]))) elif token[1] == 3: if step + 1 < len(input_list) and input_list[step+1][0]==fname and input_list[step+1][1]==2: S.push(x) step += 1 else: S.push((number,math.log(x[1]))) elif token[1] == 4: S.push((number,math.cos(x[1]))) elif token[1] == 5: S.push((number,math.sin(x[1]))) elif token[1] == 6: S.push((number,math.tan(x[1]))) elif token[1] == 7: S.push((number,math.acos(x[1]))) elif token[1] == 8: S.push((number,math.asin(x[1]))) elif token[1] == 9: S.push((number,math.atan(x[1]))) else: if token[1] in self_function.keys(): parameter=self_function_parameter[token[1]] symbol_table_copy={} symbol_table_copy=symbol_table.copy() symbol_table[parameter]=x[1] ret=calculate_function(token[1],x[1]) symbol_table=symbol_table_copy.copy() S.push((number,ret)) else: Err('Wrong function name', str(token[1])) return None elif token[0] == uminus: x = S.pop() S.push((number,-x[1])) else: Err('Unrecognized token', str(token[0])) return None step += 1 result = S.pop()[1] #result = MyFloat(result) return result 
       
self_function = {} self_function_parameter = {} line_finder = re.compile(r'\S.*$',re.MULTILINE) #function_finder = re.compile(r'Def (?P<name>[a-zA-Z]*)\((?P<parameter>[a-z])\):') function_header_finder = re.compile(r'Def (?P<name>[a-zA-Z]*)\((?P<parameter>[a-z])\):') function_end_finder = re.compile(r'End') def extract(s): pos = 0 start=0 flag=0 ss='' while pos<len(s): while pos<len(s) and s[pos]!='\n': pos=pos+1 s1=s[start:pos] #print s1 #print s1 pos=pos+1 start=pos m = line_finder.search(s1) if m: h=function_header_finder.search(s1) e=function_end_finder.search(s1) if h: flag=2 function_name=h.group('name') self_function_parameter[function_name]=h.group('parameter') sf='' #continue elif e: flag=0 self_function[function_name]=sf #continue else: if flag==0: ss=ss+'\n'+s1 elif flag==2: sf=s1 flag=1 else: sf=sf+'\n'+s1 else: continue return ss 
       
eq_finder = re.compile(r'(?P<left>.*)==(?P<right>.*)') big_finder = re.compile(r'(?P<left>.*)>(?P<right>.*)') def judge(input_string): eq=eq_finder.search(input_string) big=big_finder.search(input_string) if eq: left=eq.group('left') right=eq.group('right') if left in symbol_table.keys(): left=symbol_table[left] if right in symbol_table.keys(): right=symbol_table[right] left=int(left) right=int(right) if left==right: return 1 else: return 0 if big: left=big.group('left') right=big.group('right') if left in symbol_table.keys(): left=symbol_table[left] if right in symbol_table.keys(): right=symbol_table[right] left=int(left) right=int(right) if left>right: #print '@@@@@@@@@@@@@@@@' return 1 else: #print '#############' return 0 
       
def calculate(multiline_input_string): #global symbol_table #symbol_table = {} lex_list = lex(multiline_input_string) for s in lex_list: #print s rpn_list = RPN_Parser(s) #print rpn_list print RPN_calc(rpn_list) 
       
def calculateforfunction(multiline_input_string): #global symbol_table #symbol_table = {} ret=0 lex_list = lex(multiline_input_string) for s in lex_list: #print s rpn_list = RPN_Parser(s) #print rpn_list ret=RPN_calc(rpn_list) return ret 
       
def logic_calculate_function(s): pos = 0 flag=0 dep=0 syt=[] while_finder = re.compile(r'while (?P<judge>.*):') if_finder = re.compile(r'if (?P<judge>.*):') ce = re.compile(r'\s\s\s\s(?P<remain>.*)') st=Stack() st1=Stack() ceng_p=0 start=0 line_number=0 syt=[[0 for i in range(3)] for j in range(100)] while pos<len(s): while pos<len(s) and s[pos]!='\n': pos=pos+1 s1=s[start:pos] #print s1 pos=pos+1 start=pos m=line_finder.search(s1) if m: #print m.group() start1,n1 = m.span() #s2 = s[start1:n1] w_control=while_finder.search(s1) i_control=if_finder.search(s1) #calculate ceng ceng=0 remain=s1 while 1: cen=ce.search(remain) if cen: ceng=ceng+1 remain=cen.group('remain') else: break if ceng<ceng_p: ccp=ceng_p-ceng current_line_number=line_number-1 while ccp>0: ccp=ccp-1 temp=st.pop() if syt[int(temp)][0]==2: st1.push(temp) #print 'ceng:',ceng #print s1 syt[temp][2]=line_number #print 'line_number:',line_number ceng_p=ceng_p-1 if syt[temp][0]==1: syt[current_line_number][2]=temp current_line_number=temp while st1.depth(): syt[st1.pop()][2]=temp if w_control: syt[line_number][0]=1 syt[line_number][1]=w_control.group('judge') st.push(line_number) ceng_p=ceng_p+1 elif i_control: syt[line_number][0]=2 syt[line_number][1]=i_control.group('judge') st.push(line_number) ceng_p=ceng_p+1 else: syt[line_number][0]=0 s2=s1[start1:n1] syt[line_number][1]=s2 syt[line_number][2]=line_number+1 line_number=line_number+1 else: continue while dep>0: dep=dep-1 temp=st.pop() if syt[int(temp)][0]==2: st1.push(temp) syt[temp][2]=line_number if syt[temp][0]==1: syt[current_line_number][2]=temp current_line_number=temp while st1.depth(): syt[st1.pop()][2]=temp syt[line_number][0]=-1 #line_number=0 #while syt[line_number][0]!=-1: #print syt[line_number][0],syt[line_number][1],syt[line_number][2] #line_number=line_number+1 line_number=0 while syt[line_number][0]!=-1: if syt[line_number][0]==0: ret=calculateforfunction(syt[line_number][1]) line_number=syt[line_number][2] if syt[line_number][0]==1: if judge(syt[line_number][1])==0: line_number=syt[line_number][2] else: line_number=line_number+1 if syt[line_number][0]==2: if judge(syt[line_number][1])==0: line_number=syt[line_number][2] else: line_number=line_number+1 return ret 
       
def logic_calculate(s): pos = 0 flag=0 dep=0 syt=[] while_finder = re.compile(r'while (?P<judge>.*):') if_finder = re.compile(r'if (?P<judge>.*):') ce = re.compile(r'\s\s\s\s(?P<remain>.*)') st=Stack() st1=Stack() ceng_p=0 start=0 line_number=0 syt=[[0 for i in range(3)] for j in range(100)] while pos<len(s): while pos<len(s) and s[pos]!='\n': pos=pos+1 s1=s[start:pos] #print s1 pos=pos+1 start=pos m=line_finder.search(s1) if m: #print m.group() start1,n1 = m.span() #s2 = s[start1:n1] w_control=while_finder.search(s1) i_control=if_finder.search(s1) #calculate ceng ceng=0 remain=s1 while 1: cen=ce.search(remain) if cen: ceng=ceng+1 remain=cen.group('remain') else: break if ceng<ceng_p: ccp=ceng_p-ceng current_line_number=line_number-1 while ccp>0: ccp=ccp-1 temp=st.pop() if syt[int(temp)][0]==2: st1.push(temp) #print 'ceng:',ceng #print s1 syt[temp][2]=line_number #print 'line_number:',line_number ceng_p=ceng_p-1 if syt[temp][0]==1: syt[current_line_number][2]=temp current_line_number=temp while st1.depth(): syt[st1.pop()][2]=temp if w_control: syt[line_number][0]=1 syt[line_number][1]=w_control.group('judge') st.push(line_number) ceng_p=ceng_p+1 elif i_control: syt[line_number][0]=2 syt[line_number][1]=i_control.group('judge') st.push(line_number) ceng_p=ceng_p+1 else: syt[line_number][0]=0 s2=s1[start1:n1] syt[line_number][1]=s2 syt[line_number][2]=line_number+1 line_number=line_number+1 else: continue dep=st.depth() current_line_number=line_number-1 while dep>0: dep=dep-1 temp=st.pop() if syt[int(temp)][0]==2: st1.push(temp) syt[temp][2]=line_number if syt[temp][0]==1: syt[current_line_number][2]=temp current_line_number=temp while st1.depth(): syt[st1.pop()][2]=temp syt[line_number][0]=-1 #line_number=0 #while syt[line_number][0]!=-1: #print syt[line_number][0],syt[line_number][1],syt[line_number][2] #line_number=line_number+1 line_number=0 while syt[line_number][0]!=-1: if syt[line_number][0]==0: calculate(syt[line_number][1]) line_number=syt[line_number][2] if syt[line_number][0]==1 or syt[line_number][0]==2: if judge(syt[line_number][1])==0: line_number=syt[line_number][2] #print '##################' else: line_number=line_number+1 
       
def calculate_function(function_name,x): global symbol_table ret=0 multiline_input_string=self_function[function_name] #lex_list = lex(multiline_input_string) #for s in lex_list: #rpn_list = RPN_Parser(s) #ret=RPN_calc(rpn_list) #symbol_table=symbol_table_copy.copy() #return ret ret=logic_calculate_function(multiline_input_string) return ret 
       
def programming_calculate(s): ss=extract(s) logic_calculate(ss) 
       
 
       

 
       
 
       

Test Cases

s1 = r''' 2+3*5^2 (2+3)*5^2 (2++3*5)^2 3*5/3 3-+-18/3^2 (3-21)/3^2 (3-18/3)^2 ''' programming_calculate(s1) 
       
0 2+3*5^2 1
0 (2+3)*5^2 2
0 (2++3*5)^2 3
0 3*5/3 4
0 3-+-18/3^2 5
0 (3-21)/3^2 6
0 (3-18/3)^2 7
77.0000000000000
125.000000000000
289.000000000000
5.00000000000000
5.00000000000000
-2.00000000000000
9.00000000000000
0 2+3*5^2 1
0 (2+3)*5^2 2
0 (2++3*5)^2 3
0 3*5/3 4
0 3-+-18/3^2 5
0 (3-21)/3^2 6
0 (3-18/3)^2 7
77.0000000000000
125.000000000000
289.000000000000
5.00000000000000
5.00000000000000
-2.00000000000000
9.00000000000000
s2 = ''' length = 5 width = 2 area = length * width perimeter = 2*(length + width) length = 5.5e-2 width = .2e-2 area = length * width perimeter = 2*(length + width) ''' programming_calculate(s2) 
       
5.00000000000000
2.00000000000000
10.0000000000000
14.0000000000000
0.0550000000000000
0.00200000000000000
0.000110000000000000
0.114000000000000
5.00000000000000
2.00000000000000
10.0000000000000
14.0000000000000
0.0550000000000000
0.00200000000000000
0.000110000000000000
0.114000000000000
print symbol_table 
       
{'a': 1.00000000000000, 'perimeter': 0.114000000000000, 'c':
2.00000000000000, 'b': 1.00000000000000, 'e': 5.00000000000000, 'd':
3.00000000000000, 'g': 13.0000000000000, 'f': 8.00000000000000, 'i':
34.0000000000000, 'h': 21.0000000000000, 'sum': 88.0000000000000,
'area': 0.000110000000000000, 'width': 0.00200000000000000, 'length':
0.0550000000000000, 'x': 1.00000000000000}
{'a': 1.00000000000000, 'perimeter': 0.114000000000000, 'c': 2.00000000000000, 'b': 1.00000000000000, 'e': 5.00000000000000, 'd': 3.00000000000000, 'g': 13.0000000000000, 'f': 8.00000000000000, 'i': 34.0000000000000, 'h': 21.0000000000000, 'sum': 88.0000000000000, 'area': 0.000110000000000000, 'width': 0.00200000000000000, 'length': 0.0550000000000000, 'x': 1.00000000000000}


# Include the following built-in functions # abs(x), sqrt(x), exp(x), ln(x), # cos(x), sin(x), tan(x) # acos(x), asin(x), atan(x) s3 = ''' +---4 abs(---4) sqrt(5^2) - 5 (sqrt(2))^2 - 2 exp(0)*ln(1) ln(exp(3)) - 3 exp(ln(3)) - 3 t1 = acos(3/5) t2 = asin(4/5) cos(t1)^2+sin(t2)^2 pie = 4*atan(1.0) ''' programming_calculate(s3) 
       
-4.00000000000000
4.00000000000000
0.000000000000000
0.000000000000000
0.0
0.000000000000000
0.000000000000000
0.927295218002
0.927295218002
1.0
3.14159265358979
-4.00000000000000
4.00000000000000
0.000000000000000
0.000000000000000
0.0
0.000000000000000
0.000000000000000
0.927295218002
0.927295218002
1.0
3.14159265358979
print symbol_table 
       
{'a': 1.00000000000000, 'perimeter': 0.114000000000000, 'c':
2.00000000000000, 'b': 1.00000000000000, 'e': 5.00000000000000, 'd':
3.00000000000000, 'g': 13.0000000000000, 'f': 8.00000000000000, 'i':
34.0000000000000, 'h': 21.0000000000000, 'sum': 88.0000000000000,
'area': 0.000110000000000000, 't2': 0.9272952180016123, 'pie':
3.14159265358979, 't1': 0.9272952180016123, 'width':
0.00200000000000000, 'length': 0.0550000000000000, 'x':
1.00000000000000}
{'a': 1.00000000000000, 'perimeter': 0.114000000000000, 'c': 2.00000000000000, 'b': 1.00000000000000, 'e': 5.00000000000000, 'd': 3.00000000000000, 'g': 13.0000000000000, 'f': 8.00000000000000, 'i': 34.0000000000000, 'h': 21.0000000000000, 'sum': 88.0000000000000, 'area': 0.000110000000000000, 't2': 0.9272952180016123, 'pie': 3.14159265358979, 't1': 0.9272952180016123, 'width': 0.00200000000000000, 'length': 0.0550000000000000, 'x': 1.00000000000000}
test_1 = '''2*3+2+1 2+3-1 temp_2 = 5.1 3*(5-2) 2*temp_2 12 abs(-2) 134 2*(3+2)^abs(-2)+1-(temp_2*12.2) ''' programming_calculate(test_1) 
       
9.00000000000000
4.00000000000000
5.10000000000000
9.00000000000000
10.2000000000000
12.0000000000000
2.00000000000000
134.000000000000
-11.2200000000000
9.00000000000000
4.00000000000000
5.10000000000000
9.00000000000000
10.2000000000000
12.0000000000000
2.00000000000000
134.000000000000
-11.2200000000000
test_2 = """ 5.5*(-2)^3*2^3^--2 24/6/2 5.5*(-2)^3*24/6/2*2^3^--2 3+2*5^2*(3+2)*5^2*10-4-1 """ programming_calculate(test_2) 
       
-22528.0000000000
2.00000000000000
-45056.0000000000
62498.0000000000
-22528.0000000000
2.00000000000000
-45056.0000000000
62498.0000000000
symbol_table = {} test_3 = ''' a = 1 b = 2 b = c = a+b a b c d ''' programming_calculate(test_3) 
       
1.00000000000000
2.00000000000000
3.00000000000000
1.00000000000000
3.00000000000000
3.00000000000000
*** Error: The ident has not be assigned yet at d 

None
1.00000000000000
2.00000000000000
3.00000000000000
1.00000000000000
3.00000000000000
3.00000000000000
*** Error: The ident has not be assigned yet at d 

None
print symbol_table 
       
{'a': 1.00000000000000, 'c': 3.00000000000000, 'b': 3.00000000000000,
'd': None}
{'a': 1.00000000000000, 'c': 3.00000000000000, 'b': 3.00000000000000, 'd': None}
#factorial s=''' Def factorial(x): f=1 x=5 while x>0: f=f*x x=x-1 f End factorial(x) ''' programming_calculate(s) 
       
120.000000000000
120.000000000000
#fibonacci s= ''' Def fibonacci(x): if x==1: fib=1 if x==2: fib=1 if x>2: fib=fibonacci(x-1)+fibonacci(x-2) fib End Def sumfibonacci(x): sum=0 i=1 while x>i: sum=sum+fibonacci(i) i=i+1 sum End a=fibonacci(1) b=fibonacci(2) c=fibonacci(3) d=fibonacci(4) e=fibonacci(5) f=fibonacci(6) g=fibonacci(7) h=fibonacci(8) i=fibonacci(9) sum=a+b+c+d+e+f+g+h+i sumfibonacci(10) ''' programming_calculate(s) 
       
1.00000000000000
1.00000000000000
2.00000000000000
3.00000000000000
5.00000000000000
8.00000000000000
13.0000000000000
21.0000000000000
34.0000000000000
88.0000000000000
88.0000000000000
1.00000000000000
1.00000000000000
2.00000000000000
3.00000000000000
5.00000000000000
8.00000000000000
13.0000000000000
21.0000000000000
34.0000000000000
88.0000000000000
88.0000000000000
#a more complex s for testing reason s=''' Def test(x): i=1 j=1 k=1 sum=0 while 3>i: i=i+1 if i>1: if 3>i: while 3>j: j=j+1 k=0 while 3>k: k=k+1 sum=sum+1 sum=sum+x sum End test(10) ''' programming_calculate(s) 
       
0 test(10) 1
0 i=1 1
0 j=1 2
0 k=1 3
0 sum=0 4
1 3>i 14
0 i=i+1 6
2 i>1 4
2 3>i 4
1 3>j 4
0 j=j+1 10
0 k=0 11
1 3>k 8
0 k=k+1 13
0 sum=sum+1 11
0 sum=sum+x 15
0 sum 16
16.0000000000000
0 test(10) 1
0 i=1 1
0 j=1 2
0 k=1 3
0 sum=0 4
1 3>i 14
0 i=i+1 6
2 i>1 4
2 3>i 4
1 3>j 4
0 j=j+1 10
0 k=0 11
1 3>k 8
0 k=k+1 13
0 sum=sum+1 11
0 sum=sum+x 15
0 sum 16
16.0000000000000
# re-define logic_calculate_fuction which can print four element tuple in the self defined functions def logic_calculate_function(s): pos = 0 flag=0 dep=0 syt=[] while_finder = re.compile(r'while (?P<judge>.*):') if_finder = re.compile(r'if (?P<judge>.*):') ce = re.compile(r'\s\s\s\s(?P<remain>.*)') st=Stack() st1=Stack() ceng_p=0 start=0 line_number=0 syt=[[0 for i in range(3)] for j in range(100)] while pos<len(s): while pos<len(s) and s[pos]!='\n': pos=pos+1 s1=s[start:pos] #print s1 pos=pos+1 start=pos m=line_finder.search(s1) if m: #print m.group() start1,n1 = m.span() #s2 = s[start1:n1] w_control=while_finder.search(s1) i_control=if_finder.search(s1) #calculate ceng ceng=0 remain=s1 while 1: cen=ce.search(remain) if cen: ceng=ceng+1 remain=cen.group('remain') else: break if ceng<ceng_p: ccp=ceng_p-ceng current_line_number=line_number-1 while ccp>0: ccp=ccp-1 temp=st.pop() if syt[int(temp)][0]==2: st1.push(temp) #print 'ceng:',ceng #print s1 syt[temp][2]=line_number #print 'line_number:',line_number ceng_p=ceng_p-1 if syt[temp][0]==1: syt[current_line_number][2]=temp current_line_number=temp while st1.depth(): syt[st1.pop()][2]=temp if w_control: syt[line_number][0]=1 syt[line_number][1]=w_control.group('judge') st.push(line_number) ceng_p=ceng_p+1 elif i_control: syt[line_number][0]=2 syt[line_number][1]=i_control.group('judge') st.push(line_number) ceng_p=ceng_p+1 else: syt[line_number][0]=0 s2=s1[start1:n1] syt[line_number][1]=s2 syt[line_number][2]=line_number+1 line_number=line_number+1 else: continue while dep>0: dep=dep-1 temp=st.pop() if syt[int(temp)][0]==2: st1.push(temp) syt[temp][2]=line_number if syt[temp][0]==1: syt[current_line_number][2]=temp current_line_number=temp while st1.depth(): syt[st1.pop()][2]=temp syt[line_number][0]=-1 line_number=0 print "line_number\toperation\texpression\tnext_pointer" while syt[line_number][0]!=-1: print line_number,'\t\t',syt[line_number][0],'\t\t',syt[line_number][1],'\t\t',syt[line_number][2] line_number=line_number+1 line_number=0 while syt[line_number][0]!=-1: if syt[line_number][0]==0: ret=calculateforfunction(syt[line_number][1]) line_number=syt[line_number][2] if syt[line_number][0]==1: if judge(syt[line_number][1])==0: line_number=syt[line_number][2] else: line_number=line_number+1 if syt[line_number][0]==2: if judge(syt[line_number][1])==0: line_number=syt[line_number][2] else: line_number=line_number+1 return ret s=''' Def test(x): i=1 j=1 k=1 sum=0 while 3>i: i=i+1 if i>1: if 3>i: while 3>j: j=j+1 k=0 while 3>k: k=k+1 sum=sum+1 sum=sum+x sum End test(10) ''' programming_calculate(s) def logic_calculate_function(s): pos = 0 flag=0 dep=0 syt=[] while_finder = re.compile(r'while (?P<judge>.*):') if_finder = re.compile(r'if (?P<judge>.*):') ce = re.compile(r'\s\s\s\s(?P<remain>.*)') st=Stack() st1=Stack() ceng_p=0 start=0 line_number=0 syt=[[0 for i in range(3)] for j in range(100)] while pos<len(s): while pos<len(s) and s[pos]!='\n': pos=pos+1 s1=s[start:pos] #print s1 pos=pos+1 start=pos m=line_finder.search(s1) if m: #print m.group() start1,n1 = m.span() #s2 = s[start1:n1] w_control=while_finder.search(s1) i_control=if_finder.search(s1) #calculate ceng ceng=0 remain=s1 while 1: cen=ce.search(remain) if cen: ceng=ceng+1 remain=cen.group('remain') else: break if ceng<ceng_p: ccp=ceng_p-ceng current_line_number=line_number-1 while ccp>0: ccp=ccp-1 temp=st.pop() if syt[int(temp)][0]==2: st1.push(temp) #print 'ceng:',ceng #print s1 syt[temp][2]=line_number #print 'line_number:',line_number ceng_p=ceng_p-1 if syt[temp][0]==1: syt[current_line_number][2]=temp current_line_number=temp while st1.depth(): syt[st1.pop()][2]=temp if w_control: syt[line_number][0]=1 syt[line_number][1]=w_control.group('judge') st.push(line_number) ceng_p=ceng_p+1 elif i_control: syt[line_number][0]=2 syt[line_number][1]=i_control.group('judge') st.push(line_number) ceng_p=ceng_p+1 else: syt[line_number][0]=0 s2=s1[start1:n1] syt[line_number][1]=s2 syt[line_number][2]=line_number+1 line_number=line_number+1 else: continue while dep>0: dep=dep-1 temp=st.pop() if syt[int(temp)][0]==2: st1.push(temp) syt[temp][2]=line_number if syt[temp][0]==1: syt[current_line_number][2]=temp current_line_number=temp while st1.depth(): syt[st1.pop()][2]=temp syt[line_number][0]=-1 #line_number=0 #while syt[line_number][0]!=-1: #print syt[line_number][0],syt[line_number][1],syt[line_number][2] #line_number=line_number+1 line_number=0 while syt[line_number][0]!=-1: if syt[line_number][0]==0: ret=calculateforfunction(syt[line_number][1]) line_number=syt[line_number][2] if syt[line_number][0]==1: if judge(syt[line_number][1])==0: line_number=syt[line_number][2] else: line_number=line_number+1 if syt[line_number][0]==2: if judge(syt[line_number][1])==0: line_number=syt[line_number][2] else: line_number=line_number+1 return ret 
       
line_number	operation	expression	next_pointer
0 		0 		i=1 		1
1 		0 		j=1 		2
2 		0 		k=1 		3
3 		0 		sum=0 		4
4 		1 		3>i 		14
5 		0 		i=i+1 		6
6 		2 		i>1 		4
7 		2 		3>i 		4
8 		1 		3>j 		4
9 		0 		j=j+1 		10
10 		0 		k=0 		11
11 		1 		3>k 		8
12 		0 		k=k+1 		13
13 		0 		sum=sum+1 		11
14 		0 		sum=sum+x 		15
15 		0 		sum 		16
16.0000000000000
line_number	operation	expression	next_pointer
0 		0 		i=1 		1
1 		0 		j=1 		2
2 		0 		k=1 		3
3 		0 		sum=0 		4
4 		1 		3>i 		14
5 		0 		i=i+1 		6
6 		2 		i>1 		4
7 		2 		3>i 		4
8 		1 		3>j 		4
9 		0 		j=j+1 		10
10 		0 		k=0 		11
11 		1 		3>k 		8
12 		0 		k=k+1 		13
13 		0 		sum=sum+1 		11
14 		0 		sum=sum+x 		15
15 		0 		sum 		16
16.0000000000000