From e9324f4f71a2b4136ecaf524205a7ea631ca45ee Mon Sep 17 00:00:00 2001 From: Antoine Viallon Date: Tue, 9 May 2023 01:51:52 +0200 Subject: [PATCH] errors: init dedicated error file --- compiler/__main__.py | 5 +++-- compiler/errors.py | 21 +++++++++++++++++++++ compiler/nodes.py | 1 + compiler/parser.py | 19 +++---------------- 4 files changed, 28 insertions(+), 18 deletions(-) create mode 100644 compiler/errors.py diff --git a/compiler/__main__.py b/compiler/__main__.py index 7254e27..9005393 100644 --- a/compiler/__main__.py +++ b/compiler/__main__.py @@ -4,8 +4,9 @@ import sys from pprint import pprint from . import semantic +from .errors import CompilationError from .logger import rootLogger, LogLevel -from .parser import Parser, ParsingError +from .parser import Parser from .tokenizer import Tokenizer, Tokens @@ -42,7 +43,7 @@ def main(): messages += [f"{repr(ir_item)}\n"] print("\n".join(messages)) - except ParsingError as e: + except CompilationError as e: e.location.source = data print(f"{e}\n{e.location.show_in_source()}", file=sys.stderr) if e.__cause__ is not None: diff --git a/compiler/errors.py b/compiler/errors.py new file mode 100644 index 0000000..2ae3641 --- /dev/null +++ b/compiler/errors.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +from . import source, tokenizer + + +class CompilationError(Exception): + def __init__(self, location: source.SourceLocation, message: str = "Unknown error"): + super().__init__(f"{message} at {str(location)}") + self.location = location + + +class UnexpectedTokenError(CompilationError): + def __init__(self, got: tokenizer.Token, wanted: tokenizer.Tokens | str): + message = wanted + if type(wanted) == tokenizer.Tokens: + message = str(wanted) + super().__init__(got.loc, f"Unexpected token '{got}', wanted {message}") + + +class SemanticAnalysisError(CompilationError): + pass diff --git a/compiler/nodes.py b/compiler/nodes.py index 47f13f7..a7cc9ee 100644 --- a/compiler/nodes.py +++ b/compiler/nodes.py @@ -7,6 +7,7 @@ from typing import Any, Iterable from beartype import beartype from . import ir, semantic +from .errors import SemanticAnalysisError from .logger import Logger from .source import SourceLocation diff --git a/compiler/parser.py b/compiler/parser.py index 4db1c95..533a237 100644 --- a/compiler/parser.py +++ b/compiler/parser.py @@ -2,6 +2,7 @@ from __future__ import annotations from beartype.typing import List, Dict, Callable +from .errors import CompilationError, UnexpectedTokenError from .logger import Logger from .nodes import Float, Sum, Value, Product, Node, Division, Sub, Integer, Expression from .source import SourceLocation @@ -10,20 +11,6 @@ from .tokenizer import Tokens, Token logger = Logger(__name__) -class ParsingError(Exception): - def __init__(self, location: SourceLocation, message: str = "Unknown error"): - super().__init__(f"{message} at {str(location)}") - self.location = location - - -class UnexpectedTokenError(ParsingError): - def __init__(self, got: Token, wanted: Tokens | str): - message = wanted - if type(wanted) == Tokens: - message = str(wanted) - super().__init__(got.loc, f"Unexpected token '{got}', wanted {message}") - - class Parser: def __init__(self, tokens: List[Token]): self.tokens = tokens @@ -118,10 +105,10 @@ class Parser: def parse(self) -> Node: try: return self.root() - except ParsingError: + except CompilationError: raise except Exception as e: tok = self._last_accepted_token if tok is None: tok = self.token - raise ParsingError(tok.loc) from e + raise CompilationError(tok.loc) from e