#!/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