예제 #1
0
    def generate_code(self, pos_name="pos"):

        self.get_type().add_to_context()
        cpos = gen_name("lst_cpos")
        parser_context = self.parser.gen_code_or_fncall(cpos)
        sep_context = (self.sep.gen_code_or_fncall(cpos) if self.sep else
                       ParserCodeContext(None, None, None, []))

        t_env = TemplateEnvironment(pos_name=pos_name,
                                    parser=self,
                                    pos=gen_name("lst_pos"),
                                    res=gen_name("lst_res"),
                                    cpos=cpos,
                                    parser_context=parser_context,
                                    sep_context=sep_context)

        decls = [
            (t_env.pos, Token),
            (t_env.res, self.get_type()),
            (t_env.cpos, Token),
        ] + parser_context.var_defs + sep_context.var_defs

        return ParserCodeContext(pos_var_name=t_env.pos,
                                 res_var_name=t_env.res,
                                 code=render('parsers/list_code_ada', t_env),
                                 var_defs=decls)
예제 #2
0
    def generate_code(self, pos_name="pos"):
        pos, res = gen_names('or_pos', 'or_res')
        t_env = TemplateEnvironment(
            parser=self,

            # List of ParserCodeContext instances for the sub-parsers,
            # encapsulating their results.
            results=[m.gen_code_or_fncall(pos_name) for m in self.parsers],

            # Generate a name for the exit label (when one of the sub-parsers
            # has matched).
            exit_label=gen_name("Exit_Or"),
            pos=pos,
            res=res)

        code = render('parsers/or_code_ada', t_env)

        return ParserCodeContext(
            pos_var_name=t_env.pos,
            res_var_name=t_env.res,
            code=code,

            # For var defs, we create a new list that is the concatenation of
            # all the sub parsers variable definitions, adding the Or parser's
            # own pos and res variables.
            var_defs=list(
                chain([(pos, Token), (res, self.get_type())],
                      *[sr.var_defs for sr in t_env.results])))
예제 #3
0
    def generate_code(self, pos_name="pos"):

        self.typ.add_to_context()

        parser_context = self.parser.gen_code_or_fncall(pos_name)
        ":type: ParserCodeContext"

        t_env = TemplateEnvironment(
            parser=self,
            # The template needs the compiler context to retrieve the types of
            # the tree fields (required by get_types()).
            parser_context=parser_context,
            args=(self.parser.args if isinstance(self.parser, Row) else
                  [parser_context.res_var_name]),
            res=gen_name("transform_res"),
        )

        return copy_with(parser_context,
                         res_var_name=t_env.res,
                         var_defs=parser_context.var_defs + [
                             (t_env.res, self.get_type()),
                         ],
                         code=render('parsers/transform_code_ada',
                                     t_env,
                                     pos_name=pos_name))
예제 #4
0
파일: parsers.py 프로젝트: AdaCore/langkit
    def compile(self):
        """
        Emit code for this parser as a function into the global context.
        """
        t_env = TemplateEnvironment()
        t_env._self = self

        # Don't emit code twice for the same parser
        if self.gen_fn_name in get_context().fns:
            return
        get_context().fns.add(self.gen_fn_name)

        t_env.parser_context = (
            self.generate_code()
        )

        get_context().generated_parsers.append(GeneratedParser(
            self.gen_fn_name,
            render('parsers/fn_profile_ada', t_env),
            render('parsers/fn_code_ada', t_env)))
예제 #5
0
파일: parsers.py 프로젝트: AdaCore/langkit
    def generate_code(self, pos_name="pos"):
        t_env = TemplateEnvironment(pos_name=pos_name)
        t_env._self = self

        t_env.pos, t_env.res = gen_names("row_pos", "row_res")
        decls = [(t_env.pos, Token)]

        t_env.subresults = list(gen_names(*[
            "row_subres_{0}".format(i)
            for i in range(len(self.parsers))
        ]))
        t_env.exit_label = gen_name("row_exit_label")

        self.args = [r for r, m in zip(t_env.subresults, self.parsers)
                     if not m.discard()]
        self.allargs = [r for r, m in zip(t_env.subresults, self.parsers)]

        bodies = []
        for i, (parser, subresult) in enumerate(zip(self.parsers,
                                                    t_env.subresults)):
            t_subenv = TemplateEnvironment(
                t_env, parser=parser, subresult=subresult, i=i,
                parser_context=parser.gen_code_or_fncall(t_env.pos)
            )
            decls += t_subenv.parser_context.var_defs
            if not parser.discard():
                decls.append((subresult, parser.get_type()))

            bodies.append(render('parsers/row_submatch_ada', t_subenv))

        code = render('parsers/row_code_ada', t_env, body='\n'.join(bodies))

        return ParserCodeContext(
            pos_var_name=t_env.pos,
            res_var_name=t_env.res,
            code=code,
            var_defs=decls
        )
