Fix parseBreak losing backtracking Buffer on Error (#2453)

Co-authored-by: Harendra Kumar <harendra@composewell.com>
This commit is contained in:
Ranjeet Ranjan 2023-07-24 17:37:11 +05:30 committed by GitHub
parent 7432dda203
commit f763943923
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 27 deletions

View File

@ -160,7 +160,11 @@ parse
return (Right b, unread src s1)
Error err -> do
s1 <- uextract s
return (Left (ParseError err), unread [x] s1)
let src = Prelude.reverse (getList buf)
return
( Left (ParseError err)
, unread (src ++ [x]) s1
)
Skip s -> go SPEC s buf pst
Stop -> goStop buf pst
@ -190,7 +194,11 @@ parse
return (Right b, unread src s1)
Error err -> do
s1 <- uextract s
return (Left (ParseError err), unread (x:xs) s1)
let src = Prelude.reverse (getList buf)
return
( Left (ParseError err)
, unread (src ++ (x:xs)) s1
)
-- This is a simplified gobuf
goExtract !_ buf (List []) !pst = goStop buf pst
@ -216,8 +224,12 @@ parse
let src0 = Prelude.take n (x:getList buf)
src = Prelude.reverse src0
return (Right b, unread src (source Nothing))
Error err ->
return (Left (ParseError err), unread (x:xs) (source Nothing))
Error err -> do
let src = Prelude.reverse (getList buf)
return
( Left (ParseError err)
, unread (src ++ (x:xs)) (source Nothing)
)
-- This is a simplified goExtract
{-# INLINE goStop #-}
@ -238,8 +250,9 @@ parse
let src0 = Prelude.take n (getList buf)
src = Prelude.reverse src0
return (Right b, unread src (source Nothing))
Error err ->
return (Left (ParseError err), source Nothing)
Error err -> do
let src = Prelude.reverse (getList buf)
return (Left (ParseError err), unread src (source Nothing))
{-
-- | Parse a buffered source using a parser, returning the parsed value and the

View File

@ -704,7 +704,10 @@ parseBreakK (PRD.Parser pstep initial extract) stream = do
str = K.cons arr0 (K.cons arr1 st)
return (Right b, str)
PR.Error err -> do
let str = K.cons (Array contents cur end) stream
let n = Prelude.length backBuf
arr0 = A.fromListN n (Prelude.reverse backBuf)
arr1 = Array contents cur end
str = K.cons arr0 (K.cons arr1 stream)
return (Left (ParseError err), str)
-- This is a simplified goArray
@ -746,7 +749,10 @@ parseBreakK (PRD.Parser pstep initial extract) stream = do
str = K.cons arr0 (K.fromPure arr1)
return (Right b, str)
PR.Error err -> do
let str = K.fromPure (Array contents cur end)
let n = Prelude.length backBuf
arr0 = A.fromListN n (Prelude.reverse backBuf)
arr1 = Array contents cur end
str = K.cons arr0 (K.cons arr1 stream)
return (Left (ParseError err), str)
-- This is a simplified goExtract
@ -771,8 +777,10 @@ parseBreakK (PRD.Parser pstep initial extract) stream = do
-- arr0 = A.fromListRevN n src0
arr0 = A.fromListN n (Prelude.reverse src0)
return (Right b, K.fromPure arr0)
PR.Error err ->
return (Left (ParseError err), K.nil)
PR.Error err -> do
let n = Prelude.length backBuf
arr0 = A.fromListN n (Prelude.reverse backBuf)
return (Left (ParseError err), K.fromPure arr0)
-- | Parse an array stream using the supplied 'Parser'. Returns the parse
-- result and the unconsumed stream. Throws 'ParseError' if the parse fails.
@ -866,7 +874,9 @@ runArrayParserDBreak
src = Prelude.reverse src0 ++ xs
return (Right b, D.append (D.fromList src) (D.Stream step s))
PR.Error err -> do
let strm = D.append (D.fromList (x:xs)) (D.Stream step s)
let src0 = x:getList backBuf
src = Prelude.reverse src0 ++ x:xs
strm = D.append (D.fromList src) (D.Stream step s)
return (Left (ParseError err), strm)
-- This is a simplified gobuf
@ -901,8 +911,10 @@ runArrayParserDBreak
let src0 = takeArrayListRev n (x:getList backBuf)
src = Prelude.reverse src0 ++ xs
return (Right b, D.fromList src)
PR.Error err ->
return (Left (ParseError err), D.fromList (x:xs))
PR.Error err -> do
let src0 = getList backBuf
src = Prelude.reverse src0 ++ x:xs
return (Left (ParseError err), D.fromList src)
-- This is a simplified goExtract
{-# INLINE goStop #-}
@ -927,8 +939,10 @@ runArrayParserDBreak
let src0 = takeArrayListRev n (getList backBuf)
src = Prelude.reverse src0
return (Right b, D.fromList src)
PR.Error err ->
return (Left (ParseError err), D.nil)
PR.Error err -> do
let src0 = getList backBuf
src = Prelude.reverse src0
return (Left (ParseError err), D.fromList src)
{-
-- | Parse an array stream using the supplied 'Parser'. Returns the parse

View File

@ -238,8 +238,13 @@ parseBreakD (PRD.Parser pstep initial extract) stream@(Stream step state) = do
return
( Right b,
Nesting.append (fromList src) (Stream step s))
PR.Error err ->
return (Left (ParseError err), Stream step s)
PR.Error err -> do
let src = Prelude.reverse $ x:getList buf
return
( Left (ParseError err)
, Nesting.append (fromList src) (Stream step s)
)
Skip s -> go SPEC s buf pst
Stop -> goStop SPEC buf pst
@ -295,10 +300,11 @@ parseBreakD (PRD.Parser pstep initial extract) stream@(Stream step state) = do
let src0 = Prelude.take n (x:getList buf)
src = Prelude.reverse src0
return (Right b, Nesting.append (fromList src) (Stream step s))
PR.Error err ->
PR.Error err -> do
let src = (Prelude.reverse $ getList buf) ++ x:xs
return
( Left (ParseError err)
, Nesting.append (fromList (x:xs)) (Stream step s)
, Nesting.append (fromList src) (Stream step s)
)
-- This is simplified gobuf
@ -327,7 +333,9 @@ parseBreakD (PRD.Parser pstep initial extract) stream@(Stream step state) = do
let src0 = Prelude.take n (x:getList buf)
src = Prelude.reverse src0
return (Right b, fromList src)
PR.Error err -> return (Left (ParseError err), fromList (x:xs))
PR.Error err -> do
let src = (Prelude.reverse $ getList buf) ++ x:xs
return (Left (ParseError err), fromList src)
-- This is simplified goExtract
-- XXX Use SPEC?
@ -348,8 +356,9 @@ parseBreakD (PRD.Parser pstep initial extract) stream@(Stream step state) = do
let src0 = Prelude.take n (getList buf)
src = Prelude.reverse src0
return (Right b, fromList src)
PR.Error err ->
return (Left (ParseError err), StreamD.nil)
PR.Error err -> do
let src = Prelude.reverse $ getList buf
return (Left (ParseError err), fromList src)
-- | Parse a stream using the supplied 'Parser'.
--

View File

@ -1171,7 +1171,9 @@ parseDBreak (PR.Parser pstep initial extract) stream = do
let stop = do
r <- extract pst
case r of
PR.Error err -> return (Left (ParseError err), nil)
PR.Error err -> do
let src = Prelude.reverse buf
return (Left (ParseError err), fromList src)
PR.Done n b -> do
assertM(n <= length buf)
let src0 = Prelude.take n buf
@ -1206,7 +1208,9 @@ parseDBreak (PR.Parser pstep initial extract) stream = do
let src0 = Prelude.take n (x:buf)
src = Prelude.reverse src0
return (Right b, append (fromList src) r)
PR.Error err -> return (Left (ParseError err), r)
PR.Error err -> do
let src = Prelude.reverse (x:buf)
return (Left (ParseError err), append (fromList src) r)
in foldStream defState yieldk single stop st
goBuf st buf [] !pst = goStream st buf pst
@ -1230,7 +1234,9 @@ parseDBreak (PR.Parser pstep initial extract) stream = do
let src0 = Prelude.take n (x:buf)
src = Prelude.reverse src0
return (Right b, append (fromList src) st)
PR.Error err -> return (Left (ParseError err), nil)
PR.Error err -> do
let src = Prelude.reverse buf ++ x:xs
return (Left (ParseError err), append (fromList src) st)
-- Using ParserD or ParserK on StreamK may not make much difference. We should
-- perhaps use only chunked parsing on StreamK. We can always convert a stream
@ -1324,7 +1330,9 @@ parseBreakChunks parser input = do
assertM(n1 >= 0 && n1 <= sum (Prelude.map Array.length backBuf))
let (s1, _) = backTrack n1 backBuf nil
in return (Right b, s1)
ParserK.Error _ err -> return (Left (ParseError err), nil)
ParserK.Error _ err -> do
let (s1, _) = backTrack maxBound backBuf nil
return (Left (ParseError err), s1)
seekErr n len =
error $ "parseBreak: Partial: forward seek not implemented n = "
@ -1367,7 +1375,9 @@ parseBreakChunks parser input = do
assertM(n1 <= sum (Prelude.map Array.length (arr:backBuf)))
let (s1, _) = backTrack n1 (arr:backBuf) stream
in return (Right b, s1)
ParserK.Error _ err -> return (Left (ParseError err), nil)
ParserK.Error _ err -> do
let (s1, _) = backTrack maxBound (arr:backBuf) stream
return (Left (ParseError err), s1)
go backBuf parserk stream = do
let stop = goStop backBuf parserk