有人可以给我一些关于如何处理情况的建议/想法,当需要进一步声明以便能够在当前时刻做出正确的语义操作时?例如,当某人编写某种不支持“前向声明”的编程语言的解释器/编译器时,这是众所周知的事件.我们举个例子:
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函数模板 – 不再可能在简单的表中进行此类查找.您需要在结构上与您的语言结构匹配的专门tabes. AST对于那些人来说不是最好的结构,更不用说解析期间的部分AST了.