Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/cpython
Path: blob/main/Tools/peg_generator/pegen/validator.py
12 views
1
from typing import Optional
2
3
from pegen import grammar
4
from pegen.grammar import Alt, GrammarVisitor, Rhs, Rule
5
6
7
class ValidationError(Exception):
8
pass
9
10
11
class GrammarValidator(GrammarVisitor):
12
def __init__(self, grammar: grammar.Grammar) -> None:
13
self.grammar = grammar
14
self.rulename: Optional[str] = None
15
16
def validate_rule(self, rulename: str, node: Rule) -> None:
17
self.rulename = rulename
18
self.visit(node)
19
self.rulename = None
20
21
22
class SubRuleValidator(GrammarValidator):
23
def visit_Rhs(self, node: Rhs) -> None:
24
for index, alt in enumerate(node.alts):
25
alts_to_consider = node.alts[index + 1 :]
26
for other_alt in alts_to_consider:
27
self.check_intersection(alt, other_alt)
28
29
def check_intersection(self, first_alt: Alt, second_alt: Alt) -> None:
30
if str(second_alt).startswith(str(first_alt)):
31
raise ValidationError(
32
f"In {self.rulename} there is an alternative that will "
33
f"never be visited:\n{second_alt}"
34
)
35
36
37
def validate_grammar(the_grammar: grammar.Grammar) -> None:
38
for validator_cls in GrammarValidator.__subclasses__():
39
validator = validator_cls(the_grammar)
40
for rule_name, rule in the_grammar.rules.items():
41
validator.validate_rule(rule_name, rule)
42
43