如何使用Parsec否定解析器

bea*_*rdc 6 parsing haskell parsec

我有一个带有行结尾"\ r \n \n \n"的文件,并使用解析器eol = string "\r\r\n" :: Parser String来处理它们.为了获得这些分隔符之间的行列表,我想sepBy与一个解析器一起使用,该解析器返回任何不会被捕获的文本eol.通过文档查看,我没有看到一个否定解析器的组合器(除了模式”\r\r\n”'解析器之外的任何东西).

我尝试过使用sepBy (many anyToken) end,但many anyToken似乎很贪心,没有停止eol比赛.我无法使用many (noneOf "\n\r"),因为我的文字中有几个地方有单个'\n'字符.

有没有一个组合器可以让我反过来string "\r\r\n"

And*_*ewC 8

我担心你会倒退.Parsec解析器不会切断输入,它们会构建输出.你试着通过思考你不想要的东西来解析的越多,它就越难.你需要自下而上思考什么是允许的,而不是自上而下的.

你应该用你最小的,最基础的事情开始想要的.例如,不要将标识符视为空格之前的所有内容,将其视为字母后跟字母数字数据.然后,您可以将其与空格分隔,将其与您在线上预期的其他内容分开.

line = do
       i <- identifier
       whiteSpace
       string "="
       e <- expr
       return $ Line i e
Run Code Online (Sandbox Code Playgroud)

只有当您完成一个解析器成功解析您想要的行并拒绝无效行时,才应解析多行:

lines = sepBy line eol
Run Code Online (Sandbox Code Playgroud)


bea*_*rdc 5

作为一个试探性的答案,它看起来像manyTill anyChar (try eol)我想要的那样。不过,作为我最初问题的一部分,我仍然想知道是否有一种通用的方法来否定解析器,或者是否有另一种推荐的方法来做我想做的事。

  • notFollowedBy(在 Text.Parsec.Combinator 中)有帮助吗? (3认同)