[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
>