Allow the grammar to specify a preference for a generator
Overridable, like start production
This commit is contained in:
parent
55c4675fe5
commit
e203e27407
3 changed files with 16 additions and 7 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
# This is an example grammar.
|
# This is an example grammar.
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from parser import Assoc, Grammar, Nothing, Terminal, rule, seq, Rule
|
from parser import Assoc, GenerateLALR, GenerateLR1, Grammar, Nothing, Terminal, rule, seq, Rule
|
||||||
|
|
||||||
ARROW = Terminal("Arrow")
|
ARROW = Terminal("Arrow")
|
||||||
AS = Terminal("As")
|
AS = Terminal("As")
|
||||||
|
|
@ -81,6 +81,7 @@ class FineGrammar(Grammar):
|
||||||
#
|
#
|
||||||
(Assoc.NONE, [self.is_expression]),
|
(Assoc.NONE, [self.is_expression]),
|
||||||
],
|
],
|
||||||
|
generator=GenerateLALR,
|
||||||
)
|
)
|
||||||
|
|
||||||
@rule("File")
|
@rule("File")
|
||||||
|
|
|
||||||
|
|
@ -258,11 +258,10 @@ class DynamicModule:
|
||||||
|
|
||||||
|
|
||||||
class DynamicGrammarModule(DynamicModule):
|
class DynamicGrammarModule(DynamicModule):
|
||||||
def __init__(self, file_name, member_name, start_rule, generator):
|
def __init__(self, file_name, member_name, start_rule):
|
||||||
super().__init__(file_name, member_name)
|
super().__init__(file_name, member_name)
|
||||||
|
|
||||||
self.start_rule = start_rule
|
self.start_rule = start_rule
|
||||||
self.generator = generator
|
|
||||||
|
|
||||||
def _predicate(self, member) -> bool:
|
def _predicate(self, member) -> bool:
|
||||||
if not super()._predicate(member):
|
if not super()._predicate(member):
|
||||||
|
|
@ -274,7 +273,7 @@ class DynamicGrammarModule(DynamicModule):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _transform(self, value):
|
def _transform(self, value):
|
||||||
return value().build_table(start=self.start_rule, generator=self.generator)
|
return value().build_table(start=self.start_rule)
|
||||||
|
|
||||||
|
|
||||||
class DynamicLexerModule(DynamicModule):
|
class DynamicLexerModule(DynamicModule):
|
||||||
|
|
@ -319,7 +318,7 @@ class Harness:
|
||||||
self.max_entries = 0
|
self.max_entries = 0
|
||||||
|
|
||||||
self.grammar_module = DynamicGrammarModule(
|
self.grammar_module = DynamicGrammarModule(
|
||||||
self.grammar_file, self.grammar_member, self.start_rule, generator=parser.GenerateLALR
|
self.grammar_file, self.grammar_member, self.start_rule
|
||||||
)
|
)
|
||||||
|
|
||||||
self.lexer_module = DynamicLexerModule(self.lexer_file, self.lexer_member)
|
self.lexer_module = DynamicLexerModule(self.lexer_file, self.lexer_member)
|
||||||
|
|
|
||||||
13
parser.py
13
parser.py
|
|
@ -1850,8 +1850,14 @@ class Grammar:
|
||||||
|
|
||||||
_precedence: dict[str, typing.Tuple[Assoc, int]]
|
_precedence: dict[str, typing.Tuple[Assoc, int]]
|
||||||
_start: str
|
_start: str
|
||||||
|
_generator: type[GenerateLR0]
|
||||||
|
|
||||||
def __init__(self, start: str, precedence: PrecedenceList | None = None):
|
def __init__(
|
||||||
|
self,
|
||||||
|
start: str,
|
||||||
|
precedence: PrecedenceList | None = None,
|
||||||
|
generator: type[GenerateLR0] = GenerateLALR,
|
||||||
|
):
|
||||||
if precedence is None:
|
if precedence is None:
|
||||||
precedence = getattr(self, "precedence", [])
|
precedence = getattr(self, "precedence", [])
|
||||||
assert precedence is not None
|
assert precedence is not None
|
||||||
|
|
@ -1870,6 +1876,7 @@ class Grammar:
|
||||||
|
|
||||||
self._precedence = precedence_table
|
self._precedence = precedence_table
|
||||||
self._start = start
|
self._start = start
|
||||||
|
self._generator = generator
|
||||||
|
|
||||||
def generate_nonterminal_dict(
|
def generate_nonterminal_dict(
|
||||||
self, start: str | None = None
|
self, start: str | None = None
|
||||||
|
|
@ -1940,7 +1947,7 @@ class Grammar:
|
||||||
|
|
||||||
return grammar, transparents
|
return grammar, transparents
|
||||||
|
|
||||||
def build_table(self, start: str | None, generator=GenerateLALR):
|
def build_table(self, start: str | None, generator=None):
|
||||||
"""Construct a parse table for this grammar, starting at the named
|
"""Construct a parse table for this grammar, starting at the named
|
||||||
nonterminal rule.
|
nonterminal rule.
|
||||||
"""
|
"""
|
||||||
|
|
@ -1948,6 +1955,8 @@ class Grammar:
|
||||||
start = self._start
|
start = self._start
|
||||||
desugared, transparents = self.desugar(start)
|
desugared, transparents = self.desugar(start)
|
||||||
|
|
||||||
|
if generator is None:
|
||||||
|
generator = self._generator
|
||||||
gen = generator(start, desugared, precedence=self._precedence, transparents=transparents)
|
gen = generator(start, desugared, precedence=self._precedence, transparents=transparents)
|
||||||
table = gen.gen_table()
|
table = gen.gen_table()
|
||||||
return table
|
return table
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue