我想为Jade的子集编写一个简单的解析器,生成一些XmlHtml以供进一步处理。
解析器非常简单,但与Parsec一样,有点长。由于我不知道是否允许我发布这么长的代码,我有完整的工作示例here。
之前我曾经涉足过Parsec,但很少成功。现在,我不太明白为什么它似乎吞下了几行。例如,
的玉石输入.foo.bar
| Foo
| Bar
| Baz
使用parseTest tag txt
进行测试,返回:
Element {elementTag = "div", elementAttrs = [("class","foo bar")], elementChildren = [TextNode "Foo"]}
我的解析器似乎能够处理任何类型的嵌套,但绝不会超过一行。我错过了什么?
答案 0 :(得分:6)
如果Parsec无法匹配剩余的输入,它将在该点停止解析并简单地忽略该输入。这里的问题是,在解析了一个标记后,你不会在下一个标记之前的行开头消耗空格,因此Parsec无法解析剩余的输入和保释。 (可能还有其他问题,我现在无法测试代码)
有很多方法可以添加消耗空间的东西,但我不熟悉Jade所以我不能告诉你哪种方式是“正确的”方式(我不知道缩进语法是如何工作的)但只是添加<{1}} whiteSpace
末尾的tag
应该这样做。
顺便说一句,您应该考虑将解析器拆分为Lexer和Parser。 Lexer生成一个令牌流,如[Ident "bind", OpenParen, Ident "tag", Equals, StringLiteral "longname", ..., Indentation 1, ...]
,解析器解析该令牌流(是的,Parsec可以解析任何事物的列表)。我认为这会让你的工作更容易/更少混淆。