def __init__(self, lex_optimize=False, yacc_optimize=False): """ 创建 CParser 对象并初始化。 """ self.clex = CLexer( error_func = self._lex_error_func, on_lbrace_func = self._lex_on_lbrace_func, on_rbrace_func = self._lex_on_rbrace_func, type_lookup_func = self._lex_type_lookup_func) self.clex.build(optimize=lex_optimize) # TODO: 这个好像没有用到 self.tokens = self.clex.tokens # 在此列表中的规则会自动生成一条后缀为 _opt 的规则 # rules_with_opt = [ 'assignment_expression', 'declaration_list', 'expression', 'identifier_list', 'init_declarator_list', 'initializer_list', 'block_item_list', 'type_qualifier_list', 'declaration_specifiers' ] for rule in rules_with_opt: self._create_opt_rule(rule) self.cparser = yacc.yacc(module=self, start='translation_unit_or_empty', debug=True,optimize=yacc_optimize) # 名称范围栈 # 如果 _scope_stack[n][name]为True,则 name 在当前范围内被定义为 type # 如果为 False,则 name 在当前范围内被定义为 identifier # 如果不存在,则 name 未在此范围内定义 # _scope_stack[-1] 表示当前所在的范围 self._scope_stack = [dict()]
def __init__( self, lex_optimize=True, lextab='pycparser.lextab', yacc_optimize=True, yacctab='pycparser.yacctab', yacc_debug=False): """ Create a new CParser. Some arguments for controlling the debug/optimization level of the parser are provided. The defaults are tuned for release/performance mode. The simple rules for using them are: *) When tweaking CParser/CLexer, set these to False *) When releasing a stable parser, set to True lex_optimize: Set to False when you're modifying the lexer. Otherwise, changes in the lexer won't be used, if some lextab.py file exists. When releasing with a stable lexer, set to True to save the re-generation of the lexer table on each run. lextab: Points to the lex table that's used for optimized mode. Only if you're modifying the lexer and want some tests to avoid re-generating the table, make this point to a local lex table file (that's been earlier generated with lex_optimize=True) yacc_optimize: Set to False when you're modifying the parser. Otherwise, changes in the parser won't be used, if some parsetab.py file exists. When releasing with a stable parser, set to True to save the re-generation of the parser table on each run. yacctab: Points to the yacc table that's used for optimized mode. Only if you're modifying the parser, make this point to a local yacc table file yacc_debug: Generate a parser.out file that explains how yacc built the parsing table from the grammar. """ self.clex = CLexer( error_func=self._lex_error_func, type_lookup_func=self._lex_type_lookup_func) self.clex.build( optimize=lex_optimize, lextab=lextab) self.tokens = self.clex.tokens rules_with_opt = [ 'abstract_declarator', 'constant_expression', 'declaration_list', 'declaration_specifiers', 'expression', 'identifier_list', 'init_declarator_list', 'parameter_type_list', 'specifier_qualifier_list', 'statement_list', 'type_qualifier_list', ] for rule in rules_with_opt: self._create_opt_rule(rule) self.cparser = ply.yacc.yacc( module=self, start='translation_unit', debug=yacc_debug, optimize=yacc_optimize, tabmodule=yacctab) # A table of identifiers defined as typedef types during # parsing. # self.typedef_table = set([])
print("Got an error: {} \n line: {} col: {} ".format(err_msg, line, col)) def look_up_func(name): return False def on_lbrace_func(): pass def on_rbrace_func(): pass lexer = CLexer(error_func, on_lbrace_func, on_rbrace_func, look_up_func) lexer.build() if (len(sys.argv) > 1): for i in range(1, len(sys.argv)): file = open(sys.argv[i]) inp = file.read() lexer.input(inp) while True: tok = lexer.token() if not tok: break print(tok) else: while True: inp = raw_input(">") lexer.input(inp)