--- |Yet another parser combinator. This is mostly a subset of Parsec
--- but there are some differences:
+-- |Yet another parser combinator. This is mostly a subset of
+-- "Text.ParserCombinators.Parsec" but there are some differences:
--
--- * This parser works on ByteString instead of String.
+-- * This parser works on 'Data.ByteString.Base.LazyByteString'
+-- instead of 'Prelude.String'.
--
-- * Backtracking is the only possible behavior so there is no \"try\"
-- action.
where
import Control.Monad.State.Strict
+import Data.ByteString.Base (LazyByteString)
+import Data.ByteString.Lazy ()
import qualified Data.ByteString.Lazy.Char8 as B
-import Data.ByteString.Lazy.Char8 (ByteString)
-
--- |@Parser a@ is obviously a parser which parses and returns @a@.
+-- |@'Parser' a@ is obviously a parser which parses and returns @a@.
newtype Parser a = Parser {
runParser :: State ParserState (ParserResult a)
}
data ParserState
= PST {
- pstInput :: ByteString
+ pstInput :: LazyByteString
, pstIsEOFFatal :: !Bool
}
deriving (Eq, Show)
return x = x `seq` Parser $! return $! Success x
fail _ = Parser $! return $! IllegalInput
--- |@'failP'@ is just a synonym for @'Prelude.fail Prelude.undefined'@.
+-- |@'failP'@ is just a synonym for @'Prelude.fail'
+-- 'Prelude.undefined'@.
failP :: Parser a
failP = fail undefined
-- |@'parse' p bstr@ parses @bstr@ with @p@ and returns @(result,
-- remaining)@.
-parse :: Parser a -> ByteString -> (ParserResult a, ByteString)
+parse :: Parser a -> LazyByteString -> (ParserResult a, LazyByteString)
parse p input -- input は lazy である必要有り。
= p `seq`
let (result, state') = runState (runParser p) (PST input True)
result `seq` (result, pstInput state') -- pstInput state' も lazy である必要有り。
-- |@'parseStr' p str@ packs @str@ and parses it.
-parseStr :: Parser a -> String -> (ParserResult a, ByteString)
+parseStr :: Parser a -> String -> (ParserResult a, LazyByteString)
parseStr p input
= p `seq` -- input は lazy である必要有り。
parse p $! B.pack input