buildExpressionParser只处理一元和二元运算符。它可以处理三元运算符?:
吗?这里和这里有一些讨论,但没有一个是决定性的。
问问题
228 次
1 回答
7
monadic 解析器的一大好处是它们的组合非常好。
这意味着您不必试图欺骗一个人buildExpressionParser
来构建您想要的确切解析器。您可以简单地使用它来构建解析器,然后像其他任何东西一样使用该解析器,包括另一个buildExpressionParser
.
在您的情况下,您可以:
- 用于
buildExpressionParser
为优先级高于的表达式创建解析器?:
- 创建一个解析器以
?:
使用上述内容 - 用于
buildExpressionParser
为优先级低于?:
上述表达式的表达式创建解析器
这是一个完整的例子:
import Control.Monad.Identity
import Text.Parsec
import Text.Parsec.Expr
data Ex = Var String | Mul Ex Ex | Add Ex Ex | Assign Ex Ex | Trinary Ex Ex Ex
deriving (Show)
var = Var <$> many1 letter
topOps = [ [binary "*" Mul], [binary "+" Add] ]
topParser = buildExpressionParser topOps var
trinaryExpr = do
expr <- topParser
trinary expr <|> return expr
where
trinary expr = do
string "?"
thenV <- trinaryExpr
string ":"
elseV <- trinaryExpr
return $ Trinary expr thenV elseV
bottomOps = [ [ binary "=" Assign ] ]
bottomParser = buildExpressionParser bottomOps trinaryExpr
binary :: String -> (Ex -> Ex -> Ex) -> Operator String () Identity Ex
binary s t = Infix (string s >> return t) AssocLeft
testParse s = runParser bottomParser () "" s
main = print $ testParse "a=b+c*d?e+f:g*h"
输出(手动格式化)是:
Right
(Assign
(Var "a")
(Trinary
(Add (Var "b")
(Mul (Var "c") (Var "d")))
(Add (Var "e") (Var "f"))
(Mul (Var "g") (Var "h"))))
于 2019-09-13T23:12:59.673 回答