2

我想为Jade的一个子集编写一个简单的解析器,生成一些XmlHtml以供进一步处理。

解析器非常简单,但与Parsec一样,有点长。因为我不知道是否允许我发布这么长的代码帖子,所以我在这里有完整的工作示例。

我以前涉足过 Parsec,但很少成功。现在,我不太明白为什么它似乎吞下了以下几行。例如,jade 的输入

.foo.bar
    | Foo
    | Bar
    | Baz

用 测试parseTest tag txt,返回:

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

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

4

1 回答 1

6

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

有很多方法可以添加一些消耗空格的东西,但我不熟悉 Jade,所以我不能告诉你哪种方式是“正确”的方式(我不知道缩进语法是如何工作的),但只是whiteSpace在某处添加结束tag应该这样做。

顺便说一句,您应该考虑将解析器拆分为 Lexer 和 Parser。Lexer 产生一个类似的令牌流[Ident "bind", OpenParen, Ident "tag", Equals, StringLiteral "longname", ..., Indentation 1, ...],解析器解析该令牌流(是的,Parsec 可以解析任何东西的列表)。我认为这会让你的工作更轻松/更少混乱。

于 2012-05-05T23:26:26.077 回答