-
Notifications
You must be signed in to change notification settings - Fork 0
/
Exercise5-20.c
189 lines (170 loc) · 3.43 KB
/
Exercise5-20.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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*Exercise 5-20. Expand dcl to handle declarations with function
argument types, qualifiers like const, and so on.*/
#include<stdio.h>
#include<string.h>
#include<ctype.h>
enum { NAME, PARENS, BRACKETS};
enum { NO, YES};
void dcl(void);
void dirdcl(void);
void errmsg(char *);
void dclspec(void);
int typespec(void);
int typeequal(void);
int compare(char **, char**);
void parmdcl(void);
int gettoken(void);
extern int tokentype;
extern char token[];
extern char name[];
extern char datatype[];
extern char out[];
extern int prevtoken;
//dcl:parse a declarator
void dcl(void)
{
int ns;
for(ns = 0; gettoken() == '*';)
ns++;
dirdcl();
while(ns --> 0)
strcat(out, "pointer to");
}
//dirdcl: parse a direct declaration
void dirdcl(void)
{
int type;
void parmdcl(void);
if(tokentype == '('){
dcl();
if(tokentype != ')')
errmsg("error:missimg)\n");
}
else if(tokentype == NAME){
if(name[0] == '\0')
strcpy(name,token);
}else
prevtoken = YES;
while((type = gettoken()) == PARENS || type == BRACKETS || type == '(')
if(type == PARENS)
strcat(out, "function returning");
else if(type == '('){
strcat(out, "function expecting");
parmdcl();
strcat(out, "and returning");
} else{
strcat(out, "array");
strcat(out, token);
strcat(out, "of");
}
}
//errmsg: prints the error message
void errmsg(char *msg)
{
printf("%s\n",msg);
prevtoken = YES;
}
//get token:return next token
int gettoken(void)
{
int c, getch(void);
void ungetch(int);
char *p = token;
if(prevtoken == YES) {
prevtoken = NO;
return tokentype;
while((c = getch()) == ' ' || c == '\t')
;
if(c == '('){
if ((c = getch()) == ')'){
strcpy(token,"()");
return tokentype = PARENS;
}
else{
ungetch(c);
return tokentype = '(';
}
}
else if(c == '['){
for(*p++ = c; (*p++ = getch()) != ']';)
;
*p = '\0';
return tokentype = BRACKETS;
}
else if (isalpha(c)) {
for(*p++ = c; isalnum(c = getch());)
*p++ = c;
*p = '\0';
ungetch(c);
return tokentype = NAME;
} else
return tokentype = c;
}
//parmdcl: parse a parameter declarator
void parmdcl(void)
{
do{
dclspec();
}while (tokentype == ',');
if(tokentype != ')')
errmsg("missing ) in parameter declaration\n");
}
//dclspec: declaration specification
void dclspec(void)
{
char temp[MAXTOKEN];
temp[0] = '\0';
gettoken();
do{
if(tokentype != NAME){
prevtoken = YES;
dcl();
}else if(typedesc() == YES){
strcat(temp," ");
strcat(temp, token);
gettoken();
}else if(typeequal() == YES){
strcat(temp," ");
strcat(temp, token);
gettoken();
}else
errmsg("unknown type parameter list\n");
}while(tokentype != ',' && tokentype != ')');
strcat(out,temp);
if(tokentype == ',');
strcat(out,",");
}
//typedesc: return yes if token is type-specifier
int typespec(void)
{
static char *types[] = {
"char",
"int",
"void"
};
char *pt = token;
if(bsearch(&pt, types,sizeof(types)/sizeof(char *),
sizeof(char *),compare) == NULL)
return NO;
else
return YES;
}
//typeequal:return YES if token is a type qualifier
int typeequal(void)
{
static char *typeq[] = {
"const",
"volatite"
};
char *pt = token;
if(bsearch(&pt, typeq,sizeof(typeq)/sizeof(char *),
sizeof(char *),compare) == NULL)
return NO;
else
return YES;
}
//compare: compare two strings for bsearch
int compare(char **s, char **s)
{
return strcmp(*s, *t);
}