Skip to content

Commit a024d55

Browse files
committed
consumeWith doesn't consume if position does not advance
This will effect parsers: * rest * string * takeN * regex * whiteSpace * skipSpaces
1 parent 44ef16b commit a024d55

File tree

4 files changed

+41
-5
lines changed

4 files changed

+41
-5
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ Notable changes to this project are documented in this file. The format is based
44

55
## [Unreleased]
66

7+
Bugfixes:
8+
9+
- consumeWith doesn't consume if position does not advance
10+
11+
This will effect parsers:
12+
13+
* rest
14+
* string
15+
* takeN
16+
* regex
17+
* whiteSpace
18+
* skipSpaces
19+
20+
721
## [v9.1.0](https://github.com/purescript-contrib/purescript-parsing/releases/tag/v9.1.0) - 2022-06-12
822

923
Breaking changes:

src/Parsing/String.purs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ consumeWith f = ParserT
296296
Left err ->
297297
runFn2 throw state1 (ParseError err pos)
298298
Right { value, consumed, remainder } ->
299-
runFn2 done (ParseState remainder (updatePosString pos consumed remainder) true) value
299+
runFn2 done (ParseState remainder (updatePosString pos consumed remainder) (not (String.null consumed))) value
300300
)
301301

302302
-- | Combinator which finds the first position in the input `String` where the

src/Parsing/String/Basic.purs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,17 @@ satisfyCP :: forall m. (CodePoint -> Boolean) -> ParserT String m Char
148148
satisfyCP p = satisfy (p <<< codePointFromChar)
149149

150150
-- | Match zero or more whitespace characters satisfying
151-
-- | `Data.CodePoint.Unicode.isSpace`. Always succeeds.
151+
-- | `Data.CodePoint.Unicode.isSpace`.
152+
-- |
153+
-- | Always succeeds. Will consume only when matched whitespace string
154+
-- | is non-empty.
152155
whiteSpace :: forall m. ParserT String m String
153156
whiteSpace = fst <$> match skipSpaces
154157

155-
-- | Skip whitespace characters and throw them away. Always succeeds.
158+
-- | Skip whitespace characters satisfying `Data.CodePoint.Unicode.isSpace`
159+
-- | and throw them away.
160+
-- |
161+
-- | Always succeeds. Will only consume when some characters are skipped.
156162
skipSpaces :: forall m. ParserT String m Unit
157163
skipSpaces = consumeWith \input -> do
158164
let consumed = takeWhile isSpace input

test/Main.purs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ import Effect (Effect)
3333
import Effect.Console (log, logShow)
3434
import Effect.Unsafe (unsafePerformEffect)
3535
import Node.Process (lookupEnv)
36-
import Parsing (ParseError(..), Parser, ParserT, Position(..), consume, fail, initialPos, parseErrorMessage, parseErrorPosition, position, region, runParser)
36+
import Parsing (ParseError(..), ParseState(..), Parser, ParserT, Position(..), consume, fail, getParserT, initialPos, parseErrorMessage, parseErrorPosition, position, region, runParser)
3737
import Parsing.Combinators (advance, between, chainl, chainl1, chainr, chainr1, choice, empty, endBy, endBy1, lookAhead, many, many1, many1Till, many1Till_, manyIndex, manyTill, manyTill_, notFollowedBy, optionMaybe, sepBy, sepBy1, sepEndBy, sepEndBy1, skipMany, skipMany1, try, (<?>), (<??>), (<~?>))
3838
import Parsing.Combinators.Array as Combinators.Array
3939
import Parsing.Expr (Assoc(..), Operator(..), buildExprParser)
4040
import Parsing.Language (haskellDef, haskellStyle, javaStyle)
4141
import Parsing.String (anyChar, anyCodePoint, anyTill, char, eof, match, regex, rest, satisfy, string, takeN)
42-
import Parsing.String.Basic (intDecimal, letter, noneOfCodePoints, number, oneOfCodePoints, whiteSpace)
42+
import Parsing.String.Basic (intDecimal, letter, noneOfCodePoints, number, oneOfCodePoints, skipSpaces, whiteSpace)
4343
import Parsing.String.Replace (breakCap, replace, replaceT, splitCap, splitCapT)
4444
import Parsing.Token (TokenParser, makeTokenParser, token, when)
4545
import Parsing.Token as Token
@@ -685,6 +685,22 @@ main = do
685685
parseErrorTestPosition (string "a\nb\nc\n" *> eof) "a\nb\nc\nd\n" (Position { index: 6, column: 1, line: 4 })
686686
parseErrorTestPosition (string "\ta" *> eof) "\tab" (Position { index: 2, column: 10, line: 1 })
687687

688+
assertEqual' "skipSpaces consumes if position advancement issue #200"
689+
{ actual: runParser " " do
690+
skipSpaces
691+
ParseState _ _ c <- getParserT
692+
pure c
693+
, expected: Right true
694+
}
695+
696+
assertEqual' "skipSpaces doesn't consume if no position advancement issue #200"
697+
{ actual: runParser "x" do
698+
skipSpaces
699+
ParseState _ _ c <- getParserT
700+
pure c
701+
, expected: Right false
702+
}
703+
688704
log "\nTESTS number\n"
689705

690706
-- assert' "Number.fromString" $ Just infinity == Data.Number.fromString "Infinity"

0 commit comments

Comments
 (0)