Haskell 解析器跳过行

Haskell 解析器跳过行,haskell,pug,parsec,Haskell,Pug,Parsec,我想为的一个子集编写一个简单的解析器,生成一些用于进一步处理 解析器非常简单,但通常都有一点长。因为我不知道我是否可以写这么长的代码,所以我有完整的工作示例 我以前涉猎过Parsec,但很少成功。现在,我不太明白为什么它似乎吞下了下面的句子。例如,玉石的输入 .foo.bar | Foo | Bar | Baz 使用parseTest标记txt测试,返回以下内容: Element {elementTag = "div", elementAttrs = [("class"

我想为的一个子集编写一个简单的解析器,生成一些用于进一步处理

解析器非常简单,但通常都有一点长。因为我不知道我是否可以写这么长的代码,所以我有完整的工作示例

我以前涉猎过Parsec,但很少成功。现在,我不太明白为什么它似乎吞下了下面的句子。例如,玉石的输入

.foo.bar
    | Foo
    | Bar
    | Baz
使用
parseTest标记txt测试,返回以下内容:

Element {elementTag = "div", elementAttrs = [("class","foo bar")], elementChildren = [TextNode "Foo"]}

我的解析器似乎能够处理任何类型的嵌套,但不会超过一行。我遗漏了什么?

如果Parsec无法匹配剩余的输入,它将在该点停止解析,并忽略该输入。这里的问题是,在解析了一个标记之后,您不会使用下一个标记之前的行开头的空格,因此Parsec无法解析剩余的输入并将其释放。(可能还有其他问题,我现在无法测试代码)

有很多方法可以添加占用空格的内容,但我不熟悉Jade,因此我无法告诉您哪种方法是“正确”的方法(我不知道缩进语法是如何工作的),而只需在
标记
的末尾添加
空格
就可以了


顺便说一下,您应该考虑将解析器拆分为词法分析器和解析器。Lexer生成一个令牌流,如
[Ident“bind”、OpenParen、Ident“tag”、Equals、StringLiteral“longname”、…、Indentation 1、…]
,解析器解析该令牌流(是的,Parsec可以解析任何东西的列表)。我认为这将使您的工作更容易/更少混乱。

使用令牌模块通常是使用Parsec进行词法分析的惯用方法。然而,由于Jade似乎显著地使用了空格,我认为您建议编写一个单独的扫描仪是正确的,请参阅稍微过时的Parsec手册的第2.11节:不幸的是,我在
标记
标记
解析器周围添加了空格,结果仍然是…@Scán-这是一个问题。因为Jade似乎对缩进敏感,所以不能直接使用Parsec的
空格
词素
解析器,因为它们会占用所有空格。缩进敏感解析非常高级(有一些库可以帮助进行黑客攻击-我不知道它们有多有用或有多文档)。如果你对Parsec/解析还不熟悉,我建议你选择一种比Jade简单一点的语言来练习。@stephentelley可以说,因为
空格在某一点上会消耗空格,所以你仍然可以在该点上获得parser列并使其工作。但是我同意当前的解析器不适合这个任务。