Path: blob/main/Tools/peg_generator/pegen/validator.py
12 views
from typing import Optional12from pegen import grammar3from pegen.grammar import Alt, GrammarVisitor, Rhs, Rule456class ValidationError(Exception):7pass8910class GrammarValidator(GrammarVisitor):11def __init__(self, grammar: grammar.Grammar) -> None:12self.grammar = grammar13self.rulename: Optional[str] = None1415def validate_rule(self, rulename: str, node: Rule) -> None:16self.rulename = rulename17self.visit(node)18self.rulename = None192021class SubRuleValidator(GrammarValidator):22def visit_Rhs(self, node: Rhs) -> None:23for index, alt in enumerate(node.alts):24alts_to_consider = node.alts[index + 1 :]25for other_alt in alts_to_consider:26self.check_intersection(alt, other_alt)2728def check_intersection(self, first_alt: Alt, second_alt: Alt) -> None:29if str(second_alt).startswith(str(first_alt)):30raise ValidationError(31f"In {self.rulename} there is an alternative that will "32f"never be visited:\n{second_alt}"33)343536def validate_grammar(the_grammar: grammar.Grammar) -> None:37for validator_cls in GrammarValidator.__subclasses__():38validator = validator_cls(the_grammar)39for rule_name, rule in the_grammar.rules.items():40validator.validate_rule(rule_name, rule)414243