diff --git a/grammar.py b/grammar.py index 1ecf61f..41c2064 100644 --- a/grammar.py +++ b/grammar.py @@ -1,7 +1,7 @@ # This is an example grammar. import re -from parser import Assoc, GenerateLALR, GenerateLR1, Grammar, Nothing, Terminal, rule, seq, Rule +from parser import Assoc, Grammar, Nothing, Terminal, rule, seq, Rule ARROW = Terminal("Arrow") AS = Terminal("As") @@ -54,11 +54,10 @@ RSQUARE = Terminal("RightBracket") class FineGrammar(Grammar): - generator = GenerateLALR - start = "File" def __init__(self): super().__init__( + start="File", precedence=[ (Assoc.RIGHT, [EQUAL]), (Assoc.LEFT, [OR]), diff --git a/harness.py b/harness.py index acf48ff..268b6cd 100644 --- a/harness.py +++ b/harness.py @@ -258,10 +258,11 @@ class DynamicModule: class DynamicGrammarModule(DynamicModule): - def __init__(self, file_name, member_name, start_rule): + def __init__(self, file_name, member_name, start_rule, generator): super().__init__(file_name, member_name) self.start_rule = start_rule + self.generator = generator def _predicate(self, member) -> bool: if not super()._predicate(member): @@ -273,7 +274,7 @@ class DynamicGrammarModule(DynamicModule): return False def _transform(self, value): - return value().build_table(start=self.start_rule) + return value().build_table(start=self.start_rule, generator=self.generator) class DynamicLexerModule(DynamicModule): @@ -318,7 +319,7 @@ class Harness: self.max_entries = 0 self.grammar_module = DynamicGrammarModule( - self.grammar_file, self.grammar_member, self.start_rule + self.grammar_file, self.grammar_member, self.start_rule, generator=parser.GenerateLALR ) self.lexer_module = DynamicLexerModule(self.lexer_file, self.lexer_member) diff --git a/parser.py b/parser.py index 4ad5683..583d8bd 100644 --- a/parser.py +++ b/parser.py @@ -1850,30 +1850,12 @@ class Grammar: _precedence: dict[str, typing.Tuple[Assoc, int]] _start: str - _generator: type[GenerateLR0] - - def __init__( - self, - start: str | None = None, - precedence: PrecedenceList | None = None, - generator: type[GenerateLR0] | None = None, - ): - if start is None: - start = getattr(self, "start", None) - if start is None: - raise ValueError( - "The default start rule must either be specified in the constructor or as an " - "attribute in the class." - ) + def __init__(self, start: str, precedence: PrecedenceList | None = None): if precedence is None: precedence = getattr(self, "precedence", []) assert precedence is not None - if generator is None: - generator = getattr(self, "generator", GenerateLALR) - assert generator is not None - precedence_table = {} for prec, (associativity, symbols) in enumerate(precedence): for symbol in symbols: @@ -1888,7 +1870,6 @@ class Grammar: self._precedence = precedence_table self._start = start - self._generator = generator def generate_nonterminal_dict( self, start: str | None = None @@ -1959,7 +1940,7 @@ class Grammar: return grammar, transparents - def build_table(self, start: str | None, generator=None): + def build_table(self, start: str | None, generator=GenerateLALR): """Construct a parse table for this grammar, starting at the named nonterminal rule. """ @@ -1967,8 +1948,6 @@ class Grammar: start = self._start desugared, transparents = self.desugar(start) - if generator is None: - generator = self._generator gen = generator(start, desugared, precedence=self._precedence, transparents=transparents) table = gen.gen_table() return table