当需要查看进一步的声明以便能够在当前时刻做出正确的语义操作时,有人可以给我一些关于如何处理这种情况的建议/想法吗?例如,当有人编写不支持“前向声明”的某种编程语言的解释器/编译器时,这是众所周知的事件。让我们举个例子:
foo(123);//<-- our parser targets here. we estimate we have a function
// invocation, but we have no idea about foo declaration/prototype,
// so we can't be sure that "foo" takes one integer argument.
void foo(int i){
//...
}
很明显我们必须至少有两次通过。首先,我们解析所有函数声明并获取所有需要的信息,例如:函数采用的参数数量、它们的类型,然后我们能够处理函数调用并解决上述困难。如果我们这样做,我们将必须使用一些 AST 来完成所有这些传递。遍历机制/访问者。在这种情况下,我们必须处理 AST 遍历/应用访问者,我们必须对直接集成在我们的解析器中的所有美丽的凤凰结构说“再见”。
你会如何处理这个问题?
最佳答案
[第二个答案,关于语义] 这个特殊的例子恰好很简单。您可以做的是记录对尚未声明的函数进行的函数调用以及实际参数类型。当您稍后确实遇到函数声明时,您会检查是否有前面的函数调用与这个新函数(更好)匹配。显然,您只会在解析结束时检测到错误,因为最后一行可能会引入缺失的函数。但是在该行之后,任何根本没有匹配的函数调用都是错误的。
现在,问题是这适用于简单的语义。如果您查看更复杂的语言 - 例如使用类似 C++ 的函数 templates - 不再可能在简单的表中进行此类查找。您将需要在结构上与您的语言结构相匹配的专门标签。 AST 并不是最好的结构,更不用说解析期间的部分 AST 了。
关于c++ - 振奋精神,推进申报问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1678653/