def visit_Rule(self, node: Rule) -> None: is_loop = node.is_loop() is_gather = node.is_gather() rhs = node.flatten() if is_loop or is_gather: result_type = "asdl_seq *" elif node.type: result_type = node.type else: result_type = "void *" for line in str(node).splitlines(): self.print(f"// {line}") if node.left_recursive and node.leader: self.print(f"static {result_type} {node.name}_raw(Parser *);") self.print(f"static {result_type}") self.print(f"{node.name}_rule(Parser *p)") if node.left_recursive and node.leader: self._set_up_rule_memoization(node, result_type) self.print("{") if is_loop: self._handle_loop_rule_body(node, rhs) else: self._handle_default_rule_body(node, rhs, result_type) self.print("}")
def visit_Rule(self, node: Rule) -> None: is_loop = node.is_loop() is_gather = node.is_gather() rhs = node.flatten() if node.left_recursive: if node.leader: self.print("@memoize_left_rec") else: # Non-leader rules in a cycle are not memoized, # but they must still be logged. self.print("@logger") else: self.print("@memoize") node_type = node.type or "Any" self.print(f"def {node.name}(self) -> Optional[{node_type}]:") with self.indent(): self.print(f"# {node.name}: {rhs}") if node.nullable: self.print(f"# nullable={node.nullable}") self.print("mark = self.mark()") if is_loop: self.print("children = []") self.visit(rhs, is_loop=is_loop, is_gather=is_gather) if is_loop: self.print("return children") else: self.print("return None")
def visit_Rule(self, node: Rule) -> None: is_loop = node.is_loop() is_gather = node.is_gather() rhs = node.flatten() if node.left_recursive: if node.leader: self.print("@memoize_left_rec") else: # Non-leader rules in a cycle are not memoized, # but they must still be logged. self.print("@logger") else: self.print("@memoize") node_type = node.type or "Any" self.print(f"def {node.name}(self) -> Optional[{node_type}]:") with self.indent(): self.print(f"# {node.name}: {rhs}") self.print("mark = self._mark()") if self.alts_uses_locations(node.rhs.alts): self.print("tok = self._tokenizer.peek()") self.print("start_lineno, start_col_offset = tok.start") if is_loop: self.print("children = []") self.visit(rhs, is_loop=is_loop, is_gather=is_gather) if is_loop: self.print("return children") else: self.print("return None")
def visit_Rule(self, node: Rule) -> None: is_loop = node.is_loop() is_gather = node.is_gather() rhs = node.flatten() if is_loop or is_gather: result_type = "asdl_seq *" elif node.type: result_type = node.type else: result_type = "void *" for line in str(node).splitlines(): self.print(f"// {line}") if node.left_recursive and node.leader: self.print(f"static {result_type} {node.name}_raw(Parser *);") self.print(f"static {result_type}") self.print(f"{node.name}_rule(Parser *p)") if node.left_recursive and node.leader: self._set_up_rule_memoization(node, result_type) self.print("{") if node.name.endswith("without_invalid"): with self.indent(): self.print("int _prev_call_invalid = p->call_invalid_rules;") self.print("p->call_invalid_rules = 0;") self.cleanup_statements.append( "p->call_invalid_rules = _prev_call_invalid;") if is_loop: self._handle_loop_rule_body(node, rhs) else: self._handle_default_rule_body(node, rhs, result_type) if node.name.endswith("without_invalid"): self.cleanup_statements.pop() self.print("}")
def visit_Rule(self, node: Rule) -> None: is_loop = node.is_loop() is_repeat1 = node.name.startswith("_loop1") memoize = not node.left_recursive rhs = node.flatten() if is_loop: type = "asdl_seq *" elif node.type: type = node.type else: type = "void *" self.print(f"// {node}") if node.left_recursive and node.leader: self.print(f"static {type} {node.name}_raw(Parser *);") self.print(f"static {type}") self.print(f"{node.name}_rule(Parser *p)") if node.left_recursive and node.leader: self.print("{") with self.indent(): self.print(f"{type} res = NULL;") self.print(f"if (is_memoized(p, {node.name}_type, &res))") with self.indent(): self.print("return res;") self.print("int mark = p->mark;") self.print("int resmark = p->mark;") self.print("while (1) {") with self.indent(): self.call_with_errorcheck_return( f"update_memo(p, mark, {node.name}_type, res)", "res") self.print("p->mark = mark;") self.print(f"void *raw = {node.name}_raw(p);") self.print("if (raw == NULL || p->mark <= resmark)") with self.indent(): self.print("break;") self.print("resmark = p->mark;") self.print("res = raw;") self.print("}") self.print("p->mark = resmark;") self.print("return res;") self.print("}") self.print(f"static {type}") self.print(f"{node.name}_raw(Parser *p)") self.print("{") with self.indent(): if is_loop: self.print(f"void *res = NULL;") else: self.print(f"{type} res = NULL;") if memoize: self.print(f"if (is_memoized(p, {node.name}_type, &res))") with self.indent(): self.print("return res;") self.print("int mark = p->mark;") if is_loop: self.print("void **children = PyMem_Malloc(0);") self.out_of_memory_return(f"!children", "NULL") self.print("ssize_t n = 0;") self.visit(rhs, is_loop=is_loop, rulename=node.name if memoize else None) if is_loop: if is_repeat1: self.print("if (n == 0) {") with self.indent(): self.print("PyMem_Free(children);") self.print("return NULL;") self.print("}") self.print("asdl_seq *seq = _Py_asdl_seq_new(n, p->arena);") self.out_of_memory_return(f"!seq", "NULL", message=f"asdl_seq_new {node.name}") self.print( "for (int i = 0; i < n; i++) asdl_seq_SET(seq, i, children[i]);" ) self.print("PyMem_Free(children);") if node.name: self.print(f"insert_memo(p, mark, {node.name}_type, seq);") self.print("return seq;") else: if self.debug: self.print( f'fprintf(stderr, "Fail at %d: {node.name}\\n", p->mark);' ) self.print("res = NULL;") if not is_loop: self.print(" done:") with self.indent(): if memoize: self.print(f"insert_memo(p, mark, {node.name}_type, res);") self.print("return res;") self.print("}")