Parser Combinator in SML -- Problem with MLton

René Neumann <[email protected]>
Newsgroups gmane.comp.lang.ml.mlton.user
Message-ID <[email protected]>
Dear all,

for our project we are using a parser written with a homebrewn parser
combinator library. This worked out pretty well. But the library was
very verbose and using an ugly syntax:

(bind (trim (keyword [#"f", #"o", #"r"]))
(fn _ => bind (trim (symbol [#"{"]))
(fn _ => bind (seq ())
(fn sps => bind (trim (symbol [#"}"]))
(fn _ => return (For sps))))))

Therefore I changed it to use SML's ability to define new operators. For
example "bind p q" became "p >>= q" and the idiom
"bind p (fn _ => q)" became "p >> q" (I also changed from char lists to
strings). So the example above becomes:

$$ "for" >> $"{" >> seq() -- $"}" ==> For

With this I ran into a first problem: Nontermination on compilation when
using mutual recursive parsers, as everything is now an argument to a
function (therefore evaluated on the spot) instead of being wrapped in a
lambda term. But this I could solve by adding some "fn _ =>" to some
critical spots.

But now I noticed another BIG problem: It is slow as hell (for larger
files). While the old ran instantanious, the new one takes several
seconds. It also takes a lot more memory. What's worse: in PolyML it
still _is_ instantanious.

Does anyone have an idea what is going on here? Is some optimization in
MLton backfiring? Especially where nearly everything is now evaluated
right-away as a function argument instead of the delayed(?) evaluation
of deeply-nested functions as before?


Thanks,
René


Some more code snippets just to make sure, I did not forgot to mention
something important:


fun priority _ = $$ "priority" >> constant

(* consumes a variable reference and returns error message in case of fail*)
fun varRef _ = "variable reference expected" !!
            trim identifier
            >>= (fn id => maybe ($"[" >> expr () -- $"]" )
            >>= (fn e  => maybe ($"." >> varRef ())
            ==> (fn v  => VarRef {name = id, index = e, next = v})))

(* consumes a list of variables *)
and varArgs _ = sequence ($",") (varRef ())

(* consumes a list of expressions *)		
and exprArgs _ = sequence ($",") (expr ())

and … (* a lot more *)

(* consumes a comment and returns error message in case of fail *)
val comment =
  let
    fun p () = try (
          list (satisfy (fn c => not (c = #"*")))
       >> item #"*"
       >>= (fn _ => item #"/" || p ())
       >> return #" ")
  in
       items [#"/", #"*"]
    >> (p () || fail "open comment")
end

--
René Neumann

Institut für Informatik (I7)
Technische Universität München
Boltzmannstr. 3
85748 Garching b. München

Tel: +49-89-289-17232
Office: MI 03.11.055

------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk

_______________________________________________
MLton-user mailing list
[email protected]; [email protected]
https://lists.sourceforge.net/lists/listinfo/mlton-user
smime.p7s (application/pkcs7-signature, 4.7 KB) - not displayed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.