Refactor the ambiguity tests a bit, see #70

This commit is contained in:
Dave Halter
2019-07-13 20:14:52 +02:00
parent 0032bae041
commit e723b3e74b
2 changed files with 22 additions and 38 deletions

View File

@@ -292,41 +292,22 @@ def test_left_recursion():
generate_grammar('foo: foo NAME\n', tokenize.PythonTokenTypes)
def test_ambiguities():
with pytest.raises(
ValueError,
match=r"foo is ambiguous.*given a TokenType\(NAME\).*bar or baz"
):
generate_grammar('foo: bar | baz\nbar: NAME\nbaz: NAME\n', tokenize.PythonTokenTypes)
with pytest.raises(
ValueError,
match=r"foo is ambiguous.*given a ReservedString\(x\).*bar or baz"
):
generate_grammar('''foo: bar | baz\nbar: 'x'\nbaz: "x"\n''', tokenize.PythonTokenTypes)
with pytest.raises(
ValueError,
match=r"foo is ambiguous.*given a ReservedString\(x\).*bar or foo"
):
generate_grammar('''foo: bar | 'x'\nbar: 'x'\n''', tokenize.PythonTokenTypes)
# an ambiguity with the second (not the first) child of a production
with pytest.raises(
ValueError,
match=r"outer is ambiguous.*given a ReservedString\(b\).*inner or outer"
):
generate_grammar(
'outer: "a" [inner] "b" "c"\ninner: "b" "c" [inner]\n',
tokenize.PythonTokenTypes,
)
# an ambiguity hidden by a level of indirection (middle)
with pytest.raises(
ValueError,
match=r"outer is ambiguous.*given a ReservedString\(b\).*middle or outer"
):
generate_grammar(
'outer: "a" [middle] "b" "c"\nmiddle: inner\ninner: "b" "c" [inner]\n',
tokenize.PythonTokenTypes,
)
@pytest.mark.parametrize(
'grammar, error_match', [
['foo: bar | baz\nbar: NAME\nbaz: NAME\n',
r"foo is ambiguous.*given a TokenType\(NAME\).*bar or baz"],
['''foo: bar | baz\nbar: 'x'\nbaz: "x"\n''',
r"foo is ambiguous.*given a ReservedString\(x\).*bar or baz"],
['''foo: bar | 'x'\nbar: 'x'\n''',
r"foo is ambiguous.*given a ReservedString\(x\).*bar or foo"],
# An ambiguity with the second (not the first) child of a production
['outer: "a" [inner] "b" "c"\ninner: "b" "c" [inner]\n',
r"outer is ambiguous.*given a ReservedString\(b\).*inner or outer"],
# An ambiguity hidden by a level of indirection (middle)
['outer: "a" [middle] "b" "c"\nmiddle: inner\ninner: "b" "c" [inner]\n',
r"outer is ambiguous.*given a ReservedString\(b\).*middle or outer"],
]
)
def test_ambiguities(grammar, error_match):
with pytest.raises(ValueError, match=error_match):
generate_grammar(grammar, tokenize.PythonTokenTypes)