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