main+parser: greatly improve error reporting

This commit is contained in:
Antoine Viallon 2023-05-08 17:36:10 +02:00
parent 272bed25b9
commit fd13900e9b
Signed by: aviallon
GPG key ID: D126B13AB555E16F
2 changed files with 34 additions and 4 deletions

View file

@ -1,19 +1,35 @@
from __future__ import annotations from __future__ import annotations
import sys
from .logger import rootLogger, LogLevel
from .parser import Parser, ParsingError
from .tokenizer import Tokenizer, Tokens from .tokenizer import Tokenizer, Tokens
from .parser import Parser from .parser import Parser
data = "2 * (32.9 + 1)" data = "2 * (32.9 + 1)"
def main(): def main():
data = """
2 + 3 / (8 - 1 + 3) * 1
+ 34.2
"""
tokenizer = Tokenizer() tokenizer = Tokenizer()
tokens = tokenizer.tokenize("2 + 3") tokens = tokenizer.tokenize(data)
tokens = [token for token in tokens if token.kind not in [Tokens.Blank, Tokens.Newline]] tokens = [token for token in tokens if token.kind not in [Tokens.Blank, Tokens.Newline]]
print(tokens) print(tokens)
parser = Parser(tokens) parser = Parser(tokens)
parser.root() try:
print(parser.parse())
except ParsingError as e:
e.location.source = data
print(f"{e}\n{e.location.show_in_source()}", file=sys.stderr)
if e.__cause__ is not None:
if rootLogger.level <= LogLevel.Debug:
raise e.__cause__
print(f"Caused by:\n{e.__cause__.__class__.__name__}: {e.__cause__}", file=sys.stderr)
if __name__ == "__main__": if __name__ == "__main__":

View file

@ -103,5 +103,19 @@ class Parser:
return summation return summation
def root(self): def root(self):
self.expression() blocks = [
self.expect(Tokens.EOF) self.expression(),
self.expect(Tokens.EOF),
]
return blocks
def parse(self) -> Node:
try:
return self.root()
except ParsingError:
raise
except Exception as e:
tok = self._last_accepted_token
if tok is None:
tok = self.token
raise ParsingError(tok.loc) from e