diff --git a/lexer_parser.py b/lexer_parser.py new file mode 100644 index 0000000..0cbb0ac --- /dev/null +++ b/lexer_parser.py @@ -0,0 +1,76 @@ +from enum import Enum + +class Tokens(Enum): + QUOTE = 1, + CHAR = 2, + NEWLINE = 3, + SPACE = 4 + +class Lexer: + tokens = list() + def __init__(self): + pass + def lex(self, str): + for c in str: + if c == "'" or c == '"': + self.tokens.append(Tokens.QUOTE) + print("Token: QUOTE") + elif c == "\n": + self.tokens.append(Tokens.NEWLINE) + print("Token: NEWLINE") + elif c == " ": + self.tokens.append(Tokens.SPACE) + print("Token: SPACE") + else: + self.tokens.append(Tokens.CHAR) + print("Token: CHAR") + def __str__(self): + return ",".join(Tokens(token).name for token in self.tokens) + +class States(Enum): + INITIAL = 0, + BEGINQUOTE = 1 + +class Parser: + def __init__(self): + self.state = States.INITIAL + self.line = 1 + + def transition(self, state): + print(f"{States(self.state).name} -> {States(state).name}") + self.state = state + + def parse(self, tokens): + for token in tokens: + if self.state == States.INITIAL: + if token == Tokens.QUOTE: + self.transition(States.BEGINQUOTE) + elif token == Tokens.NEWLINE: + self.line += 1 + continue + if self.state == States.BEGINQUOTE: + if token == Tokens.QUOTE: + self.transition(States.INITIAL) + elif token == Tokens.CHAR or token == Tokens.SPACE: + pass + elif token == Tokens.NEWLINE: + raise ValueError(f"Unterminated string on line {self.line}") + continue + +if __name__ == "__main__": + test1 = """abcdefg + "abcde + 'a' + bareword +""" + + lexer = Lexer() + lexer.lex(test1) + # print(lexer) + parser = Parser() + try: + parser.parse(lexer.tokens) + except ValueError as error: + print(error) + +