mvk_loader.py 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. from io import open
  2. import os
  3. import re
  4. import sys
  5. from plyplus import grammars
  6. from plyplus import Grammar
  7. from plyplus.plyplus import TokValue
  8. from plyplus.strees import Str
  9. from plyplus.strees import STree
  10. import copy
  11. import time
  12. from mvk.impl.python.constants import CreateConstants, UpdateConstants
  13. from mvk.impl.python.datatype import TypeFactory, Type, IntegerType, StringType, \
  14. BooleanType, FloatType
  15. from mvk.impl.python.datavalue import MappingValue, \
  16. LocationValue, StringValue, FloatValue, \
  17. IntegerValue, BooleanValue, InfiniteValue, Iterator
  18. from mvk.impl.python.object import ClabjectReference, Clabject
  19. from mvk.mvk import MvK
  20. import mvk
  21. from sccd_asg_mapper import SCCD_ASG_Mapper
  22. pathname = os.path.dirname(os.path.realpath(__file__))
  23. #from shell import Shell
  24. from sccd_modelverse_sources.sccd_metamodel import Gen as GenSCCD
  25. DEBUG = False
  26. JUST_TESTS = False
  27. CALL_TESTS = False
  28. def debug(defname, var):
  29. if(DEBUG is False or var is None):
  30. return
  31. if(var.is_success()):
  32. print('\t' + defname + ': is_success() = True')
  33. else:
  34. print('\t' + defname + ': is_success() = False')
  35. print var.get_status_message()
  36. def debug_print(_str_):
  37. if(DEBUG is False):
  38. return
  39. print(_str_)
  40. def isType(v):
  41. return isinstance(v, Type)
  42. def isStringValue(v):
  43. return (isinstance(v, StringValue) or
  44. isinstance(v, LocationValue) or
  45. isinstance(v, InfiniteValue))
  46. class ClassRepresenter(object):
  47. def __init__(self, name, ident, idlist, parent, body):
  48. self.name = name
  49. self.id = ident
  50. self.children = idlist
  51. self.parent = parent
  52. self.body = body
  53. self.classname = ''
  54. self.super = []
  55. debug_print('elem: ' + self.typestring() + '(' + self.name + ', ' + str(self.id) +') ' +
  56. str(self.children))
  57. def fillDynamicAttributes(self, context):
  58. for key in self.body:
  59. if(isinstance(self.body[key],list)):
  60. self.body.update({
  61. key:context.evaluate_statement(
  62. None,
  63. {'source': self, 'target': self},
  64. self.body[key])}
  65. )
  66. def fillSuperTypes(self, context):
  67. location = context.location + '.' + self.name
  68. rl = context.mvk.read(LocationValue(location))
  69. if(not rl.is_success()):
  70. raise Exception('Invalid location: ' + str(location))
  71. item = rl.get_item()
  72. iterator = Iterator(item.get_all_super_classes())
  73. while(iterator.has_next()):
  74. itemin = iterator.next()
  75. debug_print('storesupertypes: ' + str(itemin.get_location()))
  76. lastname = re.compile('\w+').findall(str(itemin.get_location())).pop()
  77. debug_print('lastname: ' + lastname)
  78. self.super.append(lastname)
  79. def typestring(self):
  80. return 'ClassRepresenter'
  81. def store(self, context, target):
  82. location = context.location + '.' + self.name
  83. self.create(context.mvk, MappingValue({CreateConstants.TYPE_KEY: LocationValue(location),
  84. CreateConstants.LOCATION_KEY: LocationValue(target),
  85. CreateConstants.ATTRS_KEY: MappingValue(
  86. self.buildDict(context.mvk, target, location, self.body)
  87. )}))
  88. key = self.getIdField(context, target, location)
  89. element = target + '.' + str(self.body[key])
  90. self.classname = element
  91. def getNthOfType(self, context, index, typename):
  92. searchid = 0
  93. for childid in self.children:
  94. child = context.get_class_by_id(childid)
  95. if(child.name == typename or typename in child.super):
  96. if(searchid == index):
  97. return childid
  98. else:
  99. searchid += 1
  100. return -1 ## meaning: not found
  101. def getIndexOfChildIdWithType(self, context, ident, typename):
  102. index = 0
  103. for childid in self.children:
  104. child = context.get_class_by_id(childid)
  105. if(child.name == typename or typename in child.super):
  106. if(child.id == ident):
  107. return index
  108. else:
  109. index += 1
  110. return -1 ## meaning: not found
  111. def create(self, modelverse, mv):
  112. self.write_call('create', mv)
  113. if(JUST_TESTS is True):
  114. return None
  115. return modelverse.create(mv)
  116. def getAllAttributes(self, modelverse, typename):
  117. attributes = {}
  118. #debug_print(typename)
  119. lastname = re.compile('\w+').findall(typename).pop()
  120. #debug_print(typename)
  121. cl = modelverse.read(LocationValue(typename))
  122. if(cl.is_success() == False):
  123. raise Exception('getAllAttributes: Object not found: ' + typename)
  124. item = cl.get_item()
  125. iterator = Iterator(item.get_attributes())
  126. while(iterator.has_next()):
  127. attribute = iterator.next()
  128. name = attribute.get_name()
  129. typevalue = attribute.get_type()
  130. attributes.update({str(name): (lastname,str(typevalue))})
  131. if(isinstance(item, mvk.interfaces.object.Clabject)):
  132. iterator = Iterator(item.get_all_super_classes())
  133. while(iterator.has_next()):
  134. itemin = iterator.next()
  135. innerattrs = self.getAllAttributes(modelverse, str(itemin.get_location()))
  136. attributes = dict(innerattrs.items() + attributes.items())
  137. return attributes
  138. def getMvKValue(self, location, attrtype, attrvalue):
  139. ## single types
  140. if(attrtype == 'IntegerType'):
  141. return IntegerValue(int(attrvalue))
  142. if(attrtype == 'FloatType'):
  143. return FloatValue(float(attrvalue))
  144. if(attrtype == 'StringType'):
  145. return StringValue(str(attrvalue))
  146. if(attrtype == 'BooleanType'):
  147. if attrvalue == "True":
  148. return BooleanValue(bool(True))
  149. else:
  150. return BooleanValue(bool(False))
  151. if(attrtype == 'Type'):
  152. return TypeFactory.get_type(str(attrvalue + 'Type'))
  153. return LocationValue(attrvalue)
  154. def buildDict(self, mvk, location, typename, attributes):
  155. attribute_dict = {}
  156. attributes_from_type = self.getAllAttributes(mvk, typename)
  157. for key in attributes:
  158. if(not isinstance(attributes[key],tuple)): ## ignore unparsed values
  159. if(key in attributes_from_type): ## also ignore inexisting keys on type (decoration only)
  160. dict_key = attributes_from_type[key][0] + '.' + key
  161. attribute_dict.update({
  162. StringValue(dict_key)
  163. :
  164. self.getMvKValue(location, attributes_from_type[key][1], attributes[key])
  165. })
  166. return attribute_dict
  167. def write_call(self, name, mv):
  168. if(CALL_TESTS is False):
  169. return
  170. typename = str(mv[CreateConstants.TYPE_KEY])
  171. location = str(mv[CreateConstants.LOCATION_KEY])
  172. attr_it = mv[CreateConstants.ATTRS_KEY].__iter__()
  173. attrs = '\t\t\t\t'
  174. while attr_it.has_next():
  175. k = attr_it.next()
  176. v = mv[CreateConstants.ATTRS_KEY][k]
  177. ktype = k.__class__.__name__
  178. if isStringValue(k):
  179. attrs = attrs + ktype + '(\'' + str(k) + '\'): '
  180. else:
  181. attrs = attrs + ktype + '(' + str(k) + '): '
  182. vtype = v.__class__.__name__
  183. if(isType(v)):
  184. if(isinstance(v, ClabjectReference)):
  185. attrs = attrs + vtype + '(LocationValue(\'' + str(v.get_path()) + '\'))'
  186. else:
  187. if(isinstance(v, Clabject)):
  188. attrs = attrs + str(v)
  189. else:
  190. attrs = attrs + vtype + '()'
  191. else:
  192. if isStringValue(v):
  193. attrs = attrs + vtype + '(\'' + str(v) + '\')'
  194. else:
  195. attrs = attrs + vtype + '(' + str(v) + ')'
  196. if(attr_it.has_next()):
  197. attrs = attrs + ',\n\t\t\t\t'
  198. else:
  199. attrs = attrs + '\n'
  200. p = '\t\tcl = self.mvk.' + name + '(MappingValue({\n'
  201. p = p + '\t\t\tCreateConstants.TYPE_KEY: LocationValue(\'' + typename + '\'),\n'
  202. p = p + '\t\t\tCreateConstants.LOCATION_KEY: LocationValue(\'' + location + '\'),\n'
  203. p = p + '\t\t\tCreateConstants.ATTRS_KEY: MappingValue({\n'
  204. p = p + attrs
  205. p = p + '\t\t\t})\n'
  206. p = p + '\t\t}))\n'
  207. p = p + '\t\tif(cl.is_success()):\n'
  208. p = p + '\t\t\tprint(\'\\t: cl.is_success() = True\')\n'
  209. p = p + '\t\telse:\n'
  210. p = p + '\t\t\tprint(\'\\t: cl.is_success() = False\')\n'
  211. p = p + '\t\t\tprint(cl.get_status_message())\n'
  212. print p
  213. def resolveTypename(self, context, location, typename):
  214. rl = context.mvk.read(LocationValue(typename))
  215. if(not rl is None and not rl.is_success()):
  216. prevtypename = typename
  217. while(True):
  218. rl = context.mvk.read(LocationValue(location))
  219. if(not rl.is_success()):
  220. raise RuntimeError('Location ' + location + ' not found while resolving typename: ' + prevtypename)
  221. if(isinstance(rl.get_item(), mvk.interfaces.object.Model)):
  222. typename = str(rl.get_item().typed_by().get_path()) + '.' + typename
  223. break
  224. else:
  225. tmploc = re.compile('\w+').findall(location)
  226. tmploc.pop()
  227. if(len(tmploc) == 0):
  228. typename = location + '.' + typename
  229. break
  230. else:
  231. location = '.'.join(tmploc)
  232. rl = context.mvk.read(LocationValue(typename))
  233. if(not rl.is_success()):
  234. raise RuntimeError('Type not found: ' + prevtypename)
  235. return typename
  236. def getIdField(self, context, location, typename):
  237. typename = self.resolveTypename(context, location, typename)
  238. rl = context.mvk.read(LocationValue(typename))
  239. try:
  240. id_field = str(rl.get_item().get_attribute(StringValue('Class.id_field')).get_value())
  241. #debug_print('IDFIELD: ' + id_field)
  242. id_field = re.compile('\w+').findall(id_field).pop()
  243. return id_field
  244. except Exception:
  245. #debug_print('default IDFIELD: name')
  246. return 'name'
  247. class ModelRepresenter(ClassRepresenter):
  248. def __init__(self, name, ident, idlist, body):
  249. self.name = name
  250. self.id = self.parent = ident
  251. self.children = idlist
  252. self.body = body
  253. self.modelname = ''
  254. self.super = []
  255. def typestring(self):
  256. return 'ModelRepresenter'
  257. def store(self, context, target):
  258. location = context.location
  259. self.create(context.mvk, MappingValue({CreateConstants.TYPE_KEY: LocationValue(location),
  260. CreateConstants.LOCATION_KEY: LocationValue(target),
  261. CreateConstants.ATTRS_KEY: MappingValue(
  262. self.buildDict(context.mvk, target, location, self.body)
  263. )}))
  264. key = self.getIdField(context, target, location)
  265. self.modelname = str(self.body[key])
  266. class AssociationRepresenter(ClassRepresenter):
  267. def __init__(self, name, body, fromid, toid):
  268. self.name = name
  269. self.body = body
  270. self.id = self.parent = 0
  271. self.children = []
  272. self.super = []
  273. self.from_node = fromid
  274. self.to_node = toid
  275. def typestring(self):
  276. return 'AssociationRepresenter'
  277. def resolveIds(self, ctx):
  278. self.from_node = ctx.get_class_by_id(self.from_node).classname
  279. self.to_node = ctx.get_class_by_id(self.to_node).classname
  280. def store(self, context, target):
  281. location = context.location + '.' + self.name
  282. values = self.buildDict(context.mvk, target, location, self.body)
  283. rl = context.mvk.read(LocationValue(location))
  284. from_port_name = str(rl.get_item().get_attribute(
  285. StringValue('Association.from_port')).get_value())
  286. #debug_print('from_port_name: ' + from_port_name)
  287. #debug_print('self.from_node: ' + str(self.from_node))
  288. values.update({
  289. StringValue(from_port_name)
  290. :
  291. LocationValue(self.from_node)
  292. })
  293. to_port_name = str(rl.get_item().get_attribute(
  294. StringValue('Association.to_port')).get_value())
  295. #debug_print('to_port: ' + to_port_name)
  296. values.update({
  297. StringValue(to_port_name)
  298. :
  299. LocationValue(self.to_node)
  300. })
  301. self.create(context.mvk, MappingValue({CreateConstants.TYPE_KEY: LocationValue(location),
  302. CreateConstants.LOCATION_KEY: LocationValue(target),
  303. CreateConstants.ATTRS_KEY: MappingValue(values)}))
  304. ####################################################################################
  305. class Context(object):
  306. def __init__(self, location, rules, target):
  307. self.mvk = MvK()
  308. self.treemarker = []
  309. self.idtable = {}
  310. self.pivots = []
  311. self.asg = []
  312. self.location = location
  313. self.target = target
  314. self.modelname = ''
  315. self.modelrules = {}
  316. self.classrules = {}
  317. self.assocrules = {}
  318. for rulename in rules:
  319. if(rules[rulename]['type'] == 'Model'):
  320. self.modelrules.update({rulename:rules[rulename]})
  321. elif(rules[rulename]['type'] == 'Class'):
  322. self.classrules.update({rulename:rules[rulename]})
  323. elif(rules[rulename]['type'] == 'Association'):
  324. self.assocrules.update({rulename:rules[rulename]})
  325. def getctx(self):
  326. retstr = ''
  327. first = True
  328. for elem in self.treemarker:
  329. if first:
  330. retstr = elem
  331. first = False
  332. else:
  333. retstr += '.' + elem
  334. return retstr
  335. def addTreePath(self, item):
  336. self.treemarker.append(item)
  337. def popTreePath(self):
  338. self.treemarker.pop()
  339. def get_class_by_id(self, ident):
  340. return self.idtable[ident]
  341. def getChildElemsofType(self, elemtype, child_list):
  342. elems = []
  343. for ident in child_list:
  344. elem = self.get_class_by_id(ident)
  345. if(isinstance(elem, ClassRepresenter)):
  346. #debug_print('searching ' + elemtype + ' of type ' + elem.name + ' in ' + str(elem.super))
  347. if(elem.name == elemtype or elemtype in elem.super):
  348. #debug_print('matchlist: ' + elem.classname)
  349. elems.append(elem)
  350. return elems
  351. def betweenChildren(self, rule, child_list):
  352. lelems = self.getChildElemsofType(rule['source']['type'], child_list)
  353. if lelems == []:
  354. return
  355. #debug_print('source elems: ' + str(len(lelems)))
  356. relems = self.getChildElemsofType(rule['target']['type'], child_list)
  357. if relems == []:
  358. return
  359. #debug_print('target elems: ' + str(len(relems)))
  360. self.crossProduct(rule, lelems, relems)
  361. def processChildren(self, this_id, child_list):
  362. for rulename in self.assocrules:
  363. debug_print('running rule: ' + str(rulename))
  364. rule = self.assocrules[rulename]
  365. self.betweenChildren(rule, child_list)
  366. self.betweenParentsAndChildren(rule, this_id, child_list)
  367. def betweenParentsAndChildren(self, rule, this_id, child_list):
  368. lelems = self.getChildElemsofType(rule['source']['type'], [this_id])
  369. if lelems == []:
  370. return
  371. #debug_print('source elems: ' + str(len(lelems)))
  372. relems = self.getChildElemsofType(rule['target']['type'], child_list)
  373. if relems == []:
  374. return
  375. #debug_print('target elems: ' + str(len(relems)))
  376. self.crossProduct(rule, lelems, relems)
  377. def crossProduct(self, rule, lelems, relems):
  378. for elem1 in lelems:
  379. for elem2 in relems:
  380. if(elem1.id != elem2.id):
  381. if(self.evaluate_condition(rule,
  382. {'source':elem1, 'target':elem2})):
  383. self.applyrelation(rule,
  384. {'source':elem1, 'target':elem2})
  385. def processNonAST(self):
  386. for rulename in self.assocrules:
  387. rule = self.assocrules[rulename]
  388. if(rule['condition'][0] != 'equals'):
  389. continue
  390. debug_print('running rule: ' + str(rulename))
  391. lelems = getElemsofType(self, rule['source']['type'])
  392. if lelems == []:
  393. continue
  394. relems = getElemsofType(self, rule['target']['type'])
  395. if relems == []:
  396. continue
  397. self.crossProduct(rule, lelems, relems)
  398. def evaluate_condition(self, rule, elems):
  399. f = getattr(self, 'eval_' + rule['condition'][0], None)
  400. if f:
  401. return f(rule, elems)
  402. else:
  403. raise Exception('Internal error.')
  404. def getLeftRight(self, rule, elems):
  405. condition = rule['condition']
  406. leftelem = rightelem = None
  407. if(not str(condition[1]).startswith('@') or
  408. not str(condition[2]).startswith('@')):
  409. raise Exception('Can only be applied to identifiers with @: ' +
  410. str(condition[1]) + ', ' + str(condition[2]))
  411. if(rule['source']['name'] == condition[1][1:]):
  412. leftelem = elems['source']
  413. elif(rule['target']['name'] == condition[1][1:]):
  414. leftelem = elems['target']
  415. else:
  416. raise Exception('Name not found: ' + condition[1][1:])
  417. if(rule['source']['name'] == condition[2][1:]):
  418. rightelem = elems['source']
  419. elif(rule['target']['name'] == condition[2][1:]):
  420. rightelem = elems['target']
  421. else:
  422. raise Exception('Name not found: ' + condition[2][1:])
  423. debug_print('left: ' + str(leftelem.id) + ' right: ' + str(rightelem.id))
  424. return { 'left': leftelem, 'right': rightelem }
  425. def eval_first(self, rule, elems):
  426. debug_print('condition: ' + str(rule['condition']))
  427. debug_print('elems: ' + str(elems))
  428. leftright = self.getLeftRight(rule, elems)
  429. left = self.get_class_by_id(leftright['left'].id)
  430. debug_print('completelist: ' + str(left.children))
  431. searchid = left.getNthOfType(self, 0, rule['target']['type'])
  432. #debug_print('searched for: ' + rule['target']['type'] + ' and found: ' + str(searchid))
  433. return searchid == leftright['right'].id
  434. def eval_second(self, rule, elems):
  435. #debug_print('condition: ' + str(rule['condition']))
  436. #debug_print('elems: ' + str(elems))
  437. leftright = self.getLeftRight(rule, elems)
  438. left = self.get_class_by_id(leftright['left'].id)
  439. #debug_print('completelist: ' + str(left.children))
  440. searchid = left.getNthOfType(self, 1, rule['target']['type'])
  441. debug_print('searched for: ' + rule['target']['type'] + ' and found: ' + str(searchid))
  442. return searchid == leftright['right'].id
  443. def eval_nextTo(self, rule, elems):
  444. #debug_print('condition: ' + str(rule['condition']))
  445. #debug_print('elems: ' + str(elems))
  446. leftright = self.getLeftRight(rule, elems)
  447. leftparent = self.get_class_by_id(leftright['left'].parent)
  448. rightparent = self.get_class_by_id(leftright['right'].parent)
  449. if(leftparent != rightparent):
  450. return False
  451. leftindex = leftparent.getIndexOfChildIdWithType(
  452. self, leftright['left'].id, rule['source']['type'])
  453. #debug_print('searched for: ' + rule['source']['type'] + ' on id ' +
  454. #str(leftright['left'].id) + ' and found: ' + str(leftindex))
  455. leftindex += 1
  456. rightindex = leftparent.getIndexOfChildIdWithType(
  457. self, leftright['right'].id, rule['target']['type'])
  458. #debug_print('searched for: ' + rule['target']['type'] + ' on id ' +
  459. #str(leftright['right'].id) + ' and found: ' + str(rightindex))
  460. #debug_print('completelist: ' + str(leftparent.children))
  461. return rightindex == leftindex
  462. def eval_direct(self, rule, elems):
  463. leftright = self.getLeftRight(rule, elems)
  464. return leftright['right'].id in leftright['left'].children
  465. def eval_equals(self, rule, elems):
  466. left = right = ''
  467. condition = rule['condition']
  468. leftvalue = condition[1]
  469. left = self.eval_atom(rule, elems, leftvalue)
  470. rightvalue = condition[2]
  471. right = self.eval_atom(rule, elems, rightvalue)
  472. return left == right
  473. def eval_atom(self, rule, elems, value):
  474. if(value.startswith('@')):
  475. expr = re.compile('\w+').findall(value[1:])
  476. varname = expr[0]
  477. elem = None
  478. if(rule['source']['name'] == varname):
  479. elem = elems['source']
  480. elif(rule['target']['name'] == varname):
  481. elem = elems['target']
  482. else:
  483. raise Exception('Name not found: ' + varname)
  484. if(len(expr) == 1):
  485. #debug_print('eval_atom value 1: ' + value + ' ' + str(elem.id))
  486. return elem.id
  487. elif(len(expr) == 2):
  488. #debug_print('eval_atom value 2: ' + value + ' ' + str(elem.body[expr[1]]))
  489. return elem.body[expr[1]]
  490. else:
  491. raise Exception('Access error: ' + value[1:])
  492. else:
  493. return value
  494. def applyrelation(self, rule, elems):
  495. #debug_print('applyrelation: ' + str(elems))
  496. relname = rule['name']
  497. body = copy.deepcopy(rule['body'])
  498. for key in body:
  499. if isinstance(body[key],str):
  500. body.update({key:self.eval_atom(rule, elems, body[key])})
  501. elif isinstance(body[key],list):
  502. body.update({key:self.evaluate_statement(rule, elems, body[key])})
  503. elem = AssociationRepresenter(relname, body,elems['source'].id, elems['target'].id)
  504. self.asg.append(elem)
  505. def evaluate_statement(self, rule, elems, statement):
  506. f = getattr(self, 'eval_' + statement[0], None)
  507. if f:
  508. return f(rule, elems, statement)
  509. else:
  510. raise Exception('Internal error.')
  511. def eval_getNodeId(self, rule, elems, statement):
  512. return str(elems['source'].id)
  513. def eval_concat(self, rule, elems, statement):
  514. #debug_print('eval_concat')
  515. leftvalue = statement[1]
  516. rightvalue = statement[2]
  517. #debug_print('leftvalue ' + str(leftvalue))
  518. #debug_print('rightvalue ' + str(rightvalue))
  519. if(isinstance(leftvalue, str)):
  520. left = self.eval_atom(rule, elems, leftvalue)
  521. elif(isinstance(leftvalue,list)):
  522. left = self.evaluate_statement(rule, elems, leftvalue)
  523. else:
  524. Exception('Internal error: ' + leftvalue)
  525. if(isinstance(rightvalue, str)):
  526. right = self.eval_atom(rule, elems, rightvalue)
  527. elif(isinstance(rightvalue,list)):
  528. right = self.evaluate_statement(rule, elems, rightvalue)
  529. else:
  530. Exception('Internal error: ' + rightvalue)
  531. #debug_print('right ' + right)
  532. return left + right
  533. def getElemsofType(context, elemtype):
  534. elems = []
  535. for elem in context.asg:
  536. if(isinstance(elem, ClassRepresenter)):
  537. #debug_print('searching ' + elemtype + ' of type ' + elem.name + ' in ' + str(elem.super))
  538. if(elem.name == elemtype or elemtype in elem.super):
  539. #debug_print('matchlist: ' + elem.classname)
  540. elems.append(elem)
  541. return elems
  542. ####################################################################################
  543. class MvKLoader(object):
  544. def __init__(self, rules, location, path, targetlocation):
  545. self.idx = 0 ## tree node identifier
  546. self.rules = rules
  547. self.location = location
  548. self.path = path
  549. self.targetlocation = targetlocation
  550. def getNextId(self):
  551. self.idx += 1
  552. return self.idx
  553. def istok(self, item):
  554. if(isinstance(item, TokValue)):
  555. return True
  556. elif(isinstance(item, unicode)):
  557. return True
  558. return False
  559. def visit(self, context, tree, parent_id=0):
  560. #debug_print('visit with parent: ' + str(parent_id))
  561. this_id = -1
  562. child_idlist = []
  563. if (tree == None or self.istok(tree)):
  564. return {'this_id': -1, 'children': []}
  565. context.addTreePath(tree.head)
  566. if(self.activaterules(context)):
  567. this_id = self.getNextId()
  568. #debug_print(tree.head + ' activated with new id: ' + str(this_id))
  569. else:
  570. this_id = parent_id
  571. #debug_print(tree.head + ' not activated so id is ' + str(parent_id))
  572. if(not self.matchattr(context, tree)):
  573. for elem in tree.tail:
  574. visitvalue = self.visit(context, elem, this_id)
  575. child_id = visitvalue['this_id']
  576. innerlist = visitvalue['children']
  577. if(child_id == -1):
  578. continue
  579. #debug_print('innerchildren are: ' + str(innerlist)
  580. # + ' from element: ' + str(child_id))
  581. if(child_id == this_id): ## my children are your children..
  582. #debug_print('\t\tpassing around children.. to parent ' + str(parent_id))
  583. #debug_print('we still in element: ' + str(this_id))
  584. for elem in innerlist:
  585. if(not elem in child_idlist):
  586. child_idlist.append(elem)
  587. else:
  588. if(not child_id in child_idlist):
  589. child_idlist.append(child_id)
  590. #debug_print('we keep this: ' + str(child_id))
  591. #debug_print('but we lose even more... ' + str(innerlist))
  592. value = {'this_id': this_id, 'children': child_idlist}
  593. #debug_print('\t\t\tbailing out: ' + str(value))
  594. self.deactivaterules(context, this_id, child_idlist, parent_id)
  595. context.popTreePath()
  596. return value
  597. def matchattr(self, context, tree):
  598. for elem in context.pivots:
  599. for key in elem[1]['body']:
  600. attr = elem[1]['body'][key]
  601. if(not isinstance(attr,tuple)):
  602. continue # its already set..
  603. if(context.getctx().endswith('.' + attr[0])):
  604. #debug_print('context.getctx(): ' + context.getctx() + ' ends with elem ' + attr[0])
  605. #debug_print('btw the whole attr ' + str(attr))
  606. value = self.getAsValue(tree)
  607. if(value[0] == '\'' and value[len(value)-1] == '\''):
  608. value = value[1:-1]
  609. elif(value[0] == '\"' and value[len(value)-1] == '\"'):
  610. value = value[1:-1]
  611. #debug_print('prevkey ' + str(elem[1]['body'][key]))
  612. elem[1]['body'].update({key: value})
  613. #debug_print('newkey ' + str(elem[1]['body'][key]))
  614. return True
  615. return False
  616. def getAsValue(self, tree):
  617. value = ''
  618. for elem in tree.tail:
  619. if(not self.istok(elem)):
  620. value += self.getAsValue(elem)
  621. else:
  622. value += str(elem)
  623. return value
  624. def activaterules(self, context):
  625. activated = False
  626. for elem in self.rules: ## cycle in rules
  627. ## only applies to model and class rules
  628. if(self.rules[elem]['type'] != 'Association'):
  629. if(context.getctx().endswith('.' + elem)):
  630. context.pivots.insert(0,(elem,copy.deepcopy(self.rules[elem])))
  631. activated = True
  632. return activated
  633. def deactivaterules(self, context, this_id, child_idlist, parent_id):
  634. for elem in context.pivots: ## cycle in pivots
  635. if(context.getctx().endswith('.' + elem[0])):
  636. if(elem[1]['type'] == 'Model'):
  637. mr = ModelRepresenter(elem[1]['name'], this_id, child_idlist, elem[1]['body'])
  638. context.idtable.update({this_id:mr})
  639. context.modelname = mr.modelname
  640. context.asg.append(mr)
  641. context.pivots.remove(elem)
  642. return
  643. elif(elem[1]['type'] == 'Class'):
  644. cr = ClassRepresenter(elem[1]['name'], this_id, child_idlist, parent_id, elem[1]['body'])
  645. context.idtable.update({this_id:cr})
  646. context.asg.append(cr)
  647. cr.fillDynamicAttributes(context)
  648. cr.fillSuperTypes(context)
  649. context.processChildren(this_id, child_idlist)
  650. context.pivots.remove(elem)
  651. return
  652. def load(self, path='sccd_examples/bouncing_tkinter.sccd'):
  653. grammarname = 'sccd_grammar.g'
  654. grammar = Grammar(grammars.open(os.path.join(pathname, grammarname)), auto_filter_tokens=False)
  655. sentence = grammar.parse(_read(path))
  656. debug_print(sentence.pretty())
  657. debug_print('loading precompiled sccd metamodel on the mvk...')
  658. start = time.clock()
  659. ctx = Context(self.location, self.rules, self.targetlocation)
  660. gmm = GenSCCD()
  661. gmm.mvk = ctx.mvk
  662. gmm.instance()
  663. tick1 = time.clock()
  664. debug_print('done after: %.2gs' % (tick1-start))
  665. debug_print('processing classes and topological relations...')
  666. self.visit(ctx, sentence)
  667. tick2 = time.clock()
  668. debug_print('done after: %.2gs' % (tick2-tick1))
  669. # get model: we assume only one model can be generated from this tree
  670. # virtually we could have more, but then we have to define a new notion of scope
  671. for elem in ctx.asg:
  672. if(elem.typestring() == 'ModelRepresenter'):
  673. elem.store(ctx, self.targetlocation)
  674. ctx.modelname = elem.modelname
  675. break
  676. debug_print('storing classes on the mvk...')
  677. for elem in ctx.asg:
  678. if(elem.typestring() == 'ClassRepresenter'):
  679. elem.store(ctx, self.targetlocation + '.' + ctx.modelname)
  680. tick3 = time.clock()
  681. debug_print('done after: %.2gs' % (tick3-tick2))
  682. debug_print('processing non topological relations...')
  683. ctx.processNonAST()
  684. tick4 = time.clock()
  685. debug_print('done after: %.2gs' % (tick4-tick3))
  686. debug_print('storing all relations on the mvk...')
  687. for elem in ctx.asg:
  688. if(elem.typestring() == 'AssociationRepresenter'):
  689. elem.resolveIds(ctx)
  690. elem.store(ctx, self.targetlocation + '.' + ctx.modelname)
  691. tick5 = time.clock()
  692. debug_print('done after: %.2gs' % (tick5-tick4))
  693. return ctx
  694. def debugasg(self, ctx):
  695. if(DEBUG is False):
  696. return
  697. for elem in ctx.asg:
  698. print(str(elem.id) + ', ' + str(elem.children) + ', ')
  699. print(str(elem.name) + ', ')
  700. printdic(elem.body)
  701. print(ctx.pivots)
  702. ###############################################################################
  703. def printdic(dict):
  704. print('{')
  705. for elem in dict:
  706. print(str(elem) + ': ' + str(dict[elem]) + ', ')
  707. print('}')
  708. def _read(n, *args):
  709. kwargs = {'encoding': 'utf-8'}
  710. with open(os.path.join(os.getcwd(), n), *args, **kwargs) as f:
  711. return f.read()
  712. """
  713. if __name__ == '__main__':
  714. mapper = SCCD_ASG_Mapper()
  715. if(len(sys.argv) > 1):
  716. script = sys.argv[1]
  717. packagename = sys.argv[2]
  718. context = MvKLoader(mapper.rules, mapper.metamodel_location, mapper.metamodel_path, packagename).load(script)
  719. else: # call the default one
  720. context = MvKLoader(mapper.rules, mapper.metamodel_location, mapper.metamodel_path, 'MyFormalisms').load()
  721. shell = Shell()
  722. shell.mvk = context.mvk
  723. shell.setupCommandLine()
  724. """