parsec --- 2.4 Adding semantics

ただパーサを書いて何をパースしたか出力するだけでは意味がないので,意味のあるものを返そうというお話.前に作ったparens

parens::Parser ()
parens = do char '(' >> parens >> char ')'
            parens
         <|> 
         return ()

を書き直して,括弧が何重になってるかを数えてみます.

nesting::Parser Int
nesting =    do char '(' 
                n <- nesting 
                char ')'
                m <- nesting
                return $ max (n+1) m
         <|> return 0

実行してみると

*Main> parseTest nesting "()((()))"
3
*Main>  parseTest nesting "("
parse error at (line 1, column 2):
unexpected end of input
expecting "(" or ")"
*Main>  parseTest nesting "a"
0
*Main> parseTest nesting "()((())) (()()"
3
*Main> parseTest nesting "()((())) )(()()"
3

となりました.やっぱり書かれたとおりの動作で,きちんと「最後まで」というのを教えてあげないと当然最後まではパースしませんね.