Commit d9b26f0c authored by di68kap's avatar di68kap
Browse files

- parser.py: full memoization simplified

parent 6d96b270
...@@ -240,8 +240,8 @@ def add_parser_guard(parser_func): ...@@ -240,8 +240,8 @@ def add_parser_guard(parser_func):
# if location has already been visited by the current parser, # if location has already been visited by the current parser,
# return saved result # return saved result
if location in parser.visited: if location in parser.visited:
node, rlen = parser.visited[location] node = parser.visited[location]
assert rlen == location - (0 if node is None else node.len) rlen = location - (0 if node is None else node.len)
rest = grammar.document__[-rlen:] if rlen else '' rest = grammar.document__[-rlen:] if rlen else ''
return node, rest return node, rest
...@@ -261,15 +261,15 @@ def add_parser_guard(parser_func): ...@@ -261,15 +261,15 @@ def add_parser_guard(parser_func):
if node is None: if node is None:
# retrieve an earlier match result (from left recursion) if it exists # retrieve an earlier match result (from left recursion) if it exists
node, rlen = parser.visited.get(location, (None, len(rest))) node = parser.visited.get(location, None)
assert rlen == location - (0 if node is None else node.len) rlen = location - (0 if node is None else node.len)
rest = grammar.document__[-rlen:] if rlen else '' rest = grammar.document__[-rlen:] if rlen else ''
# don't overwrite any positive match (i.e. node not None) in the cache # don't overwrite any positive match (i.e. node not None) in the cache
# and don't add empty entries for parsers returning from left recursive calls! # and don't add empty entries for parsers returning from left recursive calls!
# TODO: uncomment the following for full memoizazion # TODO: uncomment the following for full memoizazion
if node is None and location not in grammar.recursion_locations__: if node is None and location not in grammar.recursion_locations__:
# otherwise also cache None-results # otherwise also cache None-results
parser.visited[location] = None, len(rest) parser.visited[location] = None
else: else:
# variable manipulating parsers will be excluded, though, # variable manipulating parsers will be excluded, though,
# because caching would interfere with changes of variable state # because caching would interfere with changes of variable state
...@@ -278,7 +278,7 @@ def add_parser_guard(parser_func): ...@@ -278,7 +278,7 @@ def add_parser_guard(parser_func):
# matches will store its result in the cache # matches will store its result in the cache
# TODO: remove if clause for full memoization # TODO: remove if clause for full memoization
# if location in grammar.recursion_locations__: # if location in grammar.recursion_locations__:
parser.visited[location] = (node, len(rest)) parser.visited[location] = node
parser.recursion_counter[location] -= 1 parser.recursion_counter[location] -= 1
...@@ -358,8 +358,8 @@ class Parser(ParserBase, metaclass=ParserMetaClass): ...@@ -358,8 +358,8 @@ class Parser(ParserBase, metaclass=ParserMetaClass):
contained parser is repeated zero times. contained parser is repeated zero times.
Attributes: Attributes:
visited: Dictionary of places this parser has already been to visited: Mapping of places this parser has already been to
during the current parsing process and the results the during the current parsing process onto the node the
parser returned at the respective place. This dictionary parser returned at the respective place. This dictionary
is used to implement memoizing. is used to implement memoizing.
...@@ -398,7 +398,7 @@ class Parser(ParserBase, metaclass=ParserMetaClass): ...@@ -398,7 +398,7 @@ class Parser(ParserBase, metaclass=ParserMetaClass):
"""Initializes or resets any parser variables. If overwritten, """Initializes or resets any parser variables. If overwritten,
the `reset()`-method of the parent class must be called from the the `reset()`-method of the parent class must be called from the
`reset()`-method of the derived class.""" `reset()`-method of the derived class."""
self.visited = dict() # type: Dict[int, Tuple[Node, str]] self.visited = dict() # type: Dict[int, Node]
self.recursion_counter = dict() # type: Dict[int, int] self.recursion_counter = dict() # type: Dict[int, int]
self.cycle_detection = set() # type: Set[Callable] self.cycle_detection = set() # type: Set[Callable]
return self return self
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment