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

@@ -141,6 +141,9 @@ class NFAArc(object):
self.next = next_ self.next = next_
self.nonterminal_or_string = nonterminal_or_string self.nonterminal_or_string = nonterminal_or_string
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self.nonterminal_or_string)
class NFAState(object): class NFAState(object):
def __init__(self, from_rule): def __init__(self, from_rule):

View File

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