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)
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])))
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))
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)))
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 )
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)))
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 [])))
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())])
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)