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

如何获取Parsec解析器所消耗的输入流?

获取Parsec解析器消耗的输入流片段

可以借助Parsec提供的getInput工具实现一个通用包装combinator,无需修改所有底层解析器,仅需在顶层或目标子解析器上使用即可。

实现思路

通过在解析前后分别获取当前输入流,计算两者的差异得到解析器消耗的输入片段。对于String类型的输入,直接通过前后输入的长度差截取对应的字符即可。

代码实现

import Text.Parsec
import Text.Parsec.String (Parser)

-- 包装解析器,返回解析结果与消耗的输入片段的元组
trackConsumed :: Parser a -> Parser (a, String)
trackConsumed parser = do
  preInput <- getInput
  result <- parser
  postInput <- getInput
  -- 计算消耗的输入:从原输入开头到剩余输入开头的部分
  let consumed = take (length preInput - length postInput) preInput
  return (result, consumed)

使用方式

将你的顶层解析器传入trackConsumed即可,示例:

-- 假设你的顶层解析器是topLevelParser
mainParser :: Parser (YourAST, String)
mainParser = trackConsumed topLevelParser

细节说明

  1. 这个方法无需修改任何底层解析逻辑,仅通过包装器实现输入跟踪,完全符合你不想重写所有解析器的需求。
  2. 如果解析过程中存在回溯(比如使用try combinator),该方法依然有效——回溯后postInput会回到preInput的状态,此时consumed为空字符串,符合预期。
  3. 若需要基于位置(行号、列号)更精确地计算消耗的输入,可以结合getPosition和getSourcePos相关函数,但对于纯字符流的解析,长度差的方式已经足够简单高效。
  4. parsecMap仅用于映射解析结果,单独无法实现输入跟踪,但可以配合上述逻辑对返回的元组进行进一步处理,比如只保留消耗的输入或修改解析结果格式。

内容的提问来源于stack exchange,提问作者Peter Bergman

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:40:23