Exemple #1
0
def gen_code(src: str):
    parser = CParser()
    ast = parser.parse(src, '')
    sts = symtab_store(ast)
    block = genTACs(ast, sts)  # 现在没有输出了
    asm_code_text = asm_ctrl.gen_code_text()
    print(asm_code_text)
def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='',
               parser=None):
  '''Modified version of pycparser's parse_file.

  Args:
    filename (string): Name of file to be parsed
    use_cpp (optional[bool]): True if cpp will be used
    cpp_path (optional[string]): Path to cpp
    cpp_args (optional[string]): Arguments for cpp
    parser (optional[CParser]): Parser to be used

  Returns:
    tuple: (filename, source, AST)

  '''

  with open(filename, 'rU') as f:
    text = f.read()

  if use_cpp:
    processedText = preprocess_file(filename, cpp_path, cpp_args)
  else:
    processedText = text

  if parser is None:
    parser = CParser()
  return (filename, text, parser.parse(processedText, filename))
Exemple #3
0
    def _parse_file(
        self,
        filename: str,
        use_cpp: bool = False,
        cpp_path: str = "cpp",
        cpp_args: str = "",
        parser: pycparser.CParser = None,
    ) -> pycparser.c_ast.FileAST:
        if use_cpp:
            text = self._preprocess_file(filename, cpp_path, cpp_args)
        else:
            with open(filename, "rU") as f:
                text = f.read()

        if parser is None:
            parser = pycparser.CParser()
        try:
            return parser.parse(text, filename)
        except pycparser.c_parser.ParseError as error:
            if isinstance(error, pycparser.c_parser.ParseError):
                context = self._parse_error_context(text, error)
            else:
                context = ""
            LOGGER.error(
                f"Parsing of {filename} failed. Details:\t{str(error)}\n{context}"
            )
            raise error
Exemple #4
0
    def __init__(self,
                 hfiles,
                 includes=[],
                 include_dirs=[],
                 predefs={},
                 prelude=[],
                 debug=False):
        self.hfiles = hfiles
        self.types = OrderedDict()
        self.funcs = OrderedDict()
        self.macros = OrderedDict()
        self.macros.update(predefs)
        self.include_dirs = include_dirs

        lines = []
        self._included = set()
        for hfile in hfiles:
            lines.extend(self._load_with_includes(hfile, includes))
        lines[0:0] = prelude
        text = self._preprocess(lines)
        if debug:
            with open("tmp.c", "w") as f:
                f.write(text)

        self.packed_lines = set(self._get_packed_regions(text))

        parser = CParser()
        ast = parser.parse(text, "tmp.c")
        visitor = CtypesGenVisitor(self)
        visitor.visit(ast)
Exemple #5
0
def parse_file(filename, use_cpp=True):
    if use_cpp:
        path_list = [
                'cpp',
                '-U __GNUC__',
                '-isystem', os.path.join(HEADER_REPLACEMENTS, 'usr', 'include'),
                # We just provide with a custom (but hackish) va_list
                # typedef in our own .h
                '-include', os.path.join(HEADER_REPLACEMENTS, 'valist.h'),
                filename,
                ]
        print path_list
        pipe = Popen(path_list,
                    stdout=PIPE,
                    universal_newlines=True)
        text = pipe.communicate()[0]
    else:
        text = open(filename).read()

    parser = CParser()
    # strip __extension__
    text = text.replace('__extension__', '')
    try:
        return parser.parse(text, filename)
    except ParseError:
        print >>sys.stderr, text
        raise
 def _cached_shared_ast(
     source: str, fn_name: str
 ) -> Tuple[ca.FuncDef, int, ca.FileAST]:
     parser = CParser()
     ast = parser.parse(source)
     orig_fn, fn_index = ast_util.extract_fn(ast, fn_name)
     ast_util.normalize_ast(orig_fn, ast)
     return orig_fn, fn_index, ast
Exemple #7
0
def ExtractFuncDeclFromSource(source):
    try:
        p     = CParser()
        ast   = p.parse(source + ';')
        funcs = ExtractAllFuncDecls(ast)
        for name, func in funcs.items():
            return func
    except Exception as e:
        import traceback
        traceback.print_exc()
Exemple #8
0
def ExtractFuncDeclFromSource(source):
    try:
        p = CParser()
        ast = p.parse(source + ';')
        funcs = ExtractAllFuncDecls(ast)
        for name, func in funcs.items():
            return func
    except Exception as e:
        import traceback
        traceback.print_exc()
Exemple #9
0
def makeAST(code):
    try:
        parser = CParser(lex_optimize=False, yacc_optimize=False)
        #parser = CParser()
        ast = parser.parse(code, filename=g.filename)
    except Exception as e:
        print(e)
        exit()

    #ast.show()

    node = projectAST(ast)

    #print(json.dumps(node, default=lambda x: {x.__class__.__name__: x.__dict__}, indent=2))
    #g.r.addReport(m.Report('fatal', a2t(ast), f"debugmode"))
    return node
