我尝试使用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,但我不确定如何使用空格作为运算符。
感谢您的帮助!
答案 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
一起使用的运算符表中,为其提供高优先级。