[Haskell-cafe] How to use notFollowedBy function in Parsec

Daniel Fischer daniel.is.fischer at web.de
Tue Nov 22 08:51:52 EST 2005


Am Montag, 21. November 2005 03:27 schrieb Sara Kenedy:

May I suggest

endBy anyToken semi ? -- optionally replace semi by "char ';'", if you don't 
want to skip whitespace

I think this is what you want --- stop at the first semicolon.

If you want to ignore just a final semicolon, you might use

endBy anyToken (optional semi >> eof),

if you want to stop at the last semicolon, whatever comes thereafter, you have 
a problem, you'd need long lookahead.

Cheers,
Daniel


> Thanks for your solution. However, when I try this,
>
> >     str1 :: Parser String
> >    str1 = do str <- many anyToken
> >	          notFollowedBy' semi
> >                 return str
> >
> >     notFollowedBy' :: Show a => GenParser tok st a -> GenParser tok st ()
> >     notFollowedBy' p  = try $ join $  do  a <- try p
> >                                                         return
> > (unexpected (show a)) <|>
> >                                                  return (return ())
> >      run:: Show a => Parser a -> String -> IO()
> >
> >      run p input
> >
> >	= case (parse p "" input) of
> >
> >		Left err -> do {putStr "parse error at " ;print err}
> >
> >		Right x -> print
>
> When I compile, it still displays ";" at the end of the string.
>
>   Parser> run str1 "Hello ;"
>   "Hello ;"
>
> The reason, as I think, because anyToken accepts any kind of token, it
> considers ";" as token of its string. Thus, it does not understand
> notFollowedBy' ???
>
> Do you have any ideas about this ??? Thanks.
>
> On 11/19/05, Andrew Pimlott <andrew at pimlott.net> wrote:
> > On Sat, Nov 19, 2005 at 06:43:48PM -0500, Sara Kenedy wrote:
> > > str1 :: Parser String
> > > str1 = do {str <- many anyToken; notFollowedBy semi; return str}
> > >
> > > However, when I compile, there is an error.
> > >
> > > ERROR "Test.hs":17 - Type error in application
> > > *** Expression     : notFollowedBy semi
> > > *** Term           : semi
> > > *** Type           : GenParser Char () String
> > > *** Does not match : GenParser [Char] () [Char]
> >
> > The problem is that notFollowedBy has type
> >
> >     notFollowedBy  :: Show tok => GenParser tok st tok -> GenParser tok
> > st ()
> >
> > ie, the result type of the parser you pass to notFollowedBy has to be
> > the same as the token type, in this case Char.  (The reason for this
> > type is obscure.)  But semi has result type String.  You could fix the
> > type error by returning a dummy Char:
> >
> >     str1 = do {str <- many anyToken
> >               ; notFollowedBy (semi >> return undefined)
> >               ; return str}
> >
> > I think this will even work; however notFollowedBy is a pretty
> > squirrelly function.  There was a discussion about it:
> >
> >     http://www.haskell.org/pipermail/haskell/2004-February/013621.html
> >
> > Here is a version (which came out of that thread) with a nicer type,
> > that probably also works more reliably (though I won't guarantee it):
> >
> >     notFollowedBy' :: Show a => GenParser tok st a -> GenParser tok st ()
> >     notFollowedBy' p  = try $ join $  do  a <- try p
> >                                           return (unexpected (show a))
> >                                       <|>
> >                                       return (return ())
> >
> > Andrew
>
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



More information about the Haskell-Cafe mailing list