Example #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))
Example #3
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)
Example #4
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
Example #5
0
 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
Example #6
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()
Example #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()
 def setUp(self):
     source = """
     typedef struct { int i; } newtComponent;
     int newtInit(void);
     int newtFoo(int i, newtComponent string);
     """
     self.ast = CParser().parse(source, "aname")
 def testDeclVisitorIntReturnTypeWhenFunctionIsInt(self):
     v = wrapper_generator.DeclVisitor()
     ast = CParser().parse("""
     int f(int foo, ...);
     """, "aname")
     v.visit(ast)
     self.assertEqual("int", v.functions[0].return_type)
Example #10
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
Example #11
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
 def testDeclVisitorCharStarReturnTypeWhenFunctionIsString(self):
     v = wrapper_generator.DeclVisitor()
     ast = CParser().parse("""
     char * f(int foo, ...);
     """, "aname")
     v.visit(ast)
     self.assertEqual("char *", v.functions[0].return_type)
Example #13
0
def parse(iterrows, rownum, until=None):
    parser = CParser()
    generator = c_generator.CGenerator()
    res = []
    for row_i, row in enumerate(iter(iterrows), rownum):
        if until and row.startswith(until):
            break
        m = ifdef_pat.match(row)
        if m:
            defined = m.groups()[0]
            block = parse(iterrows, row_i, until='#endif')
            if defined in definitions:
                res.extend(block)
            continue
        m = define_pat.match(row)
        if m:
            alias, value = m.groups()
            definitions[alias] = value.strip()
            continue
        for k, v in definitions.items():
            row = row.replace(k, v)

        #ast = parser.parse(row)
        #print(generator.visit(ast))
        res.append(row)
    return res
Example #14
0
def extract_types(header):
    tree = CParser().parse("".join(decls + header), "gs.h")
    types = []
    for d in tree.children():
        if not isinstance(d.type, TypeDecl):
            continue
        t = dict(name=d.name)
        types.append(t)
        if isinstance(d.type.type, IdentifierType):
            t["type"] = d.type.type.names[0]
        elif isinstance(d.type.type, Enum):
            t["type"] = "enum"
            t["values"] = [v.name for v in d.type.type.values.children()]

        # d.show(attrnames=True)
    return types
Example #15
0
 def __init__(self, text, filename):
     ast = CParser().parse(text, filename)
     self.visitor = DeclVisitor()
     self.visitor.visit(ast)
     self.env = Environment(loader=FileSystemLoader('templates'))
     self.env.filters['without_variadic'] = without_variadic
     self.env.filters['string_to_type'] = string_to_type
     self.env.filters['type_to_string'] = type_to_string
 def testDeclVisitorReturnEllipsis(self):
     v = wrapper_generator.DeclVisitor()
     ast = CParser().parse("""
     void f(int foo, ...);
     """, "aname")
     v.visit(ast)
     self.assertEqual(2, len(v.functions[0].args))
     self.assertEqual(('ellipsis', '...'), v.functions[0].args[1])
 def testDeclVisitorReturnStructParam(self):
     v = wrapper_generator.DeclVisitor()
     ast = CParser().parse("""
     void f(struct bar a);
     """, "aname")
     v.visit(ast)
     argtype, name = v.functions[0].args[0]
     self.assertEqual('a', name)
     self.assertEqual('struct bar', argtype)
Example #18
0
def parse_file_text(filename, use_cpp=False, cpp_path='cpp', cpp_args=''):
    with open(filename) as f:
        raw_text = f.read()

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

    return raw_text, CParser().parse(text, filename)
 def testDeclVisitorReturnEnumParam(self):
     v = wrapper_generator.DeclVisitor()
     ast = CParser().parse(
         """
     void f(enum newtFlagsSense sense);
     """, "aname")
     v.visit(ast)
     argtype, name = v.functions[0].args[0]
     self.assertEqual('sense', name)
     self.assertEqual('enum newtFlagsSense', argtype)
 def testDeclVisitorReturnPointerParam(self):
     v = wrapper_generator.DeclVisitor()
     ast = CParser().parse("int newtInit(char * foo, char ** bar);",
                           "aname")
     v.visit(ast)
     argtype, name = v.functions[0].args[0]
     self.assertEqual('foo', name)
     self.assertEqual('char *', argtype)
     argtype, name = v.functions[0].args[1]
     self.assertEqual('bar', name)
     self.assertEqual('char **', argtype)
Example #21
0
def find_functions(text):
    '''Takes in preprocessed C sourcecode.
    Returns a list of function names like ['printf', 'sprintf', 'snprintf'].
    '''
    tree = CParser().parse(text, "")
    results = []
    
    for item in tree.ext:
        if isinstance(item, c_ast.Decl) and isinstance(item.type, c_ast.FuncDecl):
            results.append(item.name)
    
    return results
Example #22
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
Example #23
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)
Example #24
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`
 def testDeclVisitorReturnFuncName(self):
     v = wrapper_generator.DeclVisitor()
     ast = CParser().parse("int newtInit(void);", "aname")
     v.visit(ast)
     self.assertEqual('newtInit', v.functions[0].name)
 def testDeclVisitorReturnEmptyParam(self):
     v = wrapper_generator.DeclVisitor()
     ast = CParser().parse("int newtInit(void);", "aname")
     v.visit(ast)
     self.assertEqual([], v.functions[0].args)
Example #27
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()
Example #28
0
# Notes:
# Had to add SC2_Cam.dll, sc2_cl_me4.dll (MUST BE 64-bit versions, can find these in CamView's
# folder)
# Had to fuse a bunch of header files together, manually add some typedefs, preprocess this, append
# some #defines that don't get preprocessed, save to clean.h, and open this with cffi
# It may make sense to do some simple regex-style parsing of the header files to parse out the
# #defines that we care about
# Also, I'm using the errortext module I compiled for the pixelfly library. Still unsure whether I
# should code my own version in Python so we don't require the end-user to compile it.

# Hack to prevent lextab.py and yacctab.py from littering the working directory
tmp_dir = os.path.join(tempfile.gettempdir(), 'instrumental_pycparser')
if not os.path.exists(tmp_dir):
    os.mkdir(tmp_dir)
cparser._parser_cache = CParser(taboutputdir=tmp_dir)

ffi = FFI()
with open(os.path.join(os.path.dirname(__file__), '_pco', 'clean.h')) as f:
    ffi.cdef(f.read())
ffi.cdef("""
    #define WAIT_OBJECT_0       0x00L
    #define WAIT_ABANDONED      0x80L
    #define WAIT_TIMEOUT        0x102L
    #define WAIT_FAILED         0xFFFFFFFF
    #define INFINITE            0xFFFFFFFF
    DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
    BOOL ResetEvent(HANDLE hEvent);
""")
lib = ffi.dlopen('SC2_Cam.dll')
winlib = ffi.dlopen('Kernel32.dll')
Example #29
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)
Example #30
0
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)
Example #31
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)
Example #32
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)