94 lines
2.2 KiB
Python
94 lines
2.2 KiB
Python
import ptoken as token
|
|
import tokenizer
|
|
import uuid
|
|
from collections import deque
|
|
|
|
class Op:
|
|
def __init__(self, left, op, right):
|
|
self.left = left
|
|
self.op = op
|
|
self.right = right
|
|
|
|
def __str__(self):
|
|
return "%s (%s) and (%s)" %(token.TokenType.get_operator_verb(self.op), self.left, self.right)
|
|
|
|
class Num:
|
|
def __init__(self, token):
|
|
self.value = token.value
|
|
|
|
def __str__(self):
|
|
return self.value
|
|
|
|
class Variable:
|
|
def __init__(self, token):
|
|
self.symbol = token.value
|
|
self.value = None
|
|
|
|
def __str__(self):
|
|
if self.value == None:
|
|
return self.symbol
|
|
else:
|
|
return str(self.value)
|
|
|
|
class Parser:
|
|
def __init__(self, tokens):
|
|
if len(tokens) == 0:
|
|
raise ValueError("Token list can't be empty")
|
|
self.tokens = tokens
|
|
self.current_token = None
|
|
self.advance_current_token()
|
|
self.ast = self.generate_ast()
|
|
|
|
def advance_current_token(self):
|
|
|
|
if len(self.tokens) > 0:
|
|
self.current_token = self.tokens.popleft()
|
|
|
|
def factor(self):
|
|
if self.current_token.type == token.TokenType.constant:
|
|
node = Num(self.current_token)
|
|
self.advance_current_token()
|
|
return node
|
|
elif self.current_token.type == token.TokenType.variable:
|
|
node = Variable(self.current_token)
|
|
self.advance_current_token()
|
|
return node
|
|
elif self.current_token.type == token.TokenType.exp_start:
|
|
self.advance_current_token() # (
|
|
node = self.topLevel()
|
|
self.advance_current_token() # )
|
|
return node
|
|
|
|
def lowLevel(self):
|
|
node = self.factor()
|
|
|
|
while self.current_token.type == token.TokenType.power:
|
|
tmp = self.current_token
|
|
self.advance_current_token()
|
|
node = Op(left=node, op=tmp.type, right=self.factor())
|
|
|
|
return node
|
|
|
|
def midLevel(self):
|
|
node = self.lowLevel()
|
|
|
|
while self.current_token.type in (token.TokenType.multiply, token.TokenType.divide):
|
|
tmp = self.current_token
|
|
self.advance_current_token()
|
|
node = Op(left=node, op=tmp.type, right=self.lowLevel())
|
|
|
|
return node
|
|
|
|
def topLevel(self):
|
|
node = self.midLevel()
|
|
|
|
while self.current_token.type in (token.TokenType.add, token.TokenType.subtract):
|
|
tmp = self.current_token
|
|
self.advance_current_token()
|
|
node = Op(left=node, op=tmp.type, right=self.midLevel())
|
|
|
|
return node
|
|
|
|
def generate_ast(self):
|
|
return self.topLevel()
|