【发布时间】:2016-09-30 08:56:50
【问题描述】:
我是 Haskell、Parsec 和编写解析器的初学者。我正在尝试解析一种简单的语言,它(为了这个问题而进一步简化它)仅由嵌套括号的字符串组成,例如[[][]][].
我有下面的 Haskell 代码,它工作正常。但是,我想扩展它,以便不匹配的括号将匹配字符串的末尾。例如,]][][[ 应该等价于[[]][][[]],而[]] 应该等价于[[]]。对匹配字符串结尾的左括号执行此操作很容易,但对匹配字符串开头的右括号执行此操作会导致左递归和无限循环,我还没有找到解决此问题的方法。我不确定原因是否与我对语法的思考方式或我使用 Parsec 库的方式有关,但无论哪种方式,我都希望能看到前进的方向。
这是我的工作代码:
{-# LANGUAGE NoMonomorphismRestriction #-}
import qualified Text.Parsec as Parsec
import Control.Applicative
-- for testing
parse rule text = Parsec.parse rule "(source)" text
data Expr = Brackets [Expr]
deriving(Show)
openBracket = Parsec.char '['
closeBracket = Parsec.char ']'
parseBrackets = do
expr <- Parsec.between openBracket closeBracket parseExpr
return $ Brackets expr
parseExpr = Parsec.many parseBrackets
如果我想让右括号匹配字符串的结尾,我可以将closeBracket 的定义更改为
closeBracket = (Parsec.char ']' >> return ()) <|> Parsec.eof
但是,尽管经过大量试验和错误,我还没有找到将不匹配的]s 与字符串开头匹配的解决方案。我知道 Parsec 中左递归的常用解决方案是 chainl1 函数,但这似乎对中缀运算符非常专业,我在这里看不到使用它的方法。
【问题讨论】: