如何通过C编译器解析类型转换?

时间:2014-07-21 23:15:52

标签: c parsing

在语法上不可能知道f / g是函数调用还是类型转换而不知道它们是如何声明的。编译器是否知道解析步骤中的差异,或者他们通常在第二次通过中解决这个问题?

void f(int x){};
typedef short g;

int main(void){
   ((f)(1));
   ((g)(1));
   return 0;
}

2 个答案:

答案 0 :(得分:6)

C的早期版本(在K& R的第一版于1978年出版之前)没有typedef功能。在该C版本中,始终可以在语法上识别类型名称。 intfloatcharstruct等是关键字;类型名称的其他元素是标点符号,例如*[]。 (解析器可以区分不是关键字的关键字和标识符,因为它们只有很小且固定的数量。)

添加typedef时,必须将其加入到现有语言中。 typedef为现有类型创建新名称。该名称是单个标识符 - 与语法不同于任何其他普通标识符。

C编译器在解析其输入时必须维护一个符号表。当遇到标识符时,需要查询符号表以确定它是否是类型名称。没有这些信息,语法就不明确了。

从某种意义上说,typedef声明可以被认为是创建一个新的临时关键字。但它们是可以被内部范围中的新声明隐藏的关键字。

例如:

{
    typedef short g;
    /* g is now a type name, and the parser has
     * to treat it almost like a keyword
     */
    {
        int g;
        /* now g is an ordinary identifier as far as the parser is concerned */
    }
    /* And now g is a type name again */
}

解析C很难。

答案 1 :(得分:4)

我认为他们懒洋洋地这样做:每当解析一个令牌时,下一个令牌的解析会被延迟,直到知道该符号的语义信息为止。然后,当解析下一个标记时,编译器已经知道被引用的符号是否是类型名称(它必须先前已声明),并且可以相应地执行。 (因此在这种方法中,语义和句法分析交织在一起,不能分开。)