faster: Significant performance boost on large grammar
15s to 5s
This commit is contained in:
parent
6fa89a9757
commit
f656dbd8f3
2 changed files with 31 additions and 17 deletions
|
|
@ -419,7 +419,7 @@ grammar = {
|
|||
# dump_yacc(grammar)
|
||||
grammar, precedence = desugar(grammar, precedence)
|
||||
gen = parser_faster.GenerateLR1("File", grammar, precedence=precedence)
|
||||
table = gen.gen_table()
|
||||
print(parser_faster.format_table(gen, table))
|
||||
print()
|
||||
gen.gen_table()
|
||||
# print(parser_faster.format_table(gen, table))
|
||||
# print()
|
||||
# tree = parse(table, ["id", "+", "(", "id", "[", "id", "]", ")"])
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ It also supports precedence.
|
|||
import collections
|
||||
import dataclasses
|
||||
import enum
|
||||
import functools
|
||||
import typing
|
||||
|
||||
|
||||
|
|
@ -516,7 +517,7 @@ class GenerateLR0(object):
|
|||
self.start_symbol = start_symbol
|
||||
self.end_symbol = end_symbol
|
||||
|
||||
|
||||
@functools.cache
|
||||
def gen_closure_next(self, config: Configuration):
|
||||
"""Return the next set of configurations in the closure for
|
||||
config.
|
||||
|
|
@ -547,14 +548,20 @@ class GenerateLR0(object):
|
|||
"""
|
||||
closure = set()
|
||||
pending = list(seeds)
|
||||
pending_next = []
|
||||
while len(pending) > 0:
|
||||
config = pending.pop()
|
||||
for config in pending:
|
||||
if config in closure:
|
||||
continue
|
||||
|
||||
closure.add(config)
|
||||
for next_config in self.gen_closure_next(config):
|
||||
pending.append(next_config)
|
||||
pending_next.append(next_config)
|
||||
|
||||
temp = pending
|
||||
pending = pending_next
|
||||
pending_next = temp
|
||||
pending_next.clear()
|
||||
|
||||
return tuple(sorted(closure)) # TODO: Why tuple?
|
||||
|
||||
|
|
@ -596,14 +603,20 @@ class GenerateLR0(object):
|
|||
|
||||
successors = []
|
||||
pending = [config_set]
|
||||
pending_next = []
|
||||
while len(pending) > 0:
|
||||
config_set = pending.pop()
|
||||
|
||||
for config_set in pending:
|
||||
id, is_new = result.register_config_set(config_set)
|
||||
if is_new:
|
||||
for symbol, successor in self.gen_all_successors(config_set):
|
||||
successors.append((id,symbol,successor))
|
||||
pending.append(successor)
|
||||
pending_next.append(successor)
|
||||
|
||||
|
||||
temp = pending
|
||||
pending = pending_next
|
||||
pending_next = temp
|
||||
pending_next.clear()
|
||||
|
||||
for id,symbol,successor in successors:
|
||||
result.add_successor(id, symbol, result.config_set_key[successor])
|
||||
|
|
@ -940,6 +953,7 @@ class GenerateLR1(GenerateSLR1):
|
|||
In an LR1 parser, this is the lookahead of the configuration."""
|
||||
return config.lookahead
|
||||
|
||||
@functools.cache
|
||||
def gen_closure_next(self, config: Configuration):
|
||||
"""Return the next set of configurations in the closure for
|
||||
config.
|
||||
|
|
@ -967,7 +981,7 @@ class GenerateLR1(GenerateSLR1):
|
|||
lookahead = tuple(sorted(lookahead))
|
||||
next.append(Configuration.from_rule(config_next, rule, lookahead=lookahead))
|
||||
|
||||
return tuple(next)
|
||||
return tuple(sorted(next))
|
||||
|
||||
def gen_all_sets(self):
|
||||
"""Generate all of the configuration sets for the grammar.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue