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::do_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.dat
{ fields => {
"anonymous" => "off",
"canonical-url" => "https://goethebier.space/fossil/p-acme",
"crlf-glob" => "*.bat *.cmd",
"crnl-glob" => "",
"default-user" => "karl",
"hash-policy" => "sha3", "http-port" => 8081,
"ignore-glob" => ["*.o", "*.swp", "*.tmp", ".direnv/", "_build/", "_opam/"],
"localauth" => "on",
"max-upload" => "20MB", "project-description" => "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/sexp.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.
Parsing LISP seems to be a good way to get started with a grammar engine like Marpa::R2
Much appreciated!
Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery
I can't test it but I would start with:
atom ::= string
| number
| symbol
number_chars ::= SIGN? DIGITS action => Sexp::Tiny::Actions::do_join
SIGN ~ "+" | "-"
DIGITS ~ [0-9]
# Exclude the new starting characters for numbers from the "symbol" character class
SYMCHAR ~ [^()\s"0-9+-]
number ~ sign_maybe digit_many e
| sign_maybe digit_any '.' digit_many e_maybe
| sign_maybe digit_many e_maybe
| sign_maybe non_zero digit_any
empty ~
sign_maybe ~ [+-] | empty
digit ~ [0-9]
non_zero ~ [1-9]
digit_any ~ digit*
digit_many ~ digit+
e ~ [Ee] sign_maybe digit_many
e_maybe ~ e | empty
map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]