def __init__(self, ps1='> ', ps2='>> ', globals=None, locals=None): super().__init__() self.ps1 = ps1 self.ps2 = ps2 self.globals = globals self.locals = locals self.parser = Parser() self.prompt = ps1 self.stmt = ''
def 调用(源码, 文件名): 分析器 = Parser() 节点 = 分析器.parse(源码, 文件名) code = compile(节点, 文件名, 'exec') globals = create_globals(argv=[], fname=文件名) # 传出变量, 参考: # https://stackoverflow.com/questions/45535284/exec-and-variable-scope # https://stackoverflow.com/questions/1463306/how-does-exec-work-with-locals # https://docs.python.org/3/library/functions.html#exec 本地量 = {} exec(code, globals, 本地量)
def main(argv=None): if argv is None: argv = sys.argv try: opts, args = getopt.getopt(argv[1:], 'hdapbctisDTe:v', [ 'dump-ast', 'dump-python', 'dump-blockly', 'dump-bytecode', 'dump-tokens', 'python-to-ulang', 'exec-code=', 'debug', 'disassemble', 'show-backtrace', 'help', 'version', 'interact']) except getopt.GetoptError as e: try: sys.stderr.write(str(e) + '\n') usage(argv[0]) finally: e = None del e input_file = None dump_ast = False dump_python = False dump_blockly = False dump_bytecode = False dump_tokens = False disassemble = False trace_exception = False interactive = False python2ulang = False exec_code = None debug = False for opt, value in opts: if opt in ('-i', '--interact'): interactive = True elif opt in ('-p', '--dump-python'): dump_python = True elif opt in ('-a', '--dump-ast'): dump_ast = True elif opt in ('-b', '--dump-blockly'): dump_blockly = True elif opt in ('-c', '--dump-bytecode'): dump_bytecode = True elif opt in ('-d', '--disassemble'): disassemble = True elif opt in ('-s', '--python-to-ulang'): python2ulang = True elif opt in ('-D', '--debug'): debug = True elif opt in ('-t', '--show-backtrace'): trace_exception = True elif opt in ('-T', '--dump-tokens'): dump_tokens = True elif opt in ('-e', '--exec-code'): exec_code = value elif opt in ('-v', '--version'): from ulang import __version__ sys.stderr.write('%s\n' % __version__) sys.exit() if len(argv) == 1: sys.exit(repl()) if len(args) > 0: input_file = args[0] if input_file is None: if len(argv) == 1: sys.exit(repl()) if not exec_code: usage(argv[0]) try: source = None if exec_code: source = exec_code input_file = '<CLI>' elif input_file == '-': source = sys.stdin.read() input_file = '<STDIN>' else: with open(input_file, 'r') as f: source = f.read() if not source: sys.stderr.write('cannot open file "%s"!\n' % input_file) sys.exit(-1) if python2ulang: nodes = ast.parse(source, input_file) print(ulgen.dump(nodes)) return if dump_tokens: tokens = lexer.lex(source) for token in tokens: print((token.gettokentype()), end=' ') return parser = Parser() nodes = parser.parse(source, input_file) if dump_ast: print(ast.dump(nodes, True, True)) return if dump_python: print(python.dump(nodes)) return if dump_blockly: print(blockly.dump(nodes)) return if dump_bytecode: from pygen.compiler import Compiler print(Compiler().compile(nodes, input_file).dump()) return code = compile(nodes, input_file, 'exec') if disassemble: dis.dis(code) return globals = create_globals(argv=(args[1:]), fname=input_file) if debug: import pdb while True: try: pdb.run(code, globals, None) except pdb.Restart: pass else: break else: exec(code, globals) if interactive: repl(globals=globals) except Exception as e: try: sys.stderr.write('%s: %s\n' % (e.__class__.__name__, str(e))) if trace_exception: import pdb extype, value, tb = sys.exc_info() pdb.post_mortem(tb) raise e finally: e = None del e
def parse_and_compile(input_file): with open(input_file, 'r') as file: parser = Parser() nodes = parser.parse(source=(file.read()), filename=input_file) return compile(nodes, input_file, 'exec')
class Repl(cmd.Cmd): """ A simple wrapper for REPL using the python cmd module. """ def __init__(self, ps1='> ', ps2='>> ', globals=None, locals=None): super().__init__() self.ps1 = ps1 self.ps2 = ps2 self.globals = globals self.locals = locals self.parser = Parser() self.prompt = ps1 self.stmt = '' def do_help(self, arg): self.default('help(%s)' % arg) def do_quit(self, arg): self.default('quit(%s)' % arg) def do_EOF(self, arg): self.default('quit()') def onecmd(self, line): if line == 'EOF': return self.do_EOF(line) self.default(line) self.prompt = self.ps1 if len(self.stmt) == 0 else self.ps2 def default(self, line): if line is not None: self.stmt += '%s\n' % line if not self.is_close(): return try: try: node = self.parser.parse('___=(%s);__print__(___)' % self.stmt, '<STDIN>') except Exception: node = self.parser.parse(self.stmt, '<STDIN>') code = compile(node, '<STDIN>', 'exec') exec(code, self.globals, self.locals) except SystemExit: sys.exit() except BaseException as e: try: sys.stderr.write('%s: %s\n' % (e.__class__.__name__, str(e))) finally: e = None del e finally: self.stmt = '' def is_close(self): return is_close(self.stmt) def cmdloop(self, *args, **kwargs): orig_input_func = cmd.__builtins__['input'] cmd.__builtins__['input'] = input_swallowing_interrupt(orig_input_func) try: (super().cmdloop)(*args, **kwargs) finally: cmd.__builtins__['input'] = orig_input_func
class Repl(cmd.Cmd): """ A simple wrapper for REPL using the python cmd module. """ __module__ = __name__ __qualname__ = "Repl" def __init__(self, ps1="> ", ps2=">> ", globals=None, locals=None): super().__init__() self.ps1 = ps1 self.ps2 = ps2 self.globals = globals self.locals = locals self.parser = Parser() self.prompt = ps1 self.stmt = "" def do_help(self, arg): self.default("help(%s)" % arg) def do_quit(self, arg): self.default("quit(%s)" % arg) def do_EOF(self, arg): self.default("quit()") def onecmd(self, line): if line == "EOF": return self.do_EOF(line) self.default(line) self.prompt = self.ps1 if len(self.stmt) == 0 else self.ps2 def default(self, line): if line is not None: self.stmt += "%s\n" % line if not self.is_close(): return try: try: try: node = self.parser.parse( "___=(%s);__print__(___)" % self.stmt, "<STDIN>") except Exception: node = self.parser.parse(self.stmt, "<STDIN>") code = compile(node, "<STDIN>", "exec") exec(code, self.globals, self.locals) except SystemExit: sys.exit() except BaseException as e: try: sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) finally: e = None del e finally: self.stmt = "" def is_close(self): return is_close(self.stmt) def cmdloop(self, *args, **kwargs): orig_input_func = cmd.__builtins__["input"] cmd.__builtins__["input"] = input_swallowing_interrupt(orig_input_func) try: (super().cmdloop)(*args, **kwargs) finally: cmd.__builtins__["input"] = orig_input_func
def main(argv=None): if argv is None: argv = sys.argv else: try: opts, args = getopt.getopt( argv[1:], "hdapbctisDTe:v", [ "dump-ast", "dump-python", "dump-blockly", "dump-bytecode", "dump-tokens", "python-to-ulang", "exec-code=", "debug", "disassemble", "show-backtrace", "help", "version", "interact", ], ) except getopt.GetoptError as e: try: sys.stderr.write(str(e) + "\n") usage(argv[0]) finally: e = None del e input_file = None dump_ast = False dump_python = False dump_blockly = False dump_bytecode = False dump_tokens = False disassemble = False trace_exception = False interactive = False python2ulang = False exec_code = None debug = False for opt, value in opts: if opt in ("-i", "--interact"): interactive = True elif opt in ("-p", "--dump-python"): dump_python = True elif opt in ("-a", "--dump-ast"): dump_ast = True elif opt in ("-b", "--dump-blockly"): dump_blockly = True elif opt in ("-c", "--dump-bytecode"): dump_bytecode = True elif opt in ("-d", "--disassemble"): disassemble = True elif opt in ("-s", "--python-to-ulang"): python2ulang = True elif opt in ("-D", "--debug"): debug = True elif opt in ("-t", "--show-backtrace"): trace_exception = True elif opt in ("-T", "--dump-tokens"): dump_tokens = True elif opt in ("-e", "--exec-code"): exec_code = value else: if opt in ("-v", "--version"): from ulang import __version__ sys.stderr.write("%s\n" % __version__) sys.exit() if input_file is None: if len(args) > 0: input_file = args[0] if input_file is None: if len(argv) == 1: sys.exit(repl()) else: if not exec_code: usage(argv[0]) try: source = None if exec_code: source = exec_code input_file = "<CLI>" else: if input_file == "-": source = sys.stdin.read() input_file = "<STDIN>" else: with open(input_file, "r") as (f): source = f.read() if not source: sys.stderr.write('cannot open file "%s"!\n' % input_file) sys.exit(-1) if python2ulang: nodes = ast.parse(source, input_file) print(ulgen.dump(nodes)) return if dump_tokens: tokens = lexer.lex(source) for token in tokens: print((token.gettokentype()), end=" ") return parser = Parser() nodes = parser.parse(source, input_file) if dump_ast: print(ast.dump(nodes, True, True)) return if dump_python: print(python.dump(nodes)) return if dump_blockly: print(blockly.dump(nodes)) return if dump_bytecode: from pygen.compiler import Compiler print(Compiler().compile(nodes, input_file).dump()) return code = compile(nodes, input_file, "exec") if disassemble: dis.dis(code) return globals = create_globals(argv=(args[1:]), fname=input_file) if debug: import pdb while True: try: pdb.run(code, globals, None) except pdb.Restart: pass else: break else: exec(code, globals) if interactive: repl(globals=globals) except Exception as e: try: sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) if trace_exception: raise e finally: e = None del e