用于遇到[..]的Haskell Parsec Parser



我正试图使用Parsec在Haskell中编写一个解析器。目前我有一个程序可以解析

test x [1,2,3] end

完成此操作的代码如下所示

testParser = do { 
  reserved "test"; 
  v <- identifier; 
  symbol "["; 
  l <- sepBy natural commaSep;
  symbol "]";
  p <- pParser;
  return $ Test v (List l) p
 } <?> "end"

其中commaSep定义为

commaSep        = skipMany1 (space <|> char ',')

现在有什么方法可以让我解析类似的语句,特别是:

test x [1...3] end

作为Haskell和Parsec的新手,我相信有一些我不知道的简洁的方法可以做到这一点。如有任何帮助,我们将不胜感激。

再次感谢。

我将使用Control.Applicative中的一些函数,如(*>)。如果你想避免Parsec的一元接口,而更喜欢应用接口,这些函数是有用的,因为在我看来,这样解析器更容易阅读。

如果你不熟悉基本的应用函数,请留言,我会为你解释的。如果你不确定,你可以在Hoogle上查找它们。


正如我理解你的问题一样,你想要一个像这样的数据结构的解析器:

data Test = Test String Numbers
data Numbers = List [Int] | Range Int Int

一个可以解析这样一个数据结构的解析器看起来是这样的(我还没有编译代码,但它应该可以工作):

-- 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"

最新更新