标签:exp 分析器 exception 体系 error ini obj 复制 current
一、实验目的
1.熟悉体系结构的风格的概念
2.理解和应用管道过滤器型的风格。
3、理解解释器的原理
4、理解编译器模型
二、实验环境
硬件:
软件:Python或任何一种自己喜欢的语言
三、实验内容
1、实现“四则运算”的简易翻译器。
结果要求:
1)实现加减乘除四则运算,允许同时又多个操作数,如:2+3*5-6 结果是11
2)被操作数为整数,整数可以有多位
3)处理空格
4)输入错误显示错误提示,并返回命令状态“CALC”

图1 实验结果示例
加强练习:
1、有能力的同学,可以尝试实现赋值语句,例如x=2+3*5-6,返回x=11。(注意:要实现解释器的功能,而不是只是显示)
2、尝试实现自增和自减符号,例如x++
2、采用管道-过滤器(Pipes and Filters)风格实现解释器

图2 管道-过滤器风格

图 3 编译器模型示意图
本实验,实现的是词法分析和语法分析两个部分。
四、实验步骤:
要求写具体实现代码,并根据实际程序,画出程序的总体体系结构图和算法结构图。
总体结构图参照体系结构风格。
算法结构图参照如下:
源代码:
1 INTEGER, PLUS, MINUS, MUL, DIV, LPAREN, RPAREN, EOF = (
2 ‘INTEGER‘, ‘PLUS‘, ‘MINUS‘, ‘MUL‘, ‘DIV‘, ‘LPAREN‘, ‘RPAREN‘, ‘EOF‘)
3
4
5 class Token(object):
6 def __init__(self, type, value):
7 self.type = type
8 self.value = value
9
10 def __str__(self):
11 return ‘Token({type},{value})‘.format(
12 type=self.type,
13 value=self.value
14 )
15
16
17 class Lexer(object):
18 # 词法分析器
19 # 给每个词打标记
20 def __init__(self, text):
21 self.text = text
22 self.pos = 0
23 self.current_char = self.text[self.pos]
24
25 def error(self):
26 raise Exception(‘Invalid Char‘)
27
28 def advance(self):
29 # 往下走,取值
30 self.pos += 1
31 if self.pos > len(self.text) - 1:
32 self.current_char = None
33 else:
34 self.current_char = self.text[self.pos]
35
36 def integer(self):
37 # 多位整数处理
38 result = ‘‘
39 while self.current_char is not None and self.current_char.isdigit():
40 result = result + self.current_char
41 # 往下走,取值
42 self.advance()
43 return int(result)
44
45 def deal_space(self):
46 while self.current_char is not None and self.current_char.isspace():
47 self.advance()
48
49 def get_next_token(self):
50 # 打标记:1)pos+1,2)返回Token(类型,数值)
51 while self.current_char is not None:
52 if self.current_char.isspace():
53 self.deal_space()
54
55 if self.current_char.isdigit():
56 return Token(INTEGER, self.integer())
57 if self.current_char == ‘+‘:
58 self.advance()
59 return Token(PLUS, ‘+‘)
60 if self.current_char == ‘-‘:
61 self.advance()
62 return Token(MINUS, ‘-‘)
63 if self.current_char == ‘*‘:
64 self.advance()
65 return Token(MUL, ‘*‘)
66 if self.current_char == ‘/‘:
67 self.advance()
68 return Token(DIV, ‘/‘)
69 if self.current_char == ‘(‘:
70 self.advance()
71 return Token(LPAREN, ‘(‘)
72 if self.current_char == ‘)‘:
73 self.advance()
74 return Token(RPAREN, ‘)‘)
75 self.error()
76 return Token(EOF, None)
77
78
79 class Interpreter(object):
80 # 句法分析
81 # 语法树
82 def __init__(self, lexer):
83 self.lexer = lexer
84 self.current_token = self.lexer.get_next_token()
85
86 def error(self):
87 raise Exception(‘Invalid Syntax‘)
88
89 def eat(self, token_type):
90 if self.current_token.type == token_type:
91 self.current_token = self.lexer.get_next_token()
92 else:
93 self.error()
94
95 def factor(self):
96 token = self.current_token
97 if token.type == INTEGER:
98 self.eat(INTEGER)
99 return token.value
100 elif token.type == LPAREN:
101 self.eat(LPAREN)
102 result = self.expr()
103 self.eat(RPAREN)
104 return result
105
106 def term(self):
107 result = self.factor()
108 while self.current_token.type in (MUL, DIV):
109 token = self.current_token
110 if token.type == MUL:
111 self.eat(MUL)
112 result = result * self.factor()
113 if token.type == DIV:
114 self.eat(DIV)
115 result = result / self.factor()
116 return result
117
118 def expr(self):
119 try:
120 result = self.term()
121 while self.current_token.type in (PLUS, MINUS):
122 token = self.current_token
123 if token.type == PLUS:
124 self.eat(PLUS)
125 result = result + self.term()
126 if token.type == MINUS:
127 self.eat(MINUS)
128 result = result - self.term()
129 return result
130 except Exception as e:
131 print("输入错误,请重新输入")
132
133
134 def main():
135 while True:
136 try:
137 text = input(‘calc_> ‘)
138 except EOFError:
139 Interpreter.error()
140 break
141 if not text:
142 continue
143 lexer = Lexer(text)
144 result = Interpreter(lexer).expr()
145 if (result is not None):
146 print(result)
147
148
149 if __name__ == ‘__main__‘:
150 main()
运算截图:

对应结果图:

标签:exp 分析器 exception 体系 error ini obj 复制 current
原文地址:http://www.cnblogs.com/hly960308/p/7748643.html