Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Perl 6 grammars - setting the actions object

by Anonymous Monk
on Jul 17, 2016 at 22:24 UTC ( [id://1167927]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hello dear monks,

I am trying to work my way through Perl grammars and, more specifically, actions objects.

I have written this grammar for a subset of JSON (as a shorter example of my larger problem):

grammar My-Grammar { token TOP { \s* <object> \s* } rule object { '{' \s* <pairlist> '}' \s* } rule pairlist { <pair> * % \, } rule pair { <string>':' <value> } token string { \" <[ \w \s \- ' ]>+ \" } token number { [ \d+ [ \. \d+ ]? ] | [ \. \d+ ] } token value { <object> | <string> | <number> | true | false | null } }
Used with the following JSON subset string and parsing call:
my $source-string = q/{ "firstName": "John", "lastName": "Smith", "isAlive": true, "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100" }, "spouse": null }/; my $match = My-Grammar.parse($source-string); say ~$match if $match; # say $match.made if $match;
I get the following stringified match object:
{ "firstName": "John", "lastName": "Smith", "isAlive": true, "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100" }, "spouse": null }
So parsing the string with the grammar seems to work correctly.

I have a problem when I try to add an actions object.

This is about the best actions class I could come up with so far:

class My-actions { method TOP($/) { make $/.values.[0].made; }; method object ($/) { make $<pairlist>.made.hash.item; } method pairlist($/) { make $<pair>>>.made.flat; } method pair($/) { make $<string>.made => $<value>.made ; } method string($/) { make ~$/; } method number($/) { make +$/.Str; } method value($/) { given ~$/ { when "true" {make Bool::True;} when "false" {make Bool::False;} when "null" {make Any;} default { make ~$/;} } } }
With this actions class, I get the following AST:
{"address" => { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100" }, "age" => 25, "firstName" => "John", "isAlive" => True, "lastName" + => "Smith", "spouse" => (Any)}
Except for the address component, the AST seems correct.

The address component is not transformed into AST nodes obviously because of this line:

default { make ~$/;}
in the value method of the actions class, which just stringifies the address sub-object. I have put that line so far as a temporary workaround just to get the overall shebang sort of working, but I have no idea how to get further. Specifically, I have tried many things, but I just can't figure out how to identify that the value is itself (recursively) an object and, even if I knew how to identify that, I still probably wouldn't know how to process it to produce a proper AST subtree for it.

Would a nice monk around here be kind enough to enlighten me on this last part?

Replies are listed 'Best First'.
Re: Perl 6 grammars - setting the actions object
by duelafn (Parson) on Jul 19, 2016 at 01:37 UTC

    One solution is to pass-through the made value instead of stringifying. There may be a better way of doing this (update: the post by moritz below is that better way), but this at least works:

    token value { <val=object> | <val=string> | <val=number> | true | false | null } # ... given ~$/ { when "true" {make Bool::True;} when "false" {make Bool::False;} when "null" {make Any;} default { make $<val>.made; } }

    Though it would probably be better to pass-through if $<val> is defined at all rather than rely on the stringified fall-through:

    return make $<val>.made if $<val>; given ~$/ { when "true" {make Bool::True;} when "false" {make Bool::False;} when "null" {make Any;} default { die; } }

    Good Day,
        Dean

      Thank you very much. I did not think at all about this solution, I'll try it as soon as possible.

      I definitely agree that stringifying the parts I couldn't handle better is not a good solution, I only did it as a cheap temporary debugging scaffolding so that the overall thing could succeed and that I could check that at least the rest was working properly.

Re: Perl 6 grammars - setting the actions object
by moritz (Cardinal) on Jul 21, 2016 at 21:30 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1167927]
Approved by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-19 13:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found