MCPcopy Index your code
hub / github.com/python/cpython / memoize_left_rec_wrapper

Function memoize_left_rec_wrapper

Tools/peg_generator/pegen/parser.py:83–155  ·  view source on GitHub ↗
(self: "Parser")

Source from the content-addressed store, hash-verified

81 method_name = method.__name__
82
83 def memoize_left_rec_wrapper(self: "Parser") -> T | None:
84 mark = self._mark()
85 key = mark, method_name, ()
86 # Fast path: cache hit, and not verbose.
87 if key in self._cache and not self._verbose:
88 tree, endmark = self._cache[key]
89 self._reset(endmark)
90 return tree
91 # Slow path: no cache hit, or verbose.
92 verbose = self._verbose
93 fill = " " * self._level
94 if key not in self._cache:
95 if verbose:
96 print(f"{fill}{method_name} ... (looking at {self.showpeek()})")
97 self._level += 1
98
99 # For left-recursive rules we manipulate the cache and
100 # loop until the rule shows no progress, then pick the
101 # previous result. For an explanation why this works, see
102 # https://github.com/PhilippeSigaud/Pegged/wiki/Left-Recursion
103 # (But we use the memoization cache instead of a static
104 # variable; perhaps this is similar to a paper by Warth et al.
105 # (http://web.cs.ucla.edu/~todd/research/pub.php?id=pepm08).
106
107 # Prime the cache with a failure.
108 self._cache[key] = None, mark
109 lastresult, lastmark = None, mark
110 depth = 0
111 if verbose:
112 print(f"{fill}Recursive {method_name} at {mark} depth {depth}")
113
114 while True:
115 self._reset(mark)
116 self.in_recursive_rule += 1
117 try:
118 result = method(self)
119 finally:
120 self.in_recursive_rule -= 1
121 endmark = self._mark()
122 depth += 1
123 if verbose:
124 print(
125 f"{fill}Recursive {method_name} at {mark} depth {depth}: {result!s:.200} to {endmark}"
126 )
127 if not result:
128 if verbose:
129 print(f"{fill}Fail with {lastresult!s:.200} to {lastmark}")
130 break
131 if endmark <= lastmark:
132 if verbose:
133 print(f"{fill}Bailing with {lastresult!s:.200} to {lastmark}")
134 break
135 self._cache[key] = lastresult, lastmark = result, endmark
136
137 self._reset(lastmark)
138 tree = lastresult
139
140 self._level -= 1

Callers

nothing calls this directly

Calls 3

methodFunction · 0.85
showpeekMethod · 0.80
_resetMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…