File: memo.py

package info (click to toggle)
python-pegen 0.3.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,980 kB
  • sloc: python: 15,064; makefile: 89
file content (45 lines) | stat: -rw-r--r-- 1,414 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
def memoize(func):
    """Memoize a parsing method.

    The functon must be a method on a class deriving from Parser.

    The method must have either no arguments or a single argument that
    is an int or str (the latter being the case for expect()).

    It must return either None or an object that is not modified (at
    least not while we're parsing).

    We memoize positive and negative outcomes per input position.

    The function is expected to move the input position iff it returns
    a not-None value.

    The memo is structured as a dict of dict, the outer dict indexed
    by input position, the inner by function and arguments.
    """

    def memoize_wrapper(self, *args):
        vis = self.tokenizer.vis
        pos = self.mark()
        if vis is not None:
            vis.show_call(pos, func.__name__, args)
        memo = self.memos.get(pos)
        if memo is None:
            memo = self.memos[pos] = {}
        key = (func, args)
        if key in memo:
            res, endpos = memo[key]
            self.reset(endpos)
        else:
            res = func(self, *args)
            endpos = self.mark()
            if res is None:
                assert endpos == pos
            else:
                assert endpos > pos
            memo[key] = res, endpos
        if vis is not None:
            vis.show_return(pos, res, endpos)
        return res

    return memoize_wrapper