130242014048-Xie tihua-2nd labs, 130242014048-Xie tihua
I. Tutorial Purpose
1. familiar with the concept of architecture style
2. understand and apply the pipeline filter style.
3. Understand the principle of interpreter
4. Understand the compiler model
Ii. experiment environment
Hardware:
Software: Python or any of your favorite languages
Iii. experiment content
1. A simple translator that implements "Four arithmetic operations.
Result requirements:
1) implements addition, subtraction, multiplication, division, and division of four arithmetic operations. Multiple operands are allowed at the same time. For example, the result of 2 + 3*5-6 is 11.
2) the operand is an integer. An integer can contain multiple digits.
3) process Spaces
4) When an error is entered, an error prompt is displayed and the command status "CALC" is returned"
Figure 1 example of experiment results
Enhanced exercise:
1. competent personnel can try to implement the assignment statement, for example, x = 2 + 3*5-6, returns x = 11. (Note: to implement the interpreter function, rather than just display it)
2. Try to implement auto-increment and auto-subtraction symbols, such as x ++
2. The interpreter is implemented in the Pipes and Filters style.
Figure 2 MPs queue-filter Style
Figure 3 compiler model
This experiment implements lexical analysis and syntax analysis.
Iv. Experiment steps:
Actual implementation code:
INTEGER, PLUS, MINUS, MUL, DIV, LPAREN, RPAREN, EOF = 'integer', 'plus ', 'minus', "MUL", "DIV", "LPAREN ", "RPAREN", 'eof 'variable, EQUALITY = 'variable', 'Equality 'B _ INCREMENT, B _DECREMENT, A_INCREMENT, A_DECREMENT = "B _INCREMENT", "B _DECREMENT", "A_INCREMENT ", "A_DECREMENT" VARIABLE_DICT = {} 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 = repr (self. value) def _ repr _ (self): return self. _ str _ () # lexical analyzer # mark each word as class Lexer (object): def _ init _ (self, text): self. text = text. replace ("", "") self. pos =-1 self. current_char = None def error (self): raise Exception ("") # def advance (self): self. pos + = 1 if self. pos> = len (self. text): self. current_char = None else: self. current_char = self. text [self. pos] # Start def recover (self): self. pos =-1 self. current_char = None # invalid space def deal_space (self) when processing Input: # loop traversal. When a space is encountered, while self. current_char is not None and self. current_char.isspace (): self. advance () # multi-digit integer processing def deal_integer (self): result = ''while self. current_char is not None and self. current_char.isdigit (): result = result + self. current_char # go down and set the value to self. advance () self. pos-= 1 self. current_char = self. text [self. pos] return int (result) # process the variable, used to mark the variable def deal_variable (self): result = ''while self. current_char is not None and self. current_char.isalpha (): result = result + self. current_char # go down and set the value to self. advance () self. pos-= 1 self. current_char = self. text [self. pos] # Add a variable ing if result not in VARIABLE_DICT: VARIABLE_DICT [result] = None return result # process the plus sign, which may be auto-increment and post-auto-increment, it may also be the plus sign def deal_plus_sign (self): if self. current_char is not None and self. current_char = '+': if self. pos <len (self. text)-1 and self. text [self. pos + 1] = '+': # two consecutive plus signs exist, that is, there is auto-increment. You need to determine whether it is pre-auto-increment or post-auto-increment if self. pos> 0 and self. text [self. pos-1]. isalpha (): # auto-increment self. advance () return A_INCREMENT elif self. pos <len (self. text)-2 and self. text [self. pos + 2]. isalpha (): # auto-increment self. advance () return B _INCREMENT else: self. error () else: return PLUS self. error () # when processing the minus mark, it may be First Auto-subtract and then auto-Subtract, or it may be def deal_minus_sign (self): if self. current_char is not None and self. current_char = '-': if self. pos <len (self. text)-1 and self. text [self. pos + 1] = '-': # two consecutive minus signs exist, that is, there is auto-subtraction. You need to determine whether it is auto-subtraction or auto-subtraction if self. pos> 0 and self. text [self. pos-1]. isalpha (): # Minus self. advance () return A_DECREMENT elif self. pos <len (self. text)-2 and self. text [self. pos + 2]. isalpha (): # Minus self. advance () return B _DECREMENT else: self. error () else: return MINUS self. error () # mark 1, pos + 1 2, return Token (type, value) def get_next_token (self): self. advance () if self. current_char is None: return Token (EOF, None) if self. current_char.isspace (): self. deal_space () if self. current_char.isdigit (): return Token (INTEGER, self. deal_integer () if self. current_char.isalpha (): return Token (VARIABLE, self. deal_variable () if self. current_char = "=": return Token (Token ity, "=") if self. current_char = "+": # process the plus sign, which may be First Auto-increment and then auto-increment, or the plus sign sign_type = self. deal_plus_sign () if sign_type = PLUS: return Token (PLUS, self. current_char) else: return Token (sign_type, "++") if self. current_char = "-": # process the minus mark, which may be First Auto-minus and then auto-minus, or minus sign_type = self. deal_minus_sign () if sign_type = MINUS: return Token (MINUS, self. current_char) else: return Token (sign_type, "--") if self. current_char = "*": return Token (MUL, self. current_char) if self. current_char = "/": return Token (DIV, self. current_char) if self. current_char = "(": return Token (LPAREN, self. current_char) if self. current_char = ")": return Token (RPAREN, self. current_char) self. error () # syntax analysis syntax number 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: # print (self. current_token.type) self. current_token = self. lexer. get_next_token () else: self. error () def printToken (self): while self. current_token.type is not EOF: print (self. current_token.type) self. eat (self. current_token.type) # Start def recover (self): self. lexer. recover () self. current_token = self. lexer. get_next_token () def factor (self): token = self. current_token result = token. value if token. type = INTEGER: # Only numbers self. eat (INTEGER) result = token. value elif token. type = LPAREN: # (expr) self. eat (LPAREN) result = self. expr () self. eat (RPAREN) elif token. type = VARIABLE: # VARIABLE processing 1. only variable 2. post-auto-increment 3. result = VARIABLE_DICT [token. value] # print (token. value) # print (VARIABLE_DICT) self. eat (VARIABLE) if self. current_token.type = A_INCREMENT: #2. there is a post-incrementing VARIABLE_DICT [token. value] = result + 1 self. eat (A_INCREMENT) elif self. current_token.type = A_DECREMENT: #3. there is a post-subtraction VARIABLE_DICT [token. value] = result-1 self. eat (A_DECREMENT) elif token. type = B _INCREMENT: # auto-increment self. eat (B _INCREMENT) if self. current_token.type = VARIABLE: VARIABLE_DICT [self. current_token.value] = VARIABLE_DICT [self. current_token.value] + 1 result = VARIABLE_DICT [self. current_token.value] self. eat (VARIABLE) else: self. error () elif token. type = B _DECREMENT: # Minus self. eat (B _DECREMENT) if self. current_token.type = VARIABLE: VARIABLE_DICT [self. current_token.value] = VARIABLE_DICT [self. current_token.value]-1 result = VARIABLE_DICT [self. current_token.value] self. eat (VARIABLE) else: self. error () else: self. error () # print (result) return int (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 () elif token. type = DIV: self. eat (DIV) result = result/self. factor () return int (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 int (result) def start (self): token = self. current_token if token. type = VARIABLE: self. eat (VARIABLE) if self. current_token.type = EQUALITY: # processing example: x = x + 1 self. eat (integrity) result = self. expr () VARIABLE_DICT [token. value] = result # print (token. value) # print (VARIABLE_DICT [token. value]) return {'var _ name': token. value, 'result': result} # processing example: x + 1 self. recover () result = self. expr () return {'var _ name': None, 'result': result} def main (): while True: try: text = input ("calc> ") failed t EOFError: break if not text: continue # Interpreter (Lexer (text )). printToken () lexer = Lexer (text) try: data = Interpreter (lexer ). start () # print (data) if data ["var_name"] = None: print (data ['result']) else: print ('{0} = {1 }'. format (data ['var _ name'], data ['result']) failed t Exception: print ("the input expression is incorrect ") continueif _ name _ = '_ main _': main ()
Corresponding structure: (start value assignment Operation)
Lab:
V. Experiment Summary
The architecture is to simplify complicated things and have a deeper understanding of this. The architecture includes a set of components and links between components. Taking this experiment as an example, although it is just a simple calculator, it is enough to interpret the sentence "complicated things are simplified. The parser includes addition, subtraction, multiplication, division, auto-increment, auto-subtraction, and variable-containing operations. This expression is a complex operation, but as long as it is split and split into simple tasks, the priority is as follows, this operation can be split into addition and subtraction of multiple units, that is, the term unit. Then, the term unit is split into the multiplication and division of multiple smaller units, that is, the factor unit; the factor unit can be an integer, variable auto-increment, variable auto-subtraction, and variable. Of course, it can also be an expression surrounded by parentheses. In this way, complicated things can be simplified.