我正在使用带有自定义Stream
类型的 Parsec。这个流本质上是String
但有时它将在字符串中找到的输入扩展为其他字符串(想想别名扩展)。例如,给定“§4.1 ¶3”,它可能会向解析器提供“第 4.1 节第 3 段”。
我有这一切工作。我的类型看起来像:
data DealiasingStream = ...
instance (Monad m) => Stream DealiasingStream m Char where ...
type ShellParser = Parsec DealiasingStream ()
请注意,依赖类型DealiasingStream
是 just Char
。这允许我的解析器(好吧,我ShellParser
的 s 使用所有标准字符解析器。
我的问题是关于让 Parsec 根据我的流的原始输入报告位置。的文档Stream
说:
一个
Stream
实例负责在流状态中维护“流中的位置”s
。除非您以非平凡的方式使用 monad,否则这是微不足道的。
事实上,我的流类型知道它想在任何给定时刻报告什么位置......但我不知道如何让 Parsec 使用它!Parsec 似乎将其自身SourcePos
作为其内部State
. 这似乎是由各种token
prim 更新的,因此对于标准Char
解析器来说,这是我无法控制的。
一个人应该如何做到这一点?