[C语言]声明解析器cdecl修改版

 

一、写在前面

    K&R曾经在书中承认,"C语言声明的语法有时会带来严重的问题。"。由于历史原因(BCPL语言只有唯一一个类型——二进制字),C语言声明的语法在各种合理的组合下会变得晦涩难懂。不过在15级的优先级规则加持下,C语言的声明仍然有迹可循。这篇文章讲解了一个通常取名为"cdecl"(不同于函数调用约定)的小型程序,该程序常用来解析C语言的声明。本程序的基始版本来源于《C专家编程》p75,约140行代码。

    博主在这个程序的基础上,增加了两个模块的功能:

        1、struct/enum/union关键字后标签变量名的甄别

            有如下声明:struct student a; 在这个声明中student是作为struct后可选的"结构标签"出现的,a才是变量名称。

        2、函数参数的处理

            源程序略过了函数参数处理的模块,在此,我们加入了此功能,尽管有些简化。

 

二、声明的组成部分

    通常情况下来讲,一个C语言声明由三部分组成:类型说明符+声明名称(declarator)+分号,如int a;

 

三、优先级规则

    1、声明从它的名字开始读取,随后按照优先级顺序依次读取。

    2、优先级从高到低依次是:

        2.1、声明中被括号括起来的那部分

        2,2、后缀操作符:

            符号 () 表示这是一个函数

            符号 [] 表示这是一个数组

        2.3、前缀操作符:*代表"指向...的指针"

    3、如果const/volatile关键字后面紧跟类型说明符(如int),那么该关键字作用于类型说明符。在其他情况下,const/volatile关键字作用于它左边紧邻的指针星号。

 

    因此运用该规则分析如下声明:char *(*c[10])();

    第一步:找到变量名c

    第二步:处理c后的[10],表示"c是一个有10个元素的数组"

    第三步:处理c前的*,表示"数组元素为指针"

    第四步:处理c所在括号后的括号,表示"数组的元素类型是函数指针"

    第五步:处理(*c[10])前的星号,表示"数组元素指向的函数的返回值是一个指针"

    第六步:处理char,表示"数组元素指向的函数的返回值是一个指向char的指针"

    综上,该声明表示:C是一个有10个元素的数组,数组元素类型是函数指针,其所指向的函数的返回值是一个指向char的指针。

 

四、程序执行流程

    由于C语言声明并不可以从左往右直接解析,所以我们需要一个栈结构来保存在读取到声明名称前的所有字段,以便在读取到id后再分析。

  1. struct token{  
  2.     char type;  
  3.     char string[MAXTOKENLEN];  
  4. };  
  5. struct token stack[MAXTOKENS];  

    将所有字段分为三类:名称、类型以及限定词,使用枚举类型,使之与char type对应。

  6. enum type_tag {  
  7.     IDENTIFIER,QUALIFIER,TYPE  
  8. };  

    主函数有两大功能,一是找到identifier,二是处理剩下的声明。

  9. int main (void)  
  10. {  
  11.     read_to_first_identifier();   
  12.     deal_with_declarator();   
  13.         
  14.     return 0;  
  15. }  

    第一个函数从左往右读入输入数据,一个读取一个字段(声明的基本单位),若字段不是id(标识符),则将其压入栈中,再读取下一个字段,直到读取到字段,该阶段任务结束。

    第二个函数在得到id后开始工作。根据语法规则,先读取id后的字符,判断其为数组还是函数。在处理完id后的字段后,再依次出栈解析前面的声明。

    

    

五、各模块代码

    5.1、读取标识符:read_to_first_identifier();

        使用一个循环,每次读取一个字段,并判断其是否为标识符,是,则退出,并输出。对于正在读取的标识符,使用一个全局变量struct token thistoken存储,在处理完该字段后,若其不为标识符,则压入栈中。

  1. void read_to_first_identifier()  
  2. 关键字:
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信