on master help sign in
Switched over completely to monadic parsing
commit5860fa9b7203d89159247670de3fe3e88180b180 authorMichael Snoyman <michael@snoyman.com> dateThu 14 Jan 2010, 19:24 (17 years ago) parentf27016c
2 files changed+41−75
Text/Libyaml.hs+6−31 runtests.hs+35−44
Text/Libyaml.hs+6−31
@@ -15,7 +15,6 @@ module Text.Libyaml
1515 -- * Exceptions
1616 , YamlException (..)
1717 -- * Enumerator
18− , EnumResult (..)
1918 , With (..)
2019 -- * Encoder
2120 , YamlEncoder
@@ -27,7 +26,6 @@ module Text.Libyaml
2726 , decode
2827 , encodeFile
2928 , decodeFile
30− , decodeFile'
3129 ) where
3230
3331import qualified Data.ByteString.Internal as B
@@ -317,18 +315,6 @@ getEvent er = do
317315 YamlMappingStartEvent -> return EventMappingStart
318316 YamlMappingEndEvent -> return EventMappingEnd
319317
320−parserParse :: (MonadFailure YamlException m, With m)
321− => (a -> Event -> m (EnumResult a b))
322− -> a
323− -> Parser
324− -> m b
325−parserParse fold accum parser = do
326− event <- parserParseOne parser
327− res <- fold accum event
328− case res of
329− Done accum' -> return accum'
330− More accum' -> parserParse fold accum' parser
331−
332318-- Emitter
333319
334320data EmitterStruct
@@ -552,9 +538,6 @@ newtype ToEventRawException = ToEventRawException CInt
552538 deriving (Show, Typeable)
553539instance Exception ToEventRawException
554540
555−data EnumResult a b = More a | Done b
556− deriving (Eq, Show)
557−
558541encode :: (With m, MonadFailure YamlException m)
559542 => YamlEncoder m ()
560543 -> m B.ByteString
@@ -568,20 +551,12 @@ encodeFile filePath = withEmitterFile filePath . runMyReaderT
568551
569552decode :: (With m, MonadFailure YamlException m)
570553 => B.ByteString
571− -> (a -> Event -> m (EnumResult a b))
572− -> a
573− -> m b
574−decode bs fold accum = withParser bs $ parserParse fold accum
554+ -> YamlDecoder m a
555+ -> m a
556+decode bs dec = withParser bs $ runMyReaderT dec
575557
576558decodeFile :: (With m, MonadFailure YamlException m)
577559 => FilePath
578− -> (a -> Event -> m (EnumResult a b))
579− -> a
580− -> m b
581−decodeFile fp fold accum = withFileParser fp $ parserParse fold accum
582−
583−decodeFile' :: (With m, MonadFailure YamlException m)
584− => FilePath
585− -> YamlDecoder m a
586− -> m a
587−decodeFile' fp dec = withFileParser fp $ runMyReaderT dec
560+ -> YamlDecoder m a
561+ -> m a
562+decodeFile fp dec = withFileParser fp $ runMyReaderT dec
runtests.hs+35−44
@@ -17,67 +17,72 @@ main = defaultMain
1717 , testCase "encode/decode" caseEncodeDecode
1818 , testCase "encode/decode file" caseEncodeDecodeFile
1919 , testCase "interleaved encode/decode" caseInterleave
20− , testCase "interleaved encode/decode monadic" caseInterleaveMonad
2120 ]
2221
2322caseCountScalars :: Assertion
2423caseCountScalars = do
25− res <- decode yamlBS fold accum
24+ res <- decode yamlBS $ counter accum
2625 res @?= (7, 1, 2)
2726 where
2827 yamlString = "foo:\n baz: [bin1, bin2, bin3]\nbaz: bazval"
2928 yamlBS = B8.pack yamlString
30− fold (s, l, m) (EventScalar {}) = return $ More (s + 1, l, m)
31− fold (s, l, m) EventSequenceStart = return $ More (s, l + 1, m)
32− fold (s, l, m) EventMappingStart = return $ More (s, l, m + 1)
33− fold res EventNone = return $ Done res
34− fold res _ = return $ More res
29+ counter (s, l, m) = do
30+ e <- parseEvent
31+ case e of
32+ EventScalar {} -> counter (s + 1, l, m)
33+ EventSequenceStart -> counter (s, l + 1, m)
34+ EventMappingStart -> counter (s, l, m + 1)
35+ EventNone -> return (s, l, m)
36+ _ -> counter (s, l, m)
3537 accum = (0, 0, 0) :: (Int, Int, Int)
3638
3739caseLargestString :: Assertion
3840caseLargestString = do
39− res <- decodeFile filePath fold accum
41+ res <- decodeFile filePath $ dec accum
4042 res @?= (length expected, expected)
4143 where
4244 expected = "this one is just a little bit bigger than the others"
4345 filePath = "test/largest-string.yaml"
44− fold (i, s) (EventScalar bs _ _) =
45− let s' = B8.unpack bs
46− i' = length s'
47− in if i' > i
48− then return $ More (i', s')
49− else return $ More (i, s)
50− fold res EventNone = return $ Done res
51− fold res _ = return $ More res
46+ dec (i, s) = do
47+ e <- parseEvent
48+ case e of
49+ (EventScalar bs _ _) -> do
50+ let s' = B8.unpack bs
51+ i' = length s'
52+ dec $ if i' > i then (i', s') else (i, s)
53+ EventNone -> return (i, s)
54+ _ -> dec (i, s)
5255 accum = (0, "no strings found")
5356
5457caseEncodeDecode :: Assertion
5558caseEncodeDecode = do
56− eList' <- decode yamlBS fold id
57− let eList = eList' []
59+ eList <- decode yamlBS $ dec id
5860 bs <- encode $ mapM_ emitEvent eList
59− eList2' <- decode bs fold id
60− let eList2 = eList2' []
61+ eList2 <- decode bs $ dec id
6162 map MyEvent eList @=? map MyEvent eList2
6263 where
6364 yamlString = "foo: bar\nbaz:\n - bin1\n - bin2\n"
6465 yamlBS = B8.pack yamlString
65− fold x EventNone = return $ Done x
66− fold x e = return $ More $ x . (:) e
66+ dec front = do
67+ e <- parseEvent
68+ case e of
69+ EventNone -> return $ front []
70+ _ -> dec $ front . (:) e
6771
6872caseEncodeDecodeFile :: Assertion
6973caseEncodeDecodeFile = do
70− eList' <- decodeFile filePath fold id
71− let eList = eList' []
74+ eList <- decodeFile filePath $ dec id
7275 encodeFile tmpPath $ mapM_ emitEvent eList
73− eList2' <- decodeFile filePath fold id
74− let eList2 = eList2' []
76+ eList2 <- decodeFile filePath $ dec id
7577 map MyEvent eList @=? map MyEvent eList2
7678 where
7779 filePath = "test/largest-string.yaml"
7880 tmpPath = "tmp.yaml"
79− fold x EventNone = return $ Done x
80− fold x e = return $ More $ x . (:) e
81+ dec front = do
82+ e <- parseEvent
83+ case e of
84+ EventNone -> return $ front []
85+ _ -> dec $ front . (:) e
8186
8287newtype MyEvent = MyEvent Event deriving Show
8388instance Eq MyEvent where
@@ -87,22 +92,8 @@ instance Eq MyEvent where
8792
8893caseInterleave :: Assertion
8994caseInterleave = do
90− encodeFile tmpPath $ decodeFile filePath emitEvent' ()
91− encodeFile tmpPath2 $ decodeFile tmpPath emitEvent' ()
92− f1 <- readFile tmpPath
93− f2 <- readFile tmpPath2
94− f1 @=? f2
95− where
96− filePath = "test/largest-string.yaml"
97− tmpPath = "tmp.yaml"
98− tmpPath2 = "tmp2.yaml"
99− emitEvent' () EventNone = return $ Done ()
100− emitEvent' () e = emitEvent e >> return (More ())
101−
102−caseInterleaveMonad :: Assertion
103−caseInterleaveMonad = do
104− decodeFile' filePath $ encodeFile tmpPath inside
105− decodeFile' tmpPath $ encodeFile tmpPath2 inside
95+ decodeFile filePath $ encodeFile tmpPath inside
96+ decodeFile tmpPath $ encodeFile tmpPath2 inside
10697 f1 <- readFile tmpPath
10798 f2 <- readFile tmpPath2
10899 f1 @=? f2