예제 #6
0
    def compile(self):
        """
        Emit code for this parser as a function into the global context.
        """
        t_env = TemplateEnvironment()
        t_env.parser = self

        check_source_language(
            self.get_type() is not None
            and issubclass(self.get_type(), ASTNode),
            'Grammar rules must yield an AST node')

        # Don't emit code twice for the same parser
        if self.gen_fn_name in get_context().fns:
            return
        get_context().fns.add(self.gen_fn_name)

        t_env.parser_context = self.generate_code()

        get_context().generated_parsers.append(
            GeneratedParser(self.gen_fn_name,
                            render('parsers/fn_profile_ada', t_env),
                            render('parsers/fn_code_ada', t_env)))
예제 #7
0
    def generate_code(self, pos_name="pos"):
        parser_context = copy(self.parser.gen_code_or_fncall(pos_name))

        t_env = TemplateEnvironment(pos_name=pos_name,
                                    parser=self,
                                    bool_res=gen_name("opt_bool_res"),
                                    parser_context=parser_context)

        return copy_with(
            parser_context,
            code=render('parsers/opt_code_ada', t_env),
            res_var_name=(t_env.bool_res if self._booleanize else
                          parser_context.res_var_name),
            var_defs=(parser_context.var_defs +
                      ([(t_env.bool_res,
                         self._booleanize[0])] if self._booleanize else [])))
예제 #8
0
    def generate_code(self, pos_name="pos"):

        self.enum_type_inst.add_to_context()

        parser_context = (
            copy(self.parser.gen_code_or_fncall(pos_name))
            if self.parser else ParserCodeContext(
                pos_var_name=pos_name, res_var_name="", code="", var_defs=[]))

        env = TemplateEnvironment(parser=self,
                                  res=gen_name("enum_res"),
                                  parser_context=parser_context)

        return copy_with(parser_context,
                         res_var_name=env.res,
                         code=render('parsers/enum_code_ada', env),
                         var_defs=parser_context.var_defs +
                         [(env.res, self.get_type())])
예제 #9
0
    def generate_code(self, pos_name="pos"):
        t_env = TemplateEnvironment(pos_name=pos_name)
        t_env.parser = self

        t_env.pos, t_env.res = gen_names("row_pos", "row_res")
        decls = [(t_env.pos, Token)]

        t_env.subresults = list(
            gen_names(
                *
                ["row_subres_{0}".format(i)
                 for i in range(len(self.parsers))]))
        t_env.exit_label = gen_name("row_exit_label")

        self.args = [
            r for r, m in zip(t_env.subresults, self.parsers)
            if not m.discard()
        ]
        self.allargs = [r for r, m in zip(t_env.subresults, self.parsers)]

        bodies = []
        for i, (parser,
                subresult) in enumerate(zip(self.parsers, t_env.subresults)):
            t_subenv = TemplateEnvironment(
                t_env,
                parser=parser,
                subresult=subresult,
                i=i,
                parser_context=parser.gen_code_or_fncall(t_env.pos))
            decls += t_subenv.parser_context.var_defs
            if not parser.discard():
                decls.append((subresult, parser.get_type()))

            bodies.append(render('parsers/row_submatch_ada', t_subenv))

        code = render('parsers/row_code_ada', t_env, body='\n'.join(bodies))

        return ParserCodeContext(pos_var_name=t_env.pos,
                                 res_var_name=t_env.res,
                                 code=code,
                                 var_defs=decls)