130242014062-黃淩逸-第2次實驗
阿新 • • 發佈:2017-10-29
-1 理解 dea expr cto 過濾器 __init__ str else
一、實驗目的
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()
運算截圖:
對應結果圖:
130242014062-黃淩逸-第2次實驗