From 2eb49f03eb62caacd23d6d4ebb0a4793b5db003d Mon Sep 17 00:00:00 2001
From: Robin Sonnabend <robin@fsmpi.rwth-aachen.de>
Date: Sat, 3 Sep 2016 15:37:29 +0200
Subject: [PATCH] Small changes on the parser

---
 parser.py | 43 ++++++++++++++++++++++++++++++++++---------
 1 file changed, 34 insertions(+), 9 deletions(-)

diff --git a/parser.py b/parser.py
index ce110ba..f27103d 100644
--- a/parser.py
+++ b/parser.py
@@ -1,11 +1,25 @@
 import regex as re
+import sys
 from collections import OrderedDict
 
 class ParserException(Exception):
+    name = "Parser Exception"
+    has_explanation = False
+    #explanation = "The source did generally not match the expected protocol syntax."
     def __init__(self, message, linenumber=None):
         self.message = message
         self.linenumber = linenumber
 
+    def __str__(self):
+        result = ""
+        if self.linenumber is not None:
+            result = "Exception at line {}: {}".format(self.linenumber, self.message)
+        else:
+            result = "Exception: {}".format(self.message)
+        if self.has_explanation:
+            result += "\n" + self.explanation
+        return result
+
 class Element:
     """
     Generic (abstract) base element. Should never really exist.
@@ -71,7 +85,7 @@ class Element:
             return element
         return current
 
-    PATTERN = r"x(?<!x)" # yes, a master piece
+    PATTERN = r"x(?<!x)" # yes, a master piece, but it should never be called
 
 class Content(Element):
     def __init__(self, children):
@@ -115,7 +129,10 @@ class Content(Element):
                 raise ParserException("Content does not match inner!", linenumber)
         return Content(children)
 
-    PATTERN = r"\s*(?<content>(?:[^\[\];]+)?(?:\[[^\]]+\][^;\[\]]*)*);"
+    # v1: has problems with missing semicolons
+    #PATTERN = r"\s*(?<content>(?:[^\[\];]+)?(?:\[[^\]]+\][^;\[\]]*)*);"
+    # v2: does not require the semicolon, but the newline
+    PATTERN = r"\s*(?<content>(?:[^\[\];\r\n]+)?(?:\[[^\]\r\n]+\][^;\[\]\r\n]*)*);?"
 
 class Text:
     def __init__(self, text):
@@ -152,7 +169,7 @@ class Tag:
     def dump(self, level=None):
         if level is None:
             level = 0
-        return "{}tag: {}: {}".format(" " * level, self.name, "; ".join(self.values))
+        print("{}tag: {}: {}".format(" " * level, self.name, "; ".join(self.values)))
 
     @staticmethod
     def parse(match, linenumber):
@@ -301,16 +318,24 @@ def parse(source):
                 break
         if not found:
             raise ParserException("No matching syntax element found!", linenumber)
+    if current is not tree:
+        raise ParserException("Source ended within fork!")
     return tree
 
-def main():
+def main(test_file_name=None):
     source = ""
-    with open("test/source0.txt") as f:
+    test_file_name = test_file_name or "source0"
+    with open("test/{}.txt".format(test_file_name)) as f:
         source = f.read()
-    tree = parse(source)
-    #tree.dump()
-    print(tree.render())
+    try:
+        tree = parse(source)
+        tree.dump()
+    except ParserException as e:
+        print(e)
+    else:
+        print("worked!")
     
 
 if __name__ == "__main__":
-    exit(main())
+    test_file_name = sys.argv[1] if len(sys.argv) > 1 else None
+    exit(main(test_file_name))
-- 
GitLab