我对(Mega)Parsec 的内部运作有一个有点技术性的问题,其非正式的上下文是:
通过 continuation 控制错误消息的累积/传播的想法是什么
Parsec
?
具体来说:考虑mplus
制作ParsecT
. MonadPlus
( source )
mplus m n
将要解析的字符串作为输入,并根据解析的结果s
继续cok
, cerr
, eok
, 和eerr
跟随。
s
首先解析m
:
- 如果解析成功并消耗(分别不消耗)的一部分
s
,则遵循cok
(分别eok
)继续。 s
如果在使用 的部分时with的解析m
失败s
,请cerr
继续。s
假设with的解析m
失败而没有消耗任何东西;让err
成为与此失败相关的解析错误。s
然后我们尝试用解析n
,并相应地选择一个延续:- 如果在使用输入时解析
s
withn
成功,请cok
继续。 s
如果使用输入时with的解析n
失败,请cerr
继续。s
如果with的解析成功而没有消耗输入,请遵循从 派生n
的延续:neok
eok
neok y s' err' = eok y s' (mergeError err err')
s
如果with的解析失败而没有消耗输入,请遵循从 派生n
的延续:neerr
eerr
neerr y s' err' = eerr (mergeError err err')
- 如果在使用输入时解析
我的问题是:
为什么我们在跟随“空”延续而不是跟随“消耗”延续时合并错误,从而忘记所有先前的错误?
这一定是一个设计决定,但我无法弄清楚它背后的原因。也许有一个简单的例子可以澄清这一点?