mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 19:34:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			52 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			52 lines
		
	
	
	
		
			1.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
from pegen import grammar
 | 
						|
from pegen.grammar import (
 | 
						|
    Alt,
 | 
						|
    Cut,
 | 
						|
    Gather,
 | 
						|
    GrammarVisitor,
 | 
						|
    Group,
 | 
						|
    Lookahead,
 | 
						|
    NamedItem,
 | 
						|
    NameLeaf,
 | 
						|
    NegativeLookahead,
 | 
						|
    Opt,
 | 
						|
    PositiveLookahead,
 | 
						|
    Repeat0,
 | 
						|
    Repeat1,
 | 
						|
    Rhs,
 | 
						|
    Rule,
 | 
						|
    StringLeaf,
 | 
						|
)
 | 
						|
 | 
						|
class ValidationError(Exception):
 | 
						|
    pass
 | 
						|
 | 
						|
class GrammarValidator(GrammarVisitor):
 | 
						|
    def __init__(self, grammar: grammar.Grammar):
 | 
						|
        self.grammar = grammar
 | 
						|
        self.rulename = None
 | 
						|
 | 
						|
    def validate_rule(self, rulename: str, node: Rule):
 | 
						|
        self.rulename = rulename
 | 
						|
        self.visit(node)
 | 
						|
        self.rulename = None
 | 
						|
 | 
						|
 | 
						|
class SubRuleValidator(GrammarValidator):
 | 
						|
    def visit_Rhs(self, node: Rule):
 | 
						|
        for index, alt in enumerate(node.alts):
 | 
						|
            alts_to_consider = node.alts[index+1:]
 | 
						|
            for other_alt in alts_to_consider:
 | 
						|
                self.check_intersection(alt, other_alt)
 | 
						|
 | 
						|
    def check_intersection(self, first_alt: Alt, second_alt: Alt) -> bool:
 | 
						|
        if str(second_alt).startswith(str(first_alt)):
 | 
						|
            raise ValidationError(
 | 
						|
                    f"In {self.rulename} there is an alternative that will "
 | 
						|
                    f"never be visited:\n{second_alt}")
 | 
						|
 | 
						|
def validate_grammar(the_grammar: grammar.Grammar):
 | 
						|
    for validator_cls in GrammarValidator.__subclasses__():
 | 
						|
        validator = validator_cls(the_grammar)
 | 
						|
        for rule_name, rule in the_grammar.rules.items():
 | 
						|
            validator.validate_rule(rule_name, rule)
 |