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)
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)))