makeTokenParser で作った int lexer が空白を食べる
こんな事してうまいこと動かないので、ちょっと悩んだ。
module Main where import Text.ParserCombinators.Parsec import qualified Text.ParserCombinators.Parsec.Token as P import Text.ParserCombinators.Parsec.Language (emptyDef) num :: GenParser Char st Int num = (P.integer $ P.makeTokenParser emptyDef) >>= return . fromInteger hspace = many $ oneOf " \t" numline :: GenParser Char st [Int] numline = do nums <- sepBy num hspace char '\n' return nums main = do parseTest (sepBy num $ char ' ') "1 2 3" -- 最初のだけ parse される parseTest numline "0132 234\n"-- error parseTest numline "0132 \n"-- error parseTest numline "0132\n"-- error
入力 file format が line-oriented なので、行ごとに区切って space-separated な数値 list を読んでいきたいのだけど、makeTokenParser が返す lexer が既に余分な空白を消費する仕様になっているので、区切り文字を上記のように user 側から指定できない (token parser が \n まで喰った挙句、後続部分曰く「\n 無えぞゴルァ」だってさ)。数字だけを消費してほしいんだけどな…。
LanguageDef の定義を見る限り、そこで "whitespace" から \n を除外するよう指定できるかと思ったけど、そんな member どこにも無いし。これでは Python style とか追加できないんでは?
こういう↓もっさい事しないといけないのかなあ?
num :: GenParser Char st Int num = many1 digit >>= return . fst . head . readDec
↑この code では絶対例外処理が発生しないけど、そういう保証が無い場合の error 処理はどうするのか…fail "msg" か?
何かめんどくさ。