chicken-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Chicken-users] Mutual recursion w/ comparse


From: Ivan Raikov
Subject: Re: [Chicken-users] Mutual recursion w/ comparse
Date: Thu, 28 May 2015 17:30:50 -0700

`vac' means `vacuous' because it is just a vacuous macro that delays
the application of a function.

   -Ivan


On Thu, May 28, 2015 at 5:24 PM, Matt Gushee <address@hidden> wrote:
> Okay, well, I found a solution. I'm using this simple macro:
>
>     (define-syntax mrp
>         (syntax-rules ()
>              ((_ fn) (lambda args (apply function args)))))
>
> Actually, this is just a copy of the 'vac' macro from json-abnf; I changed
> the name because I had no idea what 'vac' means - whereas 'mrp' stands for
> 'mutually recursive parser'.
>
> So, I wrap the body of the first parser definition in the mutually recursive
> group, like so:
>
>     (define dict-value
>         (mrp
>             (any-of integer float number boolean string~ list~ dict)))
>
> ... and everything's good.
>
> I also saw that comparse provides a similar macro called 'recursive-parser',
> but for some reason that didn't work when I tried it. Maybe I was using it
> wrong.
>
> I'd still be interested to know if my solution here is the best one, or if
> there are other good ways to handle this type of situation.
>
> --
> Matt Gushee
>
>
>
> On Wed, May 27, 2015 at 6:30 PM, Matt Gushee <address@hidden> wrote:
>>
>> 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
> address@hidden
> https://lists.nongnu.org/mailman/listinfo/chicken-users
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]