One extra point. You may need to post-process the parse to get what you
want. In the 'restricted' line, if you don't have a #gen then 'gen negate'
will have succeeded and will generate its own node in the parse - in your
example of ' Paul' as input it will be $P. Assuming you don't want this (!),
you can add ==> [:nodes| nodes second] to the definition of restricted.

I had realized this after I posted on Sunday, as well as the fact that I had
put the anded elements in the wrong order, but I didn't want to generate a
stream of supplementaries.



-----Original Message-----
From: Pharo-users [] On Behalf Of
Sean P. DeNigris
Sent: 09 August 2017 03:41
Subject: Re: [Pharo-users] PetitParser: Parse X as long as it's not Y

Peter Kenny wrote
> This seems to be what the PPAndParser is designed for. 

Thanks for the pointer, Peter! I finally figured it out based on your
example. To get more concrete, I'm trying to parse a name, where the end of
the input might be an optional middle name, followed by an optional
generational (e.g. 'Paul III'). What I think the restricted line says is:
"peek to make sure we don't have a #gen, then try to parse an #identifier".
Interestingly the order is important. If the peek and identifier are
reversed, it tries to peek after the identifier, causing an error when there
is only a middle name (i.e. no more input).

identifier := #letter asParser plus flatten.
gen := 'Jr' asParser / 'Sr' asParser.
restricted := gen negate and, identifier.
parser := ((#space asParser, restricted) optional, (#space asParser, gen)
optional) end.
parser parse: ' Paul Jr'. 
parser parse: ' Paul'. 
parser parse: ' Jr'. 

This really had me baffled. Thanks again!!

View this message in context:
Sent from the Pharo Smalltalk Users mailing list archive at

Reply via email to