Learning Haskell Parsec and dealing with optional Parsers -


i'm redoing old homework assignment fun learn how use parsec , i'm having trouble structuring parsers exits (and included datatype). first file list of rooms. each room contains room name (below -- room --), description or story , list of exits in format of (direction, destination). person choose direction , you'd room name , bring player next room.

-- room -- center in square room. there doors north, south, east, , west. -- exits -- north: north hall south: south room east: east room west: west room  -- room -- north hall in hallway. there doors north , south. 

as can see rooms have no exits (nothing how i'm storing it). there maybe exits.

i have gotten far exits part , parsers before step seem work. problem handling fact there no exits or more 1 exit. how handle exits think affects how handle exits types (aka type exits might become maybe [ exit ]

anyway here code:

--module loader -- game parser go here -- import text.parsercombinators.parsec import data.list.split  astory = unlines [" -- room --",       "cell",       "you have been locked in dungeon cell. prisoner next",       "to whipsers, there's tunnel behind bed on the",       "south wall. luck!",       "-- exits --",       "south: tunnel"]  type rooms = [room] type story = string type destination = string data exit = exit { direction :: direction, destination :: destination } deriving (ord, show, eq) type exits = [ exit ]  data room = room { name  :: string                  , story :: string                  , exits :: exits                  } deriving (ord, show, eq)  data direction = nothing | north | south | east | west | quit deriving (ord, show, eq)  an_exit = "north: tunnel \n" a_full_exit = "-- exits --\nsouth: tunnel"  directionparser :: parser direction directionparser =     (string "south:" >> return south)  <|> (string "north:" >> return north)  <|> (string "east:"  >> return east)  <|> (string "west:"  >> return west)  parseexit :: parser exit parseexit =     direction <- directionparser     spaces     destination <- many (noneof "\n")     return $ exit direction destination  parseexits :: parse exits parseexits =     string "-- exits --\n"  --oneroom :: parser room --oneroom = --  string "--room--\n" --  name <- many (noneof "\n") --  newline --  story <- manytill anychar (string "-- exits --") --  optionmaybe (string "-- exits --") --  exits <- optionmaybe $ many1 anyexits --  return $ room name story exits   --main = --    file <- readfile "cave.adventure" --    let stories = spliton "\n\n" file --    mapm putstrln stories 

i commented out room testing smaller parsers.

my approach:

  1. make parseexits parses -- exits -- , "many of parseexit".
  2. if --exit-- isn't found parser fails (i think returns nothing then)
  3. in oneroom parser 0 or many parseexits or eof (since i'm pre splitting on \n\n)

questions:

  1. how do none or many according parsec docs optionmaybe or optional trick applied ? in exits or 1 room ? the docs easy access
  2. is approach of dealing mini parsers correct way deal problem in haskell , parsec?
  3. finally oneroom receives file strings split on \n\n think can include in parser last line of oneroom parser correct ?
  4. in oneroom parser i'm parsing story element ends @ -- exit -- i'm not convinced story doesn't consume next -- exits -- or eof? how story parser end @ either first -- exits -- finds or eof(or \n\n if parse full file)

i hope questions , code clear enough if not please let me know how can clarify. in advance.

i don't want write whole parser you, i'm trying answer individual questions.

  • how do none or many [...]

just use many instead of many1.

to make whole "-- exits --" block optional, can try like

exits <- parseexists <|> return [] 
  • is approach of dealing mini parsers correct way deal problem in haskell , parsec?

yes. rule of thumb, try write @ least 1 parser every datatype, more.

  • finally oneroom receives file strings split on \n\n think can include in parser last line of oneroom parser correct?

i think shouldn't use split in main function instead use newline in parsers wherever want have newline character.

  • in oneroom parser i'm parsing story element ends @ -- exit -- i'm not convinced story doesn't consume next -- exits -- or eof? how story parser end @ either first -- exits -- finds or eof(or \n\n if parse full file)

maybe want following:

-- succeeds if we're @ end of story -- never consumes input endofstory :: parser () endofstory = lookahead $   try (string "-- room --" >> newline) <|>   try (string "-- exits --" >> newline) <|>   try (newline >> newline) <|>   eof 

with function this, use manytill ... endofstory.


Comments

Popular posts from this blog

Detect support for Shoutcast ICY MP3 without navigator.userAgent in Firefox? -

web - SVG not rendering properly in Firefox -

java - JavaFX 2 slider labelFormatter not being used -