On Dec 28 2009, 7:03 am, Konrad Hinsen <[email protected]>
wrote:
> On 27.12.2009, at 01:47, samppi wrote:
>
> > creates a new rule that repeats a given subrule. The problem with rep+
> > right now is that it increases the stack for every token it consumes,
> > which overflows the stack with large amounts of tokens.
>
> > Is there, then, a way to rewrite rep+ so that it does not grow the
> > stack?
>
> I don't see one immediately. The problem is not really related to
> monads, it's that your rep+ is recursive but not tail-recursive. Tail-
> recursive monadic functions can be handled using lazy evaluation, but
> this simple solution does not work in your case. Your rep+ needs to be
> written in a very different way.
>
> One idea: if you can express rep+ in terms of m-until, you can then
> use the specialized version state-m-until that is not recursive any
> more.
>
> Konrad.
I also found this problem with Jim Duey's none-or-more and one-or-
more. After finding this post I took Konrad's advise and came up with
this:
(defn none-or-more2
"Makes a parser repeat none or more times."
[mv]
(state-m-until
#(:done (meta %))
#((fn [s]
(if-let [x (mv s)]
[(conj % (first x)) (second x)]
[(with-meta % {:done true}) s])))
#^{:done false} []))
Not liking the metadata solution I hacked this up:
(defn none-or-more
"Makes a parser repeat none or more times."
[mv]
(fn [s1]
(let [[v s2] ((state-m-until
first
#(fn [s3]
(if-let [x (mv s3)]
[[false (conj (second %) (first x))] (second
x)]
[[true (second %)] s3]))
[false []]) s1)]
[(second v) s2])))
I'd like to see what you guys think and if anyone can clean these up
more.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en