コード例 #1
0
ファイル: larc_module.py プロジェクト: wowngasb/larva-lang_4j
 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)
コード例 #2
0
ファイル: larc_module.py プロジェクト: wowngasb/larva-lang_4j
 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)
コード例 #3
0
    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()
コード例 #4
0
ファイル: larc.py プロジェクト: wowngasb/larva-lang_4j
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)
コード例 #5
0
ファイル: larc_type.py プロジェクト: fibphp/larva-lang
    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
コード例 #6
0
ファイル: larc_module.py プロジェクト: wowngasb/larva-lang_4j
 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()
コード例 #7
0
 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()
コード例 #8
0
ファイル: larc_stmt.py プロジェクト: fibphp/larva-lang
    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
コード例 #9
0
 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)
コード例 #10
0
 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()
コード例 #11
0
#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
コード例 #12
0
ファイル: larc_type.py プロジェクト: fibphp/larva-lang
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
コード例 #13
0
ファイル: larc_stmt.py プロジェクト: github1-2-3/larva-lang
    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
コード例 #14
0
ファイル: larc_stmt.py プロジェクト: markhsiu/dsl-larva-lang
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
コード例 #15
0
ファイル: larc_module.py プロジェクト: wowngasb/larva-lang_4j
 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()
コード例 #16
0
ファイル: larc_type.py プロジェクト: fibphp/larva-lang
def get_array_construct_arg_map():
    arg_map = larc_common.OrderedDict()
    arg_map["size"] = LONG_TYPE
    return arg_map
コード例 #17
0
    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
コード例 #18
0
ファイル: larc_expr.py プロジェクト: larva-lang/larva-lang
    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
コード例 #19
0
    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