119 lines
2.5 KiB
Python
119 lines
2.5 KiB
Python
NUMBER_TOKEN = 0
|
|
PLUS_TOKEN = 1
|
|
MINUS_TOKEN = 2
|
|
TIMES_TOKEN = 3
|
|
DIVIDE_TOKEN = 4
|
|
LEFT_BRACKET_TOKEN = 5
|
|
RIGHT_BRACKET_TOKEN = 6
|
|
WHITESPACE_TOKEN = 7
|
|
EOF_TOKEN = 8
|
|
|
|
program = input("Please enter an expression to evaluate: ")
|
|
tokens = []
|
|
|
|
i = 0
|
|
while i < len(program):
|
|
if program[i].isdigit():
|
|
tmp_number = 0
|
|
while i < len(program) and program[i].isdigit() :
|
|
tmp_number *= 10
|
|
tmp_number += ord(program[i]) % 48
|
|
i += 1
|
|
tokens.append([NUMBER_TOKEN, tmp_number])
|
|
i -= 1
|
|
elif program[i] == "+":
|
|
tokens.append([PLUS_TOKEN])
|
|
elif program[i] == "-":
|
|
tokens.append([MINUS_TOKEN])
|
|
elif program[i] == "*":
|
|
tokens.append([TIMES_TOKEN])
|
|
elif program[i] == "/":
|
|
tokens.append([DIVIDE_TOKEN])
|
|
elif program[i] == "(":
|
|
tokens.append([LEFT_BRACKET_TOKEN])
|
|
elif program[i] == ")":
|
|
tokens.append([RIGHT_BRACKET_TOKEN])
|
|
elif program[i] == " ":
|
|
tokens.append([WHITESPACE_TOKEN])
|
|
else:
|
|
print("Invalid charatcer: " + i)
|
|
i += 1
|
|
tokens.append([EOF_TOKEN])
|
|
|
|
ast = []
|
|
NUMBER_AST = 0
|
|
PLUS_AST = 1
|
|
MINUS_AST = 2
|
|
TIMES_AST = 3
|
|
DIVIDE_AST = 4
|
|
NEGATE_AST = 5
|
|
|
|
index = 0
|
|
|
|
def current ():
|
|
return (tokens[index])[0]
|
|
|
|
def eat(token):
|
|
global index
|
|
if current() == token:
|
|
index += 1
|
|
else:
|
|
print("Invalid token")
|
|
|
|
def eat_whitespace():
|
|
while current() == WHITESPACE_TOKEN:
|
|
eat (WHITESPACE_TOKEN)
|
|
|
|
def factor():
|
|
node = []
|
|
eat_whitespace()
|
|
if current() == NUMBER_TOKEN:
|
|
node = [NUMBER_AST, tokens[index][1]]
|
|
eat (NUMBER_TOKEN)
|
|
elif current() == LEFT_BRACKET_TOKEN:
|
|
eat (LEFT_BRACKET_TOKEN)
|
|
node = expr()
|
|
eat (RIGHT_BRACKET_TOKEN)
|
|
else:
|
|
eat (MINUS_TOKEN)
|
|
node = [NEGATE_AST, factor()]
|
|
eat_whitespace()
|
|
return node
|
|
def term():
|
|
node = factor()
|
|
while current() in [TIMES_TOKEN, DIVIDE_TOKEN]:
|
|
if current () == TIMES_TOKEN:
|
|
eat (TIMES_TOKEN)
|
|
node = [TIMES_AST, node, factor()]
|
|
else:
|
|
eat (DIVIDE_TOKEN)
|
|
node = [DIVIDE_AST, node, factor()]
|
|
return node
|
|
def expr():
|
|
node = term()
|
|
while current() in [PLUS_TOKEN, MINUS_TOKEN]:
|
|
if current() == PLUS_TOKEN:
|
|
eat (PLUS_TOKEN)
|
|
node = [PLUS_AST, node, term()]
|
|
else:
|
|
eat (MINUS_TOKEN)
|
|
node = [MINUS_AST, node, term()]
|
|
return node
|
|
|
|
def interpret (ast):
|
|
if ast[0] == NUMBER_AST:
|
|
return ast[1]
|
|
elif ast[0] == PLUS_AST:
|
|
return interpret(ast[1]) + interpret(ast[2])
|
|
elif ast[0] == MINUS_AST:
|
|
return interpret(ast[1]) - interpret(ast[2])
|
|
elif ast[0] == TIMES_AST:
|
|
return interpret(ast[1]) * interpret(ast[2])
|
|
elif ast[0] == DIVIDE_AST:
|
|
return interpret(ast[1]) / interpret(ast[2])
|
|
elif ast[0] == NEGATE_AST:
|
|
return -interpret(ast[1])
|
|
|
|
ast = expr()
|
|
print("Your answer: " + str(interpret(ast)))
|