使用Parsec解析功能应用程序

时间:2014-04-07 05:33:11

标签: parsing haskell parsec

我尝试使用parsec解析如下表达式:

f a b c
=> (Appl (Appl (Appl f a) b) c)

我尝试使用以下内容:

appl :: Parser Expr
appl = do
    f <- expr
    gs <- many expr
    return $ foldr (\x y -> Appl x y) f gs

但是我陷入了无限循环。 expr是一个解析所有可能的函数 表达式,包括通过创建词法分析器获得的空格(特别是使用Parsec.Token.makeTokenParser)。

我想知道是否有一些简单的方法可以做到这一点,或者其他建议是如何解决这个问题。我曾考虑过尝试使用Parsec.Expr,但我不确定如何使用空格作为运算符。

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

正如您所建议的,一种解决方案是将空格视为二元运算符。首先,为函数应用程序定义解析器。

spacef :: Parser ()
spacef = whiteSpace
         *> notFollowedBy (choice . map reservedOp $ opNames)
         >> return Appl

这里reservedOp是保留运算符的解析器,opNames是这些名称的列表。现在让它成为语法中的运算符

functionOp :: Operator String () Identity Expr
functionOp = Infix spacef AssocLeft

并将functionOp添加到与buildExpressionParser一起使用的运算符表中,为其提供高优先级。