I will use some functions from Control.Applicative
, for example (*>)
. These functions are useful if you want to avoid the Parsec monadic interface and prefer the applicative interface, because analyzers are easier to read in this way, in my opinion.
If you are not familiar with the basic application functions, leave a comment and I will explain them. You can find them on Hoogle if you are not sure.
As I understand your problem, you need a parser for some data structure, for example:
data Test = Test String Numbers data Numbers = List [Int] | Range Int Int
A parser that can analyze such a data structure will look like this (I have not compiled the code, but it should work):
-- parses "test <identifier> [<numbers>] end" testParser :: Parser Test testParser = Test <$> reserved "test" *> identifier <*> symbol "[" *> numbersParser <* symbol "]" <* reserved "end" <?> "test" numbersParser :: Parser Numbers numbersParser = try listParser <|> rangeParser -- parses "<natural>, <natural>, <natural>" etc listParser :: Parser Numbers listParser = List <$> sepBy natural (symbol ",") <?> "list" -- parses "<natural> ... <natural>" rangeParser :: Parser Numbers rangeParser = Range <$> natural <* symbol "..." <*> natural <?> "range"
source share