(root)/
Python-3.12.0/
Tools/
peg_generator/
pegen/
validator.py
       1  from typing import Optional
       2  
       3  from pegen import grammar
       4  from pegen.grammar import Alt, GrammarVisitor, Rhs, Rule
       5  
       6  
       7  class ESC[4;38;5;81mValidationError(ESC[4;38;5;149mException):
       8      pass
       9  
      10  
      11  class ESC[4;38;5;81mGrammarValidator(ESC[4;38;5;149mGrammarVisitor):
      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 ESC[4;38;5;81mSubRuleValidator(ESC[4;38;5;149mGrammarValidator):
      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)