标签:分析 连续 col incr ima object 整数 计算器 lte
一、实验目的
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 编译器模型示意图
本实验,实现的是词法分析和语法分析两个部分。
四、实验步骤:
实际实现代码:
INTEGER, PLUS, MINUS, MUL, DIV, LPAREN, RPAREN, EOF = ‘INTEGER‘, ‘PLUS‘, ‘MINUS‘, "MUL", "DIV", "LPAREN", "RPAREN", ‘EOF‘ VARIABLE, EQUALITY = ‘VARIABLE‘, ‘EQUALITY‘ B_INCREMENT, B_DECREMENT, A_INCREMENT, A_DECREMENT = "B_INCREMENT", "B_DECREMENT", "A_INCREMENT", "A_DECREMENT" VARIABLE_DICT = {} class Token(object): def __init__(self, type, value): self.type = type self.value = value def __str__(self): return ‘Token({type}, {value})‘.format( type=self.type, value=repr(self.value) ) def __repr__(self): return self.__str__() # 词法分析器 # 给每个词打标记 class Lexer(object): def __init__(self, text): self.text = text.replace(" ", "") self.pos = -1 self.current_char = None def error(self): raise Exception("") # 前进一步 def advance(self): self.pos += 1 if self.pos >= len(self.text): self.current_char = None else: self.current_char = self.text[self.pos] # 重头开始 def recover(self): self.pos = -1 self.current_char = None # 处理输入时的非法空格 def deal_space(self): # 循环遍历,遇到空格则 while self.current_char is not None and self.current_char.isspace(): self.advance() # 多位整数的处理 def deal_integer(self): result = ‘‘ while self.current_char is not None and self.current_char.isdigit(): result = result + self.current_char # 往下走,取值 self.advance() self.pos -= 1 self.current_char = self.text[self.pos] return int(result) # 处理变量,用于打变量的标记 def deal_variable(self): result = ‘‘ while self.current_char is not None and self.current_char.isalpha(): result = result + self.current_char # 往下走,取值 self.advance() self.pos -= 1 self.current_char = self.text[self.pos] # 添加变量映射 if result not in VARIABLE_DICT: VARIABLE_DICT[result] = None return result # 处理加号标记的, 有可能是先自增和后自增,也有可能是加号 def deal_plus_sign(self): if self.current_char is not None and self.current_char == ‘+‘: if self.pos < len(self.text) - 1 and self.text[self.pos + 1] == ‘+‘: # 存在连续的两个加号,即存在自增,需判断是前自增还是后自增 if self.pos > 0 and self.text[self.pos - 1].isalpha(): # 后自增 self.advance() return A_INCREMENT elif self.pos < len(self.text) - 2 and self.text[self.pos + 2].isalpha(): # 前自增 self.advance() return B_INCREMENT else: self.error() else: return PLUS self.error() # 处理减号标记的, 有可能是先自减和后自减,也有可能是减号 def deal_minus_sign(self): if self.current_char is not None and self.current_char == ‘-‘: if self.pos < len(self.text) - 1 and self.text[self.pos + 1] == ‘-‘: # 存在连续的两个减号,即存在自减,需判断是前自减还是后自减 if self.pos > 0 and self.text[self.pos - 1].isalpha(): # 后自减 self.advance() return A_DECREMENT elif self.pos < len(self.text) - 2 and self.text[self.pos + 2].isalpha(): # 前自减 self.advance() return B_DECREMENT else: self.error() else: return MINUS self.error() # 打标记 1、pos+1 2、返回 Token(类型,数值) def get_next_token(self): self.advance() if self.current_char is None: return Token(EOF, None) if self.current_char.isspace(): self.deal_space() if self.current_char.isdigit(): return Token(INTEGER, self.deal_integer()) if self.current_char.isalpha(): return Token(VARIABLE, self.deal_variable()) if self.current_char == "=": return Token(EQUALITY, "=") if self.current_char == "+": # 处理加号标记的, 有可能是先自增和后自增,也有可能是加号 sign_type = self.deal_plus_sign() if sign_type == PLUS: return Token(PLUS, self.current_char) else: return Token(sign_type, "++") if self.current_char == "-": # 处理减号标记的, 有可能是先自减和后自减,也有可能是减号 sign_type = self.deal_minus_sign() if sign_type == MINUS: return Token(MINUS, self.current_char) else: return Token(sign_type, "--") if self.current_char == "*": return Token(MUL, self.current_char) if self.current_char == "/": return Token(DIV, self.current_char) if self.current_char == "(": return Token(LPAREN, self.current_char) if self.current_char == ")": return Token(RPAREN, self.current_char) self.error() # 句法分析 创建语法数 class Interpreter(object): def __init__(self, lexer): self.lexer = lexer self.current_token = self.lexer.get_next_token() def error(self): raise Exception(‘Invalid Syntax‘) def eat(self, token_type): if self.current_token.type == token_type: # print(self.current_token.type) self.current_token = self.lexer.get_next_token() else: self.error() def printToken(self): while self.current_token.type is not EOF: print(self.current_token.type) self.eat(self.current_token.type) # 重头开始 def recover(self): self.lexer.recover() self.current_token = self.lexer.get_next_token() def factor(self): token = self.current_token result = token.value if token.type == INTEGER: # 只有数字 self.eat(INTEGER) result = token.value elif token.type == LPAREN: # ( expr ) self.eat(LPAREN) result = self.expr() self.eat(RPAREN) elif token.type == VARIABLE: # 变量处理 1.只有变量 2.有后自增 3.有后自减 result = VARIABLE_DICT[token.value] # print(token.value) # print(VARIABLE_DICT) self.eat(VARIABLE) if self.current_token.type == A_INCREMENT: # 2.有后自增 VARIABLE_DICT[token.value] = result + 1 self.eat(A_INCREMENT) elif self.current_token.type == A_DECREMENT: # 3.有后自减 VARIABLE_DICT[token.value] = result - 1 self.eat(A_DECREMENT) elif token.type == B_INCREMENT: # 前自增 self.eat(B_INCREMENT) if self.current_token.type == VARIABLE: VARIABLE_DICT[self.current_token.value] = VARIABLE_DICT[self.current_token.value] + 1 result = VARIABLE_DICT[self.current_token.value] self.eat(VARIABLE) else: self.error() elif token.type == B_DECREMENT: # 前自减 self.eat(B_DECREMENT) if self.current_token.type == VARIABLE: VARIABLE_DICT[self.current_token.value] = VARIABLE_DICT[self.current_token.value] - 1 result = VARIABLE_DICT[self.current_token.value] self.eat(VARIABLE) else: self.error() else: self.error() # print(result) return int(result) def term(self): result = self.factor() while self.current_token.type in (MUL, DIV): token = self.current_token if token.type == MUL: self.eat(MUL) result = result * self.factor() elif token.type == DIV: self.eat(DIV) result = result / self.factor() return int(result) def expr(self): result = self.term() while self.current_token.type in (PLUS, MINUS): token = self.current_token if token.type == PLUS: self.eat(PLUS) result = result + self.term() elif token.type == MINUS: self.eat(MINUS) result = result - self.term() return int(result) def start(self): token = self.current_token if token.type == VARIABLE: self.eat(VARIABLE) if self.current_token.type == EQUALITY: # 处理如: x=x+1 self.eat(EQUALITY) result = self.expr() VARIABLE_DICT[token.value] = result # print(token.value) # print(VARIABLE_DICT[token.value]) return {‘var_name‘:token.value,‘result‘:result} # 处理如: x+1 self.recover() result = self.expr() return {‘var_name‘:None,‘result‘:result} def main(): while True: try: text = input("calc> ") except EOFError: break if not text: continue # Interpreter(Lexer(text)).printToken() lexer = Lexer(text) try: data = Interpreter(lexer).start() # print(data) if data["var_name"] == None: print(data[‘result‘]) else: print(‘{0}={1}‘.format(data[‘var_name‘], data[‘result‘])) except Exception: print("输入的表达式有误") continue if __name__ == ‘__main__‘: main()
对应结构图: (start处理赋值操作)
实验截图:
五、实验总结
体系架构就是将复杂事情简单化,对此有了更深刻的理解。体系结构包括一组部件以及部件之间的联系。就拿此次实验来说,虽然只是做一个简单的计算器,但也足以诠释“复杂事情简单化”这一句了。运算器包括加减乘除、自增、自减,以及含有变量的运算,这个表达式本身是一个复杂的运算,但只要拆分开,拆分成简单的事情,就优先级来说,可以把该运算拆分多个单元的相加减,即term单元;然后再term单元拆分多个更小单元的乘除,即factor单元;而factor单元则可以是一个整数、变量自增、变量自减、变量,当然也可以是一个括号包围的表达式,如此一来,即可将复杂事情简单化。
标签:分析 连续 col incr ima object 整数 计算器 lte
原文地址:http://www.cnblogs.com/Xth8013/p/7748501.html