PetitParser Example

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

PetitParser Example

Sean P. DeNigris
Administrator
What do you think of this PetitParser example? Is there a better way to do this?

Parse a string like '{"login", "bash"}' (an Applescript list) into a collection of items (i.e. #("login" "bash))...

        | delimiter item contents listParser result listClose |
        delimiter := ', ' asParser.
        listClose := $} asParser.
        item := (delimiter / listClose) negate plus flatten.
        contents := (item separatedBy: delimiter) ==> [ :nodes | nodes reject: [ :n | n = ', ' ] ].
        listParser := ${ asParser, contents optional, listClose ==> #second.
        result := listParser parse: returnString.
        ^ result isNil
                ifTrue: [ OrderedCollection new ]
                ifFalse: [ result collect: [ :e | self processAtom: e ] ].

Thanks.
Sean
Cheers,
Sean
Reply | Threaded
Open this post in threaded view
|

Re: PetitParser Example

Lukas Renggli
If you'd write the describe the items in the list, the code would
become simpler:

item := $" asParser , $" asParser negate star flatten , $" asParser
        ==> #second.
items := (item separatedBy: $, asParser trim)
        withoutSeparators.
list := ${ asParser , items , $} asParser
        ==> #second.

#withoutSeparators also simplifies the code further. I just added that
to the latest version.

Lukas

On 25 February 2012 13:44, Sean P. DeNigris <[hidden email]> wrote:

> What do you think of this PetitParser example? Is there a better way to do
> this?
>
> Parse a string like '{"login", "bash"}' (an Applescript list) into a
> collection of items (i.e. #("login" "bash))...
>
>        | delimiter item contents listParser result listClose |
>        delimiter := ', ' asParser.
>        listClose := $} asParser.
>        item := (delimiter / listClose) negate plus flatten.
>        contents := (item separatedBy: delimiter) ==> [ :nodes | nodes reject: [ :n
> | n = ', ' ] ].
>        listParser := ${ asParser, contents optional, listClose ==> #second.
>        result := listParser parse: returnString.
>        ^ result isNil
>                ifTrue: [ OrderedCollection new ]
>                ifFalse: [ result collect: [ :e | self processAtom: e ] ].
>
> Thanks.
> Sean
>
> --
> View this message in context: http://forum.world.st/PetitParser-Example-tp4420008p4420008.html
> Sent from the Moose mailing list archive at Nabble.com.
> _______________________________________________
> Moose-dev mailing list
> [hidden email]
> https://www.iam.unibe.ch/mailman/listinfo/moose-dev



--
Lukas Renggli
www.lukas-renggli.ch

_______________________________________________
Moose-dev mailing list
[hidden email]
https://www.iam.unibe.ch/mailman/listinfo/moose-dev
Reply | Threaded
Open this post in threaded view
|

Re: PetitParser Example

Tudor Girba-2
In reply to this post by Sean P. DeNigris
Hi Sean,

Looks ok, but I think it's a bit too particular to your input.

Some things you could take into account:

- the delimiter should probably allow multiple white spaces both before and after the comma. You could replace the definition like:
delimiter := $, asParser trim.

- the item should probably be defined in terms of what can go inside, not just as a negation of delimiter and listClose. This would allow you to transform the values into corresponding Smalltalk objects. So, for example, if you only want to allow strings then you can define the item like:
item := $" asParser , $" asParser negate star flatten , $" asParser ==> #second.

So, all in all:
        | delimiter item contents listParser |
        delimiter := $, asParser trim.
        item := $" asParser , $" asParser negate star flatten , $" asParser ==> #second.
        contents := (item separatedBy: delimiter) ==> [ :nodes | nodes reject: [ :n | n = $, ] ].
        listParser := ${ asParser, contents optional, $} asParser ==> #second.
        listParser parse: '{"lo, gin", "bash"}'.


        ==>  #('lo, gin' 'bash')

Cheers,
Doru


On 25 Feb 2012, at 13:44, Sean P. DeNigris wrote:

> What do you think of this PetitParser example? Is there a better way to do
> this?
>
> Parse a string like '{"login", "bash"}' (an Applescript list) into a
> collection of items (i.e. #("login" "bash))...
>
> | delimiter item contents listParser result listClose |
> delimiter := ', ' asParser trim.
> listClose := $} asParser.
> item := (delimiter / listClose) negate plus flatten.
> contents := (item separatedBy: delimiter) ==> [ :nodes | nodes reject: [ :n
> | n = ', ' ] ].
> listParser := ${ asParser, contents optional, listClose ==> #second.
> result := listParser parse: returnString.
> ^ result isNil
> ifTrue: [ OrderedCollection new ]
> ifFalse: [ result collect: [ :e | self processAtom: e ] ].
>
> Thanks.
> Sean
>
> --
> View this message in context: http://forum.world.st/PetitParser-Example-tp4420008p4420008.html
> Sent from the Moose mailing list archive at Nabble.com.
> _______________________________________________
> Moose-dev mailing list
> [hidden email]
> https://www.iam.unibe.ch/mailman/listinfo/moose-dev

--
www.tudorgirba.com

"Live like you mean it."


_______________________________________________
Moose-dev mailing list
[hidden email]
https://www.iam.unibe.ch/mailman/listinfo/moose-dev