Я переделываю старое домашнее задание, чтобы развлечься, чтобы узнать, как использовать Parsec, и у меня возникли проблемы со структурированием моих синтаксических анализаторов для выходов (и включенного типа данных). Итак, сначала мы получаем файл со списком комнат. Каждая комната содержит название комнаты (ниже - Комната -), некоторое описание или историю, а затем список выходов в формате (direction, destination)
. В конце концов человек выбирал направление, и вы смотрели на название комнаты и переносили игрока в следующую комнату.
-- Room --
Center
You are in a square room. There are doors to the
north, south, east, and west.
-- Exits --
North: North Hall
South: South Room
East: East Room
West: West Room
-- Room --
North Hall
You are in a hallway. There are doors to the north and south.
Как видите, в некоторых комнатах нет выходов (я не храню их так, как это было). Так что возможны выходы.
Я дошел до части выхода, и все мои парсеры до этого шага, кажется, работают. Проблема заключается в том, что не может быть выходов или больше одного выхода. Также то, как я обрабатываю выходы, которые я думаю, влияет на то, как я обрабатываю свои типы выходов (также известный как выход типа может стать Может быть [Выход]
В любом случае вот мой код:
--module Loader
-- Game parser will go here
--
import Text.ParserCombinators.Parsec
import Data.List.Split
astory = unlines [" -- Room --",
"Cell",
"You have been locked in a dungeon cell. The prisoner next",
"to you whipsers, there's a tunnel behind the bed on the",
"south wall. Good 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 = do
direction <- directionParser
spaces
destination <- many (noneOf "\n")
return $ Exit direction destination
parseExits :: Parse Exits
parseExits = do
string "-- Exits --\n"
--oneRoom :: Parser Room
--oneRoom = do
-- 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 = do
-- file <- readFile "cave.adventure"
-- let stories = splitOn "\n\n" file
-- mapM putStrLn stories
В настоящее время я закомментировал комнату, когда тестировал парсеры меньшего размера.
Мой подход:
- Сделайте parseExits, которые анализируют - Exits - и «многие из parseExit».
- Если --Exit-- не найден, то парсер не работает (тогда я думаю, что он ничего не возвращает)
- В парсере oneRoom я ищу 0 или много parseExits или eof (так как я предварительно разбиваю на \ n \ n)
Вопросы:
- Как сделать вариант "none" или "many" в соответствии с parsec docs? Может быть, или необязательно, но где это применимо? В выходах или в одной комнате? Документы для легкого доступа а>
- Является ли мой подход к мини-синтаксическим анализаторам правильным способом решения этой проблемы в haskell и parsec?
- Наконец, oneRoom в настоящее время получает строки файла, разделенные на \ n \ n, но я думаю, что могу включить это в свой синтаксический анализатор как последнюю строку синтаксического анализатора oneRoom, правильно?
- В моем парсере oneRoom я в настоящее время разбираю историю как элемент, заканчивающийся на - Exit - но я не уверен, что история не потребляет следующий - Exits - или eof? Как заставить анализатор истории заканчиваться либо на первом - Exits - он находит, либо на eof (или \ n \ n, если я разбираю весь файл)
Я надеюсь, что мои вопросы и код достаточно ясны, если нет, дайте мне знать, как я могу уточнить. Заранее спасибо.
[]
так же хорош, какNothing
. ВведениеMaybe
только усложняет ситуацию, и, кроме того, что будет означатьJust []
? - person firefrorefiddle   schedule 20.08.2013