Use peek to improve directObject parser avoiding a large <|> disjunction

This commit is contained in:
Tissevert 2020-02-12 17:34:27 +01:00
parent 195446e653
commit 32f9866106
2 changed files with 17 additions and 12 deletions

View File

@ -220,16 +220,18 @@ instance Output DirectObject where
Output.string (printf "%d %d R" (getObjectId objectId) versionNumber) Output.string (printf "%d %d R" (getObjectId objectId) versionNumber)
directObject :: MonadParser m => m DirectObject directObject :: MonadParser m => m DirectObject
directObject = directObject = (peek >>= dispatch) <?> "direct object"
Boolean <$> boolean where
<|> Reference <$> reference {- defined before Number because Number is a prefix of it -} dispatch 't' = Boolean <$> boolean
<|> NumberObject <$> number dispatch 'f' = Boolean <$> boolean
<|> StringObject <$> stringObject dispatch '(' = StringObject <$> stringObject
<|> NameObject <$> name dispatch '<' = StringObject <$> stringObject <|> Dictionary <$> dictionary
<|> Array <$> array dispatch '/' = NameObject <$> name
<|> Dictionary <$> dictionary dispatch '[' = Array <$> array
<|> const Null <$> nullObject dispatch 'n' = nullObject *> return Null
<?> "direct object" dispatch _ =
Reference <$> reference {- defined before Number because Number is a prefix of it -}
<|> NumberObject <$> number
-- --
-- Object -- Object

View File

@ -17,8 +17,8 @@ import Control.Monad.Fail (MonadFail(..))
import Control.Monad.State (StateT(..), evalStateT) import Control.Monad.State (StateT(..), evalStateT)
import Control.Monad.Trans (MonadTrans(..)) import Control.Monad.Trans (MonadTrans(..))
import qualified Data.Attoparsec.ByteString.Char8 as Atto ( import qualified Data.Attoparsec.ByteString.Char8 as Atto (
Parser, char, endOfInput, parseOnly, satisfy, string, take, takeWhile Parser, char, endOfInput, parseOnly, peekChar', satisfy, string, take
, takeWhile1 , takeWhile, takeWhile1
) )
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import Data.ByteString.Char8.Util (B16Int(..)) import Data.ByteString.Char8.Util (B16Int(..))
@ -36,6 +36,7 @@ class MonadDeps m => MonadParser m where
endOfInput :: m () endOfInput :: m ()
hexNumber :: m B16Int hexNumber :: m B16Int
oneOf :: String -> m Char oneOf :: String -> m Char
peek :: m Char
string :: ByteString -> m ByteString string :: ByteString -> m ByteString
takeAll :: (Char -> Bool) -> m ByteString takeAll :: (Char -> Bool) -> m ByteString
takeAll1 :: (Char -> Bool) -> m ByteString takeAll1 :: (Char -> Bool) -> m ByteString
@ -47,6 +48,7 @@ instance MonadParser Atto.Parser where
decNumber = Atto.takeWhile1 (`Set.member` digits) decNumber = Atto.takeWhile1 (`Set.member` digits)
hexNumber = B16Int <$> Atto.takeWhile1 (`Set.member` hexDigits) hexNumber = B16Int <$> Atto.takeWhile1 (`Set.member` hexDigits)
oneOf charSet = Atto.satisfy (`elem` charSet) oneOf charSet = Atto.satisfy (`elem` charSet)
peek = Atto.peekChar'
string s = Atto.string s <?> show s string s = Atto.string s <?> show s
takeAll = Atto.takeWhile takeAll = Atto.takeWhile
takeAll1 = Atto.takeWhile1 takeAll1 = Atto.takeWhile1
@ -58,6 +60,7 @@ instance (MonadParser m, MonadTrans t, MonadDeps (t m)) => MonadParser (t m) whe
decNumber = lift $ decNumber decNumber = lift $ decNumber
hexNumber = lift $ hexNumber hexNumber = lift $ hexNumber
oneOf = lift . oneOf oneOf = lift . oneOf
peek = lift $ peek
string = lift . string string = lift . string
takeAll = lift . takeAll takeAll = lift . takeAll
takeAll1 = lift . takeAll1 takeAll1 = lift . takeAll1