I'm trying to parse a text with the Shunting-yard algorithm but I've come across a problem. I don't know where to start parsing functions.
This is my goal: print('Hello ' + in())
The current tokens:
[ID print, LPAREN, STRING "Hello ", PLUS, ID in, LPAREN, RPAREN, RPAREN]
My current parser:
class Parser:
def __init__(self, tokens:list, variables:dict):
self.tokens = tokens
self.idx = -1
self.tok = None
self.variables = variables
self.value_stack = []
self.operator_stack = []
self.next_token()
def next_token(self):
self.idx += 1
self.tok = self.tokens[self.idx] if self.idx < len(self.tokens) else None
def pop(self):
newop = self.operator_stack.pop()
val1 = self.value_stack.pop()
val2 = self.value_stack.pop()
self.value_stack.append(eval_(val1, val2, newop))
def parse(self):
while self.tok:
if self.tok.type in VALUE_TYPE:
self.value_stack.append(self.tok.value)
elif self.tok.type == TT_ID:
self.id()
continue
elif self.tok.type == TT_LPAREN:
self.operator_stack.append(TT_LPAREN)
elif self.tok.type in OPERATORS:
op = self.tok.type
while self.operator_stack and PRESCEDENCE.get(self.operator_stack[-1], 0) >= PRESCEDENCE.get(op, 0):
self.pop()
self.operator_stack.append(op)
elif self.tok.type == TT_RPAREN:
while self.operator_stack and self.operator_stack[-1] != TT_LPAREN:
self.pop()
self.operator_stack.pop()
self.next_token()
while self.operator_stack:
self.pop()
return self.value_stack[-1] if self.value_stack else None
def id(self):
tok = self.tok
self.next_token()
if not self.tok: return
if self.tok.type == TT_EQUALS:
self.next_token()
self.variables[tok.value] = self.parse()
elif self.tok.type == TT_LPAREN:
self.operator_stack.append(tok.value)
else:
self.value_stack.append(self.variables.get(tok.value, 'null'))
How would I implement function handling? Every time I try to execute a function I get this error:
Traceback (most recent call last):
File "lang.py", line 19, in <module>
out = evaluate(text, variables)
File "lang.py", line 10, in evaluate
parser.parse()
File "parsing.py", line 85, in parse
self.pop()
File "parsing.py", line 52, in pop
val2 = self.value_stack.pop()
IndexError: pop from empty list
Any help is appreciated.