Spaces:
Paused
Paused
| #!E:\StoryD\StoryDiffusion\myenv\Scripts\python.exe | |
| __author__ = 'jszheng' | |
| import optparse | |
| import sys | |
| import os | |
| import importlib | |
| from antlr4 import * | |
| # this is a python version of TestRig | |
| def beautify_lisp_string(in_string): | |
| indent_size = 3 | |
| add_indent = ' '*indent_size | |
| out_string = in_string[0] # no indent for 1st ( | |
| indent = '' | |
| for i in range(1, len(in_string)): | |
| if in_string[i] == '(' and in_string[i+1] != ' ': | |
| indent += add_indent | |
| out_string += "\n" + indent + '(' | |
| elif in_string[i] == ')': | |
| out_string += ')' | |
| if len(indent) > 0: | |
| indent = indent.replace(add_indent, '', 1) | |
| else: | |
| out_string += in_string[i] | |
| return out_string | |
| if __name__ == '__main__': | |
| ############################################################# | |
| # parse options | |
| # not support -gui -encoding -ps | |
| ############################################################# | |
| usage = "Usage: %prog [options] Grammar_Name Start_Rule" | |
| parser = optparse.OptionParser(usage=usage) | |
| # parser.add_option('-t', '--tree', | |
| # dest="out_file", | |
| # default="default.out", | |
| # help='set output file name', | |
| # ) | |
| parser.add_option('-t', '--tree', | |
| default=False, | |
| action='store_true', | |
| help='Print AST tree' | |
| ) | |
| parser.add_option('-k', '--tokens', | |
| dest="token", | |
| default=False, | |
| action='store_true', | |
| help='Show Tokens' | |
| ) | |
| parser.add_option('-s', '--sll', | |
| dest="sll", | |
| default=False, | |
| action='store_true', | |
| help='Show SLL' | |
| ) | |
| parser.add_option('-d', '--diagnostics', | |
| dest="diagnostics", | |
| default=False, | |
| action='store_true', | |
| help='Enable diagnostics error listener' | |
| ) | |
| parser.add_option('-a', '--trace', | |
| dest="trace", | |
| default=False, | |
| action='store_true', | |
| help='Enable Trace' | |
| ) | |
| options, remainder = parser.parse_args() | |
| if len(remainder) < 2: | |
| print('ERROR: You have to provide at least 2 arguments!') | |
| parser.print_help() | |
| exit(1) | |
| else: | |
| grammar = remainder.pop(0) | |
| start_rule = remainder.pop(0) | |
| file_list = remainder | |
| ############################################################# | |
| # check and load antlr generated files | |
| ############################################################# | |
| # dynamic load the module and class | |
| lexerName = grammar + 'Lexer' | |
| parserName = grammar + 'Parser' | |
| # check if the generate file exist | |
| lexer_file = lexerName + '.py' | |
| parser_file = parserName + '.py' | |
| if not os.path.exists(lexer_file): | |
| print("[ERROR] Can't find lexer file {}!".format(lexer_file)) | |
| print(os.path.realpath('.')) | |
| exit(1) | |
| if not os.path.exists(parser_file): | |
| print("[ERROR] Can't find parser file {}!".format(lexer_file)) | |
| print(os.path.realpath('.')) | |
| exit(1) | |
| # current directory is where the generated file loaded | |
| # the script might be in different place. | |
| sys.path.append('.') | |
| # print(sys.path) | |
| # print("Load Lexer {}".format(lexerName)) | |
| module_lexer = __import__(lexerName, globals(), locals(), lexerName) | |
| class_lexer = getattr(module_lexer, lexerName) | |
| # print(class_lexer) | |
| # print("Load Parser {}".format(parserName)) | |
| module_parser = __import__(parserName, globals(), locals(), parserName) | |
| class_parser = getattr(module_parser, parserName) | |
| # print(class_parser) | |
| ############################################################# | |
| # main process steps. | |
| ############################################################# | |
| def process(input_stream, class_lexer, class_parser): | |
| lexer = class_lexer(input_stream) | |
| token_stream = CommonTokenStream(lexer) | |
| token_stream.fill() | |
| if options.token: # need to show token | |
| for tok in token_stream.tokens: | |
| print(tok) | |
| if start_rule == 'tokens': | |
| return | |
| parser = class_parser(token_stream) | |
| if options.diagnostics: | |
| parser.addErrorListener(DiagnosticErrorListener()) | |
| parser._interp.predictionMode = PredictionMode.LL_EXACT_AMBIG_DETECTION | |
| if options.tree: | |
| parser.buildParseTrees = True | |
| if options.sll: | |
| parser._interp.predictionMode = PredictionMode.SLL | |
| #parser.setTokenStream(token_stream) | |
| parser.setTrace(options.trace) | |
| if hasattr(parser, start_rule): | |
| func_start_rule = getattr(parser, start_rule) | |
| parser_ret = func_start_rule() | |
| if options.tree: | |
| lisp_tree_str = parser_ret.toStringTree(recog=parser) | |
| print(beautify_lisp_string(lisp_tree_str)) | |
| else: | |
| print("[ERROR] Can't find start rule '{}' in parser '{}'".format(start_rule, parserName)) | |
| ############################################################# | |
| # use stdin if not provide file as input stream | |
| ############################################################# | |
| if len(file_list) == 0: | |
| input_stream = InputStream(sys.stdin.read()) | |
| process(input_stream, class_lexer, class_parser) | |
| exit(0) | |
| ############################################################# | |
| # iterate all input file | |
| ############################################################# | |
| for file_name in file_list: | |
| if os.path.exists(file_name) and os.path.isfile(file_name): | |
| input_stream = FileStream(file_name) | |
| process(input_stream, class_lexer, class_parser) | |
| else: | |
| print("[ERROR] file {} not exist".format(os.path.normpath(file_name))) | |