Commit 7fbe71df authored by Robin Sonnabend's avatar Robin Sonnabend
Browse files

Better error messages for some errors in parser

parent 2eb49f03
...@@ -66,9 +66,7 @@ class Element: ...@@ -66,9 +66,7 @@ class Element:
if match is None: if match is None:
raise ParserException("Source does not match!", linenumber) raise ParserException("Source does not match!", linenumber)
length = match.group().count("\n") length = match.group().count("\n")
if linenumber is None: return length + (0 if linenumber is None else linenumber)
return length
return linenumber + length
@staticmethod @staticmethod
def parse_outer(element, current): def parse_outer(element, current):
...@@ -88,8 +86,9 @@ class Element: ...@@ -88,8 +86,9 @@ class Element:
PATTERN = r"x(?<!x)" # yes, a master piece, but it should never be called PATTERN = r"x(?<!x)" # yes, a master piece, but it should never be called
class Content(Element): class Content(Element):
def __init__(self, children): def __init__(self, children, linenumber):
self.children = children self.children = children
self.linenumber = linenumber
def render(self): def render(self):
return "".join(map(lambda e: e.render(), self.children)) return "".join(map(lambda e: e.render(), self.children))
...@@ -127,7 +126,7 @@ class Content(Element): ...@@ -127,7 +126,7 @@ class Content(Element):
break break
if not matched: if not matched:
raise ParserException("Content does not match inner!", linenumber) raise ParserException("Content does not match inner!", linenumber)
return Content(children) return Content(children, linenumber)
# v1: has problems with missing semicolons # v1: has problems with missing semicolons
#PATTERN = r"\s*(?<content>(?:[^\[\];]+)?(?:\[[^\]]+\][^;\[\]]*)*);" #PATTERN = r"\s*(?<content>(?:[^\[\];]+)?(?:\[[^\]]+\][^;\[\]]*)*);"
...@@ -135,8 +134,9 @@ class Content(Element): ...@@ -135,8 +134,9 @@ class Content(Element):
PATTERN = r"\s*(?<content>(?:[^\[\];\r\n]+)?(?:\[[^\]\r\n]+\][^;\[\]\r\n]*)*);?" PATTERN = r"\s*(?<content>(?:[^\[\];\r\n]+)?(?:\[[^\]\r\n]+\][^;\[\]\r\n]*)*);?"
class Text: class Text:
def __init__(self, text): def __init__(self, text, linenumber):
self.text = text self.text = text
self.linenumber = linenumber
def render(self): def render(self):
return self.text return self.text
...@@ -153,15 +153,16 @@ class Text: ...@@ -153,15 +153,16 @@ class Text:
content = match.group("text") content = match.group("text")
if content is None: if content is None:
raise ParserException("Text is empty!", linenumber) raise ParserException("Text is empty!", linenumber)
return Text(content) return Text(content, linenumber)
PATTERN = r"(?<text>[^\[]+)(?:(?=\[)|$)" PATTERN = r"(?<text>[^\[]+)(?:(?=\[)|$)"
class Tag: class Tag:
def __init__(self, name, values): def __init__(self, name, values, linenumber):
self.name = name self.name = name
self.values = values self.values = values
self.linenumber = linenumber
def render(self): def render(self):
return r"\textbf{{{}:}} {}".format(self.name, "; ".join(self.values)); return r"\textbf{{{}:}} {}".format(self.name, "; ".join(self.values));
...@@ -179,13 +180,13 @@ class Tag: ...@@ -179,13 +180,13 @@ class Tag:
if content is None: if content is None:
raise ParserException("Tag is empty!", linenumber) raise ParserException("Tag is empty!", linenumber)
parts = content.split(";") parts = content.split(";")
return Tag(parts[0], parts[1:]) return Tag(parts[0], parts[1:], linenumber)
PATTERN = r"\[(?<content>(?:[^;\]]*;)*(?:[^;\]]*))\]" PATTERN = r"\[(?<content>(?:[^;\]]*;)*(?:[^;\]]*))\]"
class Empty(Element): class Empty(Element):
def __init__(self): def __init__(self, linenumber):
pass linenumber = linenumber
def render(self): def render(self):
return "" return ""
...@@ -203,9 +204,10 @@ class Empty(Element): ...@@ -203,9 +204,10 @@ class Empty(Element):
PATTERN = r"\s+" PATTERN = r"\s+"
class Remark(Element): class Remark(Element):
def __init__(self, name, value): def __init__(self, name, value, linenumber):
self.name = name self.name = name
self.value = value self.value = value
self.linenumber = linenumber
def render(self): def render(self):
return r"\textbf{{{}}}: {}".format(self.name, self.value) return r"\textbf{{{}}}: {}".format(self.name, self.value)
...@@ -225,17 +227,18 @@ class Remark(Element): ...@@ -225,17 +227,18 @@ class Remark(Element):
if len(parts) < 2: if len(parts) < 2:
raise ParserException("Remark value is empty!", linenumber) raise ParserException("Remark value is empty!", linenumber)
name, value = parts name, value = parts
element = Remark(name, value) element = Remark(name, value, linenumber)
current = Element.parse_outer(element, current) current = Element.parse_outer(element, current)
return current, linenumber return current, linenumber
PATTERN = r"\s*\#(?<content>[^\n]+)" PATTERN = r"\s*\#(?<content>[^\n]+)"
class Fork(Element): 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.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.name = name if name is None or len(name) > 0 else None
self.parent = parent self.parent = parent
self.linenumber = linenumber
self.children = [] if children is None else children self.children = [] if children is None else children
def dump(self, level=None): def dump(self, level=None):
...@@ -259,7 +262,7 @@ class Fork(Element): ...@@ -259,7 +262,7 @@ class Fork(Element):
@staticmethod @staticmethod
def create_root(): def create_root():
return Fork(None, None, None) return Fork(None, None, None, 0)
@staticmethod @staticmethod
def parse(match, current, linenumber=None): def parse(match, current, linenumber=None):
...@@ -272,7 +275,7 @@ class Fork(Element): ...@@ -272,7 +275,7 @@ class Fork(Element):
name = name1 name = name1
if name2 is not None: if name2 is not None:
name += " {}".format(name2) name += " {}".format(name2)
element = Fork(environment, name, current) element = Fork(environment, name, current, linenumber)
current = Element.parse_outer(element, current) current = Element.parse_outer(element, current)
return current, linenumber return current, linenumber
...@@ -319,7 +322,7 @@ def parse(source): ...@@ -319,7 +322,7 @@ def parse(source):
if not found: if not found:
raise ParserException("No matching syntax element found!", linenumber) raise ParserException("No matching syntax element found!", linenumber)
if current is not tree: 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 return tree
def main(test_file_name=None): def main(test_file_name=None):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment