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))
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)
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
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)
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
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)
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
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
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)
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)
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
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
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)
}, ) 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)
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()
# 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')
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)
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)
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 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)