你会如何解析缩进(Python风格)?

问题描述 投票:0回答:2

如何定义解析器和词法分析器规则来解析使用缩进定义范围的语言。

我已经在谷歌上搜索并找到了一种通过在词法分析器中生成 INDENT 和 DEDENT 标记来解析它的巧妙方法。

如果我遇到一些有趣的事情,我会更深入地研究这个问题并发布答案,但我希望看到解决该问题的其他方法。

编辑: 正如查理指出的那样,已经有另一个线程即使不相同,也非常相似。我的帖子应该被删除吗?

python parsing indentation lexer
2个回答
12
投票

这是一种假设,因为它取决于您的词法分析器和解析器所采用的技术,但最简单的方法似乎是使用类似于 C 中的大括号的 BEGINBLOCK 和 ENDBLOCK 标记。使用 “越位规则”您的词法分析器需要跟踪一堆缩进级别。当缩进级别增加时,为解析器发出一个 BEGINBLOCK;当缩进级别降低时,发出 ENDBLOCK 并从堆栈中弹出级别。

这是关于此的另一个讨论,顺便说一句。


1
投票

您还可以在词法分析器中的某个位置跟踪第一行前面有多少个 ident 项并将其传递给解析器。最有趣的部分是尝试将其正确传递给解析器:)如果您的解析器使用前瞻(这里我的意思是解析器可能会在真正匹配一个标记之前查询可变数量的标记),那么尝试将其传递给一个全局变量似乎这是一个非常糟糕的主意(因为词法分析器可以在下一行上滑动并更改缩进计数器的值,而解析器仍在尝试解析上一行)。在许多其他情况下,全局变量也是邪恶的;)用缩进计数器以某种方式标记第一行“真实”标记更合理。我无法给你确切的例子(我什至不知道你将使用什么解析器和词法分析器生成器,如果有的话......),但是像在第一行标记上存储数据之类的东西(如果你可以的话,它可能会不舒服) t 轻松地从解析器获取此类标记)或保存自定义数据(将标记链接到缩进的映射,其中源代码中的每一行作为索引,缩进值作为元素值)似乎就足够了。这种方法的一个缺点是解析器变得更加复杂,需要区分 ident 值并根据它更改其行为。像 JavaCC 的 LOOKAHEAD({ yourConditionInJava }) 这样的东西在这里可能会起作用,但它不是一个非常好的主意。在你的方法中使用很多额外的标记似乎并不是那么邪恶的事情:) 我建议的另一种选择是混合这两种方法。仅当缩进计数器在下一行更改其值时,您才能生成附加标记。它就像人工的 BEGIN 和 END 标记。通过这种方式,您可以减少流中从词法分析器输入解析器的“人工”标记的数量。只需调整您的解析器语法即可理解其他标记...

我没有尝试过这个(对此类语言解析没有真正的经验),只是分享我对可能的解决方案的想法。检查已经为此类语言构建的解析器可能对您非常有价值。开源是你的朋友;)

© www.soinside.com 2019 - 2024. All rights reserved.