Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.3k
Closed
Description
Bug report
In the following part of pegen, the memoized result is only used ifself._should_memoize(node) is true. Since loop rules are autogenerated, they are not marked with(memo), so this is always false. Despite that, in the end the result is memoized based on the different conditionif node.name. Because of that, in the generated parser loop rules' results are always stored in the cache, but never accessed later.
cpython/Tools/peg_generator/pegen/c_generator.py
Lines 608 to 647 in8de59c1
| def_handle_loop_rule_body(self,node:Rule,rhs:Rhs)->None: | |
| memoize=self._should_memoize(node) | |
| is_repeat1=node.name.startswith("_loop1") | |
| withself.indent(): | |
| self.add_level() | |
| self._check_for_errors() | |
| self.print("void *_res = NULL;") | |
| ifmemoize: | |
| self.print(f"if (_PyPegen_is_memoized(p,{node.name}_type, &_res)) {{") | |
| withself.indent(): | |
| self.add_return("_res") | |
| self.print("}") | |
| self.print("int _mark = p->mark;") | |
| self.print("int _start_mark = p->mark;") | |
| self.print("void **_children = PyMem_Malloc(sizeof(void *));") | |
| self.out_of_memory_return(f"!_children") | |
| self.print("Py_ssize_t _children_capacity = 1;") | |
| self.print("Py_ssize_t _n = 0;") | |
| ifany(alt.actionand"EXTRA"inalt.actionforaltinrhs.alts): | |
| self._set_up_token_start_metadata_extraction() | |
| self.visit( | |
| rhs, | |
| is_loop=True, | |
| is_gather=node.is_gather(), | |
| rulename=node.name, | |
| ) | |
| ifis_repeat1: | |
| self.print("if (_n == 0 || p->error_indicator) {") | |
| withself.indent(): | |
| self.print("PyMem_Free(_children);") | |
| self.add_return("NULL") | |
| self.print("}") | |
| self.print("asdl_seq *_seq = (asdl_seq*)_Py_asdl_generic_seq_new(_n, p->arena);") | |
| self.out_of_memory_return(f"!_seq",cleanup_code="PyMem_Free(_children);") | |
| self.print("for (int i = 0; i < _n; i++) asdl_seq_SET_UNTYPED(_seq, i, _children[i]);") | |
| self.print("PyMem_Free(_children);") | |
| ifnode.name: | |
| self.print(f"_PyPegen_insert_memo(p, _start_mark,{node.name}_type, _seq);") | |
| self.add_return("_seq") |
Your environment
Does not matter - discovered through manual code analysis