I don't want to write the whole parser for you, so I'm just trying to answer the individual questions.
- How do you do the none or many [...]
Just use many
instead of many1
.
To make the whole "-- Exits --" block optional, you can try something like
exits <- parseExists <|> return []
- Is my approach of dealing with the mini parsers a correct way to deal with this problem in haskell and with parsec?
Yes. As a rule of thumb, try to write at least one parser for every datatype, often even more.
- Finally oneRoom currently receives the file strings split on \n\n but I think I can include that in my parser as the last line of the oneRoom parser correct?
I think you shouldn't use split
in the main
function but instead just use newline
in your parsers wherever you want to have a newline character.
- In my oneRoom parser I'm currently parsing Story as the element that ends at -- Exit -- but i'm not convinced that story doesn't consume the next -- Exits -- or the eof? How do you get your Story parser to end at either the first -- Exits -- it finds or the eof(or \n\n if I parse the full file)
Maybe you want something like the following:
-- succeeds if we're at the end of story
-- never consumes any input
endOfStory :: Parser ()
endOfStory = lookAhead $
try (string "-- Room --" >> newline) <|>
try (string "-- Exits --" >> newline) <|>
try (newline >> newline) <|>
eof
With a function like this, you could use manyTill ... endOfStory
.