-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
If a branch in ordered choice has a potentially non-consuming successful alternative (Optional, ZeroOrMore, Not, And), it will succeed if alternative succeeds and thus will not try further choices.
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,15 +9,20 @@ | |
####################################################################### | ||
|
||
from __future__ import unicode_literals | ||
import pytest | ||
|
||
# Grammar | ||
from arpeggio import ParserPython, Optional, EOF | ||
from arpeggio import ParserPython, Optional, NoMatch, EOF | ||
|
||
def g(): return [Optional('first'), Optional('second'), Optional('third')], EOF | ||
|
||
|
||
def test_optional_in_choice(): | ||
parser = ParserPython(g) | ||
# This input fails as the ordered choice will succeed on the first optional | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
igordejanovic
Author
Member
|
||
# without consuming the input. | ||
input_str = "second" | ||
parse_tree = parser.parse(input_str) | ||
assert parse_tree is not None | ||
with pytest.raises(NoMatch) as e: | ||
parser.parse(input_str) | ||
|
||
assert "Expected 'first' or EOF" in str(e.value) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,16 +27,13 @@ def grammar(): | |
assert "Expected 'a' or 'b'" in str(e.value) | ||
assert (e.value.line, e.value.col) == (1, 1) | ||
|
||
# This grammar always succeeds due to the optional match | ||
def grammar(): | ||
return ['b', Optional('a')] | ||
|
||
parser = ParserPython(grammar) | ||
|
||
with pytest.raises(NoMatch) as e: | ||
parser.parse('c') | ||
|
||
assert "Expected 'b'" in str(e.value) | ||
assert (e.value.line, e.value.col) == (1, 1) | ||
parser.parse('b') | ||
parser.parse('c') | ||
This comment has been minimized.
Sorry, something went wrong.
stanislaw
Contributor
|
||
|
||
|
||
def test_optional_with_better_match(): | ||
|
@@ -45,7 +42,7 @@ def test_optional_with_better_match(): | |
has precedence over non-optional. | ||
""" | ||
|
||
def grammar(): return [first, Optional(second)] | ||
def grammar(): return [first, (Optional(second), 'six')] | ||
def first(): return 'one', 'two', 'three', '4' | ||
def second(): return 'one', 'two', 'three', 'four', 'five' | ||
|
||
|
@@ -131,9 +128,10 @@ def grammar(): | |
return ['one', Not('two')], _(r'\w+') | ||
|
||
parser = ParserPython(grammar) | ||
parser.parse('three ident') | ||
|
||
with pytest.raises(NoMatch) as e: | ||
parser.parse(' three ident') | ||
parser.parse(' two ident') | ||
assert "Expected 'one' at " in str(e.value) | ||
|
||
|
||
|
@@ -165,6 +163,18 @@ def grammar(): | |
parser.parse(' three ident') | ||
assert "Expected 'one' or 'two' at" in str(e.value) | ||
|
||
with pytest.raises(NoMatch) as e: | ||
parser.parse(' four ident') | ||
assert "Expected 'one' or 'two' at" in str(e.value) | ||
parser.parse(' four ident') | ||
|
||
|
||
def test_not_succeed_in_ordered_choice(): | ||
""" | ||
Test that Not can succeed in ordered choice leading to ordered choice | ||
to succeed. | ||
See: https://github.com/textX/Arpeggio/issues/96 | ||
""" | ||
|
||
def grammar(): | ||
return [Not("a"), "a"], Optional("b") | ||
|
||
parser=ParserPython(grammar) | ||
parser.parse('b') |
This seems to be something else what I don't understand.
Why would this test not succeed? The second Optional is clearly a direct match.
You are writing that
the ordered choice will succeed on the first optional
- I cannot understand howOptional('first')
can succeed on"second"
.