
Hi Niklas,
ctrlBodyParser :: CharParser ([Value], [Property], [Control]) ([Value], [Property], [Control]) ctrlBodyParser = do { c <- ctrlParser -- parse child control ; (vs, ps, cs) <- getState ; setState (vs, ps, (c : cs)) ; ctrlBodyParser } <|> do { p <- propParser -- parse child property ; (vs, ps, cs) <- getState ; setState (vs, (p : ps), cs) ; ctrlBodyParser } <|> do { v <- valueParser -- parse value ; (vs, ps, cs) <- getState ; setState ((v : vs), ps, cs) ; ctrlBodyParser } <|> do { getState } -- we're finished, return children
Uhm, maybe I'm being clueless here but I never use state to pass around results. This looks like a place where you want to parse "many" subparsers: ctrlBodyParser = many parseOneCtrlBody parseOneCtrlBody = do { c <- ctrlParser; return (Control c)} <|> do { p <- propParser; return (Property p)} <|> do { v <- valueParser; return (Value v)} data CtrlBody = Control | Property | Value Of course, ctrlBodyParser then has type [CtrlBody] so if you want your triple of lists you have to postprocess the list. Anyway, I don't think parsec state is what you want to use here and explicit recursion of parsers can often be avoided using the many (pun intended) combinators of Parsec. Cheers, Arjan