本程序主要借助两个相互调用的函数dlc()和dir()来读取一个复杂声明中的定义情况(例如:char (*(x[3])())[5] ,对该声明应该是x:array[3] of point to function returning pointer to array[5] of char )。
在使用递归时,应将递归程序最里层要实现的目的为基础将函数写出来(因为递归程序必然每层的功能都一样),再考虑进入递归的条件,放入函数的适当位置。
在编写本程序时遇到枚举函数无法通过编译的情况(/*enum { NAME, PARENS, BRACKETS } ;),如果有看官知晓原因的麻烦指出错误之处,感激不尽!
1 #include<stdio.h> 2 #include<ctype.h> 3 #include<string.h> 4 5 #define MAXTOKEN 100 6 #define NAME 0 7 #define PARENS 1 8 #define BRACKETS 2 9 /*enum { NAME, PARENS, BRACKETS } ;为什么这段声明过不了编译(error C2143: 语法错误 : 缺少“;”(在“}”的前面))*/ 10 11 void dcl(void); 12 void dirdcl(void); 13 14 int gettoken(void); 15 int tokentype; 16 char token[MAXTOKEN]; 17 char name[MAXTOKEN]; 18 char datatype[MAXTOKEN]; 19 char out[1000]; 20 21 22 int main(void) 23 { 24 while(gettoken() != EOF){ 25 strcpy(datatype,token); 26 out[0] = '\0';/*每一行都应该将out清空*/ 27 dcl(); 28 if(tokentype != '\n') 29 printf("synatax error\n"); 30 printf("%s:%s %s",name,out,datatype); 31 } 32 return 0; 33 } 34 35 int gettoken(void) 36 { 37 int getch(void); 38 void ungetch(int); 39 int c; 40 char *p = token; 41 42 while((c = getch()) == ' ' || c == '\t') 43 ; 44 if(c == '('){ 45 if((c = getch()) == ')'){ 46 strcpy(token,"()"); 47 return tokentype = PARENS; /*这里return的用法要注意*/ 48 }else{ 49 ungetch(c); 50 return tokentype = '('; 51 } 52 }else if(c == '['){ 53 for(*p++ = c;(*p++ = getch()) != ']'; ) 54 ; 55 *p = '\0'; 56 return tokentype = BRACKETS; 57 }else if(isalpha(c)){ 58 for(*p++ = c;isalnum(c = getch()); ) 59 *p++ = c; 60 *p = '\0'; 61 ungetch(c);//当不是字母数字之后记得把提前取的字符压回缓冲区 62 return tokentype = NAME; 63 }else 64 return tokentype = c;/*这里的c有可能是'\n'、'EOF'、')'和非法字符*/ 65 } 66 67 #define BUFFSIZE 1000 68 69 int buffer[BUFFSIZE]; 70 int buffp = 0; 71 72 int getch(void) 73 { 74 return (buffp > 0) ? buffer[--buffp] : getchar(); 75 } 76 77 void ungetch(int c) 78 { 79 if (buffp >= BUFFSIZE) 80 printf("ungetch:too many characters\n"); 81 else 82 buffer[buffp++] = c; 83 } 84 85 void dcl(void) 86 { 87 int n; 88 89 for(n = 0;gettoken() == '*'; ) 90 n++; 91 dirdcl(); 92 while(n-- > 0) 93 strcat(out," pointer to");/*由里层逐渐向外层添加*/ 94 } 95 96 void dirdcl(void) 97 { 98 int type; 99 100 if(tokentype == '('){ /*又是另一个dcl*/ 101 dcl(); 102 if(tokentype != ')') 103 printf("error:missing )\n"); 104 }else if(tokentype == NAME) 105 strcpy(name,token); 106 else 107 printf("error:expected name or dcl\n"); 108 while((type = gettoken()) == BRACKETS || type == PARENS) 109 { 110 if(type == PARENS) 111 strcat(out," function returning"); 112 else{ 113 strcat(out," array"); 114 strcat(out,token); 115 strcat(out," of"); 116 } 117 } 118 }