Gain a bit of speed by using native Attoparsec for number types instead of reimplementing them with ByteString conversion and call to read
This commit is contained in:
parent
1c457d71d8
commit
923d1800b0
3 changed files with 15 additions and 12 deletions
|
@ -19,7 +19,7 @@ import PDF.Object (
|
|||
, blank, dictionary, directObject, integer, line
|
||||
)
|
||||
import PDF.Output (ObjectId(..), Offset(..))
|
||||
import PDF.Parser (Parser, (<?>), block, char, evalParser, on, takeAll)
|
||||
import PDF.Parser (MonadParser(..), Parser, (<?>), evalParser, on)
|
||||
|
||||
data UserState = UserState {
|
||||
input :: ByteString
|
||||
|
|
|
@ -45,6 +45,7 @@ import Data.Map (Map, (!), mapWithKey)
|
|||
import qualified Data.Map as Map (
|
||||
delete, empty, fromList, lookup, minViewWithKey, toList, union
|
||||
)
|
||||
import qualified Data.Set as Set (fromList, member)
|
||||
import qualified PDF.EOL as EOL (charset, parser)
|
||||
import qualified PDF.Output as Output (line, string)
|
||||
import PDF.Output (
|
||||
|
@ -76,8 +77,8 @@ delimiterCharset = "()<>[]{}/%"
|
|||
regular :: Char -> Bool
|
||||
regular = not . (`elem` (EOL.charset ++ whiteSpaceCharset ++ delimiterCharset))
|
||||
|
||||
integer :: (Read a, Num a, MonadParser m) => m a
|
||||
integer = read . Char8.unpack <$> decNumber <* blank <?> "decimal integer"
|
||||
integer :: MonadParser m => m Int
|
||||
integer = decNumber <* blank <?> "decimal integer"
|
||||
|
||||
-------------------------------------
|
||||
-- OBJECTS
|
||||
|
@ -104,13 +105,12 @@ instance Output Number where
|
|||
_ -> printf "%f" f
|
||||
|
||||
number :: MonadParser m => m Number
|
||||
number = Number . read . Char8.unpack <$>
|
||||
(mappend <$> sign <*> (integerPart <|> Char8.cons '0' <$> floatPart))
|
||||
<?> "number"
|
||||
number = Number <$> (sign <*> value) <?> "number"
|
||||
where
|
||||
sign = string "-" <|> option "" (char '+' >> return "")
|
||||
integerPart = mappend <$> decNumber <*> option "" floatPart
|
||||
floatPart = Char8.cons <$> char '.' <*> (option "0" $ decNumber)
|
||||
sign = (string "-" *> return negate) <|> option id (char '+' >> return id)
|
||||
value = floatNumber <|> (char '.' *> afterPoint)
|
||||
afterPoint = read . ("0." ++) . Char8.unpack <$> takeAll (`Set.member` digits)
|
||||
digits = Set.fromList ['0' .. '9']
|
||||
|
||||
--
|
||||
-- StringObject
|
||||
|
|
|
@ -17,7 +17,7 @@ import Control.Monad.Fail (MonadFail(..))
|
|||
import Control.Monad.State (StateT(..), evalStateT)
|
||||
import Control.Monad.Trans (MonadTrans(..))
|
||||
import qualified Data.Attoparsec.ByteString.Char8 as Atto (
|
||||
Parser, char, endOfInput, parseOnly, peekChar', satisfy, string, take
|
||||
Parser, char, decimal, double, endOfInput, parseOnly, peekChar', satisfy, string, take
|
||||
, takeWhile, takeWhile1
|
||||
)
|
||||
import Data.ByteString (ByteString)
|
||||
|
@ -32,7 +32,8 @@ type MonadDeps m = (MonadFail m, MonadPlus m)
|
|||
class MonadDeps m => MonadParser m where
|
||||
block :: Int -> m ByteString
|
||||
char :: Char -> m Char
|
||||
decNumber :: m ByteString
|
||||
decNumber :: m Int
|
||||
floatNumber :: m Double
|
||||
endOfInput :: m ()
|
||||
hexNumber :: m B16Int
|
||||
oneOf :: String -> m Char
|
||||
|
@ -45,7 +46,8 @@ instance MonadParser Atto.Parser where
|
|||
block = Atto.take
|
||||
char = Atto.char
|
||||
endOfInput = Atto.endOfInput
|
||||
decNumber = Atto.takeWhile1 (`Set.member` digits)
|
||||
decNumber = Atto.decimal
|
||||
floatNumber = Atto.double
|
||||
hexNumber = B16Int <$> Atto.takeWhile1 (`Set.member` hexDigits)
|
||||
oneOf charSet = Atto.satisfy (`elem` charSet)
|
||||
peek = Atto.peekChar'
|
||||
|
@ -58,6 +60,7 @@ instance (MonadParser m, MonadTrans t, MonadDeps (t m)) => MonadParser (t m) whe
|
|||
char = lift . char
|
||||
endOfInput = lift $ endOfInput
|
||||
decNumber = lift $ decNumber
|
||||
floatNumber = lift $ floatNumber
|
||||
hexNumber = lift $ hexNumber
|
||||
oneOf = lift . oneOf
|
||||
peek = lift $ peek
|
||||
|
|
Loading…
Reference in a new issue