streamly icon indicating copy to clipboard operation
streamly copied to clipboard

Bug in the workflow of parsers

Open adithyaov opened this issue 2 years ago • 2 comments

Consider the following parser:

data LineContent
    = LineContentText String
    | LineContentIdentifier String
    deriving (Show)

lineParser :: MonadCatch m => Parser m Char Line
lineParser = Parser.many content Fold.toList

    where

    identifierSimple =
        Parser.some (alphaNumP `alt_` charP '\'' `alt_` charP '_') Fold.toList
    identifierInBraces = charP '{' *> identifierSimple <* charP '}'
    identifier =
        fmap LineContentIdentifier
            $ charP '$' *> (identifierInBraces `alt_` identifierSimple)
    escapedDollar = fmap (LineContentText . (: [])) $ charP '$' *> charP '$'
    -- "Parser.count" is undefined. The current implementation eats the
    -- malformed '$' instead of erroring out. This should be fixed if 'count' is
    -- used.
    -- escapedDollar =
    --     fmap LineContentText
    --         $ charP '$' *> Parser.count 1 (charP '$') Fold.toList
    anySingle = Parser.satisfy (const True)
    end =
        void (Parser.lookAhead escapedDollar)
            `alt_` void (Parser.lookAhead identifier)
            `alt_` Parser.eof
    contentText = LineContentText <$> Parser.manyTill anySingle end Fold.toList
    content = escapedDollar `alt_` identifier `alt_` contentText

With alt_ = (<|>), the ParserK alternative, the last identifier is not parsed properly. The rest of the input returned by parse_ is also improper because of the incorrect parsing.

With alt_ = alt, the ParserD alternative, few identifiers are reversed.

adithyaov avatar Feb 21 '22 10:02 adithyaov

Bug in the interconversion of parsers,

import qualified Streamly.Internal.Data.Parser as Parser
import qualified Streamly.Internal.Data.Parser.ParserD as D
import qualified Streamly.Internal.Data.Fold as Fold
import qualified Streamly.Internal.Data.Stream as Stream

main1 =
    Stream.parse
        (Parser.takeWhile (== '1') Fold.drain
             *> Parser.takeWhile (== ' ') Fold.drain)
        $ Stream.fromList "1"

The above does not produce expected result.

EDIT: This was solved.

adithyaov avatar Sep 15 '22 13:09 adithyaov

See https://github.com/composewell/streamly/pull/1838

adithyaov avatar Sep 16 '22 11:09 adithyaov