Exemple #10
0
def parse_c(source: str) -> ca.FileAST:
    try:
        parser = CParser()
        return parser.parse(source, "<source>")
    except ParseError as e:
        msg = str(e)
        position, msg = msg.split(": ", 1)
        parts = position.split(":")
        if len(parts) >= 2:
            lineno = int(parts[1])
            posstr = f" at approximately line {lineno}"
            if len(parts) >= 3:
                posstr += f", column {parts[2]}"
            posstr += " (after PERM expansion)"
            try:
                line = source.split("\n")[lineno - 1].rstrip()
                posstr += "\n\n" + line
            except IndexError:
                posstr += "(out of bounds?)"
        else:
            posstr = ""
        raise CandidateConstructionFailure(
            f"Syntax error in base.c.\n{msg}{posstr}") from None
Exemple #11
0
 def __init__(self, hfiles, includes = [], include_dirs = [], predefs = {}, prelude = [], debug = False):
     self.hfiles = hfiles
     self.types = OrderedDict()
     self.funcs = OrderedDict()
     self.macros = OrderedDict()
     self.macros.update(predefs)
     self.include_dirs = include_dirs
     
     lines = []
     self._included = set()
     for hfile in hfiles:
         lines.extend(self._load_with_includes(hfile, includes))
     lines[0:0] = prelude
     text = self._preprocess(lines)
     if debug:
         with open("tmp.c", "w") as f:
             f.write(text)
     
     self.packed_lines = set(self._get_packed_regions(text))
     
     parser = CParser()
     ast = parser.parse(text, "tmp.c")
     visitor = CtypesGenVisitor(self)
     visitor.visit(ast)
Exemple #12
0
 def parse_file(self, filename):
     parser = CParser()
     buf = file(filename).read()
     buf = DIRECTIVE_RE.sub("", buf)  #r"/* directive \1 elided */", buf)
     t = parser.parse(buf, filename)
     self.visit(t)
def main(text):
    logging.debug("Running main function")

    print("start", json.dumps(text))

    # STAGE 1 - PREPROCESSOR
    text = preprocess(text, INTERACTIVE_MODE)
    logging.info("After preprocessing, text is: " + text)

    # STAGE 2 - LEXICAL AND SYNTAX ANALYSIS
    parser = CParser()
    tree = parser.parse(text)
    logging.info(tree)

    if INTERACTIVE_MODE:
        tree_dict = to_dict(tree)
        trim_tree(tree_dict)
        print("tree", json.dumps(tree_dict))

    # STAGE 3 - GLOBAL VARIABLE TABLE
    global_symbols = global_parser(tree.ext, INTERACTIVE_MODE)
    ID.globals = global_symbols

    # STAGE 4 - Store local variables and perform type checking
    top_compound = None
    for top_level in tree.ext:
        if isinstance(top_level, FuncDef) and top_level.decl.name == "main":
            top_compound = top_level.body
            break
    if top_compound is None:
        logging.fatal("No main function found")
        return
    parse_compound(top_compound, [], global_symbols)

    if INTERACTIVE_MODE:
        print("locals")

    # STAGE 5 - HIERARCHICAL INSTRUCTION GENERATION
    main_block = generate_code_block(top_compound, global_symbols)

    # STAGE 6 - ASSEMBLY GENERATION
    if INTERACTIVE_MODE:
        print("start_codegen")

    assembly = """section.meta
mem_amt={mem_amt}

section.data
{data_section}

section.text
{text_section}
""".format(mem_amt=4,
           data_section=produce_data_section(global_symbols, INTERACTIVE_MODE),
           text_section=produce_text_section(main_block, global_symbols,
                                             INTERACTIVE_MODE))

    # STAGE 7 - POST-GENERATION OPTIMISATION
    assembly = optimise(assembly)

    if INTERACTIVE_MODE:
        print("finish", json.dumps(assembly))
    else:
        print(assembly)
