Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 当试图处理ParseError时,parsec会产生奇怪的错误_Parsing_Haskell - Fatal编程技术网

Parsing 当试图处理ParseError时,parsec会产生奇怪的错误

Parsing 当试图处理ParseError时,parsec会产生奇怪的错误,parsing,haskell,Parsing,Haskell,如果我有此代码: import Text.Parsec ispositive a = if (a<0) then Nothing else (Just a) f a b = a+b parserfrommaybe :: String -> (Maybe c) -> Parsec a b c parserfrommaybe msg Nothing = fail msg parserfrommaybe _ (Just res) = return res (&

如果我有此代码:

import Text.Parsec

ispositive a = if (a<0) then Nothing else (Just a)

f a b = a+b  

parserfrommaybe :: String -> (Maybe c) -> Parsec a b c
parserfrommaybe msg Nothing  = fail msg
parserfrommaybe _ (Just res)  = return res    

(<!>) :: Parsec a b (Maybe c) -> String -> Parsec a b c
(<!>) p1 msg = p1 >>= (parserfrommaybe msg)    

integermaybeparser = (ispositive <$> integer) <!> "negative numbers are not allowed"
testparser = f <$> (integermaybeparser <* whiteSpace) <*> integermaybeparser
我希望它在第1列给出错误,并给出错误消息,但没有“unexpected 3”这句话,但它似乎在继续解析


为什么会这样?如何让parsec给出我期望的错误消息

我找到了解决方案,问题的原因是第一个解析器运行,即使失败也会消耗输入

解决方案是像这样使用
lookAhead

(<!>) :: (Monad m,Stream a m t) => ParsecT a b m (Maybe c) -> String -> ParsecT a b m c
(<!>) p1 msg =  ((lookAhead p1) >>= (parserfrommaybe msg)) *> (p1 >>= (parserfrommaybe msg))
()::(Monad m,Stream a m t)=>解析a b m(可能是c)->字符串->解析a b m c
()p1 msg=((前瞻p1)>>=(parserfrommable msg))*>(p1>>=(parserfrommable msg))
如果
lookAhead p1
返回
Nothing
,则
*>
的第一个参数将因
lookAhead
而在不使用输入的情况下失败,现在,如果
lookAhead p1
返回
Just res
,那么它将再次成功,而不使用输入,并且结果将从
*>
的第二个参数获得


当然,我必须将
parserfromaybe
类型注释更改为
(Monad m)=>String->(Maybe c)->解析一个bmc
,以满足ghc的要求

只需指出,这将是非常低效的-
p1
几乎总是被解析两次。问题更为基本——如果负整数无效,那么为什么还要解析负符号呢?如果你想特别报告负整数错误(因此你必须解析负号),当你遇到负整数时,你应该使用
parserFail
(而不是
ispositive..
-
Nothing
并不代表你所认为的错误)-这将导致实际的解析器失败,正好在负整数之后<代码>不能导致解析器失败。
(<!>) :: (Monad m,Stream a m t) => ParsecT a b m (Maybe c) -> String -> ParsecT a b m c
(<!>) p1 msg =  ((lookAhead p1) >>= (parserfrommaybe msg)) *> (p1 >>= (parserfrommaybe msg))