From 7fbe71dff650ae7db0dd2a9c9bc701aeea318093 Mon Sep 17 00:00:00 2001 From: Robin Sonnabend <robin@fsmpi.rwth-aachen.de> Date: Sat, 3 Sep 2016 15:49:30 +0200 Subject: [PATCH] Better error messages for some errors in parser --- parser.py | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/parser.py b/parser.py index f27103d..e450c5e 100644 --- a/parser.py +++ b/parser.py @@ -66,9 +66,7 @@ class Element: if match is None: raise ParserException("Source does not match!", linenumber) length = match.group().count("\n") - if linenumber is None: - return length - return linenumber + length + return length + (0 if linenumber is None else linenumber) @staticmethod def parse_outer(element, current): @@ -88,8 +86,9 @@ class Element: PATTERN = r"x(?<!x)" # yes, a master piece, but it should never be called class Content(Element): - def __init__(self, children): + def __init__(self, children, linenumber): self.children = children + self.linenumber = linenumber def render(self): return "".join(map(lambda e: e.render(), self.children)) @@ -127,7 +126,7 @@ class Content(Element): break if not matched: raise ParserException("Content does not match inner!", linenumber) - return Content(children) + return Content(children, linenumber) # v1: has problems with missing semicolons #PATTERN = r"\s*(?<content>(?:[^\[\];]+)?(?:\[[^\]]+\][^;\[\]]*)*);" @@ -135,8 +134,9 @@ class Content(Element): PATTERN = r"\s*(?<content>(?:[^\[\];\r\n]+)?(?:\[[^\]\r\n]+\][^;\[\]\r\n]*)*);?" class Text: - def __init__(self, text): + def __init__(self, text, linenumber): self.text = text + self.linenumber = linenumber def render(self): return self.text @@ -153,15 +153,16 @@ class Text: content = match.group("text") if content is None: raise ParserException("Text is empty!", linenumber) - return Text(content) + return Text(content, linenumber) PATTERN = r"(?<text>[^\[]+)(?:(?=\[)|$)" class Tag: - def __init__(self, name, values): + def __init__(self, name, values, linenumber): self.name = name self.values = values + self.linenumber = linenumber def render(self): return r"\textbf{{{}:}} {}".format(self.name, "; ".join(self.values)); @@ -179,13 +180,13 @@ class Tag: if content is None: raise ParserException("Tag is empty!", linenumber) parts = content.split(";") - return Tag(parts[0], parts[1:]) + return Tag(parts[0], parts[1:], linenumber) PATTERN = r"\[(?<content>(?:[^;\]]*;)*(?:[^;\]]*))\]" class Empty(Element): - def __init__(self): - pass + def __init__(self, linenumber): + linenumber = linenumber def render(self): return "" @@ -203,9 +204,10 @@ class Empty(Element): PATTERN = r"\s+" class Remark(Element): - def __init__(self, name, value): + def __init__(self, name, value, linenumber): self.name = name self.value = value + self.linenumber = linenumber def render(self): return r"\textbf{{{}}}: {}".format(self.name, self.value) @@ -225,17 +227,18 @@ class Remark(Element): if len(parts) < 2: raise ParserException("Remark value is empty!", linenumber) name, value = parts - element = Remark(name, value) + element = Remark(name, value, linenumber) current = Element.parse_outer(element, current) return current, linenumber PATTERN = r"\s*\#(?<content>[^\n]+)" class Fork(Element): - def __init__(self, environment, name, parent, children=None): + def __init__(self, environment, name, parent, linenumber, children=None): self.environment = environment if environment is None or len(environment) > 0 else None self.name = name if name is None or len(name) > 0 else None self.parent = parent + self.linenumber = linenumber self.children = [] if children is None else children def dump(self, level=None): @@ -259,7 +262,7 @@ class Fork(Element): @staticmethod def create_root(): - return Fork(None, None, None) + return Fork(None, None, None, 0) @staticmethod def parse(match, current, linenumber=None): @@ -272,7 +275,7 @@ class Fork(Element): name = name1 if name2 is not None: name += " {}".format(name2) - element = Fork(environment, name, current) + element = Fork(environment, name, current, linenumber) current = Element.parse_outer(element, current) return current, linenumber @@ -319,7 +322,7 @@ def parse(source): if not found: raise ParserException("No matching syntax element found!", linenumber) if current is not tree: - raise ParserException("Source ended within fork!") + raise ParserException("Source ended within fork! (started at line {})".format(current.linenumber)) return tree def main(test_file_name=None): -- GitLab