123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- from visitor import Visitor
- from compiler import main as do_compile
- import os
- def jsonstr(s):
- return '"%s"' % s
- def empty(s):
- return None
- class ModelVisitor(Visitor):
- def __init__(self, args):
- Visitor.__init__(self, args)
- self.constructors = []
- self.free_id = 0
- self.name_maps = {}
- self.current_model = None
- self.current_element = None
- self.includes = []
- def dump(self):
- print(self.constructors)
- return self.constructors
- def __getattr__(self, attr):
- if attr.startswith("visit_"):
- return empty
- else:
- raise AttributeError()
- def visit_start(self, tree):
- for t in tree.get_tail():
- self.visit(t)
- def visit_include_files(self, tree):
- self.includes.append(tree.get_children("STRVALUE")[0].get_text())
- def visit_import(self, tree):
- url = tree.get_children("MV_URL")[0]
- target = tree.get_children("MODEL_ID")[0]
- self.constructors.extend(['"import_node"', jsonstr(url.get_text()), jsonstr(target.get_text())])
- def visit_export(self, tree):
- url = tree.get_children("MV_URL")[0]
- target = tree.get_children("MODEL_ID")[0]
- self.constructors.extend(['"export_node"', jsonstr(target.get_text()), jsonstr(url.get_text())])
- def visit_model(self, tree):
- children = tree.get_children("MODEL_ID")
- model_type = children[0].get_text()
- model_name = children[1].get_text()
- self.constructors.extend(['"instantiate_model"', jsonstr(model_type), jsonstr(model_name)])
- self.constructors.extend(['"define_inheritance"', jsonstr(model_name), jsonstr("Inheritance")])
- self.current_model = model_name
- for element in tree.get_children("model_element"):
- self.visit(element)
- def visit_model_element(self, tree):
- children = tree.get_children("MODEL_ID")
- element_type = children[0].get_text()
- if len(children) == 2 or len(children) == 4:
- element_name = children[1].get_text()
- else:
- element_name = "__%s" % self.free_id
- self.free_id += 1
- if len(children) > 2:
- # So we have a source and target; but aren't sure which is which, because the name is optional!
- source_name = children[-2].get_text()
- target_name = children[-1].get_text()
- self.constructors.extend(['"instantiate_link"', jsonstr(self.current_model), jsonstr(element_type), jsonstr(element_name), jsonstr(source_name), jsonstr(target_name)])
- else:
- self.constructors.extend(['"instantiate_node"', jsonstr(self.current_model), jsonstr(element_type), jsonstr(element_name)])
- self.current_element = element_name
-
- for attr in tree.get_children("model_attribute"):
- self.visit(attr)
- def visit_model_attribute(self, tree):
- children = tree.get_children("MODEL_ID")
- is_definition = bool(tree.get_children("COLON"))
- is_constraint = bool(tree.get_children("DOLLAR"))
- is_assign = bool(tree.get_children("model_attr_instance"))
- if is_definition:
- attr_name = children[0].get_text()
- attr_type = children[1].get_text()
- self.constructors.extend(['"instantiate_link"', jsonstr(self.current_model), jsonstr("Association"), jsonstr(self.current_element + "_" + attr_name), jsonstr(self.current_element), jsonstr(attr_type)])
- full_attribute_name = self.current_element + "_" + attr_name
- self.constructors.extend(['"instantiate_attribute"', jsonstr(self.current_model), jsonstr(full_attribute_name), jsonstr("name"), jsonstr(attr_name)])
- if is_assign:
- # There are also some attributes to set!
- old_element = self.current_element
- self.current_element = full_attribute_name
- for f in tree.get_children("model_attr_instance"):
- self.visit(f)
- self.current_element = old_element
- elif is_assign:
- self.visit(tree.get_children("model_attr_instance")[0])
- elif is_constraint:
- constraint = tree.get_children("ANYTHING_EXCEPT_DOLLAR")[0].get_text()
- whitespaces = len(constraint) - len(constraint.lstrip())
- constraint = "\n".join(["\t" + line[whitespaces-1:].replace(" ", "\t") for line in constraint.split("\n") if len(line.strip()) != 0])
- constraint = "".join(["include %s\n" % i for i in self.includes]) + \
- "String function constraint(model : Element, element : String):\n" + \
- "\tElement self\n" + \
- '\tself = model["model"][element]\n' + \
- constraint + "\n"
- with open(".constraint.alc", 'w') as f:
- f.write(constraint)
- f.flush()
- directory = os.path.realpath(__file__).rsplit(os.sep, 1)[0]
- self.constructors.extend(['"add_constraint"', jsonstr(self.current_model), jsonstr(self.current_element)] + do_compile(".constraint.alc", directory + "/../grammars/actionlanguage.g", "CS"))
- def visit_model_attr_instance(self, tree):
- children = tree.get_children("MODEL_ID")
- attr_name = children[0].get_text()
- attr_value = tree.get_children("value")[0]
- self.constructors.extend(['"instantiate_attribute"', jsonstr(self.current_model), jsonstr(self.current_element), jsonstr(attr_name), jsonstr(attr_value.get_text()) if attr_value.head == "STRVALUE" else attr_value.get_text()])
|