Browse Source

Change the complete interface of Visitors (using arguments)

Yentl Van Tendeloo 9 years ago
parent
commit
9831fb72c3

+ 36 - 95
interface/HUTN/hutn_compiler/compiler.py

@@ -81,7 +81,7 @@ def find_file(filename, include_paths):
     else:
         raise Exception("Could not resolve file %s. Tried: %s" % (filename, attempts))
 
-def do_compile(inputfile, grammarfile, compile_visitor = None, compile_visitor2 = None, include_paths = []):
+def do_compile(inputfile, grammarfile, visitors=[], include_paths = []):
     import os.path
     global working_file
     working_file = os.path.abspath(inputfile)
@@ -89,19 +89,8 @@ def do_compile(inputfile, grammarfile, compile_visitor = None, compile_visitor2
     result = do_parse(inputfile, grammarfile)
     error = result["status"] != Parser.Constants.Success
     if error:
-        print 'not a valid input file!'
-        print '{}:{}: error: {}'.format(result['line'], result['column'],
-                                        result['text'])
-        for r in result['partialresults']:
-            print r
-            if isinstance(r['tree'], Tree):
-                print r['tree'].head, [x.head for x in r['tree'].tail if hasattr(x, 'head')]
-            # print "-"*20+"partial-result"+"-"*20
-            # from prettyprint_visitor import PrintVisitor
-            # pv = PrintVisitor()
-            # pv.visit(r['tree'])
-            # print pv.dump()
-
+        msg = "Not a valid input file!\n%s:%s: error: %s" % (result['line'], result['column'], result['text'])
+        raise Exception(msg)
     else:
         for child in result["tree"].tail:
             child.inputfile = inputfile
@@ -121,10 +110,8 @@ def do_compile(inputfile, grammarfile, compile_visitor = None, compile_visitor2
                                 name = str(j.tail[0])[1:-1]
                                 subtree = do_parse(find_file(name, include_paths), grammarfile)["tree"].tail
                                 if subtree is None:
-                                    if compile_visitor is None:
-                                        return False
-                                    else:
-                                        return None
+                                    raise Exception("Parsing error for included file %s" % find_file(name, include_paths))
+
                                 for t in subtree:
                                     t.inputfile = name
                                 included.add(f)
@@ -141,87 +128,41 @@ def do_compile(inputfile, grammarfile, compile_visitor = None, compile_visitor2
                 # The outer for finally finished, so there were no includes remaining, thus terminate the infinite while loop
                 break
 
-    if compile_visitor is None:
-        return not error
-    else:
-        if error:
-            return None
-        else:
-            try:
-                compile_visitor.visit(result["tree"])
-                if compile_visitor2:
-                    compile_visitor2.visit(result["tree"])
-            except RuntimeError as e:
-                print e.message
-                sys.exit(1)
-
-            if compile_visitor2:
-                return compile_visitor2.dump()
-            else:
-                return compile_visitor.dump()
-
-def main(input_file, grammar_file, mode, args):
-    if mode == "None":
-        visitor = None
-        visitor2 = None
-    elif mode == "PP":
-        from prettyprint_visitor import PrettyPrintVisitor
-        visitor = PrettyPrintVisitor()
-        visitor2 = None
-    elif mode == "P":
-        from prettyprint_visitor import PrintVisitor
-        visitor = PrintVisitor()
-        visitor2 = None
-    elif mode == "S":
-        from semantics_visitor import SemanticsVisitor
-        visitor = SemanticsVisitor()
-        visitor2 = None
-    elif mode == "SP":
-        from semantics_visitor import SemanticsVisitor
-        from prettyprint_visitor import PrettyPrintVisitor
-        visitor = SemanticsVisitor()
-        visitor2 = PrettyPrintVisitor()
-    elif mode == "BS":
-        from semantics_visitor import SemanticsVisitor
-        from bootstrap_visitor import BootstrapVisitor
-        visitor = SemanticsVisitor()
-        visitor2 = BootstrapVisitor(args)
-    elif mode == "PS":
-        from semantics_visitor import SemanticsVisitor
-        from primitives_visitor import PrimitivesVisitor
-        visitor = SemanticsVisitor()
-        visitor2 = PrimitivesVisitor(args)
-    elif mode == "PO":
-        from semantics_visitor import SemanticsVisitor
-        from primitives_object_visitor import PrimitivesObjectVisitor
-        visitor = SemanticsVisitor()
-        visitor2 = PrimitivesObjectVisitor(args)
-    elif mode == "CS":
-        from semantics_visitor import SemanticsVisitor
-        from constructors_visitor import ConstructorsVisitor
-        visitor = SemanticsVisitor()
-        visitor2 = ConstructorsVisitor(args)
-    elif mode == "CO":
-        from semantics_visitor import SemanticsVisitor
-        from constructors_object_visitor import ConstructorsObjectVisitor
-        visitor = SemanticsVisitor()
-        visitor2 = ConstructorsObjectVisitor(args)
-    else:
-        print("Visitor not understood: " + str(mode))
-        sys.exit(1)
-    return do_compile(input_file, grammar_file, visitor, visitor2)
+    for visitor in visitors:
+        visitor.visit(result["tree"])
+
+    if visitors:
+        return visitors[-1].dump()
+
+def main(input_file, grammar_file, mode, args=[]):
+    from prettyprint_visitor import PrettyPrintVisitor
+    from prettyprint_visitor import PrintVisitor
+    from semantics_visitor import SemanticsVisitor
+    from bootstrap_visitor import BootstrapVisitor
+    from primitives_visitor import PrimitivesVisitor
+    from primitives_object_visitor import PrimitivesObjectVisitor
+    from constructors_visitor import ConstructorsVisitor
+    from constructors_object_visitor import ConstructorsObjectVisitor
+
+    modes = {
+        "N" : [],
+        "P" : [PrintVisitor],
+        "PP" : [PrettyPrintVisitor],
+        "S" : [SemanticsVisitor],
+        "PS" : [SemanticsVisitor, PrimitivesVisitor],
+        "PO" : [SemanticsVisitor, PrimitivesObjectVisitor],
+        "BS" : [SemanticsVisitor, BootstrapVisitor],
+        "CS" : [SemanticsVisitor, ConstructorsVisitor],
+        "CO" : [SemanticsVisitor, ConstructorsObjectVisitor],
+    }
+    return do_compile(input_file, grammar_file, [v(args) for v in modes[mode]])
 
 if __name__ == "__main__":
     if len(sys.argv) <= 2:
         print("Invocation: ")
-        print("  %s input_file grammar_file [mode]" % sys.argv[0])
+        print("  %s input_file grammar_file mode [mode_params]*" % sys.argv[0])
         sys.exit(1)
     else:
         value = main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4:])
-        if value is None:
-            sys.exit(1)
-        else:
-            if isinstance(value, list):
-                print '\n'.join([repr(x) for x in value])
-            sys.exit(0)
-
+        if value is not None:
+            print(value)

+ 1 - 1
interface/HUTN/hutn_compiler/constructors_object_visitor.py

@@ -7,7 +7,7 @@ timeout = 100
 
 class ConstructorsObjectVisitor(ConstructorsVisitor):
     def __init__(self, args):
-        ConstructorsVisitor.__init__(self)
+        ConstructorsVisitor.__init__(self, args)
 
         self.username = args[0]
         self.obj_file = args[1]

+ 1 - 0
interface/HUTN/hutn_compiler/constructors_visitor.py

@@ -3,6 +3,7 @@ from visitor import Visitor
 
 class ConstructorsVisitor(Visitor):
     def __init__(self, args):
+        Visitor.__init__(self, args)
         self.constructors = []
         self.free_id = 0
 

+ 1 - 0
interface/HUTN/hutn_compiler/declare_functions_visitor.py

@@ -6,6 +6,7 @@ from visitor import Visitor
 # Declare the function but do not visit its body
 class DeclareFunctionsVisitor(Visitor):
     def __init__(self, symbol_table, inputfiles):
+        Visitor.__init__(self, [])
         self.symbol_table = symbol_table
         self.inputfiles = inputfiles
 

+ 7 - 6
interface/HUTN/hutn_compiler/prettyprint_visitor.py

@@ -1,7 +1,9 @@
 from hutnparser import Tree
+from visitor import Visitor
 
-class PrintVisitor(object):
-    def __init__(self):
+class PrintVisitor(Visitor):
+    def __init__(self, args):
+        Visitor.__init__(self, args)
         self.result = ''
         pass
 
@@ -16,10 +18,9 @@ class PrintVisitor(object):
     def dump(self):
         return self.result
 
-class PrettyPrintVisitor(object):
-    def __init__(self):
-        self.result = ''
-        pass
+class PrettyPrintVisitor(Visitor):
+    def __init__(self, args):
+        Visitor.__init__(self, args)
 
     def visit(self, tree, level=0):
         if isinstance(tree, Tree):

+ 1 - 1
interface/HUTN/hutn_compiler/primitives_object_visitor.py

@@ -6,7 +6,7 @@ import urllib2
 
 class PrimitivesObjectVisitor(PrimitivesVisitor):
     def __init__(self, args):
-        PrimitivesVisitor.__init__(self)
+        PrimitivesVisitor.__init__(self, args)
 
         self.username = args[0]
         self.obj_file = args[1]

+ 1 - 0
interface/HUTN/hutn_compiler/primitives_visitor.py

@@ -3,6 +3,7 @@ from visitor import Visitor
 
 class PrimitivesVisitor(Visitor):
     def __init__(self, args):
+        Visitor.__init__(self, args)
         self.output = []
         self.free_id = 0
         self.function_values = dict()

+ 0 - 93
interface/HUTN/hutn_compiler/sample_test_script.py

@@ -1,93 +0,0 @@
-#!/opt/local/bin/python
-import json
-import urllib
-import urllib2
-import sys
-from compiler import main
-
-
-input_file = '../test/acceptance/mirror.al'
-mode = "CS"
-test_input = 1
-test_output = "1"
-
-
-user = 'test'
-timeout = 10
-grammar_file = '../grammars/actionlanguage.g'
-
-
-if mode == "CS":
-    interface = 1
-elif mode == "PS":
-    interface = 0
-else:
-    raise RuntimeError("Mode be either PS or CS")
-
-
-def set_input(value, user=user, timeout=timeout):
-    if type(value) in (list, tuple):
-        args = {"op": "set_input",
-                "data": json.dumps(value),
-                "username": user}
-    else:
-        args = {"op": "set_input",
-                "element_type": "V",
-                "value": value,
-                "username": user}
-    urllib2.urlopen(
-        urllib2.Request("http://localhost:8001/", urllib.urlencode(args)),
-        timeout=timeout).read()
-
-
-def get_output(user=user, timeout=timeout):
-    return urllib2.urlopen(
-        urllib2.Request("http://localhost:8001/",
-                        urllib.urlencode({"op": "get_output",
-                                          "username": user})),
-        timeout=timeout).read()
-
-
-# create user
-set_input('"{}"'.format(user), "user_manager")
-
-# set interface
-set_input(interface)
-
-# compile to code
-code = main(input_file, grammar_file, mode)
-
-# send code
-if mode == "CS":
-    var_list = {}
-    data = []
-    for p in code:
-        if isinstance(p, int):
-            if p not in var_list:
-                set_input(data)
-                data = []
-                val = get_output()
-                val = val.split("=", 2)[1].split("&", 1)[0]
-                var_list[p] = val
-                continue
-            else:
-                val = var_list[p]
-                t = "R"
-        else:
-            val = p
-            t = "V"
-        data.append([t, val])
-    set_input(data)
-elif mode == "PS":
-    set_input(json.dumps(code))
-
-# send input (may be a list or a single value)
-set_input(test_input)
-
-# get output
-val = get_output()
-val = val.split("=", 2)[2]
-# print("For input %s, got output %s, instead of %s" % (test_input, val,
-#                                                       test_output))
-assert val == test_output
-print val == test_output

+ 2 - 1
interface/HUTN/hutn_compiler/semantics_visitor.py

@@ -7,7 +7,8 @@ from visitor import Visitor
 
 
 class SemanticsVisitor(Visitor):
-    def __init__(self):
+    def __init__(self, args):
+        Visitor.__init__(self, args)
         self.symbol_table = st.SymbolTable()
 
         # there is only one input file, list is for sharing it among visitors

+ 6 - 0
interface/HUTN/hutn_compiler/visitor.py

@@ -2,6 +2,12 @@ import symbol_table as st
 
 
 class Visitor(object):
+    def __init__(self, args):
+        pass
+
+    def dump(self):
+        return ""
+
     def visit(self, tree):
         if not tree.head.startswith("implicit_autogenerated_"):
             val = tree.head

+ 0 - 68
interface/HUTN/hutn_compiler/visitor_objects.py

@@ -1,68 +0,0 @@
-from visitor_mvs import VisitorMvS
-import urllib
-import urllib2
-
-class VisitorObjects(VisitorMvS):
-    def __init__(self, args):
-        self.username = args[0]
-        self.obj_file = args[1]
-        self.real_file = args[2]
-        self.mode = args[3]
-        VisitorMvS.__init__(self, [None])
-
-        with open(self.real_file, 'r') as f:
-            import hashlib
-            md5 = hashlib.md5()
-            md5.update(f.read())
-        self.hash_file = md5.hexdigest()
-
-        # Check if file is already compiled (with same hash) in Modelverse
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.username, "username": "user_manager"}))).read()
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '3', "username": self.username}))).read()
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"is_defined"', "username": self.username}))).read()
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.obj_file, "username": self.username}))).read()
-
-        v = urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "get_output", "username": self.username}))).read()
-        v = v.split("=", 2)[2]
-        if v == "None":
-            # Not defined, so recompile
-            print("[CC] %s" % self.real_file)
-        else:
-            # Is defined already, so let's compare hashes
-            if v != self.hash_file:
-                print("[RC] %s" % self.real_file)
-
-                # Remove in Modelverse and recompile
-                urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '3', "username": self.username}))).read()
-                urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"remove_obj"', "username": self.username}))).read()
-                urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.obj_file, "username": self.username}))).read()
-            else:
-                self.visit = lambda i: i
-                self.dump = lambda: True
-                print("[SO] %s" % self.real_file)
-
-
-    def dump(self):
-        v = VisitorMvS.dump(self)
-        import json
-        # Set up interface
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '3', "username": self.username}))).read()
-
-        # Start uploading the code
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"upload"', "username": self.username}))).read()
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.obj_file, "username": self.username}))).read()
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": '"%s"' % self.hash_file, "username": self.username}))).read()
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": 'false', "username": self.username}))).read() # Use old interface
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": json.dumps(v), "username": self.username}))).read()
-
-        # Upload symbol table
-        data = []
-        for e, v in self.object_symbols.iteritems():
-            data.append(["V", "true"])
-            data.append(["V", '"%s"' % e])
-            data.append(["V", "true" if v else "false"])
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "data": json.dumps(data), "username": self.username}))).read()
-
-        # Finish the symbol table
-        urllib2.urlopen(urllib2.Request("http://localhost:8001/", urllib.urlencode({"op": "set_input", "element_type": "V", "value": 'false', "username": self.username}))).read()
-        return True

+ 6 - 2
interface/HUTN/test/grammar_action_language/test_invalids.py

@@ -1,10 +1,14 @@
 import unittest
 import util
 
-from hutn_compiler.compiler import do_compile
+from hutn_compiler.compiler import main
 
 def parse_file(filename):
-    return not do_compile(util.get_code_path(filename), "grammars/actionlanguage.g", None)
+    try:
+        main(util.get_code_path(filename), "grammars/actionlanguage.g", "N", [])
+        return False
+    except:
+        return True
 
 class TestValids(unittest.TestCase):
     def test_empty(self):

+ 6 - 2
interface/HUTN/test/grammar_action_language/test_valids.py

@@ -1,10 +1,14 @@
 import unittest
 import util
 
-from hutn_compiler.compiler import do_compile
+from hutn_compiler.compiler import main
 
 def parse_file(filename):
-    return do_compile(util.get_code_path(filename), "grammars/actionlanguage.g", None)
+    try:
+        main(util.get_code_path(filename), "grammars/actionlanguage.g", "N", [])
+        return True
+    except:
+        return False
 
 class TestValids(unittest.TestCase):
     def test_empty(self):