Exemple #14
0
def main():
    argparser = argparse.ArgumentParser(description='Compile C to a Minecraft datapack')
    argparser.add_argument('file', metavar='Cfile', type=pathlib.Path, help='Path to the C file')
    argparser.add_argument('target', metavar='target', type=pathlib.Path, help='Location to write functions in')
    argparser.add_argument('--preprop', dest='preprop', action='store_const', const=True, default=False,
                           help='Don\'t run the C preprocessor on the file')
    argparser.add_argument('--file-input', help='Take constant input from file', dest='finput', metavar='file',
                           default=False, type=pathlib.Path)
    program_args = argparser.parse_args()
    if program_args.preprop:
        preprocessed = open(program_args.file).read()
    else:
        preprocessed = subprocess.check_output(
            ['gcc', '-nostdinc', '-E', program_args.file, f'-I{os.path.dirname(os.path.abspath(__file__))}/libc']).decode()
    print(program_args.target)
    if program_args.finput:
        inp = list(reversed(program_args.finput.open('rb').read()))
    try:
        shutil.rmtree(program_args.target / 'functions')
    except IOError:
        pass
    os.mkdir(program_args.target / 'functions')
    os.mkdir(program_args.target / 'functions' / 'tree')
    copy_stdlib(program_args.target / 'functions')
    os.chdir(program_args.target / 'functions')
    parser = CParser()
    parsed = parser.parse(preprocessed)
    obj_name = {}
    vtypes = {}
    vars = {}
    methods = {}
    for global_definition in parsed.ext:
        if cname(global_definition) == 'Typedef':
            add_type(global_definition.name, get_type(global_definition.type, obj_name, vtypes))
        elif cname(global_definition) == 'Decl' and cname(global_definition.type) != 'FuncDecl':
            vars[global_definition.name] = global_definition
            global varaddr
        elif cname(global_definition) == 'Decl' and cname(global_definition.type) == 'FuncDecl':
            return_types[global_definition.name] = get_type(global_definition.type.type)
            arguments[global_definition.name] = parse_arguments(global_definition.type.args)
        elif cname(global_definition) == 'FuncDef':
            return_types[global_definition.decl.name] = get_type(global_definition.decl.type.type)
            arguments[global_definition.decl.name] = parse_arguments(global_definition.decl.type.args)
            # print(functions)
            methods[global_definition.decl.name] = global_definition
        else:
            print(cname(global_definition))
    update_types()
    file = open('main.mcfunction', 'w')
    file.write(generate_head(vars, obj_name, vtypes))
    for method in methods:
        f = open(f'method_{method.lower()}.mcfunction', 'w')
        set_rtype(return_types[method])
        args = methods[method].decl.type.args
        if args is None:
            args = []
        clear_used()
        reset_locals()
        j = 0
        for arg in args:
            if cname(arg) == 'EllipsisParam':
                j += 10
                for i in range(10): create_local()
                break
            var_type = arg.type
            vtypes[arg.name] = get_type(var_type)
            obj_name[arg.name] = [create_local() for i in range(get_type(arg.type).size)]
            j += vtypes[arg.name].size
        new_cid()
        f.write(generate_expression([], methods[method].body, vtypes, obj_name, False, True)[0])
        f.write(f'scoreboard players set $returned {NAMESPACE} 0')
        f.close()
    generate_trees()
    if program_args.finput:
        file.write(f'data modify storage {NAMESPACE}:main input set value {inp}\n')
    file.write(f'data modify storage {NAMESPACE}:main rec set value []\n')
    file.write(f'data modify storage {NAMESPACE}:main ibuffer set value []\n')

    for strg in stringss:
        for i, c in enumerate(stringss[strg]):
            # TODO: change it to direct access to the heap, as index is known in compile time.
            file.write(f'scoreboard players set $index {NAMESPACE} {strg + i}\n')
            file.write(f'scoreboard players set $value {NAMESPACE} {c}\n')
            file.write(f'function {NAMESPACE}:set_heap\n')
    file.write(f'function {NAMESPACE}:method_main\n')
    file.close()
    goto_postprocess()
    remove_zerolines()
    inline_oneline()
    make_pausable({'method_getc', 'method__get_setjmp'})
    remove_unused()
Exemple #15
0
        dfs(u.cond)
        dfs(u.stmt)

    @register('DoWhile')
    def DoWhile(u):
        dfs(u.cond)
        dfs(u.stmt)

    @register('TernaryOp')
    def TernaryOp(u: c_ast.TernaryOp):
        dfs(u.cond)
        dfs(u.iftrue)
        dfs(u.iffalse)

    dfs(ast)
    return sts


if __name__ == '__main__':

    argparser = argparse.ArgumentParser('Dump AST with ...')
    argparser.add_argument('filename', help='name of file to parse')
    args = argparser.parse_args()

    parser = CParser()
    with open(args.filename, 'r') as f:
        ast = parser.parse(f.read(), args.filename)
    print(ast)
    sts = symtab_store(ast)
    sts.show(ast)
Exemple #16
0
    )

    preprocessed = ""
    # pycparser requires each symbol must be defined, hence provide a dummy
    # definition of the needed stdlib types.
    # Note those definitions will then be detected and ignored by PatchedAutoPxd.
    for stdtype in STDLIB_TYPES:
        preprocessed += f"typedef int {stdtype};\n"
    preprocessed += cccp.parse(source)

    with open("output.preprocessed.c", "w") as fd:
        fd.write(preprocessed)

    # Step 2: C parsing
    parser = CParser()
    ast = parser.parse(preprocessed)

    # Step 3: .pxd generation
    p = PatchedAutoPxd(header_name)
    p.visit(ast)

    pxd_cdef = p.lines()
    # Remove the cdef part given we want to add the `nogil` option and
    # we also want to add the `godot_method_flags` C inline code
    assert pxd_cdef[0].startswith("cdef extern from")
    pxd_cdef_body = "\n".join(pxd_cdef[1:])

    pxd = f"""\
# /!\\ Autogenerated code, modifications will be lost /!\\
# see `generation/generate_gdnative_api_struct.py`
Exemple #17
0
	def parse_file(self, filename):
		parser = CParser()
		buf = file(filename).read()
		buf = DIRECTIVE_RE.sub("", buf)#r"/* directive \1 elided */", buf)
		t = parser.parse(buf, filename)
		self.visit(t)