From b79949a98935e4fdf923b4392eea275e2ed1c83d Mon Sep 17 00:00:00 2001 From: Robert Spralja Date: Thu, 3 Mar 2022 17:59:34 +0100 Subject: [PATCH 1/2] Implemented SyntaxError SyntaxError takes three positional arguments `message, tokens, current` Printing syntax error will print the line that the error occured and the offending token will be surrounded by '~~'. --- src/errors/__init__.py | 42 ++++++++++++++++++++++++++++++++++++++++++ src/pychart/runner.py | 28 ++++++++++++++++------------ 2 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 src/errors/__init__.py diff --git a/src/errors/__init__.py b/src/errors/__init__.py new file mode 100644 index 0000000..7277895 --- /dev/null +++ b/src/errors/__init__.py @@ -0,0 +1,42 @@ + + +class BaseError(Exception): + def __init__(self, message): + super().__init__(message) + + @property + def traceback(self): + return self._traceback + + +class SyntaxError(BaseError): + def __init__(self, message, tokens, current): + self.tokens = tokens + self.current = current + super().__init__(message) + + def __str__(self): + string = '' + current_token = self.tokens[self.current] + current_line = current_token.line + + start_of_line = self.current + while self.tokens[start_of_line].line == current_line: + start_of_line -= 1 + + start_of_line += 1 + + end_of_line = self.current + while self.tokens[end_of_line].line == current_line: + end_of_line += 1 + + + for token in self.tokens[start_of_line:end_of_line]: + if token == current_token: + string += '~~' + string += token.lexem + ' ' + + if token == current_token: + string += '~~' + + return string diff --git a/src/pychart/runner.py b/src/pychart/runner.py index 89e990d..1e85ccd 100644 --- a/src/pychart/runner.py +++ b/src/pychart/runner.py @@ -1,24 +1,28 @@ from src.scanner import Scanner from src.pyparser import Parser +from src import errors def run(source: str): - scanner = Scanner(source) - tokens = scanner.get_tokens() - ast = Parser(tokens).parse() + try: + scanner = Scanner(source) + tokens = scanner.get_tokens() + ast = Parser(tokens).parse() - if ast is None: - return + if ast is None: + return - value = ast() + value = ast() - try: - value = int(value) - except: - pass + try: + value = int(value) + except: + pass - # print(f"AST: {ast}") - print(value) + # print(f"AST: {ast}") + print(value) + except errors.BaseError as e: + print(e) def run_prompt(): From 7783ab3239ae6e4349bdb44728bd6c9c15ef6ecf Mon Sep 17 00:00:00 2001 From: Robert Spralja Date: Thu, 3 Mar 2022 18:10:16 +0100 Subject: [PATCH 2/2] fixed errors in SyntaxError.__str__ --- src/errors/__init__.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/errors/__init__.py b/src/errors/__init__.py index 7277895..13a1f1a 100644 --- a/src/errors/__init__.py +++ b/src/errors/__init__.py @@ -21,22 +21,20 @@ def __str__(self): current_line = current_token.line start_of_line = self.current - while self.tokens[start_of_line].line == current_line: + while start_of_line > 0 and self.tokens[start_of_line].line == current_line: start_of_line -= 1 - start_of_line += 1 - end_of_line = self.current - while self.tokens[end_of_line].line == current_line: + while end_of_line < len(self.tokens) and self.tokens[end_of_line].line == current_line: end_of_line += 1 - for token in self.tokens[start_of_line:end_of_line]: - if token == current_token: - string += '~~' - string += token.lexem + ' ' + for token, index in zip(self.tokens[start_of_line:end_of_line], range(start_of_line, end_of_line)): + if index == self.current: + string += '~~ ' + string += token.lexeme + ' ' - if token == current_token: + if index == self.current: string += '~~' return string