Haskell语言学习笔记(46)Parsec(3)

Applicative Parsing

使用 Applicative 式的 Parser。
包括使用 (< >),(<\*>),(< ), (<*), (*>), (<|>), many 等运算符。

应用实例1

import Control.Monad
import Text.Parsec
import Control.Applicative hiding ((<|>))

number = many1 digit
plus = char '+' *> number
minus = (:) <$> char '-' <*> number
integer = plus <|> minus <|> number
float = fmap rd $ (++) <$> integer <*> decimal
    where rd      = read :: String -> Float
          decimal = option "" $ (:) <$> char '.' <*> number

main = forever $ do putStrLn "Enter a float: "
                    input <- getLine
                    parseTest float input
*Main> main
Enter a float: 
2.3
2.3
Enter a float: 
1
1.0
Enter a float: 
-1
-1.0
Enter a float: 
+6.98
6.98
  • plus = char ‘+’ *> number
    p1 *> p2 依次匹配 p1 和 p2,但是 p1 被舍弃,只返回 p2。
  • minus = (:)

应用实例2

import Text.Parsec
import Control.Applicative ((<$), (<*), (*>), liftA)
import Data.Char           (chr)

parseCSV :: String -> Either ParseError [[String]]
parseCSV = parse csvp ""

csvp :: Parsec String () [[String]]
csvp = line `endBy` newline <* eof

line :: Parsec String () [String]
line = cell `sepBy1` char ','

cell :: Parsec String () String
cell = cell' <|> many (noneOf ",\n")
    where cell' = between (char '"') (char '"') $ many chr
          chr   = noneOf "\"" <|> try ('"' <$ string "\"\"")
*Main> parseCSV "a,b,c\n"
Right [["a","b","c"]]
*Main> parseCSV "a,b,\"c\"\n"
Right [["a","b","c"]]
*Main> parseCSV "a,b,\"c\"\"d\"\n"
Right [["a","b","c\"d"]]
  • csvp = line `endBy` newline <* eof
    p1 <* p2 依次匹配 p1 和 p2,但是 p2 被舍弃,只返回 p1。
    endBy p sep 匹配0次或多次 p + sep 所组成的序列,返回 p 的 list。
  • line = cell `sepBy1` char ‘,’
    sepBy1 p sep 匹配 p 后接0次或多次 sep + p 组成的序列,返回 p 的 list。
  • chr = noneOf “\”” <|> try (‘”’

参考链接

Parsing Floats With Parsec
A Gentle Introduction to Parsec

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值