Parsecを使ってみた
module Parser where import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Char data Expr = E_Val Val | E_Seq [Expr] instance Show Expr where showsPrec d (E_Val v) = showsPrec d v showsPrec d (E_Seq []) = showString "()" showsPrec d (E_Seq (e:[])) = showParen (d == 0) (showsPrec 0 e) showsPrec d (E_Seq (e:es)) = showParen (d == 0) (showsPrec 0 e . showString " " . showsPrec 1 (E_Seq es)) data Val = V_Int Int deriving Eq instance Show Val where showsPrec d (V_Int num) = showsPrec d num expr :: Parser Expr expr = do { char '(' ; many space ; es <- many (do { e <- expr ; many space ; return e }) ; char ')' ; return (E_Seq es) } <|> int int = do { ds <- many1 digit ; return (E_Val $ V_Int $ read ds) }
実行結果はこんな感じ。
*Parser> parseTest expr "( 1 2 (1 2) )" (1 2 (1 2))
なかなか良さそう。今度からは自作Parser Combinator Libraryモドキを使わずにParsecを使うようにしよう。