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/
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"?
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/ _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
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 All the best, Daan.
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/ _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
participants (3)
-
Daan Leijen -
L BB -
Leonid Bouriakovsky