parseString :: Char -> Parser Token
parseString endingCodePoint = do
    _ <- AP.char endingCodePoint
    go mempty

  where
    go acc = choice
        [ (AP.endOfInput <|> void (AP.char endingCodePoint)) *> return (String acc)
        , AP.string "\\\n" *> go acc
        , whenNext '\n' (BadString acc)
        , nextInputCodePoint >>= \ch -> go (acc <> T.singleton ch)
        ]
parseString :: Char -> Parser Token
parseString endingCodePoint = do
    _ <- AP.char endingCodePoint
    go mempty

  where
    go acc = choice
        [ (AP.endOfInput <|> void (AP.char endingCodePoint)) *> return (String acc)
        , AP.string "\\\n" *> go acc
        , whenNext '\n' (BadString acc)
        , nextInputCodePoint >>= \ch -> go (acc <> T.singleton ch)
        ]
parseString endingCodePoint = do
    _ <- AP.char endingCodePoint
    go mempty

  where
    go acc = choice
        [ (AP.endOfInput <|> void (AP.char endingCodePoint)) *> return (String acc)
        , AP.string "\\\n" *> go acc
        , whenNext '\n' (BadString acc)
        , nextInputCodePoint >>= \ch -> go (acc <> T.singleton ch)
        ]