【问题标题】:Parsec hanging on file inputParsec 挂在文件输入上
【发布时间】:2013-03-11 21:12:50
【问题描述】:

我正在尝试为配置文件编写解析器,但遇到了一个奇怪的错误,解析器只是冻结了。代码可见here。我已经在调试器中运行它,它似乎发生在行中

p_server_entry = many settings *> pure ()

在“纯()”的评估。也就是说,如果可以信任调试器的行为,则尝试从 p_server_entry 返回似乎会失败。我尝试删除“纯()”语句并简单地返回“[()]”(并显然调整类型签名)但它似乎挂在同一个地方。我知道 Parsec 不支持左递归,但我看不到这里发生了什么?

我正在做的是,我正在使用 Parsec 通过用户状态为我填写记录。对于返回值,我只是从所有函数中返回 (),因为配置记录将从状态中检索并作为解析结果返回。导致挂起的示例文件是:

[server]
port = 80

我通过在 ghci 中运行 Parser.hs 文件来测试这一点(尽管编译程序并运行它会得到相同的结果)然后执行

:m + Data.Monoid
parseConfigFile "test.config" mempty

感谢任何人提供的任何帮助。

编辑:我应该提到这几乎和以前一样工作。我把它从返回一个特殊的解析树改为直接更新配置结构。

【问题讨论】:

  • 疯狂猜测:settings 是否匹配空字符串?
  • 没有。我链接了上面的整个源代码,您可以在其中看到所有定义。
  • 我不愿意阅读 100 多行代码只是为了在这里回答一个问题。请在下次仍然显示错误时提供short, self-contained example。并且请不要链接到外部代码,因为外部链接可能不是持久的,但这个问题是。

标签: haskell parsec


【解决方案1】:

猜想:如果您尝试用其他东西(即`oneOf“某物”)更改ch = satisfy (notelem),会发生什么。 我想知道 notelem 是否可以匹配一个空字符串或有一些奇怪的行为。

更一般地说,我知道这很麻烦,但请尝试隔离您的问题(即重新创建解析器失败的最小状态)。就目前而言(200 行代码),评估和解决它有点困难。

【讨论】:

  • ch 函数用于 between 语句,因此即使它没有匹配任何内容,右括号也必须在之后匹配才能使模式起作用。我已经编辑了我的答案以包含一些额外的信息。我还将按照您的建议考虑减少示例,但大多数模式现在都没有运行,因此可以简单地删除它。
【解决方案2】:

我明白了。我将删除代码链接,因为该分支不应该被发布,但它的要点是:我有一个类似的记录

data Config = { port :: Int, {- ... -} }  -- "Save edits" doesn't seem to always save edits!

我创建了一个解析器来解析输入并更新其中一个结构。它丢弃了实际的解析数据,因为无论如何我想要的只是更新的记录。问题是,这丢弃了 type 信息,也阻碍了编译器指出我的逻辑中的错误。对于每个实际产生数据的语句,都会有一个

*> pure ()

在语句结束时,丢弃解析后的数据。我决定我可能不应该丢弃数据,即使我现在不需要它,所以我创建了新类型来对解析的内容进行编码,并最终返回解析树以及更新的配置结构。

一完成这个问题就很明显了。我有这样的声明

p_server_settings = case someVar of
    "server" -> many p_serverSettings
    _        -> many p_siteSettings

这两个组合子都被定义为

p_serverSettings = many settings *> pure ()
    where settings = {- bunch of possible settings -}

一旦我删除 () 返回并使用生成的内容,我立即看到 p_server_settings 试图返回 [[Setting]] 而不是 [Setting],这是因为我有

many many settings

这是一个方便的小循环,不消耗任何输入。

经验教训:如果你丢弃你的类型,你就会束缚编译器的手。

【讨论】:

    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 2014-10-14
    • 2014-07-26
    • 2014-09-02
    • 2017-01-28
    相关资源
    最近更新 更多