sccdtnc.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import argparse
  2. import os
  3. #from shell import Shell
  4. from sccd.compiler.generic_generator import GenericGenerator, Platforms
  5. from sccd.compiler.utils import Enum, Logger, FileWriter
  6. from sccd.compiler.generic_language_constructs import GenericConstruct
  7. from sccd.compiler.compiler_exceptions import CompilerException
  8. from sccd.compiler.javascript_writer import JavascriptWriter
  9. from sccd.compiler.python_writer import PythonWriter
  10. from sccd.compiler.super_class_linker import SuperClassLinker
  11. from sccd.compiler.state_linker import StateLinker
  12. from sccd.compiler.path_calculator import PathCalculator
  13. from sccd.compiler.sccd_constructs import ClassDiagram
  14. from sccd_asg_mapper import SCCD_ASG_Mapper
  15. pathname = os.path.dirname(os.path.realpath(__file__))
  16. from sccd_to_xml_JS import XML2JavaScriptRules
  17. from sccd_to_xml_PY import XML2PythonRules
  18. from mvk_loader import MvKLoader
  19. from sccd_to_xml import SCCD_to_XML
  20. def generate(input_file, output_file, target_language, platform):
  21. sccd = xmlToSccd(input_file)
  22. if not target_language:
  23. if sccd.language:
  24. target_language = sccd.language
  25. else:
  26. target_language = "python" # default
  27. elif sccd.language and target_language != sccd.language:
  28. Logger.showError("Diagram specifies target language as \"" + sccd.language + "\", but language option of compiler has been set to \"" + target_language + "\". No output has been generated.")
  29. return
  30. if target_language == "python" and not output_file.endswith(".py") :
  31. output_file += ".py"
  32. elif target_language == "javascript" and not output_file.endswith(".js") :
  33. output_file += ".js"
  34. generic = sccdToGeneric(sccd, platform)
  35. genericToTarget(generic, target_language, output_file)
  36. def xmlToSccd(xml_file):
  37. cd = ClassDiagram(xml_file) # create AST
  38. cd.accept(SuperClassLinker())
  39. #SuperClassLinker().visit(cd) # visitor linking super classs references
  40. StateLinker().visit(cd) # visitor fixing state references
  41. PathCalculator().visit(cd) # visitor calculating paths
  42. return cd
  43. def sccdToGeneric(sccd, platform):
  44. succesfull_generation = False
  45. generator = GenericGenerator(platform)
  46. sccd.accept(generator)
  47. generic = generator.get()
  48. Logger.showInfo("Classes <" + ", ".join(sccd.class_names) + "> have been converted to generic language constructs.")
  49. return generic
  50. def genericToTarget(generic, target_language, output_file):
  51. try:
  52. f = FileWriter(output_file)
  53. if target_language == "javascript":
  54. writer = JavascriptWriter(f)
  55. elif target_language == "python":
  56. writer = PythonWriter(f)
  57. else:
  58. raise Exception("Language not supported")
  59. generic.accept(writer)
  60. Logger.showInfo("Generic language constructs have been converted to target language constructs and have been written to file '" + output_file + "'.")
  61. finally:
  62. f.close()
  63. def main():
  64. mapper = SCCD_ASG_Mapper()
  65. parser = argparse.ArgumentParser()
  66. parser.add_argument('input', help='The path to the XML file to be compiled.')
  67. parser.add_argument('-o', '--output', type=str, help='The path to the generated code. Defaults to the same name as the input file but with matching extension.')
  68. parser.add_argument('-v', '--verbose', type=int, help='2 = all output; 1 = only warnings and errors; 0 = only errors; -1 = no output. Defaults to 2.', default = 2)
  69. parser.add_argument('-p', '--platform', type=str, help="Let the compiled code run on top of threads, gameloop or eventloop. The default is eventloop.")
  70. parser.add_argument('-l', '--language', type=str, help='Target language, either "javascript" or "python". Defaults to the latter.')
  71. #parser.add_argument('-m', '--mvklocation', type=str, help='Location in the Modelverse. After compilation the modelverse shell is opened.')
  72. parser.add_argument('-justxml', dest='justxml', action='store_true')
  73. parser.set_defaults(justxml=False)
  74. args = vars(parser.parse_args())
  75. #Set verbose
  76. if args['verbose'] is not None:
  77. if args['verbose'] in [-1, 0,1,2] :
  78. Logger.verbose = args['verbose']
  79. else :
  80. Logger.showError("Invalid verbose argument.")
  81. else :
  82. Logger.verbose = 2
  83. #Set source file
  84. source = args['input'].lower()
  85. if not source.endswith(".sccd") :
  86. Logger.showError("Input file not valid.")
  87. return
  88. #Set target language
  89. if args['language'] :
  90. target_language = args['language']
  91. else :
  92. target_language = ""
  93. #Set output file
  94. if args['output'] :
  95. output = args['output']
  96. else:
  97. output = os.path.splitext(os.path.split(source)[1])[0]
  98. #Set platform
  99. if args['platform'] :
  100. args['platform'] = args['platform'].lower()
  101. if args['platform'] == "threads" :
  102. platform = Platforms.Threads
  103. elif args['platform'] == "gameloop" :
  104. platform = Platforms.GameLoop
  105. elif args['platform'] == "eventloop" :
  106. platform = Platforms.EventLoop
  107. else :
  108. Logger.showError("Invalid platform.")
  109. return
  110. else :
  111. platform = Platforms.Threads
  112. mvklocation = 'unused_location'
  113. """
  114. if args['mvklocation'] :
  115. mvklocation = args['mvklocation']
  116. modelverseshell = True
  117. else:
  118. mvklocation = 'temporaryLocation'
  119. modelverseshell = False
  120. """
  121. if args['justxml']:
  122. try :
  123. generate(output+'.xml', output, target_language, platform)
  124. except CompilerException as exception :
  125. Logger.showError(str(exception));
  126. return
  127. context = MvKLoader(mapper.rules, mapper.metamodel_location, mapper.metamodel_path, mvklocation).load(source)
  128. if(target_language == "javascript"):
  129. compiler = SCCD_to_XML(XML2JavaScriptRules().rules, context.mvk)
  130. else:
  131. compiler = SCCD_to_XML(XML2PythonRules().rules, context.mvk)
  132. compiler.compile(context.target+'.'+context.modelname)
  133. if os.path.exists(output+'.xml'):
  134. os.remove(output+'.xml')
  135. compiler.outputTo(output+'.xml')
  136. #Compile
  137. try :
  138. generate(output+'.xml', output, target_language, platform)
  139. except CompilerException as exception :
  140. Logger.showError(str(exception));
  141. """
  142. if(modelverseshell):
  143. shell = Shell()
  144. shell.mvk = context.mvk
  145. shell.setupCommandLine()
  146. """
  147. if __name__ == "__main__":
  148. main()