1. 程式人生 > >130242014067+李清燦+第2次實驗

130242014067+李清燦+第2次實驗

示例 錯誤提示 format python 設置 align 如果 exce ++

軟件體系結構的第二次實驗(解釋器風格與管道過濾器風格)

一、實驗目的

  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++

    3、采用管道-過濾器(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()

130242014067+李清燦+第2次實驗