1 module Network.HTTP.Lucu.Parser
5 , parse -- Parser a -> ByteString -> ParserResult a
7 , anyChar -- Parser Char
8 , satisfy -- (Char -> Bool) -> Parser Char
9 , char -- Char -> Parser Char
10 , string -- String -> Parser String
11 , (<|>) -- Parser a -> Parser a -> Parser a
12 , oneOf -- [Char] -> Parser Char
13 , digit -- Parser Char
14 , hexDigit -- Parser Char
15 , notFollowedBy -- Parser a -> Parser ()
16 , many -- Parser a -> Parser [a]
17 , many1 -- Parser a -> Parser [a]
18 , manyTill -- Parser a -> Parser end -> Parser [a]
19 , many1Till -- Parser a -> Parser end -> Parser [a]
20 , option -- a -> Parser a -> Parser a
23 , crlf -- Parser String
28 import Control.Monad.State
29 import qualified Data.ByteString.Lazy.Char8 as B
30 import Data.ByteString.Lazy.Char8 (ByteString)
32 data Parser a = Parser {
33 runParser :: State ByteString (ParserResult a)
36 data ParserResult a = Success a
37 | IllegalInput -- 受理出來ない入力があった
38 | ReachedEOF -- 限界を越えて讀まうとした
42 -- (>>=) :: Parser a -> (a -> Parser b) -> Parser b
43 instance Monad Parser where
44 p >>= f = Parser $ do saved <- get -- 失敗した時の爲に状態を保存
47 Success a -> runParser (f a)
48 IllegalInput -> do put saved -- 状態を復歸
50 ReachedEOF -> return ReachedEOF
51 return = Parser . return . Success
52 fail _ = Parser $ return IllegalInput
55 parse :: Parser a -> ByteString -> (ParserResult a, ByteString)
56 parse p input = runState (runParser p) input
59 anyChar :: Parser Char
60 anyChar = Parser $ do input <- get
64 do let c = B.head input
69 satisfy :: (Char -> Bool) -> Parser Char
70 satisfy f = do c <- anyChar
71 unless (f c) (fail "")
75 char :: Char -> Parser Char
76 char c = satisfy (== c)
79 string :: String -> Parser String
80 string str = do mapM_ char str
86 (<|>) :: Parser a -> Parser a -> Parser a
87 f <|> g = Parser $ do saved <- get -- 状態を保存
90 Success a -> return $ Success a
91 IllegalInput -> do put saved -- 状態を復歸
93 ReachedEOF -> return ReachedEOF
96 oneOf :: [Char] -> Parser Char
97 oneOf = foldl (<|>) (fail "") . map char
100 notFollowedBy :: Parser a -> Parser ()
101 notFollowedBy p = p >>= fail "" <|> return ()
105 digit = do c <- anyChar
106 if c >= '0' && c <= '9' then
112 hexDigit :: Parser Char
113 hexDigit = do c <- anyChar
114 if (c >= '0' && c <= '9') ||
115 (c >= 'a' && c <= 'f') ||
116 (c >= 'A' && c <= 'F') then
122 many :: Parser a -> Parser [a]
130 many1 :: Parser a -> Parser [a]
131 many1 p = do ret <- many p
137 manyTill :: Parser a -> Parser end -> Parser [a]
138 manyTill p end = many $ do x <- p
143 many1Till :: Parser a -> Parser end -> Parser [a]
144 many1Till p end = many1 $ do x <- p
149 option :: a -> Parser a -> Parser a
150 option def p = p <|> return def
161 crlf :: Parser String
162 crlf = string "\x0d\x0a"