这个问题与Parsec
和uu-parsinglib
相关。当我们编写解析器组合器时,它们处理来自编译器的字符流。是否可以以某种方式解析一个字符并将其放回(或返回另一个字符)到输入流?
例如,我想解析输入“test + 5”,解析 t
、e
、s
、t
并在识别 test
模式后,将例如 v
字符放回到字符流中,因此在继续解析过程时,我们将与 v + 进行匹配5
我现在不想在任何特定情况下使用它 - 我想深入了解可能性。
最佳答案
我不确定是否可以直接使用这些解析器,但一般来说,您可以通过将解析器与一些允许注入(inject)剩余内容的流相结合来完成它。
例如,使用 attoparsec-conduit您可以使用将解析器变成管道
sinkParser :: (AttoparsecInput a, MonadThrow m)
=> Parser a b -> Consumer a m b
其中Consumer
是一种特殊的管道,它不产生任何输出,仅接收输入并返回最终值。
由于管道支持剩余,因此您可以创建一个辅助方法来转换解析器,该解析器可以选择返回要插入流中的值到管道中:
import Data.Attoparsec.Types
import Data.Conduit
import Data.Conduit.Attoparsec
import Data.Functor
reinject :: (AttoparsecInput a, MonadThrow m)
=> Parser a (Maybe a, b) -> Consumer a m b
reinject p = do
(lo, r) <- sinkParser p
maybe (return ()) leftover lo
return r
然后,使用 sinkParser
将标准解析器转换为管道,并使用 reinject
将这些特殊解析器转换为管道,然后组合管道而不是解析器。
关于parsing - 将字符插入 Haskell 中的解析器组合器字符流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18338707/