"--1"
被解析为[prefix "-", prefix "-", number 1]
并评估为negate (negate 1)
产生 1。
得到一个postfix (--)
,不runParser expr () "expr" "1--"
给你一个postfix --
?
解析似乎没有消耗整个输入。不过我说不出为什么,
module ExParse where
import Text.Parsec
import Text.Parsec.Expr
parens p = do
char '('
e <- p
char ')'
return e
reservedOp s = do
string s
notFollowedBy letter
natural = fmap read $ many1 digit
expr = buildExpressionParser table term
<?> "expression"
term = parens expr
<|> natural
<?> "simple expression"
table = [ [prefix "-" negate, prefix "+" id ]
, [postfix "++" (+1), postfix "--" (subtract 1)]
, [binary "*" (*) AssocLeft, binary "/" (div) AssocLeft ]
, [binary "+" (+) AssocLeft, binary "-" (-) AssocLeft ]
]
binary name fun assoc = Infix (do{ reservedOp name; return fun }) assoc
prefix name fun = Prefix (do{ reservedOp name; return fun })
postfix name fun = Postfix (do{ reservedOp name; return fun })
res = runParser expr () "expr" "1--"
产量
*ExParse> res
Right 0
根据需要在这里。
问题natural = P.natural lexer
在于它被定义为
natural = lexeme nat
和
lexeme p = do
x <- p
whiteSpace
return x
其中评论算作空白。现在,Haskell 中的行注释以 开头--
,因此 withnatural = P.natural lexer
会natural
消耗整个字符串"1--"
。要使其--
可用作后缀运算符,您必须选择一个不是注释起始符的语言定义。例如,您可以修改haskellDef
每个
lexer = P.makeTokenParser (haskellDef{P.commentLine = "//"})
或重新定义whiteSpace
解析器。