130242014066+王偉華+第2次實驗
阿新 • • 發佈:2017-10-29
標記 自己 height ger 編譯器 elif turn 2-2 pipe
一、實驗目的
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, EOF = ( ‘INTEGER‘, ‘PLUS‘, ‘MINUS‘, ‘MUL‘, ‘DIV‘, ‘EOF‘ ) class Token(object): def __init__(self, type, value): # 標記的類型: INTEGER, PLUS, MINUS, MUL, DIV, or EOF 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 # self.pos是self.text的索引值 self.pos = 0 self.current_char = self.text[self.pos] def error(self): raise Exception(‘Invalid character‘) def advance(self): self.pos += 1 if self.pos > len(self.text) - 1: self.current_char = None # 輸入結束 else: self.current_char = self.text[self.pos] def skip_whitespace(self): while self.current_char is not None and self.current_char.isspace(): self.advance() def integer(self): result = ‘‘ while self.current_char is not None and self.current_char.isdigit(): result += self.current_char self.advance() return int(result)
#判斷輸入的是什麽
def get_next_token(self): while self.current_char is not None: if self.current_char.isspace(): self.skip_whitespace() continue if self.current_char.isdigit(): #如果current_char是數字 return Token(INTEGER, self.integer()) if self.current_char == ‘+‘: #如果current_char是+ self.advance() return Token(PLUS, ‘+‘) if self.current_char == ‘-‘: #如果current_char是- self.advance() return Token(MINUS, ‘-‘) if self.current_char == ‘*‘: #如果current_char是* self.advance() return Token(MUL, ‘*‘) if self.current_char == ‘/‘: #如果current_char是/ self.advance() return Token(DIV, ‘/‘) self.error() #如果都不符合就返回錯誤 return Token(EOF, None) 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: self.current_token = self.lexer.get_next_token() else: self.error() def factor(self): token = self.current_token self.eat(INTEGER) return token.value 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 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 result def main(): while True: try: text = raw_input(‘calc> ‘) except EOFError: break if not text: continue lexer = Lexer(text) interpreter = Interpreter(lexer) result = interpreter.expr() print(result) if __name__ == ‘__main__‘: main()
對應結構圖:
五、實驗總結
對於體系結構應用的理解等。
130242014066+王偉華+第2次實驗