def show(s, reduced=True, dot_path=None, pdf_path=None, fmt='pretty'): """Generates a graphviz diagram of the AST for the given path. Since this is mostly debug functionality, there are also options to print various significant values. :param s: The regular expression to parse :param reduced: If True, includes only productions used for generating code in the diagram. If False, includes all productions in the diagram. Defaults to True. :param dot_path: Where to write dot file, if any :param pdf_path: Where to write PDF file. Requires dot_file to also be set. :param format: 'pretty' or 'json' """ ALLOWED_FORMATS = ('pretty', 'json') if fmt not in ALLOWED_FORMATS: raise ValueError('fmt must be one of %r' % ALLOWED_FORMATS) log.info('dot path: %s' % dot_path) if fmt == 'pretty': log.info('Tokens:') lexer.lexer.input(s) for tok in iter(lexer.lexer.token, None): log.info('%r %r' % (tok.type, tok.value)) root = parser.parse(s, (not reduced)) if dot_path: visualize.ast_dot(root, dot_path) log.info("Graphviz written to %s" % dot_path) if pdf_path: pdf_path = os.path.abspath(pdf_path) try: p = subprocess.Popen( ["dot", "-Tpdf", dot_path, "-o", pdf_path], stderr=subprocess.PIPE, stdout=subprocess.PIPE) _, stderr = p.communicate() if p.returncode != 0: raise OSError(stderr) log.info("PDF written to %s" % pdf_path) except OSError: log.error("PDF could not be written. Graphviz does not appear" " to be installed or some other error occurred.") instr_list = root.generate_instructions() instr_list.append(instructions.Instruction('match')) # Print instructions after the AST is drawn in case instruction printing # fails program = instructions.serialize(instr_list) if fmt == 'json': program = [(opcode_to_cmd[inst[0]].upper(), inst[1], inst[2]) for inst in program] json.dump(program, sys.stdout) elif fmt == 'pretty': log.info("Instructions for VM:") instructions.prettyprint_program(program)
def parse(s): """ Converts a regular expression into bytecode for the VM :param s: A regular expression :return: A list of opcode tuples in the form `[(opcode, arg1, arg2)]` """ instr_list = parser.parse(s).generate_instructions() instr_list.append(instructions.Instruction('match')) return instructions.serialize(instr_list)