haskell - Parsec 解析器在 many1 和 manyTill 组合器上失败

标签 haskell parsec

我遇到了 parsec 解析器的不明确行为,所以我想将字符串解析为相同

>  <CdId>
1

>  <Mol Weight>
270.2369

>  <Formula>
C15H10O5

>  <LOG_ER_RBA>
-0.36

>  <ACTIVITY>
1

我写了一个解析器

 parseProperties = do       
        skipMany1 newline
        char '>' >> spaces >> char '<' 
        propName <- many1 (noneOf ">")
        char '>'
        newline
        propValue <- many1 (noneOf "\n")
        return (propName,propValue)

这个解析器很好地解析了一项,也能够解析多项:

parseTest (count 5 parseProperties) "\n>  <CdId>\n1\n\n>  <Mol Weight>\n270.2369\n\n>  <Formula>\nC15H10O5\n\n>  <LOG_ER_RBA>\n-0.36\n\n>  <ACTIVITY>\n1\n\n"

结果

 [("CdId","1"),("Mol Weight","270.2369"),("Formula","C15H10O5"),("LOG_ER_RBA","-0.36"),("ACTIVITY","1")]

尽管如此,我还是找不到解析随机数属性的方法。如果我尝试

parseTest (many1 parseProperties) "\n>  <CdId>\n1\n\n>  <Mol Weight>\n270.2369\n\n>  <Formula>\nC15H10O5\n\n>  <LOG_ER_RBA>\n-0.36\n\n>  <ACTIVITY>\n1\n\n"

parseTest (manyTill parseProperties (try eof)) "\n>  <CdId>\n1\n\n>  <Mol Weight>\n270.2369\n\n>  <Formula>\nC15H10O5\n\n>  <LOG_ER_RBA>\n-0.36\n\n>  <ACTIVITY>\n1\n\n"

解析失败

parse error at (line 17, column 1):
unexpected end of input
expecting new-line or ">"

但是,如果我使用 anyChar 解析器,它不会失败。

parseTest (manyTill anyChar (try eof)) "\n>  <CdId>\n1\n\n>  <Mol Weight>\n270.2369\n\n>  <Formula>\nC15H10O5\n\n>  <LOG_ER_RBA>\n-0.36\n\n>  <ACTIVITY>\n1\n\n"

"\n>  <CdId>\n1\n\n>  <Mol Weight>\n270.2369\n\n>  <Formula>\nC15H10O5\n\n>  <LOG_ER_RBA>\n-0.36\n\n>  <ACTIVITY>\n1\n\n"

最佳答案

parseProperties 解析器在您的示例中执行了多次,直到 遇到 eof。问题是 parseProperties 不消耗 您示例中的尾随空格,因此在解析最后一个标记之后, 剩余的字符串是 "\n\n",不会触发您的终止 条件,因为它不是输入的结束。这会导致 parseProperties 再次尝试,这会消耗空白但在尝试时失败 吃一个'>'

尝试将您的 parseTest 修改为以下内容

test = "\n>  <CdId>\n1\n\n>  <Mol Weight>\n270.2369\n\n>  <Formula>\nC15H10O5\n\n>  <LOG_ER_RBA>\n-0.36\n\n>  <ACTIVITY>\n1\n\n"

parseTest (manyTill parseProperties $ try (skipMany newline >> eof)) test

这会尝试在检查它是否结束之前去除前面的空格 的输入。

关于haskell - Parsec 解析器在 many1 和 manyTill 组合器上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17859472/

相关文章:

haskell - 解析器组合器可以变得高效吗?

parsing - 如何从 Parsec 中的 optional 解析器中检索值?

haskell - 无法将预期类型 `Int' 与实际类型 `m0 Int' 匹配

list - Haskell函数交换列表中的第二个元素

web-applications - 用于 Web 应用程序开发的 Lisp 或 Haskell

haskell - 为Canvas设计一个绘图API

unit-testing - Ruby -> Haskell 单元和自动化验收测试

parsing - Haskell Parsec,将 oneOf 改编为 [String]

Haskell 使用带有 Parsec 的累加器进行解析

parsing - Haskell/Parsec : How do you use the functions in Text. Parsec.Indent?