karlgoethebier has asked for the wisdom of the Perl Monks concerning the following question:
I use this to process s-expressions with Marpa::R2:
my $DSL = <<'DSL'; :default ::= action => ::first lexeme default = latm => 1 start ::= sexp sexp ::= list | atom list ::= LPAREN elements RPAREN action => Sexp::Tiny::Actions::do_list elements ::= element* action => Sexp::Tiny::Actions::do_elements element ::= sexp atom ::= string | symbol string ::= DQUOTE string_chars DQUOTE action => Sexp::Tiny::Actions::d +o_string | DQUOTE DQUOTE action => Sexp::Tiny::Actions::do_ +empty_string string_chars ::= string_char+ action => Sexp::Tiny::Actions::do_join string_char ::= STRCHAR DQUOTE ~ '"' STRCHAR ~ [^"] symbol ::= symbol_chars action => Sexp::Tiny::Actions::do_symbol symbol_chars ::= symbol_char+ action => Sexp::Tiny::Actions::do_join symbol_char ::= SYMCHAR SYMCHAR ~ [^()\s"] LPAREN ~ '(' RPAREN ~ ')' :discard ~ WS WS ~ [\s]+ DSL
Probably awkward and there are certainly better ways, but it works: (i skip the processing part):
karl@pazuzu:~/src/perl/debug/sexp-tiny$ bin/sexp.pl examples/fossil.da +t { fields => { "anonymous" => "off", "canonical-url" => "https://goethebier.space/fossi +l/p-acme", "crlf-glob" => "*.bat *.cmd", "crnl-glob" => "", "default-user" => "karl", "hash-policy" => "sha3", "http-port +" => 8081, "ignore-glob" => ["*.o", "*.swp", "*.tmp", ".dir +env/", "_build/", "_opam/"], "localauth" => "on", "max-upload" => "20MB", "project-d +escription" => "Private ACME tooling repository", "project-name" => "p-acme", "ssl-ca-location" => "/etc/ssl/certs", "throttle" => 0, "timeline-utc" => "on", }, type => "fossil", }
But it only works for strings so far:
karl@pazuzu:~/src/perl/debug/sexp-tiny$ echo '(acme (foo "bar"))' | bin/sexp.pl { fields => { foo => "bar" }, type => "acme" }But not with numbers:
karl@pazuzu:~/src/perl/debug/sexp-tiny$ echo '(acme (x 1))' | bin/sexp +.pl bin/sexp.pl expected (key value...)
I can only pass them in as string:
karl@pazuzu:~/src/perl/debug/sexp-tiny$ echo '(acme (x "1"))' | bin/se +xp.pl { fields => { x => 1 }, type => "acme" }
How must i modify the grammar to handle numbers (float and int)? I didn't find an example yet.
Update:
I'll try to illustrate how i did it:
#!/usr/bin/env perl use strict; use warnings; use lib 'lib'; use Sexp::Tiny::Grammar (); use Data::Dump qw(dd); use Scalar::Util qw(blessed); my $src = q{(acme (pi "3.14")(nose "cuke"))}; dd $src; my $r = Sexp::Tiny::Grammar::build_reader(); dd ref($r); $r->read( \$src ); my $ast_ref = $r->value; dd $ast_ref; sub is_qstr { my ($v) = @_; return blessed($v) && $v->isa('Sexp::Tiny::String'); } sub unwrap_qstr { my ( $v, $path ) = @_; if ( is_qstr($v) ) { warn "[unwrap] $path: ", ref($v), qq{ -> plain perl string "}, $v->value, qq{"\n}; return $v->value; } return $v; } sub maybe_number { my ( $v, $path ) = @_; return $v if ref $v; if ( defined($v) && $v =~ /\A[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?\z/ ) { warn "[numify] $path: \"$v\" -> ", 0 + $v, "\n"; return 0 + $v; } return $v; } sub normalize { my ( $node, $path ) = @_; $node = unwrap_qstr( $node, $path ); if ( ref($node) eq 'ARRAY' ) { my @out; for my $i ( 0 .. $#$node ) { push @out, normalize( $node->[$i], "$path\[$i\]" ); } return \@out; } return maybe_number( $node, $path ); } my $norm = normalize( $$ast_ref, '$ast' ); dd $norm;
Looks like it's doing what it's supposed to do:
karl@pazuzu:~/src/perl/sexp-tiny$ leftovers/ex02.pl "(acme (pi \"3.14\")(nose \"cuke\"))" "Sexp::Tiny::Grammar::Reader" \[ "acme", ["pi", bless(do{\(my $o = 3.14)}, "Sexp::Tiny::String")], ["nose", bless(do{\(my $o = "cuke")}, "Sexp::Tiny::String")], ] [unwrap] $ast[1][1]: Sexp::Tiny::String -> plain perl string "3.14" [numify] $ast[1][1]: "3.14" -> 3.14 [unwrap] $ast[2][1]: Sexp::Tiny::String -> plain perl string "cuke" ["acme", ["pi", 3.14], ["nose", "cuke"]]
my $src = q{(acme (pi 3.14)(nose "cuke"))}; works as well.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: S-expressions with Marpa::R2: Grammar for Numbers
by Corion (Patriarch) on Dec 22, 2025 at 13:32 UTC | |
by choroba (Cardinal) on Dec 22, 2025 at 22:25 UTC | |
by Fletch (Bishop) on Dec 23, 2025 at 15:41 UTC | |
|
Re: S-expressions with Marpa::R2: Grammar for Numbers
by LanX (Saint) on Dec 22, 2025 at 16:56 UTC |