- 论坛徽章:
- 0
|
实现一个简单语法语言的解释器。在运行时解释器每次输入一行语句,输出可能的输出。- # -*- coding: cp936 -*-
- def Execute(strCodeLine, output):
- local_vars = {}
- all_input = (strCodeLine.strip()).split("\n")
- all_input = [item.strip() for item in all_input]
- for index, item in enumerate(all_input):
- tmp_list = [i.strip() for i in item.split(" ")]
- all_input[index] = ""
- for i in tmp_list:
- if i != "":
- all_input[index] += i
- all_input[index] += " "
- all_input[index] = all_input[index].strip()
- flag = 0
- for every_input in all_input:
- tmp = check_input(every_input, local_vars)
- if tmp != -1:
- result = calcu_every_input(every_input, local_vars, tmp)
- if result == "error":
- flag = -1
- elif result != None:
- output.append(str(result))
- else:
- flag = -1
- return flag
-
- def calcu_every_input(every_input, local_vars, type):
- if type == 1:
- output_var = [item.strip() for item in every_input.split()]
- return local_vars[output_var[1]]
- elif type == 2:
- input_exp = every_input.split("=")
- result = calcu_expression(input_exp[0], input_exp[1], local_vars)
- if result == "error":
- return "error"
- local_vars[input_exp[0].strip()] = result
-
- def calcu_expression(var, expression, local_vars):
- symbol_stack = []
- value_stack = []
- legal_symbol = ['+', '-', '*', '/', '(', ')']
- expression = expression.strip()
- expression_list = expression.split(" ")
- result = 0
- str_tmp = ""
- for index, item in enumerate(expression_list):
- if item in local_vars:
- str_tmp += str(local_vars[item])
- elif item.isdigit():
- str_tmp += item
- elif item in legal_symbol:
- str_tmp += item
- try:
- ##分析这里的字符串使除数不能为0
- sign = str_tmp.find("/")
- if sign == 1:
- leftSign = str_tmp.split("/")
- if leftSign[1] != '0':
- result = eval(str_tmp)
- local_vars[var.strip()] = result
- else:
- return "error"
- else:
- result = eval(str_tmp)
- local_vars[var.strip()] = result
- except:
- return "error"
- return result
- def veritfy_var(var):
- if var == "print":
- return -1
- if ((var[0] >= 'A') and (var[0] <= 'Z')) or ((var[0] >= 'a') and (var[0] <= 'z')):
- index = 1
- while index < len(var):
- if not (((var[index] >= 'A') and (var[index] <= 'Z'))
- or ((var[index] >= 'a') and (var[index] <= 'z'))
- or ((var[index] >= '0') and (var[index] <= '9'))):
- return -1
- return 0
-
- def check_input(every_input, local_vars):
- legal_symbol = ['+', '-', '*', '/', '(', ')']
- index = every_input.find("print")
- if index == 0:
- output_var = [item.strip() for item in every_input.split(" ")]
- if len(output_var) == 2:
- if output_var[1] in local_vars:
- return 1
- else:
- input_var = every_input.split("=")
- input_var = [item.strip() for item in input_var]
- if len(input_var) == 2:
- if veritfy_var(input_var[0]) == -1:
- return -1
- if len(input_var[0]) == 1:
- right_in_var = input_var[1].split(" ")
- right_in_var = [item.strip() for item in right_in_var]
- for item in right_in_var:
- if (item in legal_symbol) or (item in local_vars) or item.isdigit():
- return 2
- return -1
- def CheckVarValue(output, checkList, outputret, checkret):
- if (output == checkList) and (outputret == checkret):
- print "pass"
- else:
- print "error"
- # 立即数赋值
- def testcase01():
- strCodeLine = """
- a = 90
- print a"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["90"], ret, 0)
- # 赋值语句:立即数加运算
- def testcase02():
- strCodeLine = """
- b = 2 + 7
- print b"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["9"], ret, 0)
- # 赋值语句:立即数减运算
- def testcase03():
- strCodeLine = """
- c = 9 - 1
- print c"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["8"], ret, 0)
- # 赋值语句:立即数乘运算
- def testcase04():
- strCodeLine = """
- d = 9 - 1
- e = 3 * d
- print d
- print e"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["8", "24"], ret, 0)
- # 赋值语句:立即数除运算
- def testcase05():
- strCodeLine = """
- f = 24
- g = f / 4
- print g"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["6"], ret, 0)
- # 赋值语句:变量运算
- def testcase06():
- strCodeLine = """
- h = 2 * 3
- i = h + h
- print h
- print i"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["6", "12"], ret, 0)
-
- # 赋值语句:变量值更新
- def testcase07():
- strCodeLine = """
- j = 2 * 3
- j = j * j
- print j"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["36"], ret, 0)
-
- # 赋值语句:运算符优先级
- def testcase08():
- strCodeLine = """
- a = 10 * 3
- b = 8
- print a
- c = a + b
- print b
- e = a - 5 * b / 2 + 8
- print c
- print e"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["30", "8", "38", "18"], ret, 0)
-
- # 赋值语句:括号的简单使用
- def testcase09():
- strCodeLine = """
- a = 3
- print a
- b = 8
- d = a - ( b - 4 )
- print d"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["3", "-1"], ret, 0)
- # 赋值语句:括号的使用
- def testcase10():
- strCodeLine = """
- a = 3
- print a
- b = 8
- c = a * b
- d = a - ( c - 4 ) * b
- print d"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["3", "-157"], ret, 0)
- # 赋值语句:变量名区分大小写
- def testcase11():
- strCodeLine = """
- a = 100
- A = 200
- print a
- print A
- c = A / a
- print c"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["100", "200", "2"], ret, 0)
- # 异常用例:变量使用之前必须初始化过
- def TestCase_Error_1():
- strCodeLine = """
- a = 1
- c = a + d
- print a"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["1"], ret, -1)
-
- # 异常用例:分隔符为多个空格
- def TestCase_Error_2():
- strCodeLine = """
- q = 1 + 2
- print q"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["3"], ret, 0)
-
- # 异常用例:语句必须完整
- def TestCase_Error_3():
- strCodeLine = """
- a = 1 +"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, [], ret, -1)
- # 异常用例:左值必须为变量
- def TestCase_Error_4():
- strCodeLine = """
- 90 = a
- print a"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, [], ret, -1)
-
- # 异常用例:关键字与变量之间必须有分隔符
- def TestCase_Error_5():
- strCodeLine = """
- a = 0
- printa"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, [], ret, -1)
-
- # 异常用例:运算中除0
- def TestCase_Error_6():
- strCodeLine = """
- a = 0
- b = 2
- c = 3
- c = b / a
- print c
- d = a / b
- print d"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["3", "0"], ret, -1)
-
- # 异常用例:变量名采用关键字
- def TestCase_Error_7():
- strCodeLine = """
- print = 1
- a = 3
- print print"""
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, [], ret, -1)
-
- # 异常用例:复杂程序
- def testcase12():
- strCodeLine = """
- a = 10000
- print a
- b = a * a
- c = c * 10
- print c
- e = 1000
- a = a / e
- print a
- c = a
- d = 1 + 10 + ( b / ( a * 10 ) )
- print d
- """
- output = []
-
- ret = Execute(strCodeLine, output)
-
- CheckVarValue(output, ["10000", "10", "1000011"], ret, -1)
- def main():
- testcase01()
- testcase02()
- testcase03()
- testcase04()
- testcase05()
- testcase06()
- testcase07()
- testcase08()
- testcase09()
- testcase10()
- testcase11()
- TestCase_Error_1()
- TestCase_Error_2()
- TestCase_Error_3()
- TestCase_Error_4()
- TestCase_Error_5()
- TestCase_Error_6()
- TestCase_Error_7()
- testcase12()
-
- if __name__ == '__main__':
- main()
复制代码 |
|