174 lines
4.1 KiB
Python
174 lines
4.1 KiB
Python
from ParserError import ParserError
|
|
from tokens import TokenType
|
|
from nodes import *
|
|
|
|
class Parser:
|
|
|
|
def __init__(self, tokens):
|
|
self.tokens = iter(tokens)
|
|
self.advance()
|
|
|
|
def raise_error(self):
|
|
raise ParserError("Invalid syntax")
|
|
|
|
def advance(self):
|
|
try:
|
|
self.current_token = next(self.tokens)
|
|
except StopIteration:
|
|
self.current_token = None
|
|
|
|
|
|
def parse(self):
|
|
if self.current_token == None:
|
|
return None
|
|
|
|
result = self.level1_operators()
|
|
|
|
if self.current_token != None:
|
|
self.raise_error()
|
|
|
|
return result
|
|
|
|
# Takes care of (+ -)
|
|
def level1_operators(self):
|
|
result = self.level2_operators()
|
|
|
|
while self.current_token != None and self.current_token.type in (TokenType.PLUS, TokenType.MINUS):
|
|
if self.current_token.type == TokenType.PLUS:
|
|
self.advance()
|
|
result = AddNode(result, self.level2_operators())
|
|
elif self.current_token.type == TokenType.MINUS:
|
|
self.advance()
|
|
result = SubtractNode(result, self.level2_operators())
|
|
|
|
return result
|
|
|
|
|
|
def level2_operators(self):
|
|
result = self.level3_operators()
|
|
|
|
while self.current_token != None and self.current_token.type in (TokenType.MULTIPLY, TokenType.DIVIDE):
|
|
if self.current_token.type == TokenType.MULTIPLY:
|
|
self.advance()
|
|
result = MultiplyNode(result, self.level3_operators())
|
|
elif self.current_token.type == TokenType.DIVIDE:
|
|
self.advance()
|
|
result = DivideNode(result, self.level3_operators())
|
|
|
|
return result
|
|
|
|
|
|
def level3_operators(self):
|
|
result = self.level4_operators()
|
|
|
|
while self.current_token != None and self.current_token.type == TokenType.POWER:
|
|
self.advance()
|
|
result = PowerNode(result, self.level4_operators())
|
|
|
|
return result
|
|
|
|
def level4_operators(self):
|
|
result = self.level5_operators()
|
|
|
|
while self.current_token != None and self.current_token.type in (TokenType.MODULE, TokenType.FACTORIAL):
|
|
if self.current_token.type == TokenType.MODULE:
|
|
self.advance()
|
|
result = ModuleNode(result, self.level5_operators())
|
|
elif self.current_token.type == TokenType.FACTORIAL:
|
|
self.advance()
|
|
result = FactorialNode(self.level5_operators(result))
|
|
|
|
return result
|
|
|
|
|
|
def level5_operators(self, num=None):
|
|
|
|
if num != None:
|
|
result = num
|
|
else:
|
|
result = self.level6_operators()
|
|
|
|
|
|
while self.current_token != None and self.current_token.type in (TokenType.AVERAGE, TokenType.MAXIMUM, TokenType.MINIMUM):
|
|
if self.current_token.type == TokenType.AVERAGE:
|
|
self.advance()
|
|
result = AverageNode(result, self.level6_operators())
|
|
elif self.current_token.type == TokenType.MAXIMUM:
|
|
self.advance()
|
|
result = MaximumNode(result, self.level6_operators())
|
|
elif self.current_token.type == TokenType.MINIMUM:
|
|
self.advance()
|
|
result = MinimumNode(result, self.level6_operators())
|
|
|
|
return result
|
|
|
|
|
|
def level6_operators(self):
|
|
token = self.current_token
|
|
|
|
|
|
|
|
if token.type == TokenType.LBRACKET:
|
|
self.advance()
|
|
result = self.level1_operators()
|
|
|
|
if self.current_token.type != TokenType.RBRACKET:
|
|
self.raise_error()
|
|
|
|
self.advance()
|
|
return result
|
|
|
|
elif token.type == TokenType.NUMBER:
|
|
self.advance()
|
|
return NumberNode(token.value)
|
|
|
|
elif token.type == TokenType.PLUS:
|
|
self.advance()
|
|
return PlusNode(self.level6_operators())
|
|
|
|
elif token.type == TokenType.MINUS:
|
|
self.advance()
|
|
return MinusNode(self.level6_operators())
|
|
|
|
elif token.type == TokenType.NEGATE:
|
|
self.advance()
|
|
return NegateNode(self.level6_operators())
|
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
def strip_str(level1_operators : str):
|
|
"""removes all unnecessery characters from level1_operatorsession
|
|
|
|
Args:s
|
|
level1_operators (str): the level1_operatorsession that will be stripped
|
|
|
|
Raises:
|
|
ParserError: Error if parsing failed
|
|
|
|
Returns:
|
|
str: The level1_operatorsession without the unnecessery characters
|
|
"""
|
|
try:
|
|
temp_list = level1_operators.split()
|
|
level1_operators = ''.join(temp_list)
|
|
level1_operators = level1_operators.replace('\\n', '')
|
|
level1_operators = level1_operators.replace('\\t', '')
|
|
return level1_operators
|
|
|
|
|
|
except Exception as e:
|
|
raise ParserError("Error during parsing: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|