0

我目前正在尝试使用 boost spirit x3 编写编译器。我完成了解析器(现在没有语义操作和错误处理,只是解析成 ast)。既然我想实现语言来支持作用域和函数调用,我问自己什么时候检查被调用的函数是否存在?我应该在构建 ast 时检查当前范围内是否存在函数(在使用语义操作进行解析时),还是应该在编译 ast 时检查这一点?范围堆栈也是如此。我应该在解析、使用语义操作还是编译 ast 时建立范围堆栈?

4

1 回答 1

1

这个问题被严重低估了。

其中大部分在很大程度上取决于您正在实现的语言的性质(它如何进行范围界定?你会有词法范围吗?闭包?你会有动态堆栈吗?协程?变量是动态的还是完全静态的?打字? )。

我应该在构建 ast 时检查当前范围内是否存在函数(在使用语义操作进行解析时),还是应该在编译 ast 时检查这一点?

就像我说的,两者都可以工作。我通常推荐关注点分离。在大多数情况下,只需简单地解析并在 AST 上操作(多次)就更容易思考,并且会产生更清晰、更容易扩展的代码。

根据情况(例如,当您希望变量在解析期间隐藏某些关键字或其他一些上下文感知谓词时),您可能需要维护一个符号表,其中包含范围内的已知标识符。这将 - IME - 构成设计气味,您应该考虑是否需要复杂性。

范围堆栈也是如此。我应该在解析、使用语义操作还是编译 ast 时建立范围堆栈?

同样,在编译过程中做事通常要简单得多。

于 2016-08-13T23:03:25.363 回答