免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1688 | 回复: 2
打印 上一主题 下一主题

简单算术运算解释器 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-09-13 09:49 |只看该作者 |倒序浏览
实现一个简单语法语言的解释器。在运行时解释器每次输入一行语句,输出可能的输出。
  1. # -*- coding: cp936 -*-
  2. def Execute(strCodeLine,  output):
  3.     local_vars = {}
  4.     all_input = (strCodeLine.strip()).split("\n")
  5.     all_input = [item.strip() for item in all_input]
  6.     for index, item in enumerate(all_input):
  7.         tmp_list = [i.strip() for i in item.split(" ")]
  8.         all_input[index] = ""
  9.         for i in tmp_list:
  10.             if i != "":
  11.                 all_input[index] += i
  12.                 all_input[index] += " "
  13.         all_input[index] = all_input[index].strip()
  14.     flag = 0

  15.     for every_input in all_input:
  16.         tmp = check_input(every_input, local_vars)
  17.         if  tmp != -1:
  18.             result = calcu_every_input(every_input, local_vars, tmp)
  19.             if result == "error":
  20.                 flag =  -1
  21.             elif result != None:
  22.                 output.append(str(result))
  23.         else:
  24.             flag =  -1
  25.     return flag

  26. def calcu_every_input(every_input, local_vars, type):

  27.     if type == 1:
  28.         output_var = [item.strip() for item in every_input.split()]
  29.         return local_vars[output_var[1]]
  30.     elif type == 2:
  31.         input_exp = every_input.split("=")
  32.         result = calcu_expression(input_exp[0], input_exp[1], local_vars)
  33.         if result == "error":
  34.             return "error"
  35.         local_vars[input_exp[0].strip()] = result
  36.         
  37. def calcu_expression(var, expression, local_vars):
  38.     symbol_stack = []
  39.     value_stack = []
  40.     legal_symbol = ['+', '-', '*', '/', '(', ')']   
  41.     expression = expression.strip()
  42.     expression_list = expression.split(" ")
  43.     result = 0
  44.     str_tmp = ""
  45.     for index, item in enumerate(expression_list):
  46.         if item in local_vars:
  47.             str_tmp += str(local_vars[item])
  48.         elif item.isdigit():
  49.             str_tmp +=  item
  50.         elif item in legal_symbol:
  51.             str_tmp += item
  52.     try:
  53.         ##分析这里的字符串使除数不能为0
  54.         sign = str_tmp.find("/")
  55.         if sign == 1:
  56.             leftSign = str_tmp.split("/")
  57.             if leftSign[1] != '0':
  58.                 result = eval(str_tmp)
  59.                 local_vars[var.strip()] = result  
  60.             else:
  61.                 return "error"

  62.         else:
  63.             result = eval(str_tmp)
  64.             local_vars[var.strip()] = result
  65.     except:
  66.         return "error"         
  67.     return result

  68. def veritfy_var(var):
  69.     if var == "print":
  70.         return -1
  71.     if ((var[0] >= 'A') and (var[0] <= 'Z')) or ((var[0] >= 'a') and (var[0] <= 'z')):
  72.         index = 1
  73.         while index < len(var):
  74.             if not (((var[index] >= 'A') and (var[index] <= 'Z'))  
  75.                 or ((var[index] >= 'a') and (var[index] <= 'z'))  
  76.                 or ((var[index] >= '0') and (var[index] <= '9'))):
  77.                 return -1
  78.     return 0
  79.    
  80. def check_input(every_input, local_vars):
  81.     legal_symbol = ['+', '-', '*', '/', '(', ')']
  82.     index = every_input.find("print")
  83.     if index == 0:
  84.         output_var = [item.strip() for item in every_input.split(" ")]
  85.         if len(output_var) == 2:
  86.                 if output_var[1] in local_vars:
  87.                     return 1
  88.     else:
  89.         input_var = every_input.split("=")
  90.         input_var = [item.strip() for item in input_var]
  91.         if len(input_var) == 2:
  92.             if veritfy_var(input_var[0]) == -1:
  93.                 return -1
  94.             if len(input_var[0]) == 1:
  95.                 right_in_var = input_var[1].split(" ")
  96.                 right_in_var = [item.strip() for item in right_in_var]  
  97.                 for item in right_in_var:
  98.                     if (item in legal_symbol) or (item in local_vars) or item.isdigit():
  99.                         return 2
  100.     return -1

  101. def CheckVarValue(output, checkList, outputret, checkret):
  102.     if (output == checkList) and (outputret == checkret):
  103.         print "pass"
  104.     else:
  105.         print "error"


  106. # 立即数赋值
  107. def testcase01():   
  108.     strCodeLine = """
  109. a = 90
  110. print a"""   
  111.     output = []
  112.    
  113.     ret = Execute(strCodeLine,  output)
  114.             
  115.     CheckVarValue(output, ["90"], ret, 0)

  116. # 赋值语句:立即数加运算
  117. def testcase02():   
  118.     strCodeLine = """
  119. b = 2 + 7
  120. print b"""   
  121.     output = []
  122.    
  123.     ret = Execute(strCodeLine,  output)
  124.             
  125.     CheckVarValue(output, ["9"], ret, 0)

  126. # 赋值语句:立即数减运算
  127. def testcase03():   
  128.     strCodeLine = """
  129. c = 9 - 1
  130. print c"""   
  131.     output = []
  132.    
  133.     ret = Execute(strCodeLine,  output)
  134.             
  135.     CheckVarValue(output, ["8"], ret, 0)

  136. # 赋值语句:立即数乘运算
  137. def testcase04():   
  138.     strCodeLine = """
  139. d = 9 - 1
  140. e = 3 * d
  141. print d
  142. print e"""   
  143.     output = []
  144.    
  145.     ret = Execute(strCodeLine,  output)
  146.             
  147.     CheckVarValue(output, ["8", "24"], ret, 0)

  148. # 赋值语句:立即数除运算
  149. def testcase05():   
  150.     strCodeLine = """
  151. f = 24
  152. g = f / 4
  153. print g"""   
  154.     output = []
  155.    
  156.     ret = Execute(strCodeLine,  output)
  157.             
  158.     CheckVarValue(output, ["6"], ret, 0)

  159. # 赋值语句:变量运算
  160. def testcase06():   
  161.     strCodeLine = """
  162. h = 2 * 3
  163. i = h + h
  164. print h
  165. print i"""   
  166.     output = []
  167.    
  168.     ret = Execute(strCodeLine,  output)
  169.             
  170.     CheckVarValue(output, ["6", "12"], ret, 0)
  171.    
  172. # 赋值语句:变量值更新
  173. def testcase07():      
  174.     strCodeLine = """
  175. j = 2 * 3
  176. j = j * j
  177. print j"""   
  178.     output = []
  179.    
  180.     ret = Execute(strCodeLine,  output)
  181.             
  182.     CheckVarValue(output, ["36"], ret, 0)
  183.    
  184. # 赋值语句:运算符优先级
  185. def testcase08():   
  186.     strCodeLine = """
  187. a = 10 * 3
  188. b = 8
  189. print a
  190. c = a + b
  191. print b
  192. e = a - 5 * b / 2 + 8
  193. print c
  194. print e"""   
  195.     output = []
  196.    
  197.     ret = Execute(strCodeLine,  output)
  198.             
  199.     CheckVarValue(output, ["30", "8", "38", "18"], ret, 0)
  200.    
  201. # 赋值语句:括号的简单使用
  202. def testcase09():   
  203.     strCodeLine = """
  204. a = 3
  205. print a
  206. b = 8
  207. d = a - ( b - 4 )
  208. print d"""   
  209.     output = []
  210.    
  211.     ret = Execute(strCodeLine,  output)
  212.             
  213.     CheckVarValue(output, ["3", "-1"], ret, 0)

  214. # 赋值语句:括号的使用
  215. def testcase10():   
  216.     strCodeLine = """
  217. a = 3
  218. print a
  219. b = 8
  220. c = a * b
  221. d = a - ( c - 4 ) * b
  222. print d"""   
  223.     output = []
  224.    
  225.     ret = Execute(strCodeLine,  output)
  226.             
  227.     CheckVarValue(output, ["3", "-157"], ret, 0)

  228. # 赋值语句:变量名区分大小写
  229. def testcase11():   
  230.     strCodeLine = """
  231. a = 100
  232. A = 200
  233. print a
  234. print A
  235. c = A / a
  236. print c"""   
  237.     output = []
  238.    
  239.     ret = Execute(strCodeLine,  output)
  240.             
  241.     CheckVarValue(output, ["100", "200", "2"], ret, 0)

  242. # 异常用例:变量使用之前必须初始化过
  243. def TestCase_Error_1():   
  244.     strCodeLine = """
  245. a = 1
  246. c = a + d
  247. print a"""   
  248.     output = []
  249.    
  250.     ret = Execute(strCodeLine,  output)
  251.             
  252.     CheckVarValue(output, ["1"], ret, -1)
  253.    
  254. # 异常用例:分隔符为多个空格
  255. def TestCase_Error_2():   
  256.     strCodeLine = """
  257. q = 1  +    2
  258. print q"""   
  259.     output = []
  260.    
  261.     ret = Execute(strCodeLine,  output)
  262.             
  263.     CheckVarValue(output, ["3"], ret, 0)
  264.    
  265. # 异常用例:语句必须完整
  266. def TestCase_Error_3():   
  267.     strCodeLine = """
  268. a = 1 +"""   
  269.     output = []
  270.    
  271.     ret = Execute(strCodeLine,  output)
  272.             
  273.     CheckVarValue(output, [], ret, -1)

  274. # 异常用例:左值必须为变量
  275. def TestCase_Error_4():   
  276.     strCodeLine = """
  277. 90 = a
  278. print a"""   
  279.     output = []
  280.    
  281.     ret = Execute(strCodeLine,  output)
  282.             
  283.     CheckVarValue(output, [], ret, -1)
  284.    
  285. # 异常用例:关键字与变量之间必须有分隔符
  286. def TestCase_Error_5():   
  287.     strCodeLine = """
  288. a = 0
  289. printa"""   
  290.     output = []
  291.    
  292.     ret = Execute(strCodeLine,  output)
  293.             
  294.     CheckVarValue(output, [], ret, -1)
  295.    
  296. # 异常用例:运算中除0
  297. def TestCase_Error_6():   
  298.     strCodeLine = """
  299. a = 0
  300. b = 2
  301. c = 3
  302. c = b / a
  303. print c
  304. d = a / b
  305. print d"""   
  306.     output = []
  307.    
  308.     ret = Execute(strCodeLine,  output)
  309.             
  310.     CheckVarValue(output, ["3", "0"], ret, -1)
  311.    
  312. # 异常用例:变量名采用关键字
  313. def TestCase_Error_7():   
  314.     strCodeLine = """
  315. print = 1
  316. a = 3
  317. print print"""   
  318.     output = []
  319.    
  320.     ret = Execute(strCodeLine,  output)
  321.             
  322.     CheckVarValue(output, [], ret, -1)
  323.    
  324. # 异常用例:复杂程序
  325. def testcase12():   
  326.     strCodeLine = """
  327. a = 10000
  328. print a
  329. b = a * a
  330. c = c * 10
  331. print c
  332. e = 1000
  333. a = a / e
  334. print a
  335. c  = a
  336. d =  1 + 10 + ( b / ( a * 10 ) )
  337. print d
  338. """   
  339.     output = []
  340.    
  341.     ret = Execute(strCodeLine,  output)
  342.             
  343.     CheckVarValue(output, ["10000", "10", "1000011"], ret, -1)

  344. def main():
  345.     testcase01()
  346.     testcase02()
  347.     testcase03()
  348.     testcase04()
  349.     testcase05()
  350.     testcase06()
  351.     testcase07()
  352.     testcase08()
  353.     testcase09()
  354.     testcase10()
  355.     testcase11()
  356.     TestCase_Error_1()
  357.     TestCase_Error_2()
  358.     TestCase_Error_3()
  359.     TestCase_Error_4()
  360.     TestCase_Error_5()
  361.     TestCase_Error_6()
  362.     TestCase_Error_7()
  363.     testcase12()
  364.    
  365. if __name__ == '__main__':
  366.     main()
复制代码

捕获.PNG (15.02 KB, 下载次数: 3)

捕获.PNG

论坛徽章:
0
2 [报告]
发表于 2012-09-15 10:42 |只看该作者
答案....................

Python样题答案.rar

2.08 KB, 下载次数: 8

论坛徽章:
0
3 [报告]
发表于 2012-09-16 16:52 |只看该作者
用堆栈中序转后序,然后后序运算...DS里经典算法...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP