1. 程式人生 > >130242014062-黃淩逸-第2次實驗

130242014062-黃淩逸-第2次實驗

-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次實驗