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

时间:2013-05-27 19:49:16

标签: parsing clojure

可以使用Instaparse或其他Clojure库来解析基于缩进的语言吗?我已经看到了使用Instaparse来解析EBNF / ABNF中表达的语法的示例。有没有一种好方法可以用它来解析缩进感知语言,比如Python?

2 个答案:

答案 0 :(得分:10)

显然,你不是第一个遇到Instaparse问题的人。

对于大多数解析器生成器,您可以使用自定义词法分析器解决此问题,使用@andrewcooke提出的方案的一些变体。但是,Instaparse旨在避免使用词法分析器,因此不提供使用词法分析器的接口。

这种缺陷在issue 9中被特别提出,被issue 10取代;在后者中,Instaparse作者提出了一种解决方法:

  

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

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

答案 1 :(得分:9)

通常要进行基于缩进的解析,您需要做三件事:

  • 扩展tokenizer以从每行的前导空格中创建一个标记

  • 处理标记流,为每一行比较前导空格与 当前上下文并指示是否有增加或减少(所以你改变 在每一行的开头有一个令牌,在压痕级别时有一个令牌 改变)

  • 编写一个“普通”解析器,该解析器知道指示缩进更改的标记 水平。

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

我对instaparse一无所知(我回答的唯一原因是那些问过“你到目前为止尝试了什么?”的人对这样的问题真的惹恼了我)所以你我需要看看是否有某种方法将第二阶段放置在tokenizer和解析器之间(我扫描了文档,它似乎没有任何东西可以为你做第二部分,但你可以自己写一下)。但它应该能够完成第一和第三部分。