微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在编译器构造中具有两个语义分析阶段是否常见?

如何解决在编译器构造中具有两个语义分析阶段是否常见?

我一直在使用 AST explorer 研究各种语言的语法和 AST 节点。 使用 python,我注意到在解析过程中会进行某种形式的语义分析。例如

x = 2
x = 2

产生以下由 VariableDeclaration 节点和 ExpressionStatement 节点组成的 AST。

Python AST

因此,当解析第一行 x = 2 时,它会检查符号表中是否存在 x,然后注册它并生成一个 VariableDeclaration 节点。然后当解析第二个 x = 2 行时,它发现 x 已经定义并产生一个 ExpressionStatement 节点。

但是,当我尝试使用以下语义不正确的代码时:

2 + "string"

它接受代码,并生成一个 ExpressionStatement 节点 - 即使它在语义上不正确,即 int + string,并且当我尝试使用 python 解释器执行它时正确地产生错误。>

这向我表明语义分析发生了两次:一次在解析过程中,一次是在遍历整个 AST 时。这个假设正确吗?如果是这样,为什么会这样?在解析的时候做整个语义分析阶段,而不是拆分,不是更简单吗?

解决方法

在任何语义传递中都未检测到语句 2 + "string" 中的语义错误。这是一个运行时错误,当您尝试执行该语句时会报告该错误。如果语句从不执行,则不报错,执行脚本即可看到

    if False:
        2 + "string"
    print("All good!")

解决第一次使用全局变量作为声明的问题更多的是优化,编译器执行多次优化是很常见的。

总是有一种尝试将这些多遍组合起来的诱惑,但这是一种错误的经济:走 AST 的开销相对较低,并且当它只尝试做一件事时,代码更清晰,更易于维护。将两个不相关的优化启发式交织在一起是糟糕的设计,就像将任何一组不相关的过程交织在一起一样。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。