Beispiel #1
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)
Beispiel #2
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)))