[Haskell-cafe] Re: parsebinaryoperations
Ben Franksen
ben.franksen at online.de
Thu Dec 13 16:35:39 EST 2007
Ryan Bloor wrote:
> I have a function parseInt... which needs an error guard for when the
> input is not an Int.
>
> parseInt :: ParserparseInt [] = []parseInt xs = let (digits, rest) = span
> isDigit (removeSpace xs) in [(EInt (read digits),
> removeSpace rest)]
This is how your source code happens to be rendered on my mail client. This
part of your mail is the reason:
> --===============0328857386==
> Content-Type: multipart/alternative;
> boundary="_4752b91d-a167-4274-af0a-1982e53bc6c0_"
>
> --_4752b91d-a167-4274-af0a-1982e53bc6c0_
> Content-Type: text/plain; charset="Windows-1252"
> Content-Transfer-Encoding: quoted-printable
This encoding (charset="Windows-1252") is not available on my system. It
would help others to read your message (leading to more responses to your
question and thus better help) if you could configure your mail program to
use a more widely understood encoding, for instance utf-8, or latin-1.
> Also... I have a function that does this... parseBinaryOp "+" "(5 + 2) if"
> gives...[(Int 5, Int 2, "if")] so, op is '+' or "&&". I am unsure of
> how to begin...
>
> parseBinaryOp :: String -> String -> [(Expr, Expr, String)]parseBinaryOp
> op str
>
> Thankyou
>
> Ryan
Thank you, too, for respecting mailing list netiquette :-))
Now to your question: Since Haskell is pure, you need to encode possible
parse failure into the result type of your parsing function, like this:
data Result = Success Expr
| Failure String
where the 'Expr' above is the type you want to get back on a successful
parse, and the type argument 'String' to the 'Failure' constructor is for
error messages.
Your parseExpr function could then have a type like
type Parser = String -> ParseResult Expr
which could be called (from main) thus
case parseExpr input of
Success expr -> print expr
Failure err_msg -> putStrLn $ "parse error: " ++ err_msg
Another good idea, instead of just collecting a list (in fact, a tuple) of
tokens as you did above, is to design 'Expr' so that it can represent a
complete parse _tree_. Since usually expressions can be nested arbitrarily
deep, any finite type won't do, you need a recursive type. For example
data BinOp = OpPlus | OpMinus | OpMult
-- enumerating all possible operators is more type safe than using String
-- an expression is...
Expr = EInt Integer -- either a literal integer
| EBinOp BinOp Expr Expr -- or two expressions combined with a binary
operator
Hope this helps.
Cheers
Ben
More information about the Haskell-Cafe
mailing list