Haskell 平衡括号的Parsec

Haskell 平衡括号的Parsec,haskell,Haskell,作为学习使用Parsec的练习,我正在编写一个解析器来验证平衡括号。我只担心对(),[]和{},但无法让我的解析器处理第一个括号内的多个括号组 我正在针对从exercism.io中提取的大量测试用例进行测试,但值得注意的是: isBalanced "" = True isBalanced "(some[nonsense]with)brackets" = True isBalanced "}{" = False -- reversed brackets no good. isBalanced

作为学习使用Parsec的练习,我正在编写一个解析器来验证平衡括号。我只担心对
()
[]
{}
,但无法让我的解析器处理第一个括号内的多个括号组

我正在针对从exercism.io中提取的大量测试用例进行测试,但值得注意的是:

isBalanced "" = True
isBalanced "(some[nonsense]with)brackets" = True
isBalanced "}{" = False   -- reversed brackets no good.
isBalanced "{}}" = False  -- extra ending brackets no good either.
我的解析器如下所示:

import Text.Parsec
import Text.Parsec.Char

hasMatchingBrackets = go >> eof
  where
  go = skipMany (noneOf "[{()}]")
        >> optional (
           between (char '(') (char ')') go
       <|> between (char '{') (char '}') go
       <|> between (char '[') (char ']') go )
        >> skipMany (noneOf "[{()}]")

isBalanced :: String -> Bool
isBalanced xs = case parse hasMatchingBrackets "isBalanced" xs of
                  Right _ -> True
                  Left  _ -> False
我发现问题在于我在s之间交替使用了
,只允许在一对括号之间出现一个
go
,而
[{}(…
中的打开部分是两个,但我不确定如何修复它。我试着在
go
前面拍打
skipMany1
,以便阅读

    between (char '(') (char ')') (skipMany1 go)
<|> ...etc
介于(char'(')(char'))(skipMany1 go)之间
等
但我得到了一个错误:

***异常:Text.ParserCombinators.Parsec.Prim.many:combinator“many”应用于接受空字符串的解析器


使用
many
是正确的解决方案,但首先需要去掉
可选的

问题是,正如错误消息所说,
optional
可以匹配空字符串,问题是,
many
重复匹配,只要给定的解析器仍然可以找到匹配项。如果解析器匹配空字符串,它将始终找到匹配项(空字符串),所以它永远不会停止循环。所以这是不允许的,以防止无限循环


由于
许多
已经可以匹配零次出现,因此不需要
可选的
,您可以将其删除。

就是这样,谢谢!我对进一步的测试用例有一个问题,但是如果我自己无法解决,我将发布一个新问题(现在没时间深入研究,午休时间已经结束!)
    between (char '(') (char ')') (skipMany1 go)
<|> ...etc