You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单子解析器中的否定前瞻(notFollowedBy)实现问题咨询

实现单子解析器中notFollowedBy函数的解决方案

老哥,我之前折腾单子解析器的时候也踩过这个坑!你要实现的notFollowedBy核心就是反转shouldFail的ExceptT结果对吧?给你捋捋具体的实现思路和代码:

首先得明确notFollowedBy的核心逻辑:它接收一个解析器p,如果p成功匹配了输入,那notFollowedBy就得失败;如果p匹配失败,那notFollowedBy就成功,而且绝对不能消耗任何输入——这是否定前瞻的关键特性。

基于ExceptT的结构,你可以这么写实现:

notFollowedBy :: Monad m => Parser m a -> Parser m ()
notFollowedBy p = do
  -- 第一步:先保存当前的解析状态(输入位置、剩余输入这些)
  currentState <- getParserState
  -- 运行目标解析器p,拿到ExceptT的结果
  parseResult <- runExceptT $ runParser p
  -- 第二步:恢复之前的解析状态,确保输入完全没被消耗
  putParserState currentState
  -- 第三步:反转结果判断
  case parseResult of
    -- 如果p成功匹配了,那notFollowedBy就要抛出错误
    Right _ -> throwError "notFollowedBy failed: unexpected token detected"
    -- 如果p匹配失败了,那notFollowedBy就成功返回空单元
    Left _ -> pure ()

这里有几个必须注意的点:

  • 一定要保存并恢复解析状态:否定前瞻只是“预判”,不能改变原有的解析位置,否则会影响后续的解析逻辑
  • 直接通过runExceptT的结果反转判断:你提到的shouldFail其实就是检查runExceptT的结果是否为Left,这里我们直接处理结果就行,不用额外封装(如果你的代码里已经有shouldFail,也可以替换成shouldFail p >>= \isFailed -> if isFailed then pure () else throwError ...)
  • 如果你的解析器框架支持原子操作,最好把p限制为原子解析器(比如单个字符、固定关键字),避免回溯带来的意外问题

内容的提问来源于stack exchange,提问作者Bailey Parker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:31:08