[Haskell] Parsec question: attempted 'notMatching' combinator

Andrew Pimlott andrew at pimlott.net
Tue Feb 17 14:29:18 EST 2004


On Tue, Feb 17, 2004 at 06:42:39PM +0000, Graham Klyne wrote:
> I've attempted to define a Parsec combinator thus:
> 
> [[
> notMatching :: Show a => GenParser tok st a -> GenParser tok st ()
> notMatching p = try ( do { a <- p ; unexpected (show a) } <|> return () )
> ]]

If p fails but consumes some input, return () won't be tried, thus the
whole notMatching will have failed.  The try means that it will not have
consumed any input, but that's no consolation, because notMatching
should have succeeded!  How about:

    notMatching p = try ( do { a <- p ; unexpected (show a) } ) <|> return ()

In fact, I think notFollowedBy can be considered to be buggy in the same
way.

    notFollowedBy p     = try (do{ c <- p; unexpected (show [c]) }
                               <|> return ()
                              )

It doesn't usually bite, because notFollowedBy takes a parser that
returns a token, and such a parser normally only looks at one token.
But it could look at more:

    aNoBC = do  char 'a'
                notFollowedBy $ do  char 'b'
                                    char 'c'

Intutively, (aNoBC >> char 'b') should match "abe", but

    *Main> parseTest (aNoBC >> char 'b') "abe"
    parse error at (line 1, column 2):
    unexpected "e"
    expecting "c"

If you instead put the try around the do, it works as expected.  So I
conclude that the try simply got put in the wrong place by mistake.

Andrew


More information about the Haskell mailing list