pygrun 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #!G:\Projects\Electron\AndroidRemoteController\python\py\python.exe
  2. __author__ = 'jszheng'
  3. import optparse
  4. import sys
  5. import os
  6. import importlib
  7. from antlr4 import *
  8. # this is a python version of TestRig
  9. def beautify_lisp_string(in_string):
  10. indent_size = 3
  11. add_indent = ' '*indent_size
  12. out_string = in_string[0] # no indent for 1st (
  13. indent = ''
  14. for i in range(1, len(in_string)):
  15. if in_string[i] == '(' and in_string[i+1] != ' ':
  16. indent += add_indent
  17. out_string += "\n" + indent + '('
  18. elif in_string[i] == ')':
  19. out_string += ')'
  20. if len(indent) > 0:
  21. indent = indent.replace(add_indent, '', 1)
  22. else:
  23. out_string += in_string[i]
  24. return out_string
  25. if __name__ == '__main__':
  26. #############################################################
  27. # parse options
  28. # not support -gui -encoding -ps
  29. #############################################################
  30. usage = "Usage: %prog [options] Grammar_Name Start_Rule"
  31. parser = optparse.OptionParser(usage=usage)
  32. # parser.add_option('-t', '--tree',
  33. # dest="out_file",
  34. # default="default.out",
  35. # help='set output file name',
  36. # )
  37. parser.add_option('-t', '--tree',
  38. default=False,
  39. action='store_true',
  40. help='Print AST tree'
  41. )
  42. parser.add_option('-k', '--tokens',
  43. dest="token",
  44. default=False,
  45. action='store_true',
  46. help='Show Tokens'
  47. )
  48. parser.add_option('-s', '--sll',
  49. dest="sll",
  50. default=False,
  51. action='store_true',
  52. help='Show SLL'
  53. )
  54. parser.add_option('-d', '--diagnostics',
  55. dest="diagnostics",
  56. default=False,
  57. action='store_true',
  58. help='Enable diagnostics error listener'
  59. )
  60. parser.add_option('-a', '--trace',
  61. dest="trace",
  62. default=False,
  63. action='store_true',
  64. help='Enable Trace'
  65. )
  66. options, remainder = parser.parse_args()
  67. if len(remainder) < 2:
  68. print('ERROR: You have to provide at least 2 arguments!')
  69. parser.print_help()
  70. exit(1)
  71. else:
  72. grammar = remainder.pop(0)
  73. start_rule = remainder.pop(0)
  74. file_list = remainder
  75. #############################################################
  76. # check and load antlr generated files
  77. #############################################################
  78. # dynamic load the module and class
  79. lexerName = grammar + 'Lexer'
  80. parserName = grammar + 'Parser'
  81. # check if the generate file exist
  82. lexer_file = lexerName + '.py'
  83. parser_file = parserName + '.py'
  84. if not os.path.exists(lexer_file):
  85. print("[ERROR] Can't find lexer file {}!".format(lexer_file))
  86. print(os.path.realpath('.'))
  87. exit(1)
  88. if not os.path.exists(parser_file):
  89. print("[ERROR] Can't find parser file {}!".format(lexer_file))
  90. print(os.path.realpath('.'))
  91. exit(1)
  92. # current directory is where the generated file loaded
  93. # the script might be in different place.
  94. sys.path.append('.')
  95. # print(sys.path)
  96. # print("Load Lexer {}".format(lexerName))
  97. module_lexer = __import__(lexerName, globals(), locals(), lexerName)
  98. class_lexer = getattr(module_lexer, lexerName)
  99. # print(class_lexer)
  100. # print("Load Parser {}".format(parserName))
  101. module_parser = __import__(parserName, globals(), locals(), parserName)
  102. class_parser = getattr(module_parser, parserName)
  103. # print(class_parser)
  104. #############################################################
  105. # main process steps.
  106. #############################################################
  107. def process(input_stream, class_lexer, class_parser):
  108. lexer = class_lexer(input_stream)
  109. token_stream = CommonTokenStream(lexer)
  110. token_stream.fill()
  111. if options.token: # need to show token
  112. for tok in token_stream.tokens:
  113. print(tok)
  114. if start_rule == 'tokens':
  115. return
  116. parser = class_parser(token_stream)
  117. if options.diagnostics:
  118. parser.addErrorListener(DiagnosticErrorListener())
  119. parser._interp.predictionMode = PredictionMode.LL_EXACT_AMBIG_DETECTION
  120. if options.tree:
  121. parser.buildParseTrees = True
  122. if options.sll:
  123. parser._interp.predictionMode = PredictionMode.SLL
  124. #parser.setTokenStream(token_stream)
  125. parser.setTrace(options.trace)
  126. if hasattr(parser, start_rule):
  127. func_start_rule = getattr(parser, start_rule)
  128. parser_ret = func_start_rule()
  129. if options.tree:
  130. lisp_tree_str = parser_ret.toStringTree(recog=parser)
  131. print(beautify_lisp_string(lisp_tree_str))
  132. else:
  133. print("[ERROR] Can't find start rule '{}' in parser '{}'".format(start_rule, parserName))
  134. #############################################################
  135. # use stdin if not provide file as input stream
  136. #############################################################
  137. if len(file_list) == 0:
  138. input_stream = InputStream(sys.stdin.read())
  139. process(input_stream, class_lexer, class_parser)
  140. exit(0)
  141. #############################################################
  142. # iterate all input file
  143. #############################################################
  144. for file_name in file_list:
  145. if os.path.exists(file_name) and os.path.isfile(file_name):
  146. input_stream = FileStream(file_name)
  147. process(input_stream, class_lexer, class_parser)
  148. else:
  149. print("[ERROR] file {} not exist".format(os.path.normpath(file_name)))