可能有人请给我约当它需要看看进一步的声明,以便能够使当前的时刻正确的语义动作如何处理的情况下一些建议/想法?例如,当有人写一些不支持“前声明”编程语言的翻译器/编译一个众所周知的发生。让我们的示例:

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 ++ - 等功能的模板 - 它不再能够在一个简单的表来做这种查找。您需要专门的脊髓痨在结构符合您的语言结构。一个AST只是没有对那些的最佳结构,更不用说分析过程中的部分AST。

其他提示

如果你想在第一阶段结束时做两遍,而不是语义检查,你可以有TE功能,通过你的行为称为知道通过他们在,所以,如果你有一些动作

[functionCall(name, args)]
[functionDef(name, args, body)]

它们将被定义是这样的(不正确的精神语法,但你明白了吧)

functionCall(string name, vector<string> args)
{
  if (!first_pass) {
    // check args for validity
    // whatever else you need to do
  }
} 

functionDef(string name, vector<string> args, ... body)
{
  if (first_pass)
    // Add function decleration to symbol table
  else
    // define function
}

我觉得你提出毫无假设。举例来说,“这是很清楚的,我们必须有至少两道”。不,它不是。如果语法是使得foo(123)只能被解析为function-name "(" expression ")",再一个通就足够了。

所以我会建议来设计你的语法解析明确。避免不能孤立地解析构建体,例如避免对声明elesewhere dependendencies。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top