sccdc.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import argparse
  2. import os
  3. import sys
  4. from generic_generator import GenericGenerator, Platforms
  5. from utils import Enum, Logger, FileWriter
  6. from super_class_linker import SuperClassLinker
  7. from state_linker import StateLinker
  8. from path_calculator import PathCalculator
  9. from sccd_constructs import ClassDiagram
  10. from generic_language_constructs import GenericConstruct
  11. from compiler_exceptions import CompilerException
  12. from javascript_writer import JavascriptWriter
  13. from python_writer import PythonWriter
  14. def generate(input_file, output_file, target_language, platform):
  15. sccd = xmlToSccd(input_file)
  16. if not target_language:
  17. if sccd.language:
  18. target_language = sccd.language
  19. else:
  20. target_language = "python" # default
  21. elif sccd.language and target_language != sccd.language:
  22. 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.")
  23. return
  24. if target_language == "python" and not output_file.endswith(".py") :
  25. output_file += ".py"
  26. elif target_language == "javascript" and not output_file.endswith(".js") :
  27. output_file += ".js"
  28. generic = sccdToGeneric(sccd, platform)
  29. genericToTarget(generic, target_language, output_file)
  30. def xmlToSccd(xml_file):
  31. cd = ClassDiagram(xml_file) # create AST
  32. cd.accept(SuperClassLinker())
  33. #SuperClassLinker().visit(cd) # visitor linking super classs references
  34. StateLinker().visit(cd) # visitor fixing state references
  35. PathCalculator().visit(cd) # visitor calculating paths
  36. return cd
  37. def sccdToGeneric(sccd, platform):
  38. succesfull_generation = False
  39. generator = GenericGenerator(platform)
  40. sccd.accept(generator)
  41. generic = generator.get()
  42. Logger.showInfo("Classes <" + ", ".join(sccd.class_names) + "> have been converted to generic language constructs.")
  43. return generic
  44. def genericToTarget(generic, target_language, output_file):
  45. try:
  46. f = FileWriter(output_file)
  47. if target_language == "javascript":
  48. writer = JavascriptWriter(f)
  49. elif target_language == "python":
  50. writer = PythonWriter(f)
  51. else:
  52. raise Exception("Language not supported")
  53. generic.accept(writer)
  54. Logger.showInfo("Generic language constructs have been converted to target language constructs and have been written to file '" + output_file + "'.")
  55. finally:
  56. f.close()
  57. def main():
  58. parser = argparse.ArgumentParser()
  59. parser.add_argument('input', help='The path to the XML file to be compiled.')
  60. 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.')
  61. 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)
  62. parser.add_argument('-p', '--platform', type=str, help="Let the compiled code run on top of threads, gameloop or eventloop. The default is eventloop.")
  63. parser.add_argument('-l', '--language', type=str, help='Target language, either "javascript" or "python". Defaults to the latter.')
  64. args = vars(parser.parse_args())
  65. #Set verbose
  66. if args['verbose'] is not None:
  67. if args['verbose'] in [-1, 0,1,2] :
  68. Logger.verbose = args['verbose']
  69. else :
  70. Logger.showError("Invalid verbose argument.")
  71. else :
  72. Logger.verbose = 2
  73. #Set source file
  74. source = args['input']
  75. if not source.endswith(".xml") :
  76. Logger.showError("Input file not valid.")
  77. return
  78. #Set target language
  79. if args['language'] :
  80. target_language = args['language']
  81. else :
  82. target_language = ""
  83. #Set output file
  84. if args['output'] :
  85. output = args['output']
  86. else:
  87. output = os.path.splitext(os.path.split(source)[1])[0]
  88. #Set platform
  89. if args['platform'] :
  90. args['platform'] = args['platform'].lower()
  91. if args['platform'] == "threads" :
  92. platform = Platforms.Threads
  93. elif args['platform'] == "gameloop" :
  94. platform = Platforms.GameLoop
  95. elif args['platform'] == "eventloop" :
  96. platform = Platforms.EventLoop
  97. else :
  98. Logger.showError("Invalid platform.")
  99. return
  100. else :
  101. platform = Platforms.EventLoop
  102. #Compile
  103. try :
  104. generate(source, output, target_language, platform)
  105. except CompilerException as exception :
  106. Logger.showError(str(exception));
  107. return 1
  108. return 0
  109. if __name__ == "__main__":
  110. sys.exit(main())