-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Backtracking #75
Comments
See also the docs on |
Note: This Markdown reply is executable via Imports: >>> from funcparserlib.parser import a, many, finished, forward_decl, Parser, pure
The alternative >>> x = a("x")
>>> y = a("y")
>>> z = a("z")
>>> xxy_or_xxz = x + x + y | x + x + z
>>> xxy_or_xxz.parse("xxy")
('x', 'x', 'y')
>>> xxy_or_xxz.parse("xxz")
('x', 'x', 'z')
@Kodiologist Could you please share how exacly you would have fixed the problem in your example by using Parsec's
>>> x = a("x")
>>> many_x = many(x)
>>> many_x.parse("xxx")
['x', 'x', 'x']
>>> many_x.parse("y")
[]
The problem with the greedy >>> x = a("x")
>>> many_x_then_x = many(x) + x + x
>>> many_x_then_x.parse("xxx")
Traceback (most recent call last):
...
funcparserlib.parser.NoParseError: got unexpected end of input, expected: 'x'
I guess that you, in fact, want a non-greedy version of >>> x = a("x")
>>> def non_greedy_many(p):
... # Fake implementation for a single case
... return a("x") >> list
>>> many_x_then_x = non_greedy_many(x) + x + x
>>> many_x_then_x.parse("xxx")
(['x'], 'x', 'x')
The problem is that I currenlty have no idea how to implement it easily, since Workaround 1. Extract the last >>> x = a("x")
>>> def to_results(args):
... x1, x2, xs = args
... combined = [x1] + [x2] + xs
... *rest, last1, last2 = combined
... return rest, last1, last2
>>> many_x_then_x = x + x + many(x) >> to_results
>>> many_x_then_x.parse("xxx")
(['x'], 'x', 'x')
>>> many_x_then_x.parse("xx")
([], 'x', 'x')
>>> many_x_then_x.parse("x")
Traceback (most recent call last):
...
funcparserlib.parser.NoParseError: got unexpected end of input, expected: 'x'
>>> many_x_then_x.parse("")
Traceback (most recent call last):
...
funcparserlib.parser.NoParseError: got unexpected end of input, expected: 'x'
|
It's been a long time (over a decade) since I touched Parsec and so perhaps I was wrong in thinking it can be done with |
It looks like
funcparserlib
has no way to allow backtracking, in the manner of Parsec'stry
. #43 provides one example of where you might want this. I found myself wanting it in changing Hy to parsedfor
forms like this (hylang/hy#2324):It would be the equivalent of this Python:
dfor
and friends in Hy have a relatively complicated parser, so here's a simplified example:Here the example with
lfor
returns([(1, 1), (1, 1)], 1, None)
, as desired, but fordfor
, I getfuncparserlib.parser.NoParseError: got unexpected end of input, expected: FORM
. The problem is thatloopers
consumes all theFORM FORM
pairs and doesn't try moving back one iteration ofmany
to give the finalFORM + FORM + finished
indfor
a chance to match.The text was updated successfully, but these errors were encountered: