用程序来分析C语言声明

用程序来分析C语言声明

用程序来分析C语言声明

直接给出代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<stdlib.h>
#define MAXTOKENS 100
#define MAXTOKENLEN 64
enum type_tag { IDENTIFIER,QUALIFIER,TYPE };
struct token
{
char type;
char string[MAXTOKENLEN];
};
int top = -1;
struct token stack[MAXTOKENS];
struct token current;
#define pop stack[top--]
#define push(s) stack[++top]=s
enum type_tag classify_string(void)
//推断标识符类型
{
char *s = current.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;
}
void gettoken(void)
{
char *p = current.string;
/*略过空白符*/
while ((*p = getchar()) == ' ');
if (isalnum(*p))
{
while (isalnum(*++p = getchar()));
ungetc(*p, stdin);
*p = '\0';
current.type = classify_string();
return;
}
if (*p == '*')
{
strcpy(current.string, "Pointer to ");
current.type = '*';
return;
}
current.string[1] = '\0';
current.type = *p;
return;
}
read_to_first_identifer()
{
gettoken();
while (current.type!=IDENTIFIER)
{
push(current);
gettoken();
}
printf("%s is ", current.string);
gettoken();
}
deal_with_arrays()
{
while (current.type == '[')
{
printf("array ");
gettoken();
if (isdigit(current.string[0]))
{
printf("0 to %d ", atoi(current.string) - 1);
gettoken();
}
gettoken();
printf("of ");
}
}
deal_with_function_args()
{
while (current.type != ')')
{
gettoken();
}
gettoken();
printf("function returning ");
}
deal_with_pointers()
{
while (stack[top].type == '*')
{
printf("%s", pop.string);
}
}
deal_with_declarator()
{
switch (current.type)
{
case '[': deal_with_arrays(); break;
case '(': deal_with_function_args();
}
deal_with_pointers();
/*处理都入到标识符之前压入到堆栈中的符号*/
while (top >= 0)
{
if (stack[top].type == '(')
{
pop;
gettoken();
deal_with_declarator();
}
else
{
printf("%s ", pop.string);
}
}
}
int main()
{
/*将标记压入到堆栈中,直到遇见标识符*/
read_to_first_identifer();
deal_with_declarator();
printf("\n");
return 0;
}

测试输入:int(*func())[]

结果:func is function returning Pointer to array of int