首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Haskell中将字符插入解析器组合器字符流

在Haskell中将字符插入解析器组合器字符流
EN

Stack Overflow用户
提问于 2013-08-20 23:12:45
回答 2查看 492关注 0票数 2

这个问题与Parsecuu-parsinglib都有关。当我们编写解析器组合子时,它们会处理来自编译器的字符流。有没有可能解析一个字符并将其放回(或返回另一个字符)到输入流?

例如,我希望解析输入"test + 5",解析test,并在识别test模式后,将例如v字符放回字符流中,因此在继续解析过程时,我们将根据v + 5进行匹配

我现在不想在任何特定的情况下使用它-我想深入了解其中的可能性。

EN

回答 2

Stack Overflow用户

发布于 2013-08-21 00:56:16

我不确定是否可以直接使用这些解析器,但通常您可以通过将解析器与一些允许注入剩余物的流相结合来实现。

例如,使用attoparsec-conduit可以将解析器转换为管道,使用

代码语言:javascript
复制
sinkParser :: (AttoparsecInput a, MonadThrow m)
           => Parser a b -> Consumer a m b

其中Consumer是一种特殊类型的管道,它不产生任何输出,只接收输入并返回最终值。

由于管道支持剩余物,因此您可以创建一个helper方法来转换解析器,该解析器可选地将一个值返回到流中,并将其转换为管道:

代码语言:javascript
复制
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将这些特殊解析器转换为管道,然后组合管道而不是解析器。

票数 1
EN

Stack Overflow用户

发布于 2013-08-22 18:38:58

我认为最简单的归档方法是构建一个多层解析器。考虑词法分析器+解析器的组合。这是解决这个问题的一种干净的方法。

您必须将这两种解析分开。搜索和替换解析转到第一个解析器,构建AST解析转到第二个解析器。或者,您可以创建一个中间令牌表示。

代码语言:javascript
复制
import Text.Parsec
import Text.Parsec.String

parserLvl1 :: Parser String
parserLvl1 = many (try (string "test" >> return 'v') <|> anyChar)

parserLvl2 :: Parser Plus
parserLvl2 = do text1 <- many (noneOf "+")
                char '+'
                text2 <- many (noneOf "+")
                return $ Plus text1 text2

data Plus = Plus String String
  deriving Show

wholeParse :: String -> Either ParseError Plus
wholeParse source = do res1 <- parse parserLvl1 "lvl1" source
                       res2 <- parse parserLvl2 "lvl2" res1
                       return res2

现在您可以解析您的示例了。wholeParse "test+5"结果为Right (Plus "v" "5")

可能的变体:

  • 为组合包装的解析器阶段创建一个类和一个实例。(可能带有解析器状态。)
  • 创建一个中间表示,即

的标记流

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18338707

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档