可以使用 Instaparse 或其他 Clojure 库来解析基于缩进的语言吗?我见过使用 Instaparse 解析以 EBNF/ABNF 表示的语法的示例。有没有一种好方法可以使用它来解析像 Python 这样的缩进感知语言?
2 回答
通常要进行基于缩进的解析,您需要三件事:
扩展标记器以从每行的前导空格中生成标记
处理标记流,对于每一行,将前导空格与当前上下文进行比较并指示是否增加或减少(因此,当缩进级别发生变化时,您将在每行开头使用标记更改为具有标记)
编写一个“普通”解析器,它知道指示缩进级别变化的标记。
根据语言,您可能需要将一些信息从第三部分反馈到第二部分。
我对instaparse一无所知(我回答的唯一原因是那些问“你到目前为止尝试了什么?”这样的问题真的让我很生气)所以你需要看看是否有一些在标记器和解析器之间放置第二阶段的方法(我扫描了文档,它似乎没有任何内容可以为您完成第二部分,但您可以自己编写)。但它应该能够完成第一部分和第三部分。
显然,您不是第一个遇到 Instaparse 问题的人。
对于大多数解析器生成器,您可以使用自定义词法分析器解决这个问题,使用@andrewcooke 提出的方案的一些变体。然而,Instaparse 旨在避免对词法分析器的需求,因此不提供使用词法分析器的接口。
这一不足在第 9 期中特别提出,由第 10期取代;在后者中,Instaparse 作者提出了一种解决方法:
与此同时,您可能会采用一种解决方法。您可以将 INDENT 和 DEDENT 等标记映射到未使用的字符,然后将其重建为字符串,然后对其运行 instaparse。我相信 ASCII 字符 0-8 和 11-31 是未使用的,可以用作标记。
这当然是一种可能性,尽管这是对这是否“做一些非常骇人听闻的事情”的审美判断。尽管如此,您仍然可以编写这样的 hack,希望在问题 10 解决后可以将其删除。您可能想加入对该问题的讨论。