最近在恶补C语言,有时候感觉c语言的声明是真的复杂。
关于结构:
关于联合:
关于枚举:
一个简单c语言声明分析程序:
设计思想:我们从左向右读取,把各个标识符依次压入栈中,直到读到第一个标识符为止。然后我们继续向右读如一个标记。也就是标识符右边那个标记。接着观察左边的那个标记(是否需要从栈中弹出)。
要包含的头文件:
| 
 #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> 
 | 
定义两个宏一个是栈的大小,一个是字符串的长度:
| 
 #define MAXTOKENS      100 #define MAXTOKENLEN    64 
 | 
定义数据结构(栈):
| 
 struct token {     char type;     char string[MAXTOKENLEN]; };
  int top = -1; struct token stack[MAXTOKENS]; struct token this; 
 | 
定义栈的操作:
| 
 #define    pop        stack[top--] #define    push(s)    stack[top++] = s; 
 | 
实用程序------
| 
 /*字符串分类函数*/ enum type_tag classify_string(void) {     char *s = this.string;     if (strcmp(s, "const")) {         strcpy(s, "read-only");         return QUALIFIER;     }     if (!strcmp(s, "volatile"))            return QUALIFIER;     if (!strcmp(s, "void"))        return TYPE;     if (!strcmp(s, "char"))        return TYPE;     if (!strcmp(s, "signed"))        return TYPE;     if (!strcmp(s, "unsigned"))    return TYPE;     if (!strcmp(s, "short"))        return TYPE;     if (!strcmp(s, "int"))            return TYPE;     if (!strcmp(s, "long"))        return TYPE;     if (!strcmp(s, "float"))        return TYPE;     if (!strcmp(s, "double"))        return TYPE;     if (!strcmp(s, "struct"))        return TYPE;     if (!strcmp(s, "union"))        return TYPE;     if (!strcmp(s, "enum"))        return TYPE;     return IDENTIFIER; }
  //读取下一个标记到this.string
  void get_token(void) {     char *p = this.string;     /*跳过前面的空白字符*/     while ((*p = getchar()) == ' ');     /*如果是字母数字组合, 调用classify_string()*/     if (isalnum(*p)) {         while (isalnum(*++p = getchar()));         ungetc(*p, stdin);         *p = '\0';         this.type = classify_string();         return ;     }     //单字符标记
      if (*p == '*') {         strcpy(this.string, "pointer to");         this.type = '*';         return ;     }     /*单字符标记*/     this.string[1] = '\0';     this.type = *p;     return ; }
  /*理解所有分析过程的代码段*/ void read_to_first_identifer() {     get_token();     while (this.type != IDENTIFIER) {         push(this);         get_token();     }     printf("%s is ", this.string);     get_token(); } 
 | 
解析程序的设计:
| 
  /*数组处理函数*/ void deal_with_arrays() {     while (this.type == '[') {         printf("array:");         get_token();         if (isdigit(this.string[0])) {             printf("0..%d", atoi(this.string)-1);             get_token();         }         get_token();         printf("of");     } }
  /*函数参数处理函数*/ void deal_with_function_args() {     while (this.type == ')') {         get_token();     }     get_token();     printf("function returning"); }
  /*指针处理函数*/ void deal_with_pointers() {     while (stack[top].type == '*') {         printf("%s", pop.string);     } }
  /*声明处理函数*/ void deal_with_declarator() {     /*处理标识符之后可能存在的数组和函数*/     switch (this.type) {     case '['    :deal_with_arrays(); break;     case '('    :deal_with_function_args();     }     deal_with_pointers();     /*处理在读入到标识符之前压入堆栈中的符号*/     while (top >= 0) {         if (stack[top].type == '(') {             pop;             get_token();             deal_with_declarator();         } else {             printf("%s ", pop.string);         }     } }
  int main() {     /*将标记压入栈中,直到遇见标识符*/     read_to_first_identifer();     deal_with_declarator();     printf("\n");     return 0; } 
 |