X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Network%2FHTTP%2FLucu%2FParser%2FHttp.hs;h=72d8ca1721ae7908a94cd1b2445eff1aaa16e1c8;hb=ece223c516e66223ef1d5d8e6bbe4054a235d983;hp=65ba8b27ccb1ff66f52d6bd83a6b2af86f3980be;hpb=9bb89434103e9a22f100d6ecb7e65a5d461e0454;p=Lucu.git diff --git a/Network/HTTP/Lucu/Parser/Http.hs b/Network/HTTP/Lucu/Parser/Http.hs index 65ba8b2..72d8ca1 100644 --- a/Network/HTTP/Lucu/Parser/Http.hs +++ b/Network/HTTP/Lucu/Parser/Http.hs @@ -1,6 +1,5 @@ {-# LANGUAGE - BangPatterns - , OverloadedStrings + OverloadedStrings , UnicodeSyntax #-} -- |This is an auxiliary parser utilities for parsing things related @@ -25,21 +24,19 @@ module Network.HTTP.Lucu.Parser.Http , separators , quotedStr , qvalue - - , atMost ) where import Control.Applicative -import Control.Applicative.Unicode -import Control.Monad.Unicode +import Control.Monad import Data.Ascii (Ascii) import qualified Data.Ascii as A -import Data.Attoparsec.Char8 as P +import Data.Attoparsec.Char8 as P hiding (scan) import qualified Data.Attoparsec.FastSet as FS import qualified Data.ByteString.Char8 as BS +import Network.HTTP.Lucu.Parser import Prelude.Unicode --- |@'isCtl' c@ is 'Prelude.False' iff @0x20 <= c < 0x7F@. +-- |@'isCtl' c@ returns 'False' iff @0x20 <= c < 0x7F@. isCtl ∷ Char → Bool {-# INLINE isCtl #-} isCtl c @@ -52,7 +49,7 @@ isText ∷ Char → Bool {-# INLINE isText #-} isText = (¬) ∘ isCtl --- |@'isSeparator' c@ is 'Prelude.True' iff c is one of HTTP +-- |@'isSeparator' c@ returns 'True' iff c is one of the HTTP -- separators. isSeparator ∷ Char → Bool {-# INLINE isSeparator #-} @@ -61,51 +58,54 @@ isSeparator = flip FS.memberChar set {-# NOINLINE set #-} set = FS.charClass "()<>@,;:\\\"/[]?={}\x20\x09" --- |@'isChar' c@ is 'Prelude.True' iff @c <= 0x7f@. +-- |@'isChar' c@ returns 'True' iff @c <= 0x7f@. isChar ∷ Char → Bool {-# INLINE isChar #-} isChar = (≤ '\x7F') --- |@'isToken' c@ is equivalent to @not ('isCtl' c || 'isSeparator' +-- |@'isToken' c@ is equivalent to @not ('isCtl' c '||' 'isSeparator' -- c)@ isToken ∷ Char → Bool {-# INLINE isToken #-} -isToken !c - = (¬) (isCtl c ∨ isSeparator c) +isToken c = (¬) (isCtl c ∨ isSeparator c) -- |@'listOf' p@ is similar to @'sepBy' p ('char' \',\')@ but it -- allows any occurrences of 'lws' before and after each tokens. listOf ∷ Parser a → Parser [a] {-# INLINEABLE listOf #-} listOf p - = try $ - do skipMany lws - sepBy p $ do skipMany lws - _ <- char ',' + = do skipMany lws + p `sepBy` do skipMany lws + void $ char ',' skipMany lws + + "listOf" --- |'token' is similar to @'takeWhile1' 'isToken'@ +-- |'token' is almost the same as @'takeWhile1' 'isToken'@ token ∷ Parser Ascii {-# INLINE token #-} -token = A.unsafeFromByteString <$> takeWhile1 isToken +token = (A.unsafeFromByteString <$> takeWhile1 isToken) + + "token" -- |The CRLF: 0x0D 0x0A. crlf ∷ Parser () {-# INLINE crlf #-} -crlf = string "\x0D\x0A" ≫ return () +crlf = (string "\x0D\x0A" *> return ()) + + "crlf" -- |The SP: 0x20. sp ∷ Parser () {-# INLINE sp #-} -sp = char '\x20' ≫ return () +sp = char '\x20' *> return () -- |HTTP LWS: crlf? (sp | ht)+ lws ∷ Parser () {-# INLINEABLE lws #-} -lws = try $ - do option () crlf - _ ← satisfy isSPHT - skipWhile isSPHT +lws = (option () crlf *> void (takeWhile1 isSPHT)) + + "lws" -- |Returns 'True' for SP and HT. isSPHT ∷ Char → Bool @@ -114,51 +114,52 @@ isSPHT '\x20' = True isSPHT '\x09' = True isSPHT _ = False --- |@'separators'@ is similar to @'takeWhile1' 'isSeparator'@. +-- |@'separators'@ is almost the same as @'takeWhile1' 'isSeparator'@. separators ∷ Parser Ascii {-# INLINE separators #-} -separators = A.unsafeFromByteString <$> takeWhile1 isSeparator +separators = (A.unsafeFromByteString <$> takeWhile1 isSeparator) + + "separators" -- |'quotedStr' accepts a string surrounded by double quotation -- marks. Quotes can be escaped by backslashes. quotedStr ∷ Parser Ascii {-# INLINEABLE quotedStr #-} -quotedStr = try $ - do _ ← char '"' +quotedStr = do void $ char '"' xs ← P.many (qdtext <|> quotedPair) - _ ← char '"' + void $ char '"' return $ A.unsafeFromByteString $ BS.pack xs + + "quotedStr" where qdtext ∷ Parser Char {-# INLINE qdtext #-} qdtext = satisfy (\c → c ≢ '"' ∧ (¬) (isCtl c)) + + "qdtext" quotedPair ∷ Parser Char {-# INLINE quotedPair #-} - quotedPair = char '\\' ≫ satisfy isChar + quotedPair = (char '\\' *> satisfy isChar) + + "quotedPair" -- |'qvalue' accepts a so-called qvalue. qvalue ∷ Parser Double {-# INLINEABLE qvalue #-} -qvalue = do x ← char '0' - xs ← option "" $ - do y ← char '.' - ys ← atMost 3 digit - return (y:ys) - return $ read (x:xs) - <|> - do x ← char '1' - xs ← option "" $ - do y ← char '.' - ys ← atMost 3 (char '0') - return (y:ys) - return $ read (x:xs) - --- |@'atMost' n v@ is like @'P.many' v@ but applies the given action --- at most @n@ times. -atMost ∷ Alternative f ⇒ Int → f a → f [a] -{-# INLINE atMost #-} -atMost 0 _ = pure [] -atMost n v = ( (:) <$> v ⊛ atMost (n-1) v ) - <|> - pure [] +qvalue = ( do x ← char '0' + xs ← option "" $ + do y ← char '.' + ys ← atMost 3 digit + return (y:ys) + return $ read (x:xs) + <|> + do x ← char '1' + xs ← option "" $ + do y ← char '.' + ys ← atMost 3 (char '0') + return (y:ys) + return $ read (x:xs) + ) + + "qvalue"