"--1"
被解析爲[prefix "-", prefix "-", number 1]
和評估爲negate (negate 1)
這將產生1
要獲得一個後綴(--)
,並runParser expr() "expr" "1--"
不會給你一個後綴--
?
解析似乎不消耗整個輸入。我不知道爲什麼,雖然
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中的行註釋從--
開始,因此natural = P.natural lexer
,natural
消耗整個字符串"1--"
。要使--
可用作後綴運算符,您必須選擇不是註釋啓動器的語言定義。例如,您可以修改haskellDef
每
lexer = P.makeTokenParser (haskellDef{P.commentLine = "//"})
或重新定義whiteSpace
解析器。
我用'自然= P.natural lexer'和'lexer = P.makeTokenParser haskellDef'。在Daniel Fischer的回答中,「natural = fmap read $ many1 digit」並且效果很好。有什麼不同?爲什麼它不適用於詞法分析器? –
丹尼爾給出了一個完整的答案。 ( - )作爲Haskell中行註釋的問題... –
除了解析問題之外,後綴'++'或'--'運算符的常規行爲是它只能應用於左值,產生未變形的左值,有副作用。在這種情況下,'1 - '沒有意義,因爲'1'不是左值。 – pat