#!/usr/bin/python #coding:utf-8 INTEGER = ‘INTEGER‘ PLUS = ‘+‘ MINUS = ‘-‘ MUL = ‘*‘ DIV = ‘/‘ LC = ‘(‘ RC = ‘)‘ EOF = ‘EOF‘ class Token(object): def __init__(self, type, value): self.type = type; self.value = value; def __str__(self): return "Toke({type}, {value})".format(type=self.type, value=self.value); def __repr__(self): return self.__str__(); class Lexer(object): def __init__(self, text): self.text = text self.pos = 0 self.cur_token = None self.cur_char = self.text[self.pos] self.status = 0 def next_token(self): if (self.pos > len(self.text)-1): return Token(EOF, "") while True: self.cur_char = self.text[self.pos] self.pos += 1 if (self.cur_char != ‘ ‘ and self.cur_char != ‘\t‘): break; if self.status == 0: if self.cur_char.isdigit(): self.status = 1 return Token(INTEGER, int(self.cur_char + self.next_token().value)) elif self.cur_char == ‘+‘: return Token(PLUS,self.cur_char) elif self.cur_char == ‘-‘: return Token(MINUS,self.cur_char) elif self.cur_char == ‘*‘: return Token(MUL,self.cur_char) elif self.cur_char == ‘/‘: return Token(DIV,self.cur_char) elif self.cur_char == ‘(‘: return Token(LC, self.cur_char) elif self.cur_char == ‘)‘: return Token(RC, self.cur_char) else: raise Exception("error") elif self.status == 1: if self.cur_char.isdigit(): self.status = 1 return Token(INTEGER, self.cur_char + self.next_token().value) else: self.pos -= 1 self.status = 0 return Token(INTEGER, "") else: raise Exception("error") class Interpreter(object): def __init__(self, lexer): self.lexer = lexer self.cur_token = self.lexer.next_token() def error(self): raise Exception("Invalidd syntax") def eat(self, tp): if (self.cur_token.type == tp): self.cur_token = self.lexer.next_token() else: self.error() def factor(self): token = self.cur_token if token.type==INTEGER: self.eat(INTEGER) return token.value elif token.type==LC: self.eat(LC) result=self.expr() self.eat(RC) return result def term(self): result = self.factor(); while self.cur_token.type in (MUL, DIV): token = self.cur_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.cur_token.type in (PLUS, MINUS): token = self.cur_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: text = raw_input("calc> ") if not text: continue; if text=="exit": break; lexer = Lexer(text) result = Interpreter(lexer).expr() print(result) if __name__ == ‘__main__‘: main()
原文:http://www.cnblogs.com/zhj11226/p/6286843.html