1. 程式人生 > >130242014041-曾子雲-實驗二

130242014041-曾子雲-實驗二

filters str ise and pipes 重新 type pre ger

一、實驗目的

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‘)

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=self.value

)

class Lexer(object):

# 詞法分析器

# 給每個詞打標記

def __init__(self, text):

self.text = text

self.pos = 0

self.current_char = self.text[self.pos]

def error(self):

raise Exception(‘Invalid Char‘)

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 integer(self):

# 多位整數處理

result = ‘‘

while self.current_char is not None and self.current_char.isdigit():

result = result + self.current_char

# 往下走,取值

self.advance()

return int(result)

def deal_space(self):

while self.current_char is not None and self.current_char.isspace():

self.advance()

def get_next_token(self):

# 打標記:1)pos+1,2)返回Token(類型,數值)

while self.current_char is not None:

if self.current_char.isspace():

self.deal_space()

if self.current_char.isdigit():

return Token(INTEGER, self.integer())

if self.current_char == ‘+‘:

self.advance()

return Token(PLUS, ‘+‘)

if self.current_char == ‘-‘:

self.advance()

return Token(MINUS, ‘-‘)

if self.current_char == ‘*‘:

self.advance()

return Token(MUL, ‘*‘)

if self.current_char == ‘/‘:

self.advance()

return Token(DIV, ‘/‘)

if self.current_char == ‘(‘:

self.advance()

return Token(LPAREN, ‘(‘)

if self.current_char == ‘)‘:

self.advance()

return Token(RPAREN, ‘)‘)

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

if token.type == INTEGER:

self.eat(INTEGER)

return token.value

elif token.type == LPAREN:

self.eat(LPAREN)

result = self.expr()

self.eat(RPAREN)

return 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()

if token.type == DIV:

self.eat(DIV)

result = result / self.factor()

return result

def expr(self):

try:

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()

if token.type == MINUS:

self.eat(MINUS)

result = result - self.term()

return result

except Exception as e:

print("輸入錯誤,請重新輸入")

def main():

while True:

try:

text = input(‘calc_> ‘)

except EOFError:

Interpreter.error()

break

if not text:

continue

lexer = Lexer(text)

result = Interpreter(lexer).expr()

if (result is not None):

print(result)

if __name__ == ‘__main__‘:

main()

運算截圖:

技術分享

130242014041-曾子雲-實驗二