Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:Added parser code (that does not build tree) #32

Merged
merged 14 commits into from
Jul 17, 2024
73 changes: 73 additions & 0 deletions parser/parse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import re
import sys


def error(msg: str, pos: int):
print(f"Parse error: {msg} at position {pos}", file=sys.stderr)
exit(1)


class Parser:
"""Parser object for analyzing tokens for errors"""

def __init__(self) -> None:
"""Initializes the parser with attributes to be used"""
self.pos: int = -1

def parse(self, tokens: list[str]) -> None:
"""Parses given tokens"""
self.tokens: list[str] = tokens
self.advance() # Initializes the first token
rv = self.expr()
self.assert_end()
print("Successfully completed parsing")
return rv

def assert_end(self) -> None:
if self.next_token != "<EOF>":
error(f"Expected end '<EOF>' but found {self.next_token}", self.pos)

def eat(self, expected: str) -> None:
"""Skips a token"""
if self.next_token == expected:
self.advance()
else:
error(f"Expected '{expected}' but found '{self.next_token}'", self.pos)

def advance(self) -> None:
"""Moves to the next token"""
self.pos += 1
self.next_token: str = self.tokens[self.pos]

def expr(self) -> None:
"""Parses an expression"""
if re.match("[A-Z]+", self.next_token):
self.var()
self.expr_prime()
elif self.next_token == "!":
self.eat("!")
self.expr()
elif self.next_token == "(":
self.eat("(")
self.expr()
self.eat(")")
else:
error(f"Expected [var, !, (] but found '{self.next_token}'", self.pos)

def expr_prime(self) -> None:
"""Parses an expression prime (explain what this is later)"""
if self.next_token == "&":
self.eat("&")
self.expr()
elif self.next_token == "|":
self.eat("|")
self.expr()

def var(self) -> None:
"""Parses a variable that represents a boolean expression"""
self.eat(self.next_token)


p: Parser = Parser()
tree = p.parse(["!", "(", "A", "&", "!", "B", "|", "C", ")", "<EOF>"])
print(tree)
7 changes: 7 additions & 0 deletions tests/test_parse.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from parse import Parser

p: Parser = Parser()
tree = p.parse(
["!", "(", "A", "&", "!", "B", "|", "C", ")", "<EOF>"]
)
print(tree)