Parsecの組み合わせ
パーサーの組み合わせを作る
連接
parserを並べて、
全て解析成功したら成功
途中で失敗したら失敗
普通にdo記法の中で、parserを組み合わす感じ こういうやつ
code:hs
relational :: Parser Expr
relational = do
a <- spaces *> add
r <- relOp
b <- add
return $ r a b
選択
parserを並べて、
どれか一つが成功すれば成功
全て失敗すれば失敗
(<|>) :: Parser a -> Parser a -> Parser a
BNF記法での|はText.Parsec.(<|>)が対応する >parseTest (string "hello" <|> string "heaven") "heaven"
これはパースに失敗する
左辺でheまで消費しちゃってるので、右辺が実行されない
parseTest (try (string "hello") <|> string "heaven") "heaven"
こういう場合はtryを併用すると成功する
try
lookaheadする
つまり引数のパーサーの解析が失敗すると、失敗の直前まで戻してくれる
大抵は<|>でやればいいけど、先頭の文字が同じ時はtryを使えばいい
choice :: Stream s m t => [ParsecT s u m a] -> ParsecT s u m a
引数にリストを取り、その中に複数のパーサーを入れる
上から順に試していき、うまく行ったらその結果を返す
複数の<|>を簡潔に書いた感じ
ただこれはあくまでも<|>なのでtryとは異なる
全部をtryしたければchoice $ map try [parser1, parse2, ..]のように書くと良い
parser1とかの型はParser a
参考