From e1240759eb4bbb24c761cea1cb532093b36a9393 Mon Sep 17 00:00:00 2001 From: John Doty Date: Sat, 13 Apr 2024 13:16:26 -0700 Subject: [PATCH] faster: first symbol cache --- parser_faster.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/parser_faster.py b/parser_faster.py index b9b8a21..bfce1fe 100644 --- a/parser_faster.py +++ b/parser_faster.py @@ -423,6 +423,10 @@ class GenerateSLR1(GenerateLR0): means they need to know how to generate 'first(A)', which is most of the code in this class. """ + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._first_symbol_cache = {} + def gen_first_symbol(self, symbol, visited): """Compute the first set for a single symbol. @@ -447,6 +451,10 @@ class GenerateSLR1(GenerateLR0): assert symbol in self.nonterminals visited.add(symbol) + cached_result = self._first_symbol_cache.get(symbol, None) + if cached_result: + return cached_result + # All the firsts from all the productions. firsts = [ self.gen_first(rule[1], visited) @@ -455,7 +463,9 @@ class GenerateSLR1(GenerateLR0): ] result = {f for fs in firsts for f in fs} - return tuple(sorted(result, key=lambda x: (x is None, x))) + result = tuple(sorted(result, key=lambda x: (x is None, x))) + self._first_symbol_cache[symbol] = result + return result def gen_first(self, symbols, visited=None): """Compute the first set for a sequence of symbols.