L BB | 2 Mar 08:35 2003
Picon

How to make Parser explicitly "fail"?

Hi, there. I am glad to join Haskell community. :)

Here I have a question about Parser: how to make a
parser explicitly "fail"?

My question arises from the syntax below:

<statement>::=<keyword><seperator><variable>
<keyword>::="define"
<seperator>::=':'
<variable>::=identifier other than <keyword>
<identifier>::=(<letter>)+
<letter>::=a..z|A..Z

Now I am thinking of writing a Parser for variable. My
thought is:

variable::Parser String
variable = do s<-identifier
              if not (s=="define") then return s else
--let parser fail

I will be very happy if there is some mechanism to
implement the "else" branch, for I have thought of it
for long. :)

__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - forms, calculators, tips, more
http://taxes.yahoo.com/
(Continue reading)

Leonid Bouriakovsky | 3 Mar 10:51 2003
Picon
Picon

Re: How to make Parser explicitly "fail"?

If you are using the ParseLib from the Hugs distribution,
the function you are looking for is mzero:

C:\Hugs98\lib\hugs\ParseLib.hs:

instance MonadPlus Parser where
   -- mzero            :: Parser a
   mzero                = P (\inp -> [])

   -- mplus            :: Parser a -> Parser a -> Parser a
   (P p) `mplus` (P q)  = P (\inp -> (p inp ++ q inp))

For the explanations on how this function works and
why it has such a name you can take a look at the
following paper:

Monadic parser combinators
Graham Hutton and Erik Meijer. Technical Report NOTTCS-TR-96-4,
Department of Computer Science, University of Nottingham, 1996.

http://www.cs.nott.ac.uk/Department/Staff/gmh/bib.html#monparsing

Regards,

Leonid Bouriakovsky

> Hi, there. I am glad to join Haskell community. :)
> 
> Here I have a question about Parser: how to make a
> parser explicitly "fail"?
(Continue reading)

Daan Leijen | 3 Mar 11:05 2003
Picon
Picon

Re: How to make Parser explicitly "fail"?


> Now I am thinking of writing a Parser for variable. My
> thought is:
>
> variable::Parser String
> variable = do s<-identifier
> 		    if not (s=="define") then return s else
> 		    --let parser fail

You forgot to tell which parser library you use. If you
use ParseLib (or Parsec) you can use the monadic zero
function "mzero".

Now, if you are using Parsec, you can also use
"fail :: String -> Parser a" to add some error message.

> variable = do s<-identifier
> when (s=="define") (fail "define is a keyword")
> return s

Or better:

> variable = do s<-identifier when (s=="define") (unexpected "keyword")
> return s
> <?> "variable"

Or even better, use the standard "identifier" parser from the "ParsecToken" module to handle this for you
automatically. The
user guide describes this in detail: http://www.cs.uu.nl/~daan/parsec.html

(Continue reading)


Gmane