How to work with the tree produced by (ice-9 peg)'s match-pattern?
Tomas Volf <[email protected]>
| Newsgroups | gmane.lisp.guile.user |
|---|---|
| Message-ID | <[email protected]> |
Hi :)
I recently discovered the (ice-9 peg) module, and it seems really
useful. However I have to admit I struggle a bit with processing the
tree produced by it.
Let me put forward an example:
--8<---------------cut here---------------start------------->8---
(use-modules (ice-9 peg))
(define-peg-pattern Opt body
(and Name Space (+ (and Enum Space)) Default))
(define-peg-pattern Name all
(+ Alpha))
(define-peg-pattern Enum all
(+ Alpha))
(define-peg-pattern Default all
(and (ignore "(default: ") (* Alpha) (ignore ")")))
(define-peg-pattern Alpha body
(range #\a #\z))
(define-peg-pattern Space none
" ")
--8<---------------cut here---------------end--------------->8---
Now I can feed it few strings to get the parsed trees:
--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> (peg:tree (match-pattern Opt "name a b c (default: a)"))
$11 = ((Name "name") ((Enum "a") (Enum "b") (Enum "c")) (Default "a"))
scheme@(guile-user)> (peg:tree (match-pattern Opt "name a b c (default: )"))
$12 = ((Name "name") ((Enum "a") (Enum "b") (Enum "c")) Default)
scheme@(guile-user)> (peg:tree (match-pattern Opt "name a (default: a)"))
$13 = ((Name "name") (Enum "a") (Default "a"))
scheme@(guile-user)> (peg:tree (match-pattern Opt "name a (default: )"))
$14 = ((Name "name") (Enum "a") Default)
--8<---------------cut here---------------end--------------->8---
What we see here is that it produces trees in 4 different "shapes",
depending on the input string. And I am unsure how to reasonably
process them.
My current approach looks like:
--8<---------------cut here---------------start------------->8---
(define process-tree
(match-lambda
((('Name name) (('Enum enum) ...) ('Default def))
(pk name enum def))
((('Name name) ('Enum enum) ... ('Default def))
(pk name enum def))
((('Name name) (('Enum enum) ...) 'Default)
(pk name enum #f))
((('Name name) ('Enum enum) ... 'Default)
(pk name enum #f))))
--8<---------------cut here---------------end--------------->8---
Which *does* work:
--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> (for-each process-tree (list $11 $12 $13 $14))
;;; ("name" ("a" "b" "c") "a")
;;; ("name" ("a" "b" "c") #f)
;;; ("name" ("a") "a")
;;; ("name" ("a") #f)
--8<---------------cut here---------------end--------------->8---
However it is very repetitive and the code is pretty hard to work with.
(Real code even has few more branches.) And I am not sure how to do a
better job at this.
It would really simplify things if I would be able to *always* have a
list of 'Enum, even when there is just a single one. Same for default.
I tried keyword-flatten, but probably I just do not understand how to
use it. Or maybe (ice-9 match) is just a wrong tool here?
Would someone be able to provide general guidance how to approach this,
or at least recommend some projects using (ice-9 peg) that I could
study?
Thanks and have a nice day,
Tomas
--
There are only two hard things in Computer Science:
cache invalidation, naming things and off-by-one errors.
signature.asc
(application/pgp-signature, 853 B)
-----BEGIN PGP SIGNATURE----- iQJCBAEBCgAsFiEEt4NJs4wUfTYpiGikL7/ufbZ/wakFAmdQRc0OHH5Ad29sZnNk ZW4uY3oACgkQL7/ufbZ/wakC9w/9G3fZJlRnwYP+zF56KOLnjpeljAiNYCEfYzlJ Y2tNqfPG6gYVoO5d5IVeYpk4VifBqN7mNnJKznFrPEm8die95cDxtYNmDLVolmaY QZehe8KEsR/PxV3phcPi4qz++YahJ3pBwWDI5+COzf1oxW/vfBbbuTgJn0VOOlxz q1wE67WnIb+VVuzJkc4SYvSSh0zHxvHwI5AHxys/rEHGKjGT+Y9wooSFg3zs8gmp pnHqRgi72sgI1HivbOReO4gDwYzSQ81c9tMCCuMJG2RoJuB5Ok5fxoY5kVL3KDUy WfrKe2PBTveHIY3ioOAaz97SQtUk02EM5Yvc+l9tIWqXts2krSRDpM/bBiN9Frwf j75pVrw3m1ab/Mr+lRYUPZ/eEjtqwK2CaYlI3t9UJT5GGymAWYfdetihZ3Fq7teK 1UAIPevGCPxaKpmWvoPJsATOsYPAcoUmRaH7QH7uVE9nbFd2Xi8bQasce9xZttAK +NMwpxND45eyDK69taHaDOZEG5k8ZP3iMVLPZI/GqUm9XKvJdUcKcQ384aLa8QRp Z/Umd6+Ph3t5gqLgt7gCigJknF/E395rtOL1NJr9hhkxxGOKrW3UCn6rOKNK4gY0 +S6qpJEI3AhAMQJ5tHH3Jltjh3dGY6byKcUEKeMXKjopxUlgQNBSHXm+N/MGYzRz wH+3Ths= =xkKe -----END PGP SIGNATURE-----