On Dec 28 2009, 7:03 am, Konrad Hinsen <konrad.hin...@fastmail.net>
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 clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to