def _parse_text(self, token_list): self.dep_module_set = set() import_end = False self.func_map = larc_common.OrderedDict() self.global_var_map = larc_common.OrderedDict() while token_list: token_list.pop_indent(0) t = token_list.pop() if t.is_import: #import if import_end: t.syntax_err("import必须在模块代码最前面") self._parse_import(token_list) continue import_end = True if t.is_export: if token_list.peek().is_func: #函数声明 token_list.pop() self._parse_func(token_list) continue #全局变量声明 self._parse_global_var(token_list) continue t.syntax_err() #外部模块只含有导出变量和函数 self.export_func_set = set(self.func_map) self.export_global_var_set = set(self.global_var_map)
def link(self, module_map): self.const_map = larc_common.OrderedDict() for cls in self.class_map.itervalues(): cls.link(self, module_map) for expr in self.global_var_map.itervalues(): expr.link(self, module_map) for func in self.func_map.itervalues(): func.link(self, module_map)
def _parse_text(self, token_list): self.dep_module_set = set() import_end = False self.class_map = larc_common.OrderedDict() self.func_map = larc_common.OrderedDict() self.global_var_map = larc_common.OrderedDict() self.global_var_init_map = larc_common.OrderedDict() while token_list: #解析import t = token_list.pop() if t.is_reserved("import"): #import if import_end: t.syntax_err("import必须在模块代码最前面") if self.name == "__builtins": t.syntax_err("模块'__builtins'不可以import其他模块") self._parse_import(token_list) continue import_end = True if t.is_reserved("native"): is_native = True t = token_list.pop() else: is_native = False if t.is_reserved("class"): #类定义 self._parse_class(token_list, is_native) continue if t.is_reserved("func"): #类定义 self._parse_func(token_list, is_native) continue if t.is_reserved("var"): #全局变量 self._parse_global_var(token_list, is_native) continue t.syntax_err()
def main(): #解析命令行参数 opt_list, args = getopt.getopt(sys.argv[1:], "", []) if len(args) != 1: _show_usage_and_exit() #已编译的模块,模块名映射模块Module对象 module_map = larc_common.OrderedDict() #先编译主模块 main_file_path_name = os.path.abspath(args[0]) if main_file_path_name.endswith(".lar"): main_module = larc_module.Module(main_file_path_name) elif main_file_path_name.endswith(".lar_ext"): main_module = larc_module.ExternModule(main_file_path_name) else: larc_common.exit("非法的主模块文件名[%s]" % main_file_path_name) module_map[main_module.name] = main_module #模块查找的目录列表 src_dir = os.path.dirname(main_file_path_name) compiler_dir = os.path.dirname(os.path.abspath(sys.argv[0])) lib_dir = os.path.join(os.path.dirname(compiler_dir), "lib") module_dir_list = [src_dir, lib_dir] #编译所有涉及到的模块 compiling_set = main_module.dep_module_set #需要编译的模块名集合 compiling_set |= set(["sys"]) #因为要接收argv,sys模块必须有 while compiling_set: new_compiling_set = set() for module_name in compiling_set: if module_name in module_map: #已编译过 continue module_file_path_name = (_find_module_file(module_dir_list, module_name)) if module_file_path_name.endswith(".lar"): module_map[module_name] = m = ( larc_module.Module(module_file_path_name)) elif module_file_path_name.endswith(".lar_ext"): module_map[module_name] = m = ( larc_module.ExternModule(module_file_path_name)) else: raise Exception("unreachable") new_compiling_set |= m.dep_module_set compiling_set = new_compiling_set prog = larc_prog.Prog(main_module.name, module_map) output_lib = larc_output.to_java out_dir = src_dir output_lib.output(out_dir, prog, lib_dir)
def __init__(self, array_type, name): assert array_type.is_array ret_type, arg_list = _ARRAY_METHOD_MAP[name] ret_type = _replace_array_type_tag(ret_type, array_type) self.decr_set = set(["public"]) self.name = name self.type = ret_type self.arg_map = larc_common.OrderedDict() for arg_name, arg_type in arg_list: assert arg_name not in self.arg_map arg_type = _replace_array_type_tag(arg_type, array_type) self.arg_map[arg_name] = arg_type
def _parse_text(self, token_list): self.dep_module_set = set() import_end = False self.class_map = larc_common.OrderedDict() self.export_class_set = set() self.func_map = larc_common.OrderedDict() self.export_func_set = set() self.global_var_map = larc_common.OrderedDict() self.global_var_type_info = {} self.export_global_var_set = set() while token_list: token_list.pop_indent(0) t = token_list.pop() if t.is_import: #import if import_end: t.syntax_err("import必须在模块代码最前面") self._parse_import(token_list) continue import_end = True if t.is_export: export = True t = token_list.pop() else: export = False if t.is_class: #类定义 self._parse_class(token_list, export) continue if t.is_func: #函数定义 self._parse_func(token_list, export) continue if t.is_name: #全局变量 self._parse_global_var(token_list, t, export) continue t.syntax_err()
def __init__(self, name): self.name = name if name == "Exception": self.base_class_module = None self.base_class_name = None self.base_class = None else: self.base_class_module = "*" self.base_class_name = "Exception" self.base_class = builtin_class_map["Exception"] self.method_map = larc_common.OrderedDict() self.method_map[("__init__", 0)] = None self.method_map[("__init__", 1)] = None self.attr_set = larc_common.OrderedSet()
def _parse_for_prefix(self, var_map_stk): self.token_list.pop_sym("(") for_var_map = larc_common.OrderedDict() init_expr_list = [] if self.token_list.peek().is_reserved("var"): #第一部分为var变量定义 self.token_list.pop() while True: _, _, expr, end_sym = self._parse_var(None, var_map_stk + (for_var_map,)) init_expr_list.append(expr) if end_sym == ";": break assert end_sym == "," else: tp = larc_type.try_parse_type(self.token_list, self.module, self.dep_module_map, self.gtp_map, var_map_stk) if tp is None: #第一部分为表达式列表 if not self.token_list.peek().is_sym(";"): init_expr_list += self._parse_expr_list_with_se(var_map_stk + (for_var_map,)) self.token_list.pop_sym(";") else: #第一部分为若干指定类型的变量定义 while True: _, _, expr, end_sym = self._parse_var(tp, var_map_stk + (for_var_map,)) init_expr_list.append(expr) if end_sym == ";": break assert end_sym == "," if self.token_list.peek().is_sym(";"): #没有第二部分 judge_expr = None else: judge_expr = self.expr_parser.parse(var_map_stk + (for_var_map,), larc_type.BOOL_TYPE) self.token_list.pop_sym(";") loop_expr_list = [] if not self.token_list.peek().is_sym(")"): loop_expr_list += self._parse_expr_list_with_se(var_map_stk + (for_var_map,)) self.token_list.pop_sym(")") return for_var_map, init_expr_list, judge_expr, loop_expr_list
def compile(self): self.literal_set = set() for i in self._items(): i.compile() non_local_var_used_map = larc_common.OrderedDict() for var_name, expr_token_list in self.global_var_init_map.iteritems(): if expr_token_list is not None: self.global_var_init_map[var_name] = (larc_expr.parse_expr( expr_token_list, self, None, (), non_local_var_used_map, end_at_comma=True)) t, sym = expr_token_list.pop_sym() assert not expr_token_list and sym in (",", ";") for vn in larc_stmt.iter_var_name(var_name): if vn in non_local_var_used_map: non_local_var_used_map[vn].syntax_err("全局变量'%s'在定义前使用" % vn)
def __init__(self, module, name, is_native): self.module = module self.name = name self.is_native = is_native self.attr_set = larc_common.OrderedSet() self.method_map = larc_common.OrderedDict()
#coding=utf8 """ 编译larva模块 """ import os import larc_common import larc_token import larc_stmt import larc_expr module_map = larc_common.OrderedDict() def _parse_arg_set(token_list, dep_module_set): arg_set = larc_common.OrderedSet() if token_list.peek().is_sym(")"): return arg_set while True: t, name = token_list.pop_name() if name in arg_set: t.syntax_err("参数名重定义") if name in dep_module_set: t.syntax_err("参数名和导入模块名冲突") arg_set.add(name) t = token_list.peek() if t.is_sym(","): token_list.pop_sym(",") continue if t.is_sym(")"): return arg_set
def infer_gtp(expr_list_start_token, gtp_name_list, arg_type_list, type_list, ref_tag_list): assert len(set(gtp_name_list)) == len(gtp_name_list) assert len(arg_type_list) == len(type_list) == len(ref_tag_list) class _GtpInferenceResult: def __init__(self, gtp_name): self.gtp_name = gtp_name self.tp = None self.is_freezed = False def update(self, tp): if tp.is_nil or tp.is_literal_int: expr_list_start_token.syntax_err( "参数#%d无法进行推导:实参类型不可为无类型nil或整数字面量,请指定类型" % (arg_idx + 1)) if self.tp is None: #初次推导 assert not self.is_freezed self.tp = tp return if self.is_freezed: #已经freeze,之前推导的结果必须兼容tp if not self.tp.can_convert_from(tp): expr_list_start_token.syntax_err( "无法确定泛型参数'%s'的类型,存在不兼容的推导结果:'%s', '%s'……" % (self.gtp_name, self.tp, tp)) return #之前update过但是未定,从二者之间选择兼容的那个 if self.tp.can_convert_from(tp): return if tp.can_convert_from(self.tp): self.tp = tp return expr_list_start_token.syntax_err( "无法确定泛型参数'%s'的类型,存在多种不同的推导结果:'%s', '%s'……" % (self.gtp_name, self.tp, tp)) def freeze(self, tp): assert not tp.is_nil and not tp.is_literal_int if self.tp is None: #初次推导 self.tp = tp elif self.is_freezed: #已经freeze,检查推导结果是否一致 if tp != self.tp: expr_list_start_token.syntax_err( "无法确定泛型参数'%s'的类型,存在多种不同的推导结果:'%s', '%s'……" % (self.gtp_name, self.tp, tp)) else: #已经有推导过但是还未freeze,则tp必须兼容之前的结果 if tp.can_convert_from(self.tp): self.tp = tp else: expr_list_start_token.syntax_err( "无法确定泛型参数'%s'的类型,存在不兼容的推导结果:'%s', '%s'……" % (self.gtp_name, self.tp, tp)) #将类型确定下来 assert self.tp is not None self.is_freezed = True def finish(self): if self.tp is None: expr_list_start_token.syntax_err("无法确定泛型参数'%s'的类型" % self.gtp_name) if self.tp.is_void: expr_list_start_token.syntax_err("泛型参数'%s'的类型推导为void" % self.gtp_name) return self.tp #构建gtp_infer_map,value为推导结果对象 gtp_infer_map = larc_common.OrderedDict() for gtp_name in gtp_name_list: gtp_infer_map[gtp_name] = _GtpInferenceResult(gtp_name) #通过精确匹配类型来推导arg_type中的泛型参数 def match_type(arg_type, tp): if arg_type.is_array: #数组类型匹配 if tp.array_dim_count < arg_type.array_dim_count: expr_list_start_token.syntax_err( "参数#%d类型匹配失败:数组维度不匹配,'%s'->'%s'" % (arg_idx + 1, tp, arg_type)) while arg_type.is_array: #arg_type是unchecked,因此不能直接to_elem_type,手动解决 arg_type = copy.deepcopy(arg_type) arg_type.array_dim_count -= 1 arg_type.is_array = arg_type.array_dim_count != 0 tp = tp.to_elem_type() match_type(arg_type, tp) return if arg_type.module_name is None: if arg_type.token.is_name: assert not arg_type.gtp_list and arg_type.name in gtp_infer_map assert not tp.is_nil and not tp.is_literal_int #parse到了最终泛型参数,可以确定类型了 gtp_infer_map[arg_type.name].freeze(tp) return assert arg_type.token.is_reserved #基础类型,直接忽略,tp是否匹配的检查让后面去做 return assert arg_type.token.is_name coi = larc_module.module_map[arg_type.module_name].get_coi_original( arg_type.name) assert len(coi.gtp_name_list) == len(arg_type.gtp_list) if not coi.gtp_name_list: #非泛型的类或接口,直接忽略 return assert not arg_type.is_array if (arg_type.module_name, arg_type.name) != ( tp.module_name, tp.name) or tp.is_array or len( arg_type.gtp_list) != len(tp.gtp_list): expr_list_start_token.syntax_err("参数#%d类型匹配失败:'%s'->'%s'" % (arg_idx + 1, tp, arg_type)) for arg_type_gtp, tp_gtp in zip(arg_type.gtp_list, tp.gtp_list): match_type(arg_type_gtp, tp_gtp) #遍历各匹配对,依次进行推导算法 for arg_idx, (arg_type, tp, is_ref) in enumerate( zip(arg_type_list, type_list, ref_tag_list)): #先检查ref修饰是否一致 if arg_type.is_ref and not is_ref: expr_list_start_token.syntax_err("参数#%d需要ref修饰") if not arg_type.is_ref and is_ref: expr_list_start_token.syntax_err("参数#%d存在无效的ref修饰") if arg_type.is_ref: assert is_ref #带ref修饰的类型需要精确匹配 match_type(arg_type, tp) continue #不带ref修饰的类型匹配,需要分几种情况 if not arg_type.is_array: if arg_type.token.is_name: if arg_type.module_name is None: #参数类型经历了check_ignore_gtp依然是裸name,且不是数组,则必然是单独的泛型类型 assert not arg_type.gtp_list and arg_type.name in gtp_infer_map #用update接口,类型之后还可能被进一步推导为其他兼容类型 gtp_infer_map[arg_type.name].update(tp) continue coi = larc_module.module_map[ arg_type.module_name].get_coi_original(arg_type.name) if coi.is_intf and coi.gtp_name_list: #泛型接口,展开双方的接口进行精确匹配 def match_method_type(method, tp_method): if tp_method is None: expr_list_start_token.syntax_err( "参数#%d类型匹配失败,接口方法'%s'找不到:'%s'->'%s'" % (arg_idx + 1, method.name, tp, arg_type)) if (list(method.decr_set) + list(tp_method.decr_set) ).count("public") not in (0, 2): #权限签名不同 expr_list_start_token.syntax_err( "参数#%d类型匹配失败,接口方法'%s'权限签名不同:'%s'->'%s'" % (arg_idx + 1, method.name, tp, arg_type)) if "public" not in method.decr_set and method.module is not tp_method.module: #权限私有且两个coi不在同一模块,这个接口无权访问 expr_list_start_token.syntax_err( "参数#%d类型匹配失败,对接口方法'%s'无访问权限:'%s'->'%s'" % (arg_idx + 1, method.name, tp, arg_type)) if len(method.arg_map) != len(tp_method.arg_map): expr_list_start_token.syntax_err( "参数#%d类型匹配失败,接口方法'%s'参数数量不匹配:'%s'->'%s'" % (arg_idx + 1, method.name, tp, arg_type)) match_type(method.type, tp_method.type) for method_arg_type, tp_method_arg_type in zip( method.arg_map.itervalues(), tp_method.arg_map.itervalues()): match_type(method_arg_type, tp_method_arg_type) if tp.is_array: for method in coi.method_map.itervalues(): match_method_type( method, get_array_method(tp, method.name)) continue if tp.module_name is not None: assert tp.token.is_name tp_coi = tp.get_coi() for method in coi.method_map.itervalues(): match_method_type( method, tp_coi.method_map[method.name] if method.name in tp_coi.method_map else None) continue #其余情况,必须精确匹配 match_type(arg_type, tp) #遍历gtp_map,确保所有类型都推导完毕并生成gtp_list gtp_list = [result.finish() for result in gtp_infer_map.itervalues()] return gtp_list
def _parse(self, var_map_stk, loop_deep, defer_deep, stmt_list): top_ccc_use_deep = self.ccc_use_deep while True: if self.token_list.peek().is_sym("}"): assert self.ccc_use_deep == top_ccc_use_deep break t = self.token_list.pop() def ccc_jmp(): #跳过ccc块,返回跳过的块的结束ccc token nested_ccc_use_deep = 0 while True: t = self.token_list.pop() if t.is_ccc("use"): nested_ccc_use_deep += 1 elif t.is_ccc("oruse") or t.is_ccc("enduse"): if nested_ccc_use_deep == 0: return t if t.is_ccc("enduse"): nested_ccc_use_deep -= 1 if t.is_ccc("use"): self.ccc_use_deep += 1 while True: fd_r, fd_w = os.pipe() pid = os.fork() if pid == 0: #子进程,注册管道fd后继续尝试编译 os.close(fd_r) larc_common.reg_err_report_fd(fd_w) work_ccc_use_deep = self.ccc_use_deep #记录子进程工作的deep break #父进程,等待子进程的编译结果,若失败则继续下一个use block os.close(fd_w) compile_result = os.read(fd_r, 1) assert compile_result in ("0", "1") if compile_result == "1": #成功,父进程在这个point继续编译 break #失败了,跳过这个use block继续尝试下一个 revert_idx = self.token_list.i #用于最后一个use block的回滚 t = ccc_jmp() if t.is_ccc("enduse"): #已经是最后一个了,以这个为准 self.token_list.revert(revert_idx) break continue if t.is_ccc and t.value in ("oruse", "enduse"): assert self.ccc_use_deep > top_ccc_use_deep fd = larc_common.get_err_report_fd() if fd >= 0 and self.ccc_use_deep == work_ccc_use_deep: #子进程尝试成功,汇报给父进程 os.write(fd, "1") sys.exit(0) #当前进程为一个父进程,成功选择了一个use block,跳到enduse继续编译 self.token_list.revert() while not ccc_jmp().is_ccc("enduse"): pass self.ccc_use_deep -= 1 continue if t.is_sym(";"): continue if t.is_sym("{"): #新代码块 stmt_list.append( _Stmt("block", stmt_list=self.parse( var_map_stk + (larc_common.OrderedDict(), ), loop_deep, defer_deep))) self.token_list.pop_sym("}") continue if t.is_reserved and t.value in ("break", "continue"): if loop_deep == 0: if defer_deep == 0: t.syntax_err("循环外的%s" % t.value) else: t.syntax_err("不允许从defer代码中向外部%s" % t.value) stmt_list.append(_Stmt(t.value)) continue if t.is_reserved("return"): if defer_deep > 0: t.syntax_err("不允许在defer代码中return") stmt_list.append( _Stmt("return", expr=self._parse_return(var_map_stk))) continue if t.is_reserved("for"): for_var_map, init_expr_list, judge_expr, loop_expr_list, closure_def_map = self._parse_for_prefix( var_map_stk) self.token_list.pop_sym("{") for_stmt_list = self.parse( var_map_stk + (for_var_map.copy(), ), loop_deep + 1, defer_deep) self.token_list.pop_sym("}") stmt_list.append( _Stmt("for", for_var_map=for_var_map, init_expr_list=init_expr_list, judge_expr=judge_expr, loop_expr_list=loop_expr_list, closure_def_map=closure_def_map, stmt_list=for_stmt_list)) continue if t.is_reserved("foreach"): var_tp, var_name, iter_expr = self._parse_foreach_prefix( var_map_stk) foreach_var_map = larc_common.OrderedDict() foreach_var_map[var_name] = var_tp self.token_list.pop_sym("{") foreach_stmt_list = self.parse( var_map_stk + (foreach_var_map, ), loop_deep + 1, defer_deep) self.token_list.pop_sym("}") stmt_list.append( _Stmt("foreach", var_tp=var_tp, var_name=var_name, iter_expr=iter_expr, stmt_list=foreach_stmt_list)) continue if t.is_reserved("while"): self.token_list.pop_sym("(") expr = self.expr_parser.parse(var_map_stk, larc_type.BOOL_TYPE) self.token_list.pop_sym(")") self.token_list.pop_sym("{") while_stmt_list = self.parse( var_map_stk + (larc_common.OrderedDict(), ), loop_deep + 1, defer_deep) self.token_list.pop_sym("}") stmt_list.append( _Stmt("while", expr=expr, stmt_list=while_stmt_list)) continue if t.is_reserved("if"): if_expr_list = [] if_stmt_list_list = [] else_stmt_list = None while True: self.token_list.pop_sym("(") expr = self.expr_parser.parse(var_map_stk, larc_type.BOOL_TYPE) self.token_list.pop_sym(")") self.token_list.pop_sym("{") if_stmt_list = self.parse( var_map_stk + (larc_common.OrderedDict(), ), loop_deep, defer_deep) self.token_list.pop_sym("}") if_expr_list.append(expr) if_stmt_list_list.append(if_stmt_list) if not self.token_list.peek().is_reserved("else"): break self.token_list.pop() t = self.token_list.pop() if t.is_reserved("if"): continue if not t.is_sym("{"): t.syntax_err("需要'{'") else_stmt_list = self.parse( var_map_stk + (larc_common.OrderedDict(), ), loop_deep, defer_deep) self.token_list.pop_sym("}") break stmt_list.append( _Stmt("if", if_expr_list=if_expr_list, if_stmt_list_list=if_stmt_list_list, else_stmt_list=else_stmt_list)) continue if t.is_reserved("var"): while True: tp, name, expr, end_sym = self._parse_var( None, var_map_stk) stmt_list.append(_Stmt("var", name=name, expr=expr)) if end_sym == ";": break assert end_sym == "," continue if t.is_reserved("defer"): if self.token_list.peek().is_sym("{"): #解析stmt_list时,外层loop_deep清零,defer_deep加一 self.token_list.pop_sym("{") stmt_list.append( _Stmt("defer_block", stmt_list=self.parse( var_map_stk + (larc_common.OrderedDict(), ), 0, defer_deep + 1))) self.token_list.pop_sym("}") else: #单条call表达式的defer expr = self.expr_parser.parse(var_map_stk, None) if expr.op not in ("call_method", "call_func"): t.syntax_err("defer表达式必须是一个函数或方法调用") stmt_list.append(_Stmt("defer_expr", expr=expr)) continue if t.is_native_code: stmt_list.append( _Stmt("native_code", native_code=larc_module.NativeCode( self.module, self.file_name, self.gtp_map, t), fom=self.fom)) continue self.token_list.revert() tp = larc_type.try_parse_type(self.token_list, self.module, self.dep_module_map, self.gtp_map, var_map_stk) if tp is not None: #变量定义 while True: _, name, expr, end_sym = self._parse_var(tp, var_map_stk) stmt_list.append(_Stmt("var", name=name, expr=expr)) if end_sym == ";": break assert end_sym == "," continue #表达式 expr = self._parse_expr_with_se(var_map_stk) self._check_valid_expr_stmt(t, expr) stmt_list.append(_Stmt("expr", expr=expr)) self.token_list.pop_sym(";") continue
def parse_stmt_list(token_list, module, cls, var_set_list, loop_deep): assert var_set_list stmt_list = _StmtList(var_set_list[-1]) non_local_var_used_map = larc_common.OrderedDict() while token_list: if token_list.peek().is_sym("}"): break #解析语句 t = token_list.pop() if t.is_sym(";"): t.warning("空语句") continue if t.is_sym("{"): stmt = _Stmt("block", stmt_list=parse_stmt_list( token_list, module, cls, var_set_list + (larc_common.OrderedSet(), ), loop_deep)) token_list.pop_sym("}") stmt_list.append(stmt) continue if t.is_reserved("var"): def add_to_curr_var_set(t, vn): if vn in module.dep_module_set: t.syntax_err("变量名'%s'与导入模块重名" % vn) for var_set in var_set_list: if vn in var_set: t.syntax_err("变量名'%s'重定义" % vn) if vn in non_local_var_used_map: non_local_var_used_map[vn].syntax_err("局部变量在定义之前使用") var_set_list[-1].add(vn) for t, var_name, expr in parse_var_define(token_list, module, cls, var_set_list, non_local_var_used_map): for vn in iter_var_name(var_name): add_to_curr_var_set(t, vn) stmt_list.append(_Stmt("var", name=var_name, expr=expr)) continue if t.is_reserved and t.value in ("break", "continue"): if loop_deep == 0: t.syntax_err("循环外的'%s'" % t.value) token_list.pop_sym(";") stmt_list.append(_Stmt(t.value)) continue if t.is_reserved("return"): expr = larc_expr.parse_expr(token_list, module, cls, var_set_list, non_local_var_used_map) token_list.pop_sym(";") stmt_list.append(_Stmt("return", expr=expr)) continue if t.is_reserved("for"): for_var_set, lvalue, iter_obj = parse_for_prefix( token_list, module, cls, var_set_list, non_local_var_used_map) token_list.pop_sym("{") for_stmt_list = parse_stmt_list( token_list, module, cls, var_set_list + (for_var_set.copy(), ), loop_deep + 1) token_list.pop_sym("}") stmt_list.append( _Stmt("for", var_set=for_var_set, lvalue=lvalue, iter_obj=iter_obj, stmt_list=for_stmt_list)) continue if t.is_reserved("while"): token_list.pop_sym("(") expr = larc_expr.parse_expr(token_list, module, cls, var_set_list, non_local_var_used_map) token_list.pop_sym(")") token_list.pop_sym("{") while_stmt_list = parse_stmt_list( token_list, module, cls, var_set_list + (larc_common.OrderedDict(), ), loop_deep + 1) token_list.pop_sym("}") stmt_list.append( _Stmt("while", expr=expr, stmt_list=while_stmt_list)) continue if t.is_reserved("do"): token_list.pop_sym("{") do_stmt_list = parse_stmt_list( token_list, module, cls, var_set_list + (larc_common.OrderedDict(), ), loop_deep + 1) token_list.pop_sym("}") t = token_list.pop() if not t.is_reserved("while"): t.syntax_err("需要'while'") token_list.pop_sym("(") expr = larc_expr.parse_expr(token_list, module, cls, var_set_list, non_local_var_used_map) token_list.pop_sym(")") token_list.pop_sym(";") stmt_list.append(_Stmt("do", expr=expr, stmt_list=do_stmt_list)) continue if t.is_reserved("if"): if_expr_list = [] if_stmt_list_list = [] else_stmt_list = None while True: token_list.pop_sym("(") expr = larc_expr.parse_expr(token_list, module, cls, var_set_list, non_local_var_used_map) token_list.pop_sym(")") token_list.pop_sym("{") if_stmt_list = parse_stmt_list( token_list, module, cls, var_set_list + (larc_common.OrderedDict(), ), loop_deep) token_list.pop_sym("}") if_expr_list.append(expr) if_stmt_list_list.append(if_stmt_list) if not token_list.peek().is_reserved("else"): break token_list.pop() t = token_list.pop() if t.is_reserved("if"): continue if not t.is_sym("{"): t.syntax_err("需要'{'") else_stmt_list = parse_stmt_list( token_list, module, cls, var_set_list + (larc_common.OrderedDict(), ), loop_deep) token_list.pop_sym("}") break stmt_list.append( _Stmt("if", if_expr_list=if_expr_list, if_stmt_list_list=if_stmt_list_list, else_stmt_list=else_stmt_list)) continue if t.is_sym and t.value in larc_token.INC_DEC_SYM_SET: inc_dec_op = t.value t = token_list.peek() lvalue = larc_expr.parse_expr(token_list, module, cls, var_set_list, non_local_var_used_map) if not lvalue.is_lvalue: t.syntax_err("非左值表达式不能做'%s'操作" % inc_dec_op) if lvalue.op in ("[:]", "tuple", "list"): t.syntax_err("分片和解包左值表达式不能做'%s'操作" % inc_dec_op) stmt_list.append(_Stmt(inc_dec_op, lvalue=lvalue)) token_list.pop_sym(";") continue #todo: try catch finally throw assert #剩下的就是表达式和赋值了 token_list.revert() expr = larc_expr.parse_expr(token_list, module, cls, var_set_list, non_local_var_used_map) if token_list.peek().is_sym(";"): #表达式 token_list.pop_sym(";") stmt_list.append(_Stmt("expr", expr=expr)) continue t = token_list.peek() if t.is_sym and t.value in larc_token.ASSIGN_SYM_SET: #赋值 assign_sym = t.value lvalue = expr if not lvalue.is_lvalue: t.syntax_err("赋值操作'%s'左边非左值表达式" % assign_sym) if assign_sym != "=": #增量赋值 if lvalue.op in ("[:]", "tuple", "list"): t.syntax_err("分片和解包左值表达式无法增量赋值") token_list.pop_sym(assign_sym) expr = larc_expr.parse_expr(token_list, module, cls, var_set_list, non_local_var_used_map) token_list.pop_sym(";") stmt_list.append(_Stmt(assign_sym, lvalue=lvalue, expr=expr)) continue t.syntax_err() return stmt_list
def __init__(self, name, name_token, base_class_module, base_class_name): self.name = name self.name_token = name_token self.base_class_module = base_class_module self.base_class_name = base_class_name self.method_map = larc_common.OrderedDict()
def get_array_construct_arg_map(): arg_map = larc_common.OrderedDict() arg_map["size"] = LONG_TYPE return arg_map
def _parse_for_prefix(self, var_map_stk): self.token_list.pop_sym("(") for_var_map = larc_common.OrderedDict() init_expr_list = [] closure_def_pos = 0 closure_def_map = {} #记录解析过程中遇到的closure的定义,{pos: [closure, ...]} def new_closure_hook(closure): if closure_def_pos not in closure_def_map: closure_def_map[closure_def_pos] = [] closure_def_map[closure_def_pos].append(closure) self.expr_parser.push_new_closure_hook(new_closure_hook) if self.token_list.peek().is_reserved("var"): #第一部分为var变量定义 self.token_list.pop() while True: _, _, expr, end_sym = self._parse_var( None, var_map_stk + (for_var_map, )) init_expr_list.append(expr) closure_def_pos += 1 if end_sym == ";": break assert end_sym == "," else: tp = larc_type.try_parse_type(self.token_list, self.module, self.dep_module_map, self.gtp_map, var_map_stk) if tp is None: #第一部分为表达式列表 if not self.token_list.peek().is_sym(";"): init_expr_list += self._parse_expr_list_with_se( var_map_stk + (for_var_map, )) self.token_list.pop_sym(";") else: #第一部分为若干指定类型的变量定义 while True: _, _, expr, end_sym = self._parse_var( tp, var_map_stk + (for_var_map, )) init_expr_list.append(expr) closure_def_pos += 1 if end_sym == ";": break assert end_sym == "," if self.token_list.peek().is_sym(";"): #没有第二部分 judge_expr = None else: judge_expr = self.expr_parser.parse(var_map_stk + (for_var_map, ), larc_type.BOOL_TYPE) self.token_list.pop_sym(";") loop_expr_list = [] if not self.token_list.peek().is_sym(")"): loop_expr_list += self._parse_expr_list_with_se(var_map_stk + (for_var_map, )) self.token_list.pop_sym(")") self.expr_parser.pop_new_closure_hook() return for_var_map, init_expr_list, judge_expr, loop_expr_list, closure_def_map
def parse(self, var_map_stk, need_type): start_token = self.token_list.peek() parse_stk = _ParseStk(start_token, self.curr_module, self.cls, self.fom) while True: t = self.token_list.pop() if t.is_sym and t.value in ("~", "!", "+", "-"): #单目运算 if t.value == "+": op = "pos" elif t.value == "-": op = "neg" else: op = t.value parse_stk.push_op(op) continue if t.is_sym("("): #子表达式 parse_stk.push_expr(self.parse(var_map_stk, None)) self.token_list.pop_sym(")") elif t.is_reserved("cast"): self.token_list.pop_sym("<") t = self.token_list.peek() tp = larc_type.try_parse_type( self.token_list, self.curr_module, self.dep_module_map, self.gtp_map, var_map_stk, used_dep_module_set=self.used_dep_module_set) if tp is None: t.syntax_err("需要类型") if tp == larc_type.VOID_TYPE: t.syntax_err("无效的类型强转:不能转为void类型") self.token_list.pop_sym(">") self.token_list.pop_sym("(") expr = self.parse(var_map_stk, None) self.token_list.pop_sym(")") if not tp.can_force_convert_from(expr.type): t.syntax_err("无效的强制类型转换:‘%s’到‘%s’" % (expr.type, tp)) parse_stk.push_expr(_Expr("force_convert", (tp, expr), tp)) elif t.is_name: if t.value in self.dep_module_map: m = larc_module.module_map[self.dep_module_map[t.value]] self.token_list.pop_sym(".") t, name = self.token_list.pop_name() expr = self._parse_func_or_global_var( m, (t, name), var_map_stk) parse_stk.push_expr(expr) else: for var_map in reversed(var_map_stk): if t.value in var_map: #局部变量 tp = var_map[t.value] if tp is None: #初始化变量的时候引用了变量本身 t.syntax_err("变量'%s'在初始化前使用" % (t.value)) parse_stk.push_expr(_Expr("local_var", t.value, tp)) break else: #当前模块或builtin模块 for m in self.curr_module, larc_module.builtins_module: if m.has_func(t.value) or m.has_global_var( t.value): expr = self._parse_func_or_global_var( m, (t, t.value), var_map_stk) parse_stk.push_expr(expr) break else: t.syntax_err("未定义的标识符'%s'" % t.value) elif t.is_literal: assert t.type.startswith("literal_") if t.type == "literal_int": #int字面量需要特殊处理 tp = larc_type.LITERAL_INT_TYPE else: tp = eval("larc_type.%s_TYPE" % t.type[8:].upper()) e = _Expr("literal", t, tp) if t.type == "literal_str" and self.token_list.peek().is_sym( ".") and self.token_list.peek(1).is_sym("("): #字符串常量的format语法 fmt, expr_list = self._parse_str_format(var_map_stk, t) e = _Expr("str_format", (fmt, expr_list), larc_type.STR_TYPE) parse_stk.push_expr(e) elif t.is_reserved("new"): base_type = larc_type.parse_type(self.token_list, self.dep_module_map, non_array=True) base_type.check(self.curr_module, self.gtp_map, self.used_dep_module_set) larc_module.check_new_ginst_during_compile() new_token = t t = self.token_list.pop() if t.is_sym("("): t = self.token_list.peek() expr_list = self._parse_expr_list(var_map_stk) is_new_cls = False if not (base_type.is_array or base_type.token.is_reserved): new_coi = base_type.get_coi() if new_coi.is_cls or new_coi.is_gcls_inst: if new_coi.module is not self.curr_module and "public" not in new_coi.construct_method.decr_set: base_type.token.syntax_err( "无法创建'%s'的实例:对构造方法无访问权限" % new_coi) self._make_expr_list_match_arg_map( t, expr_list, new_coi.construct_method.arg_map) parse_stk.push_expr( _Expr("new", expr_list, base_type)) is_new_cls = True if not is_new_cls: #对数组、基础类型、闭包或接口使用new语法 new_token.syntax_err("不能对类型'%s'使用new语法" % base_type) elif t.is_sym("["): if base_type.is_void: t.syntax_err("无法创建void数组") if self.token_list.peek().is_sym("]"): #通过初始化列表创建数组 self.token_list.pop_sym("]") init_list_type = base_type.to_array_type(1) while self.token_list.peek().is_sym("["): self.token_list.pop_sym("[") self.token_list.pop_sym("]") init_list_type = init_list_type.to_array_type(1) larc_module.check_new_ginst_during_compile() parse_stk.push_expr( self._parse_init_list(var_map_stk, init_list_type)) else: #创建普通数组 size_list = [ self.parse(var_map_stk, larc_type.VALID_ARRAY_SIZE_TYPES) ] init_dim_count = 1 self.token_list.pop_sym("]") while self.token_list.peek().is_sym("["): self.token_list.pop_sym("[") t = self.token_list.peek() if t.is_sym("]"): size_list.append(None) self.token_list.pop_sym("]") continue if size_list[-1] is None: t.syntax_err("需要']'") size_list.append( self.parse(var_map_stk, larc_type.VALID_ARRAY_SIZE_TYPES)) init_dim_count += 1 self.token_list.pop_sym("]") array_base_type = base_type while array_base_type.is_array: array_base_type = array_base_type.to_elem_type() size_list.append(None) array_type = array_base_type.to_array_type( len(size_list)) larc_module.check_new_ginst_during_compile() parse_stk.push_expr( _Expr("new_array", (array_base_type, size_list), array_type)) elif t.is_sym("{"): new_coi = None if base_type.is_coi_type: coi = base_type.get_coi() if coi.is_cls or coi.is_gcls_inst: new_coi = coi if new_coi is None: base_type.token.syntax_err("'%s'不是类,不能按属性初始化" % base_type) attr_map = new_coi.get_initable_attr_map( base_type.token, self.curr_module) attr_init_map = larc_common.OrderedDict() #根据下面两个token判定是否指定属性名来初始化 revert_idx = self.token_list.i t1 = self.token_list.pop() t2 = self.token_list.pop() self.token_list.revert(revert_idx) is_initing_by_attr_name = t1.is_name and t2.is_sym(":") while True: t = self.token_list.peek() if t.is_sym("}"): self.token_list.pop_sym() break if is_initing_by_attr_name: t, name = self.token_list.pop_name() if name not in attr_map: t.syntax_err("类'%s'没有属性'%s'或不可初始化它" % (base_type, name)) if name in attr_init_map: t.syntax_err("属性'%s'重复初始化" % (name)) self.token_list.pop_sym(":") else: key_idx = len(attr_init_map) if key_idx >= len(attr_map): t.syntax_err("过多的初始化值") name = attr_map.key_at(key_idx) attr_init_map[name] = self.parse( var_map_stk, attr_map[name]) t = self.token_list.peek() if not (t.is_sym and t.value in ("}", ",")): t.syntax_err("需要','或'}'") if t.value == ",": self.token_list.pop_sym() for name, tp in attr_map.iteritems(): if name not in attr_init_map: attr_init_map[name] = _Expr( "default_value", tp, tp) parse_stk.push_expr( _Expr("new_obj_init_by_attr", attr_init_map, base_type)) else: t.syntax_err("需要'('或'['") elif t.is_reserved("this"): if self.cls is None: t.syntax_err("'this'只能用于方法中") parse_stk.push_expr( _Expr("this", t, larc_type.gen_type_from_cls(self.cls))) elif t.is_sym("["): #闭包对象 if self.fom is None: t.syntax_err("闭包只能用于函数或方法中") is_simple_callable = False next_t = self.token_list.pop() if next_t.is_sym("-"): self.token_list.pop_sym("]") is_simple_callable = True elif not next_t.is_sym("]"): next_t.syntax_err("闭包表达式语法错误") closure_token = larc_token.make_fake_token_name( "closure").copy_on_pos(t) closure = self.curr_module.new_closure(self.file_name, closure_token, self.cls, self.gtp_map, var_map_stk) closure.parse(self.token_list, is_simple_callable) self.new_closure_hook_stk[-1](closure) parse_stk.push_expr( _Expr("closure", closure, larc_type.gen_closure_type(closure))) else: t.syntax_err("非法的表达式") assert parse_stk.stk #解析后缀运算符 while self.token_list: t = self.token_list.pop() if t.is_sym("["): is_slice = False if self.token_list.peek().is_sym(":"): expr = None is_slice = True else: expr = self.parse(var_map_stk, larc_type.VALID_ARRAY_IDX_TYPES) if self.token_list.peek().is_sym(":"): self.token_list.pop_sym(":") if self.token_list.peek().is_sym("]"): slice_end_expr = None else: slice_end_expr = self.parse( var_map_stk, larc_type.VALID_ARRAY_IDX_TYPES) is_slice = True self.token_list.pop_sym("]") array_expr = parse_stk.stk[-1] if not array_expr.type.is_array: t.syntax_err("'%s'非数组,不能进行下标或分片运算" % array_expr.type) if is_slice: parse_stk.stk[-1] = _Expr( "[:]", [array_expr, expr, slice_end_expr], array_expr.type) else: parse_stk.stk[-1] = _Expr( "[]", [array_expr, expr], array_expr.type.to_elem_type()) elif t.is_sym("."): t, name = self.token_list.pop_name() obj = parse_stk.stk[-1] if obj.type.is_array: #数组 method = larc_type.get_array_method(obj.type, name) if method is None: t.syntax_err("数组没有方法'%s'" % name) self.token_list.pop_sym("(") t = self.token_list.peek() expr_list = self._parse_expr_list(var_map_stk) self._make_expr_list_match_arg_map( t, expr_list, method.arg_map) parse_stk.stk[-1] = _Expr( "call_array.method", (parse_stk.stk[-1], method, expr_list), method.type) else: if obj.type.token.is_reserved: t.syntax_err("不能对基础类型取属性或调用方法") obj_coi = obj.type.get_coi() method, attr = obj_coi.get_method_or_attr(name, t) if method is not None: assert attr is None self.token_list.pop_sym("(") if method.module is not self.curr_module and "public" not in method.decr_set: t.syntax_err("无法使用方法'%s':没有权限" % method) t = self.token_list.peek() expr_list = self._parse_expr_list(var_map_stk) self._make_expr_list_match_arg_map( t, expr_list, method.arg_map) parse_stk.stk[-1] = _Expr( "call_method", (parse_stk.stk[-1], method, expr_list), method.type) else: assert attr is not None and method is None if attr.module is not self.curr_module and "public" not in attr.decr_set: t.syntax_err("无法访问属性'%s':没有权限" % attr) parse_stk.stk[-1] = _Expr( ".", (parse_stk.stk[-1], attr), attr.type) else: self.token_list.revert() break if _is_expr_end(self.token_list.peek()): #表达式结束 break #状态:解析普通二元运算符 t = self.token_list.pop() if (t.is_sym and t.value in _BINOCULAR_OP_SET) or ( t.is_reserved and t.value in ("if", "else")): #二、三元运算 parse_stk.push_op(t.value) else: t.syntax_err("需要二元或三元运算符") expr = parse_stk.finish() expr_pos_info = expr.pos_info #保存一下pos info if need_type is not None: if isinstance(need_type, (tuple, list)): need_type_list = list(need_type) else: need_type_list = [need_type] for need_type in need_type_list: if need_type == expr.type: break if expr.op == "literal" and expr.type == larc_type.LITERAL_INT_TYPE and need_type.is_number_type: e = _convert_literal_int_expr(expr, need_type) if e is None: continue expr = e if expr is not None and need_type.can_convert_from(expr.type): if need_type != expr.type: expr = _Expr("force_convert", (need_type, expr), need_type) break else: if len(need_type_list) == 1: start_token.syntax_err("表达式(类型'%s')无法隐式转换为类型'%s'" % (expr.type, need_type_list[0])) else: start_token.syntax_err("表达式(类型'%s')无法隐式转换为类型%s其中任意一个" % (expr.type, str(need_type_list))) expr.pos_info = expr_pos_info #expr可能根据need_tyep修改了,恢复一下pos info return expr
def _parse(self, var_map_stk, loop_deep, stmt_list): top_ccc_use_deep = self.ccc_use_deep while True: if self.token_list.peek().is_sym("}"): assert self.ccc_use_deep == top_ccc_use_deep break t = self.token_list.pop() def ccc_jmp(): #跳过ccc块,返回跳过的块的结束ccc token nested_ccc_stk = [] while True: t = self.token_list.pop() if t.is_ccc("use"): nested_ccc_stk.append("use") elif t.is_ccc("if"): nested_ccc_stk.append("if") elif any([ t.is_ccc(ccc) for ccc in ("oruse", "else_of_use", "enduse", "elif", "else_of_if", "endif") ]): if not nested_ccc_stk: return t if any([ t.is_ccc(ccc) for ccc in ("oruse", "else_of_use", "enduse") ]): assert nested_ccc_stk[-1] == "use" if any([ t.is_ccc(ccc) for ccc in ("elif", "else_of_if", "endif") ]): assert nested_ccc_stk[-1] == "if" if any([t.is_ccc(ccc) for ccc in ("enduse", "endif")]): nested_ccc_stk.pop() if t.is_ccc("use"): self.ccc_use_deep += 1 while True: result = larc_common.fork() if result is None: #子进程 work_ccc_use_deep = self.ccc_use_deep #记录子进程工作的deep break #父进程,根据子进程的编译结果,若失败则继续下一个use block if result == "1": #成功,父进程在这个point继续编译 break #失败了,跳过这个use block继续尝试下一个 assert result == "" t = ccc_jmp() if t.is_ccc("else_of_use"): #已经是最后一个了,以这个为准 break assert t.is_ccc("oruse") continue if any( [t.is_ccc(ccc) for ccc in ("oruse", "else_of_use", "enduse")]): assert self.ccc_use_deep > top_ccc_use_deep if larc_common.is_child( ) and self.ccc_use_deep == work_ccc_use_deep: #子进程尝试成功,汇报给父进程 larc_common.child_exit_succ("1") #当前进程为一个父进程,成功选择了一个use block,跳到enduse继续编译 self.token_list.revert() while not ccc_jmp().is_ccc("enduse"): pass self.ccc_use_deep -= 1 continue if t.is_ccc("if"): while True: ccc_if_arg_t = self.token_list.pop() assert ccc_if_arg_t.is_sub_token_list ccc_if_token_list = ccc_if_arg_t.value ccc_if_result = self._eval_ccc_if(var_map_stk, ccc_if_arg_t.value) assert ccc_if_token_list end_tag_t = ccc_if_token_list.pop() if not end_tag_t.is_end_tag: end_tag_t.syntax_err() if ccc_if_result: #选择这个block break t = ccc_jmp() if t.is_ccc("else_of_if"): #已经是最后一个了,以这个为准 break assert t.is_ccc("elif") continue if any([t.is_ccc(ccc) for ccc in ("elif", "else_of_if", "endif")]): #跳到endif继续编译 self.token_list.revert() while not ccc_jmp().is_ccc("endif"): pass continue if t.is_ccc("error"): ccc_err_msg_t = self.token_list.pop() assert ccc_err_msg_t.is_literal("str") ccc_err_msg = ccc_err_msg_t.value t.syntax_err(ccc_err_msg) if t.is_sym(";"): t.warning("空语句") continue if t.is_sym("{"): #新代码块 stmt_list.append( _Stmt("block", stmt_list=self.parse( var_map_stk + (larc_common.OrderedDict(), ), loop_deep))) self.token_list.pop_sym("}") continue if t.is_reserved and t.value in ("break", "continue"): if loop_deep == 0: t.syntax_err("循环外的%s" % t.value) stmt_list.append(_Stmt(t.value)) self.token_list.pop_sym(";") continue if t.is_reserved("return"): stmt_list.append( _Stmt("return", expr=self._parse_return(var_map_stk))) continue if t.is_reserved("for"): for_var_map, init_expr_list, judge_expr, loop_expr_list, closure_def_map = self._parse_for_prefix( var_map_stk) self.token_list.pop_sym("{") for_stmt_list = self.parse( var_map_stk + (for_var_map.copy(), ), loop_deep + 1) self.token_list.pop_sym("}") stmt_list.append( _Stmt("for", for_var_map=for_var_map, init_expr_list=init_expr_list, judge_expr=judge_expr, loop_expr_list=loop_expr_list, closure_def_map=closure_def_map, stmt_list=for_stmt_list)) continue if t.is_reserved("foreach"): var_tp, var_name, iter_expr = self._parse_foreach_prefix( var_map_stk) foreach_var_map = larc_common.OrderedDict() foreach_var_map[var_name] = var_tp self.token_list.pop_sym("{") foreach_stmt_list = self.parse( var_map_stk + (foreach_var_map, ), loop_deep + 1) self.token_list.pop_sym("}") stmt_list.append( _Stmt("foreach", var_tp=var_tp, var_name=var_name, iter_expr=iter_expr, stmt_list=foreach_stmt_list)) continue if t.is_reserved("while"): self.token_list.pop_sym("(") expr = self.expr_parser.parse(var_map_stk, larc_type.BOOL_TYPE) self.token_list.pop_sym(")") self.token_list.pop_sym("{") while_stmt_list = self.parse( var_map_stk + (larc_common.OrderedDict(), ), loop_deep + 1) self.token_list.pop_sym("}") stmt_list.append( _Stmt("while", expr=expr, stmt_list=while_stmt_list)) continue if t.is_reserved("if"): if_expr_list = [] if_stmt_list_list = [] else_stmt_list = None while True: self.token_list.pop_sym("(") expr = self.expr_parser.parse(var_map_stk, larc_type.BOOL_TYPE) self.token_list.pop_sym(")") self.token_list.pop_sym("{") if_stmt_list = self.parse( var_map_stk + (larc_common.OrderedDict(), ), loop_deep) self.token_list.pop_sym("}") if_expr_list.append(expr) if_stmt_list_list.append(if_stmt_list) if not self.token_list.peek().is_reserved("else"): break self.token_list.pop() t = self.token_list.pop() if t.is_reserved("if"): continue if not t.is_sym("{"): t.syntax_err("需要'{'") else_stmt_list = self.parse( var_map_stk + (larc_common.OrderedDict(), ), loop_deep) self.token_list.pop_sym("}") break stmt_list.append( _Stmt("if", if_expr_list=if_expr_list, if_stmt_list_list=if_stmt_list_list, else_stmt_list=else_stmt_list)) continue if t.is_reserved("var"): while True: tp, name, expr, end_sym = self._parse_var( None, var_map_stk) stmt_list.append(_Stmt("var", name=name, expr=expr)) if end_sym == ";": break assert end_sym == "," continue if t.is_reserved("defer"): expr = self.expr_parser.parse(var_map_stk, None) if expr.op not in ("call_method", "call_func"): t.syntax_err("defer表达式必须是一个函数或方法调用") stmt_list.append(_Stmt("defer_expr", expr=expr)) self.token_list.pop_sym(";") continue if t.is_native_code: stmt_list.append( _Stmt("native_code", native_code=larc_module.NativeCode( self.module, self.file_name, self.gtp_map, t), fom=self.fom)) continue if t.is_reserved("else"): t.syntax_err("未匹配if的else") self.token_list.revert() tp = larc_type.try_parse_type(self.token_list, self.module, self.dep_module_map, self.gtp_map, var_map_stk) if tp is not None: #变量定义 while True: _, name, expr, end_sym = self._parse_var(tp, var_map_stk) stmt_list.append(_Stmt("var", name=name, expr=expr)) if end_sym == ";": break assert end_sym == "," continue #表达式 expr = self._parse_expr_with_se(var_map_stk) self._check_valid_expr_stmt(t, expr) stmt_list.append(_Stmt("expr", expr=expr)) self.token_list.pop_sym(";") continue