[Pharo-dev] petit parser longest match

Chris Cunningham cunningham.cb at gmail.com
Thu Nov 21 14:25:08 EST 2013


I have a version I'm happier with, but it includes a fair amount of
invasive changes.  Latest .mcz in
http://www.smalltalkhub.com/#!/~cbc/PetitParser
It does change PPChoiceParser and has a significant change to PPFailure as
well (from a previous enhancement).

-cbc


On Thu, Nov 21, 2013 at 8:10 AM, Chris Cunningham
<cunningham.cb at gmail.com>wrote:

> There are several things wrong with it, actually.
>
> First, in my example, I never did actually return the longest error - I
> just set the location to the longest error location.  Not right at all.
>
> Next, setting the stream to the position of the error on the choice is not
> a good idea.  The problem is when you have more than 1 choice depth.  So,
> the first choice goes down path 1, which calls another choice (eventually),
> which fails and resets the location to some point further on in the stream.
>  The the rollback to the first choice seems to get fouled up and doesn't
> work quite right.  Probably.  In any case, playing with how it is storing
> and returning, I am getting wildly different points of where the track
> fails.
>
> Finally, the array at each choice doesn't necessarily pick the furthest
> failure.  If you consider a 4 choice depth parser (which is roughly what
> I'm working with - parsing Java source code), the 4th choice will fail on a
> couple of paths, and then eventually work on one.  This might then return
> back to the 3rd choice successfully (so no error, so no returned error from
> that choice) and then later fails.  That particular path might be much
> shorter (that it made it through) than the one that failed earlier (maybe a
> much more complex but also more consuming path, for example).
>
> The question is what exactly are you (we) looking for.
> * I think we want to know what was the parsing path the best describes the
> source file we are parsing, and where is it failing to parse.
> * I would also like to know what the path was that arrived at that point
> (the context) so that I can decide how to either fix the parser (if it is
> wrong) or fix the source.
>
> So, I'm still looking for a better answer than the two I tried to provide
> earlier.
>
> -cbc
>
> On Wed, Nov 20, 2013 at 5:03 PM, Norbert Hartl <norbert at hartl.name> wrote:
>
>> I'm not sure what you are trying to improve. It works quite well :)
>>
>> Norbert
>>
>> Am 20.11.2013 um 22:59 schrieb Chris Cunningham <cunningham.cb at gmail.com
>> >:
>>
>> ehh, ignore this for now.  Neither is working well enough.  If I get
>> something working well, I'll post back.
>>
>>
>> On Wed, Nov 20, 2013 at 1:45 PM, Chris Cunningham <
>> cunningham.cb at gmail.com> wrote:
>>
>>> Actually, do this [the #( 0 nil ) meant it was shared with ALL choice
>>> parsers forever - not a good choice].
>>>
>>> parseOn: aStream
>>> "This is optimized code that avoids unnecessary block activations, do
>>> not change. When all choices fail, the last failure is answered."
>>>
>>> | element longest |
>>> longest := Array with: 0 with: nil.
>>> 1 to: parsers size do: [ :index |
>>>  element := (parsers at: index)
>>> parseOn: aStream.
>>> element isPetitFailure
>>>  ifTrue: [ aStream position > longest first ifTrue: [ longest at: 1
>>> put: aStream position; at: 2 put: element ] ]
>>> ifFalse: [ ^ element ] ].
>>>  aStream position: longest first.
>>> ^ element
>>>
>>>
>>> On Wed, Nov 20, 2013 at 1:35 PM, Chris Cunningham <
>>> cunningham.cb at gmail.com> wrote:
>>>
>>>> Ho about this (replacement for yours, or just replace in PPChoiceParser
>>>> - but it will result in different behavior for that method outside of your
>>>> particular parser, so beware):
>>>>
>>>> parseOn: aStream
>>>>  "This is optimized code that avoids unnecessary block activations, do
>>>> not change. When all choices fail, the last failure is answered."
>>>>
>>>>  | element longest |
>>>> longest := #( 0 nil ).
>>>> 1 to: parsers size do: [ :index |
>>>>  element := (parsers at: index)
>>>> parseOn: aStream.
>>>> element isPetitFailure
>>>>  ifTrue: [ aStream position > longest first ifTrue: [ longest at: 1
>>>> put: aStream position; at: 2 put: element ] ]
>>>> ifFalse: [ ^ element ] ].
>>>>  aStream position: longest first.
>>>> ^ element
>>>>
>>>> I had a need for it in the past (and, just now, in fact - so minimally
>>>> tested just now).
>>>>
>>>> -cbc
>>>>
>>>>
>>>> On Wed, Nov 20, 2013 at 2:15 AM, Norbert Hartl <norbert at hartl.name>wrote:
>>>>
>>>>> I talked to Lukas two years ago about parsing the longest match [1].
>>>>> He committed it to PetitBeta back then. Now I need it and I had a look at
>>>>> the current parsers but didn’t find one that can do the same. Is there a
>>>>> parser that can do longest match?
>>>>>
>>>>> If not I would propose adding that to the default petit parser
>>>>> package. Lukas’ proposal back then was
>>>>>
>>>>> LongestChoiceParser>>parseOn: aStream
>>>>> 	| start element longestEnd longestElement |
>>>>> 	start := aStream position.
>>>>> 	1 to: parsers size do: [ :index |
>>>>> 		element := (parsers at: index)
>>>>> 			parseOn: aStream.
>>>>> 		(longestEnd isNil or: [ longestEnd < aStream position ]) ifTrue: [
>>>>> 			longestEnd := aStream position.
>>>>> 			longestElement := element ].
>>>>> 		aStream position: start ].
>>>>> 	aStream position: longestEnd.
>>>>> 	^ longestElement
>>>>>
>>>>>
>>>>> Norbert
>>>>>
>>>>> [1] http://www.iam.unibe.ch/pipermail/moose-dev/2011-July/009365.html
>>>>>
>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pharo.org/pipermail/pharo-dev_lists.pharo.org/attachments/20131121/87e43796/attachment-0002.html>


More information about the Pharo-dev mailing list