예제 #1
0
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)
예제 #2
0
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)