boom
This commit is contained in:
commit
1ac693fdc2
9 changed files with 670 additions and 0 deletions
174
parser_.py
Normal file
174
parser_.py
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
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}")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue