Skip to content

Commit 25db0c4

Browse files
committed
chapter 5
1 parent bb46084 commit 25db0c4

File tree

4 files changed

+335
-0
lines changed

4 files changed

+335
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <ctype.h>
4+
5+
#define MAXTOKEN 100
6+
7+
enum { NAME, PARENS, BRACKETS };
8+
9+
void dcl(void);
10+
void dirdcl(void);
11+
12+
int gettoken(void);
13+
int tokentype; // type of last token
14+
char token[MAXTOKEN]; // last token string
15+
char name[MAXTOKEN]; // identifier name
16+
char datatype[MAXTOKEN]; // data type = char, int, etc.
17+
char out[1000]; // output string
18+
19+
// gcc 42.dcl.c getch.c
20+
main()
21+
{
22+
while (gettoken() != EOF) { // 1st token on line
23+
strcpy(datatype, token);
24+
out[0] = '\0';
25+
dcl();
26+
if (tokentype != '\n')
27+
printf("syntax error\n");
28+
printf("%s: %s %s\n", name, out, datatype);
29+
}
30+
31+
return 0;
32+
}
33+
34+
void dcl(void)
35+
{
36+
int ns;
37+
38+
for (ns = 0; gettoken() == '*';)
39+
ns++;
40+
41+
dirdcl();
42+
while (ns-- > 0)
43+
strcat(out, " pointer to");
44+
}
45+
46+
void dirdcl(void)
47+
{
48+
int type;
49+
50+
if (tokentype == '(') {
51+
dcl();
52+
53+
if (tokentype != ')')
54+
printf("error: missing )\n");
55+
} else if (tokentype == NAME)
56+
strcpy(name, token);
57+
else
58+
printf("error: expected name or (dcl)\n");
59+
60+
while ((type = gettoken()) == PARENS || type == BRACKETS)
61+
if (type == PARENS)
62+
strcat(out, " function returning");
63+
else {
64+
strcat(out, " array");
65+
strcat(out, token);
66+
strcat(out, " of");
67+
}
68+
}
69+
70+
int gettoken(void)
71+
{
72+
int c, getch(void);
73+
void ungetch(int);
74+
char *p = token;
75+
76+
while ((c = getch()) == ' ' || c == '\t')
77+
;
78+
79+
if (c == '(') {
80+
if ((c = getch()) == ')') {
81+
strcpy(token, "()");
82+
return tokentype = PARENS;
83+
} else {
84+
ungetch(c);
85+
return tokentype = '(';
86+
}
87+
} else if (c == '[') {
88+
for (*p++ = c; (*p++ = getch()) != ']'; )
89+
;
90+
*p = '\0';
91+
return tokentype = BRACKETS;
92+
} else if (isalpha(c)) {
93+
for (*p++ = c; isalnum(c = getch()); )
94+
*p++ = c;
95+
*p = '\0';
96+
ungetch(c);
97+
return tokentype = NAME;
98+
} else {
99+
return tokentype = c;
100+
}
101+
}
102+
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <ctype.h>
4+
5+
#define MAXTOKEN 100
6+
7+
#define DATATYPE_LEN 6
8+
9+
enum { NAME, PARENS, BRACKETS };
10+
11+
void dcl(void);
12+
void dirdcl(void);
13+
14+
int isvalid_datatype(const char*);
15+
16+
int gettoken(void);
17+
int tokentype; // type of last token
18+
char token[MAXTOKEN]; // last token string
19+
char name[MAXTOKEN]; // identifier name
20+
char datatype[MAXTOKEN]; // data type = char, int, etc.
21+
char out[1000]; // output string
22+
23+
// gcc 43.dcl-error-handle.c getch.c
24+
main()
25+
{
26+
while (gettoken() != EOF) { // 1st token on line
27+
strcpy(datatype, token);
28+
29+
if (tokentype != NAME) {
30+
printf("%c is not a valid datatype\n", tokentype);
31+
continue;
32+
} else if (!isvalid_datatype(datatype)) {
33+
printf("%s is not a valid datatype\n", datatype);
34+
continue;
35+
}
36+
37+
out[0] = '\0';
38+
dcl();
39+
if (tokentype != '\n')
40+
printf("syntax error\n");
41+
printf("%s: %s %s\n", name, out, datatype);
42+
}
43+
44+
return 0;
45+
}
46+
47+
void dcl(void)
48+
{
49+
int ns;
50+
51+
for (ns = 0; gettoken() == '*';)
52+
ns++;
53+
54+
dirdcl();
55+
while (ns-- > 0)
56+
strcat(out, " pointer to");
57+
}
58+
59+
void dirdcl(void)
60+
{
61+
int type;
62+
63+
if (tokentype == '(') {
64+
dcl();
65+
66+
if (tokentype != ')')
67+
printf("error: missing )\n");
68+
} else if (tokentype == NAME)
69+
strcpy(name, token);
70+
else
71+
printf("error: expected name or (dcl)\n");
72+
73+
while ((type = gettoken()) == PARENS || type == BRACKETS)
74+
if (type == PARENS)
75+
strcat(out, " function returning");
76+
else {
77+
strcat(out, " array");
78+
strcat(out, token);
79+
strcat(out, " of");
80+
}
81+
}
82+
83+
int gettoken(void)
84+
{
85+
int c, getch(void);
86+
void ungetch(int);
87+
char *p = token;
88+
89+
while ((c = getch()) == ' ' || c == '\t')
90+
;
91+
92+
if (c == '(') {
93+
if ((c = getch()) == ')') {
94+
strcpy(token, "()");
95+
return tokentype = PARENS;
96+
} else {
97+
ungetch(c);
98+
return tokentype = '(';
99+
}
100+
} else if (c == '[') {
101+
for (*p++ = c; (*p++ = getch()) != ']'; )
102+
;
103+
*p = '\0';
104+
return tokentype = BRACKETS;
105+
} else if (isalpha(c)) {
106+
for (*p++ = c; isalnum(c = getch()); )
107+
*p++ = c;
108+
*p = '\0';
109+
ungetch(c);
110+
return tokentype = NAME;
111+
} else {
112+
return tokentype = c;
113+
}
114+
}
115+
116+
int isvalid_datatype(const char* s)
117+
{
118+
char *datatypes[DATATYPE_LEN] = { "char", "short", "int", "long", "float", "double" };
119+
120+
int len = 0;
121+
while (len < DATATYPE_LEN)
122+
if (strcmp(s, datatypes[len++]) == 0)
123+
return 1;
124+
125+
return 0;
126+
}
127+
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Exercise 5-19. Modify undcl so that it does not add redundant parentheses to declarations.
3+
* undcl: convert word description to declaration
4+
*
5+
* e.g.
6+
* x * int -> int *x
7+
* argv * * char -> char **argv
8+
* daytab * [] int -> int (*daytab)[]
9+
* daytab [] * int -> int *daytab[]
10+
* comp () * void -> void *comp()
11+
* comp * () void -> void (*comp)()
12+
* x () * [] * () char -> char (*(*x())[])()
13+
* x [] * () * [] char -> char (*(*x[])())[]
14+
*/
15+
16+
#include <stdio.h>
17+
#include <string.h>
18+
19+
#define MAXTOKEN 100
20+
21+
enum { NAME, PARENS, BRACKETS };
22+
23+
int gettoken(void);
24+
int tokentype; // type of last token
25+
char token[MAXTOKEN]; // last token string
26+
char out[1000]; // output string
27+
28+
// gcc 44.undcl.c getch.c
29+
// cat 44.undcl.test | ./a.out
30+
main()
31+
{
32+
int type;
33+
char temp[MAXTOKEN];
34+
35+
while (gettoken() != EOF) {
36+
strcpy(out, token);
37+
while ((type = gettoken()) != '\n') {
38+
if (type == PARENS) {
39+
if (out[0] == '*') {
40+
sprintf(temp, "(%s)", out);
41+
strcpy(out, temp);
42+
}
43+
strcat(out, token);
44+
} else if (type == BRACKETS) {
45+
if (out[0] == '*' || strstr(out, "()") != NULL) {
46+
sprintf(temp, "(%s)", out);
47+
strcpy(out, temp);
48+
}
49+
strcat(out, token);
50+
} else if (type == '*') {
51+
sprintf(temp, "*%s", out);
52+
strcpy(out, temp);
53+
} else if (type == NAME) {
54+
sprintf(temp, "%s %s", token, out);
55+
strcpy(out, temp);
56+
} else
57+
printf("invalid input at %s\n", token);
58+
}
59+
60+
printf("%s\n", out);
61+
}
62+
return 0;
63+
}
64+
65+
66+
int gettoken(void)
67+
{
68+
int c, getch(void);
69+
void ungetch(int);
70+
char *p = token;
71+
72+
while ((c = getch()) == ' ' || c == '\t')
73+
;
74+
75+
if (c == '(') {
76+
if ((c = getch()) == ')') {
77+
strcpy(token, "()");
78+
return tokentype = PARENS;
79+
} else {
80+
ungetch(c);
81+
return tokentype = '(';
82+
}
83+
} else if (c == '[') {
84+
for (*p++ = c; (*p++ = getch()) != ']'; )
85+
;
86+
*p = '\0';
87+
return tokentype = BRACKETS;
88+
} else if (isalpha(c)) {
89+
for (*p++ = c; isalnum(c = getch()); )
90+
*p++ = c;
91+
*p = '\0';
92+
ungetch(c);
93+
return tokentype = NAME;
94+
} else {
95+
return tokentype = c;
96+
}
97+
}
98+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
x * int
2+
argv * * char
3+
daytab * [] int
4+
daytab [] * int
5+
comp () * void
6+
comp * () void
7+
x () * [] * () char
8+
x [] * () * [] char

0 commit comments

Comments
 (0)