[Haskell-cafe] Parsers for Text Adventures

Daniel Fischer daniel.is.fischer at web.de
Sun Jan 17 09:02:59 EST 2010


Am Sonntag 17 Januar 2010 14:30:36 schrieb Mark Spezzano:
> Hi,
>
> I am writing a Text Adventure game in Haskell (like Zork)
>
> I have all of the basic parser stuff written as described in Hutton's
> Programming in Haskell and his associated papers. (I'm trying to avoid
> using 3rd party libraries, so that I can learn this myself)
>
> Everything that I have works (so far...) except for the following
> problem:
>
> I want to define a grammar using a series of Verbs like this:
>
> data Verb = Go | Get | Jump | Climb | Give etc, etc deriving (Show,
> Read)
>
> and then have my parser "get" one of these Verb tokens if possible;
> otherwise it should do something (?) else like give an error message
> stating "I don't know that command"
>
> Now, Hutton gives examples of parsing strings into string whereas I want
> to parse Strings into my Verbs
>
> So, if the user types "get sword" then it will tokenise "get" as type
> Verb's data constructor Get and perhaps "sword" into a Noun called Sword

But the Read instance can only read "Get", not "get".
You'd have to capitalise the input to work with derived Read instances.

>
> My parser is defined like this:
>
> newtype Parser a = Parser (String -> [(a, String)])
>
> So I CAN give it a Verb type
>
> but this is where I run into a problem....
>
> I've written a Parser called keyword
>
> keyword :: Parser Verb
> keyword = do x <- many1 letter
             case reads x of
               [(verb,"")] -> return verb
               _ -> fail "No verb"

fails gracefully (assuming your Monad instance for Parser has

    fail _ = Parser (\_ -> [])

).

> 			return (read x)
>
> (read this as
> "take-at-least-one-alphabetic-letter-and-convert-to-a-Verb-type")
>
> which DOES work provided that the user types in one of my Verbs. If they
> don't, well, the whole thing fails with an Exception and halts
> processing, returning to GHCi prompt.
>
> Question: Am I going about this the right way? I want to put together
> lots of "data" types like Verb and Noun etc so that I can build a kind
> of "BNF grammar".
>
> Question: If I am going about this the right way then what do I about
> the "read x" bit failing when the user stops typing in a recognised
> keyword. I could catch the exception, but typing an incorrect sentence
> is just a typo, not really appropriate for an exception, I shouldn't
> think. If it IS appropriate to do this in Haskell, then how do I catch
> this exception and continue processing.

You could try guessing what the user meant (cf. Levenshtein distance) for 
added comfort.
Or you could ask for corrected input immediately when parsing an input 
fails.
With the graceful failing of the parse as above, that doesn't need 
exceptions.

If you think catching exceptions might be preferable after all, take a look 
at Control.Exception.

>
> I thought that exceptions should be for exceptional circumstances, and
> it would seem that I might be misusing them in this context.
>
> Thanks
>
> Mark Spezzano



More information about the Haskell-Cafe mailing list