Parsing 遇到[…]的Haskell Parsec解析器

Parsing 遇到[…]的Haskell Parsec解析器,parsing,haskell,parsec,Parsing,Haskell,Parsec,我正在尝试使用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

我正在尝试使用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"
作为Haskell和Parsec的新手,我确信有一些简洁的方法可以做到这一点,但我并不知道。任何帮助都将不胜感激


再次感谢。

我将使用like的一些函数。如果您希望避免使用Parsec的一元接口,而更喜欢应用程序接口,那么这些函数非常有用,因为在我看来,这种方式使解析器更易于阅读

如果您不熟悉基本的应用程序函数,请留下评论,我将解释它们。如果你不确定的话,你可以查一下


正如我所理解的,您需要一个用于以下数据结构的解析器:

data Test = Test String Numbers
data Numbers = List [Int] | Range Int Int
能够解析此类数据结构的解析器如下所示(我没有编译代码,但应该可以工作):

--解析“测试[]结束”
testParser::Parser测试
测试分析器=
测试保留“测试”*>标识符
符号“[”*>numbersParser”列表
--解析“…”
rangeParser::解析器编号
范围分析器=

Range natural句点的数量应该是常量还是变量?数字和句点之间以及句点之间是否允许空格?顺便说一下,您的第一个解析器匹配
test x[1,2,3]end
;可能这不是您想要的。句点的数量应该是常量,即[1…3]在任何情况下都应该由3个句点组成。中间的空格如[1…3]应该忽略。希望这能进一步澄清我的想法。啊,非常感谢,这正是我所需要的。再次感谢!@VincentRusso它是
fmap
的同义词。好吧,最后一件事我仍在努力纠正。我能做点像l这样的事情吗?哪部分不起作用?我没有你的
PPAR
,所以我不能解析
end
部分,所以我只是把它做成了一个保留标记。你当然可以做
l是的,不同风格的东西让我陷入了一个循环,因为我对这个有点陌生,所以我为我的无知道歉。我试图在你的评论中加入你建议的代码,但是我得到了一些错误,我不太确定如何加入对不起,在这方面我帮不了你什么忙。
test x [1...3] end
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"