mvk_loader.py 27 KB

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