Haskell Parsec挂起文件输入

Haskell Parsec挂起文件输入,haskell,parsec,Haskell,Parsec,我试图为一个配置文件编写一个解析器,但遇到了一个奇怪的错误,解析器冻结了。代码可以看到。我在调试器中运行了它,它似乎是在一行中发生的 p_server_entry = many settings *> pure () 在“pure()”的评估中。也就是说,如果调试器行为可以信任,则尝试从p_server_条目返回时似乎失败。我试图删除“pure()”语句并简单地返回“[()]”(显然还调整了类型签名),但它似乎挂在了同一个位置。我知道Parsec不支持左递归,但我看不出这是怎么回事 我正

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

p_server_entry = many settings *> pure ()
在“pure()”的评估中。也就是说,如果调试器行为可以信任,则尝试从p_server_条目返回时似乎失败。我试图删除“pure()”语句并简单地返回“[()]”(显然还调整了类型签名),但它似乎挂在了同一个位置。我知道Parsec不支持左递归,但我看不出这是怎么回事

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

[server]
port = 80
我通过在ghci中运行Parser.hs文件(尽管编译程序并运行它会得到相同的结果)来测试这一点,然后执行以下操作

:m + Data.Monoid
parseConfigFile "test.config" mempty
我感谢任何人能提供的帮助


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

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


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

我明白了。我将删除代码链接,因为该分支不应该发布,但其要点是:我有一个

data Config = { port :: Int, {- ... -} }  -- "Save edits" doesn't seem to always save edits!
我创建了一个解析器来解析输入并更新其中一个结构。它丢弃了实际的解析数据,因为在任何情况下,我只需要更新的记录。问题是,这会丢弃类型信息,也会妨碍编译器指出我的逻辑中的错误。对于每一个实际生成数据的语句,都有一个

*> 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
这是一个方便的小循环,不消耗任何输入


经验教训:如果你扔掉你的类型,你就束缚了编译器的手脚。

胡乱猜测:
设置
是否匹配空字符串?否。我在上面链接了整个源代码,你可以看到所有的定义。我不愿意为了回答这里的问题而阅读100多行代码。请提供下一次仍显示错误的时间。请不要链接到外部代码,因为外部链接可能不是持久性的,但这个问题是。ch函数用于between语句中,因此即使它不匹配任何内容,右括号也必须在之后匹配,模式才能工作。我已经编辑了我的答案以包含一些附加信息。我还将按照您的建议减少示例,但是大多数模式现在没有运行,因此可以简单地删除它。