Hello--

I'm trying to write my first real parser with comparse, but I'm running
into some difficulty with mutual recursion. Here's the problematic portion
of my code:

    (define-values (dict dict-content dict-entry dict-value)
      (let ()
        (define dict~
          (enclosed-by (is #\{) dict-content~ (is #\})))
        (define dict-content~
          (sequence (maybe whitespace)
                    (maybe (sequence dict-entry~
                                     (zero-or-more (sequence separator
                                                             dict-entry~))))
                    (maybe whitespace)))
        (define dict-entry~
          (sequence dict-key
                    (maybe whitespace)
                    (is #\:)
                    (maybe whitespace)
                    dict-value~))
        (define dict-value~
          (any-of integer float number boolean string~ list~ dict~))
        (values dict~ dict-content~ dict-entry~ dict-value~)))

But when I try to use these parsers, e.g.

     (with-input-from-file "examples/basic.rsc"
         (lambda ()
              (let-values (((result rest)
                  (parse dict-content (read-all (current-input-port))))))))

I get this error:

Error: call of non-procedure: #<unspecified>

    Call history:

    rascl-parser.scm:166: comparse#sequence
    rascl-parser.scm:166: comparse#zero-or-more
    rascl-parser.scm:165: comparse#sequence
    rascl-parser.scm:165: comparse#maybe
    rascl-parser.scm:168: comparse#maybe
    rascl-parser.scm:164: comparse#sequence
    rascl-parser.scm:171: comparse#maybe
    rascl-parser.scm:172: comparse#is
    rascl-parser.scm:173: comparse#maybe
    rascl-parser.scm:170: comparse#sequence
    rascl-parser.scm:176: comparse#any-of
    rascl-parser.scm:177: values
    parse-basic.scm:13: with-input-from-file
    parse-basic.scm:14: ##sys#call-with-values
    parse-basic.scm:16: read-all
    parse-basic.scm:16: comparse#parse

I'm pretty sure the cause is not any of the individual parsers, but rather
the way I'm trying to implement mutual recursion. I tried a version with

        (define dict-value
          (any-of integer float number boolean string~ list~))

i.e., non-recursive, with all parsers defined with a simple sequence of
top-level (define)s, and it worked fine.

However, the actual grammar I'm trying to parse is similar, but not
identical, to JSON, and calls for nested dictionaries. I looked at the
medea source code and tried the approach used there (or as close as I could
come), and several other variations, but I always get the same error, or
else this one:

    Error: bad argument count - received 1 but expected 0: #<procedure
(rascl-parser#dict-content)>.

Obviously I'm doing something wrong, but I can't see what.

BTW, I have a closely related but more general question:

At first I tried to use top-level defines for all the parsers, and that
didn't work at all. I was surprised because I have used mutually recursive
procedures many times. But I think I understand now. I think it's because in

    (define (NAME ARG ...)  BODY ...)

the BODY expressions are evaluated at runtime, while in

    (define NAME BODY ...)

[which is the form typically used to define comparse parsers], the BODY
expressions are evaluated at compile time; thus any symbols referenced in
BODY must be previously (in lexical order) defined. Have I got that right?

Thanks for any help.

--
Matt Gushee
_______________________________________________
Chicken-users mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/chicken-users

Reply via email to