我可以使用Instaparse或任何其他clojure库来解析基于缩进的语言吗?

问题描述:

可以使用Instaparse或其他Clojure库来解析基于缩进的语言吗?我见过使用Instaparse解析EBNF/ABNF中表达的语法的例子。有没有一种很好的方法来使用它来解析像Python这样的支持缩进的语言?我可以使用Instaparse或任何其他clojure库来解析基于缩进的语言吗?

+0

@chollida:我试图得到这个问题的建议,而不是做一些非常黑客的事情。 –

+0

因为您发布了一些您正在尝试完成的内容,所以您不会得到某些黑客行为。 – octopusgrabbus

+0

@octopusgrabbus:我不确定你的意思。 我看到他们的选项是手动推出我自己的解析器(hacky),或者使用解析器生成器,其中Instaparse似乎是最发达的。但是,对于我来说,如何在A/EBNF中表达一个基于缩进的语法,或者Instaparse是否是一个合适的工具,这一点并不明显。因此,这个问题。 –

显然,您不是第一个使用Instaparse解决此问题的人。

对于大多数解析器生成器,您可以使用@andrewcooke提出的方案中的一些变体,使用自定义词法分析器来解决此问题。然而,Instaparse的设计是为了避免使用词法分析器,因此不提供使用它的界面。

这个不足是在issue 9中被特别提出的,被issue 10取代;在后者中,Instaparse作者提出了一种解决方法:

与此同时,您可能会使用一种解决方法。您可以将INDENT和DEDENT等令牌映射为未使用的字符,然后将其重新编译为字符串,然后对此执行instaparse。我相信ASCII字符0-8和11-31未被使用,可以作为令牌。

这当然是一种可能性,虽然这是否是一种审美判断,是否“做了一件非常好看的事情”。尽管如此,你仍然可以写出这样的黑客,希望一旦解决问题10就可以将其删除。您可能想加入对该问题的讨论。

+0

通过哈克,我主要是手动滚动解析器。这看起来很有希望,我会进一步追求。非常感谢。 –

通常做基于压痕解析需要三样东西:

  • 扩展标记生成器,使一个令牌从前导空格每行

  • 过程令牌的流,每个将当前上下文的前导空格与 当前上下文进行比较,并指示是否有增加或减少(因此您在每行的开始处更改 时有一个令牌,当缩进级别 更改时具有令牌)

  • 正在编写一个“正常”解析器,该解析器知道指示缩进 级别更改的标记。

取决于您可能需要反馈的信息从第三部分到第二部分的语言。

我不知道什么instaparse(我回答的唯一原因是,人们谁问“你尝试过这么远吗?”对这样的问题真的气死我了),所以你需要看看是否有某种方法可以在分词器和解析器之间放置第二个阶段(我扫描了文档并且它似乎没有任何内容会为你做第二部分,但你可以自己写)。但它应该能够完成第一部分和第三部分。

+0

谢谢,这是非常有帮助的。 –

+1

+1为'真让我失望'放在一边。 :) –