loader.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import os.path
  2. from framework.conformance import Conformance, render_conformance_check_result
  3. from concrete_syntax.textual_od import parser
  4. from transformation.rule import Rule
  5. # parse model and check conformance
  6. def parse_and_check(state, m_cs, mm, descr: str, check_conformance=True, type_transform=lambda type_name: type_name):
  7. try:
  8. m = parser.parse_od(
  9. state,
  10. m_text=m_cs,
  11. mm=mm,
  12. type_transform=type_transform,
  13. )
  14. except Exception as e:
  15. e.add_note("While parsing model " + descr)
  16. raise
  17. try:
  18. if check_conformance:
  19. conf = Conformance(state, m, mm)
  20. errors = conf.check_nominal()
  21. if len(errors) > 0:
  22. print(render_conformance_check_result(errors))
  23. except Exception as e:
  24. e.add_note("In model " + descr)
  25. raise
  26. return m
  27. # get file contents as string
  28. def read_file(filename):
  29. with open(filename) as file:
  30. return file.read()
  31. KINDS = ["nac", "lhs", "rhs"]
  32. # load model transformation rules
  33. def load_rules(state, get_filename, rt_mm_ramified, rule_names, check_conformance=True):
  34. rules = {}
  35. files_read = []
  36. for rule_name in rule_names:
  37. rule = {}
  38. def parse(kind):
  39. filename = get_filename(rule_name, kind)
  40. descr = "'"+filename+"'"
  41. if kind == "nac":
  42. suffix = ""
  43. nacs = []
  44. try:
  45. while True:
  46. base, ext = os.path.splitext(filename)
  47. processed_filename = base+suffix+ext
  48. nac = parse_and_check(state, read_file(processed_filename), rt_mm_ramified, descr, check_conformance)
  49. nacs.append(nac)
  50. suffix = "2" if suffix == "" else str(int(suffix)+1)
  51. files_read.append(processed_filename)
  52. except FileNotFoundError:
  53. if suffix == "":
  54. print(f"Warning: rule {rule_name} has no NAC ({filename} not found)")
  55. return nacs
  56. elif kind == "lhs" or kind == "rhs":
  57. try:
  58. m = parse_and_check(state, read_file(filename), rt_mm_ramified, descr, check_conformance)
  59. files_read.append(filename)
  60. return m
  61. except FileNotFoundError as e:
  62. print(f"Warning: using empty {kind} ({filename} not found)")
  63. # Use empty model as fill-in:
  64. return parse_and_check(
  65. state,
  66. "",
  67. rt_mm_ramified,
  68. descr="'"+filename+"'",
  69. check_conformance=check_conformance)
  70. rules[rule_name] = Rule(*(parse(kind) for kind in KINDS))
  71. print("Rules loaded:\n" + '\n'.join(files_read))
  72. return rules