import re #from sccd_modelverse_sources.sccd_metamodel import Gen as GenSCCD #from sccd_modelverse_sources.bouncing_tkinter import Gen as GenBBals from mvk.impl.python.constants import CreateConstants, UpdateConstants from mvk.impl.python.datatype import TypeFactory, Type, IntegerType, StringType, \ BooleanType, FloatType from mvk.impl.python.datavalue import MappingValue, \ LocationValue, StringValue, FloatValue, \ IntegerValue, BooleanValue, InfiniteValue, Iterator, AnyValue from mvk.impl.python.object import ClabjectReference, Clabject from mvk.mvk import MvK import mvk from shell import Shell #from sccd_to_xml_rules import XMLRules DEBUG = False def debug_print(_str_): if(DEBUG is False): return print('>>> debug: ' + _str_) class SCCD_to_XML(object): def __init__(self, rules, modelverse=None): self.modelpackage = '' self.modelname = '' self.modelitem = None self.rules = rules self.outputStream = '' self.reset_indentation() # if(modelverse is None): # load default... # self.mvk = MvK() # gmm = GenSCCD() # gmm.mvk = self.mvk # gmm.instance() # gbb = GenBBals() # gbb.mvk = gmm.mvk # gbb.instance() # else: self.mvk = modelverse self.reservedwords = ['@newline', '@indent', '@dedent'] def reset_indentation(self): self.indentation = 0 self.lastnewline = False def increase_indentation(self): self.indentation = self.indentation + 1 def decrease_indentation(self): self.indentation = self.indentation - 1 def getidentstring(self): ntabs = self.indentation outstring = '' while ntabs > 0: outstring = outstring + '\t' ntabs = ntabs - 1 return outstring ## override this to emmit to other outputs def emmitCode(self, string, tabs=False): string = string.replace('\[','{') string = string.replace('\]','}') if tabs is True or self.lastnewline is True: self.write(self.getidentstring() + string) else: self.write(string) self.lastnewline = False def newline(self): self.write('\n') self.lastnewline = True def write(self, string): self.outputStream += string def compile(self, location='MyFormalisms.BouncingBalls'): modelrule = None for key in self.rules: if(self.rules[key]['type'] == 'Model'): modelrule = {'key': key, 'body': self.rules[key]} if modelrule == None: raise Exception('Error: no model rule defined') rl = self.mvk.read(LocationValue(location)) if(not rl.is_success()): raise Exception('Error: Invalid location: ' + location) item = rl.get_item() typename = str(item.typed_by().get_location()) debug_print(typename) self.modelpackage = modelrule['body']['package'] self.modelname = modelrule['body']['name'] self.modelitem = item expectedtype = self.modelpackage + '.' + modelrule['body']['name'] if(typename != expectedtype): raise Exception('Model at specified location is not an ' + expectedtype + ' model!') if(self.isEnabled(modelrule, item)): self.evaluateRule(modelrule, item) def processReserved(self, elem): if(elem == '@newline'): self.newline() elif(elem == '@indent'): self.increase_indentation() elif(elem == '@dedent'): self.decrease_indentation() def evaluateRule(self, rule, item): debug_print('evaluateRule: ' + str(rule)) debug_print('evaluateRule: ' + str(item)) pattern = rule['body']['pattern'] for elem in pattern: if(elem.startswith('@')): if(elem in self.reservedwords): self.processReserved(elem) elif(elem[1:] == '@'): continue ## just ignore mute attributes elif(self.isAttributeIn(elem[1:], item)): self.processAttributeIn(elem[1:], item) elif(elem[1:] in self.rules): self.evaluateIn(elem[1:], item) else: raise Exception(elem + ' not found!') elif(elem.startswith('\@')): self.emmitCode(elem[2:]) else: self.emmitCode(elem) def evaluateRuleOnSet(self, rule, item, list): #debug_print('evaluateRuleOnSet: ' + str(rule)) #debug_print('evaluateRuleOnSet: ' + str(item)) pattern = rule['body']['pattern'] for elem in pattern: if(elem.startswith('@')): if(elem in self.reservedwords): self.processReserved(elem) elif(elem[1:] == '@'): continue ## just ignore mute attributes elif(self.isAttributeIn(elem[1:], item)): self.processAttributeIn(elem[1:], item) elif(elem[1:] in self.rules): for itemlist in list: self.evaluateIn(elem[1:], itemlist) else: raise Exception(elem + ' not found!') elif(elem.startswith('\@')): self.emmitCode(elem[2:]) else: self.emmitCode(elem) def evaluateIn(self, rulename, item): #debug_print('evaluateIn: ' + str(rulename)) #debug_print('evaluateIn: ' + str(item)) rule = {'key': rulename, 'body': self.rules[rulename]} if(not self.isEnabledIn(rulename, item)): return if(rule['body']['type'] == 'Class'): if(isinstance(item, mvk.interfaces.object.Clabject)): self.evaluateRule(rule, item) else: iterator = Iterator(self.modelitem.get_elements().keys()) while(iterator.has_next()): itemin = iterator.next() value = self.modelitem.get_elements()[itemin] #debug_print('item.get_elements()[itemin]: ' + str(value)) if(not isinstance(value, mvk.interfaces.object.Association)): typename = str(value.typed_by().get_location()) if((self.modelpackage + '.' + rule['body']['name']) == typename): self.evaluateRule(rule, value) elif(rule['body']['type'] == 'Association'): #debug_print('Association?') iterator = Iterator(item.out_associations.keys()) alist = [] while(iterator.has_next()): itemin = iterator.next() relvalue = item.out_associations[itemin] #debug_print('item.out_associations[itemin]: ' + str(relvalue)) typename = str(relvalue.typed_by().get_location()) #debug_print('typename: ' + typename) expectedtypename = self.modelpackage + '.' + rule['body']['name'] if(expectedtypename == typename): #debug_print('expectedtypename: ' + expectedtypename) alist.append(relvalue.get_to_multiplicity().get_node()) self.evaluateRuleOnSet(rule, item, alist) else: self.evaluateRule(rule, item) def processAttributeIn(self, elem, item): debug_print('processAttributeIn: ' + elem) reverse = False if(elem.startswith('-')): elem = elem[1:] reverse = True if(elem.startswith('(')): splitres = re.split('\).', elem[1:]) if(len(splitres) == 2): item = self.resolveNavItem(splitres[0], reverse, item) debug_print('setting new item: ' + str(item)) self.processAttributeIn(splitres[1], item) return else: raise Exception('Internal Syntax error on: ' + elem) value = item.get_attribute(StringValue(elem)).get_value() if(isinstance(value,AnyValue)): return self.emmitCode(str(value)) def isEnabledIn(self, rulename, item): #debug_print('isEnabledIn: ' + str(rulename)) #debug_print('isEnabledIn: ' + str(item)) rule = {'key': rulename, 'body': self.rules[rulename]} if(rule['body']['type'] == 'Class'): #debug_print('isEnabledIn: ' + str(rule['body']['name'])) if(isinstance(item, mvk.interfaces.object.Clabject)): if(self.isEnabled(rule, item)): return True else: iterator = Iterator(item.get_elements().keys()) while(iterator.has_next()): itemin = iterator.next() value = item.get_elements()[itemin] if(not isinstance(value, mvk.interfaces.object.Association)): typename = str(value.typed_by().get_location()) if((self.modelpackage + '.' + rule['body']['name']) == typename): if(self.isEnabled(rule, value)): return True elif(rule['body']['type'] == 'Association'): #debug_print('isEnabledIn: ' + str(rule['body']['target'])) iterator = Iterator(item.out_associations.keys()) while(iterator.has_next()): itemin = iterator.next() relvalue = item.out_associations[itemin] typename = str(relvalue.typed_by().get_location()) #debug_print('typename: ' + typename) expectedtypename = self.modelpackage + '.' + rule['body']['name'] #debug_print('expectedtypename: ' + expectedtypename) if(expectedtypename == typename): if(self.isEnabled(rule, relvalue.get_to_multiplicity().get_node())): return True elif(rule['body']['type'] == 'Attribute'): return self.isEnabled(rule, item) return False def hasExpectedType(self, expectedtype, elem): item = elem.typed_by() lastname = re.compile('\w+').findall(str(item.get_location())).pop() if(self.modelname + '.' + lastname == expectedtype): return True iterator = Iterator(item.get_all_super_classes()) while(iterator.has_next()): itemin = iterator.next() lastname = re.compile('\w+').findall(str(itemin.get_location())).pop() if(self.modelname + '.' + lastname == expectedtype): return True return False def isEnabled(self, rule, item): debug_print('isEnabled rule: ' + str(rule)) debug_print('isEnabled item: ' + str(item.typed_by().get_location())) if(rule['body']['type'] == 'Class'): if(not self.hasExpectedType(rule['body']['name'], item)): return False pattern = rule['body']['pattern'] nonterminalFound = False for elem in pattern: if(elem.startswith('@')): if(elem in self.reservedwords): continue if(elem[1:] == '@'): return True elif(self.isAttributeIn(elem[1:], item)): nonterminalFound = True if(self.hasValue(elem[1:], item)): return True elif(elem[1:] in self.rules): nonterminalFound = True if(self.isEnabledIn(elem[1:], item)): return True else: continue return not nonterminalFound def resolveNavItem(self, navexpr, reverse, item): debug_print('resolveNavItem: ' + navexpr) if(isinstance(item, mvk.interfaces.object.Association)): return item if(isinstance(item, mvk.interfaces.object.Clabject)): if(reverse): iterator = Iterator(item.get_in_associations()) else: iterator = Iterator(item.get_out_associations()) debug_print('here!!!!') while(iterator.has_next()): association = iterator.next() name = str(association.get_name()) typename = str(association.typed_by().get_location()) debug_print('name: ' + name) debug_print('typename: ' + typename) if(typename.endswith(navexpr)): if(reverse): return association.get_from_multiplicity().get_node() else: return association.get_to_multiplicity().get_node() raise Exception('Type not found: ' + navexpr) def isAttributeIn(self, elem, item): debug_print('isAttributeIn: ' + elem) debug_print('isAttributeIn item: ' + str(item)) reverse = False if(elem.startswith('-')): elem = elem[1:] reverse = True if(elem.startswith('(')): splitres = re.split('\).', elem[1:]) if(len(splitres) == 2): item = self.resolveNavItem(splitres[0], reverse, item) debug_print('setting new item: ' + str(item)) isattribute = self.isAttributeIn(splitres[1], item) debug_print('was found? ' + str(isattribute)) return isattribute else: raise Exception('Internal Syntax error on: ' + elem) iterator = Iterator(item.get_attributes()) while(iterator.has_next()): attribute = iterator.next() name = str(attribute.get_name()) if(elem == name): return True def hasValue(self, elem, item): debug_print('hasValue: ' + elem + ' in ' + str(item)) reverse = False if(elem.startswith('-')): elem = elem[1:] reverse = True if(elem.startswith('(')): splitres = re.split('\).', elem[1:]) if(len(splitres) == 2): item = self.resolveNavItem(splitres[0], reverse, item) debug_print('setting new item: ' + str(item)) hasValue = self.hasValue(splitres[1], item) debug_print('has value? ' + str(hasValue)) return hasValue else: raise Exception('Internal Syntax error on: ' + elem) value = item.get_attribute(StringValue(elem)).get_value() if(isinstance(value,AnyValue)): return False #debug_print('has indeed a value! on: ' + elem + str(value)) return True def outputTo(self, output='console'): if(output == 'console'): print(self.outputStream) else: fo = open(output, 'a') fo.write(self.outputStream) fo.close() if __name__ == '__main__': pass #compiler = SCCD_to_XML(XMLRules().rules) #compiler.compile() #compiler.outputTo() #shell = Shell() #shell.mvk = compiler.mvk #shell.setupCommandLine()