1import unittest
2from test import test_tools
3
4test_tools.skip_if_missing('peg_generator')
5with test_tools.imports_under_tool('peg_generator'):
6    from pegen.grammar_parser import GeneratedParser as GrammarParser
7    from pegen.validator import SubRuleValidator, ValidationError
8    from pegen.testutil import parse_string
9    from pegen.grammar import Grammar
10
11
12class TestPegen(unittest.TestCase):
13    def test_rule_with_no_collision(self) -> None:
14        grammar_source = """
15        start: bad_rule
16        sum:
17            | NAME '-' NAME
18            | NAME '+' NAME
19        """
20        grammar: Grammar = parse_string(grammar_source, GrammarParser)
21        validator = SubRuleValidator(grammar)
22        for rule_name, rule in grammar.rules.items():
23            validator.validate_rule(rule_name, rule)
24
25    def test_rule_with_simple_collision(self) -> None:
26        grammar_source = """
27        start: bad_rule
28        sum:
29            | NAME '+' NAME
30            | NAME '+' NAME ';'
31        """
32        grammar: Grammar = parse_string(grammar_source, GrammarParser)
33        validator = SubRuleValidator(grammar)
34        with self.assertRaises(ValidationError):
35            for rule_name, rule in grammar.rules.items():
36                validator.validate_rule(rule_name, rule)
37
38    def test_rule_with_collision_after_some_other_rules(self) -> None:
39        grammar_source = """
40        start: bad_rule
41        sum:
42            | NAME '+' NAME
43            | NAME '*' NAME ';'
44            | NAME '-' NAME
45            | NAME '+' NAME ';'
46        """
47        grammar: Grammar = parse_string(grammar_source, GrammarParser)
48        validator = SubRuleValidator(grammar)
49        with self.assertRaises(ValidationError):
50            for rule_name, rule in grammar.rules.items():
51                validator.validate_rule(rule_name, rule)
52