Skip to content

Commit ad0f47a

Browse files
committed
Improved error recovery
1 parent 84cb358 commit ad0f47a

File tree

3 files changed

+57
-46
lines changed

3 files changed

+57
-46
lines changed

README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
These are the answers to the exercises in K&R's The C Programming Language
44
(second Edition).
55

6-
Please note that I am still going through the book, and therefore, will upload
7-
the remaining answers as I complete them. Please let me know if you found a
8-
mistake or a bug.
6+
7+
Please let me know if you found a mistake or a bug.
98

109
Cheers!

chapter05/5-18.c

+25-21
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
#include <string.h>
88
#include <ctype.h>
99

10-
#define MAXTOKEN 100
11-
#define BUFSIZE 100
12-
13-
#define EMPTY_LINE '\n'
10+
#define MAXTOKEN 100
11+
#define BUFSIZE 100
12+
#define EMPTY_LINE (tokentype == '\n')
13+
#define RECOVER while (tokentype != EOF && gettoken() != '\n')
1414
#define SKIP_BLANKS(c) while (((c) = getch()) == ' ' || (c) == '\t')
15-
#define RECOVER while (gettoken() != '\n')
1615

17-
enum { NAME, PARENS, BRACKETS };
16+
enum { NAME, PARENS, BRACKETS, ERROR };
1817

1918
/* functions */
2019
int gettoken(void);
@@ -67,7 +66,7 @@ int gettoken(void)
6766
}
6867

6968
/* getch: get a (possibly pushed back) character */
70-
int getch(void)
69+
int getch(void)
7170
{
7271
return (bufp > 0) ? buf[--bufp] : getchar();
7372
}
@@ -103,21 +102,27 @@ void dirdcl(void)
103102

104103
if (tokentype == '(') { /* ( dcl ) */
105104
dcl ();
106-
if (tokentype != ')')
105+
if (tokentype != ')') {
107106
printf("error: missing )\n");
108-
} else if (tokentype == NAME) /* variable name */
107+
tokentype = ERROR;
108+
}
109+
} else if (tokentype == NAME) { /* variable name */
109110
strcpy(name, token);
110-
else
111+
} else {
111112
printf("error: expected name or (dcl)\n");
113+
tokentype = ERROR;
114+
}
112115

113-
while ((type = gettoken()) == PARENS || type == BRACKETS)
114-
if (type == PARENS)
115-
strcat(out, " function returning");
116-
else {
117-
strcat(out, " array");
118-
strcat(out, token);
119-
strcat(out, " of");
116+
if (tokentype != ERROR) {
117+
while ((type = gettoken()) == PARENS || type == BRACKETS)
118+
if (type == PARENS)
119+
strcat(out, " function returning");
120+
else {
121+
strcat(out, " array");
122+
strcat(out, token);
123+
strcat(out, " of");
120124
}
125+
}
121126
}
122127

123128
/* convert declaration to words */
@@ -126,13 +131,12 @@ int main(void)
126131
while (gettoken() != EOF) { /* last token on line */
127132
strcpy(datatype, token); /* is the datatype */
128133
out[0] = '\0';
129-
if (tokentype == EMPTY_LINE)
134+
if (EMPTY_LINE)
130135
continue; /* skip empty input lines */
131136
dcl();
132-
if (tokentype != '\n') {
137+
if (tokentype != '\n' || tokentype == ERROR)
133138
printf("syntax error\n");
134-
RECOVER;
135-
} else
139+
else
136140
printf("%s: %s %s\n", name, out, datatype);
137141
}
138142
return 0;

chapter05/5-20.c

+30-22
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* paramlist -> paramdecl | paramlist , paramdecl
1212
* paramdecl -> declaration-specifiers dcl
1313
*
14-
* TODO: error checking is still finicky, e.g.: "int f(" will not recover; add
14+
* TODO: error checking is still finicky, e.g.: "int f(char f()" will not recover; add
1515
* type-qualifiers support.
1616
*
1717
* By Faisal Saadatmand
@@ -27,7 +27,7 @@
2727
#define RECOVER while (tokentype != EOF && gettoken() != '\n')
2828
#define SKIP_BLANKS(c) while (((c) = getch()) == ' ' || (c) == '\t')
2929

30-
enum { NAME, PARENS, BRACKETS };
30+
enum { NAME, PARENS, BRACKETS, ERROR };
3131

3232
/* functions */
3333
int gettoken(void);
@@ -119,25 +119,33 @@ void dirdcl(void)
119119

120120
if (tokentype == '(') { /* ( dcl ) */
121121
dcl ();
122-
if (tokentype != ')')
122+
if (tokentype != ')') {
123+
tokentype = ERROR;
123124
printf("error: missing )\n");
124-
} else if (tokentype == NAME) /* variable name */
125+
}
126+
} else if (tokentype == NAME) { /* variable name */
125127
strcpy(name, token);
126-
else
128+
} else {
129+
tokentype = ERROR;
127130
printf("error: expected name or (dcl)\n");
128-
129-
while ((type = gettoken()) == PARENS || type == BRACKETS || type == '(')
130-
if (type == PARENS)
131-
strcat(out, " function returning");
132-
else if (type == '(') {
133-
strcat(out, " function accepts");
134-
paramList();
135-
strcat(out, " returning");
136-
} else {
137-
strcat(out, " array");
138-
strcat(out, token);
139-
strcat(out, " of");
131+
}
132+
133+
if (tokentype != ERROR) {
134+
while ((type = gettoken()) == PARENS || type == BRACKETS || type == '(')
135+
if (type == PARENS)
136+
strcat(out, " function returning");
137+
else if (type == '(') {
138+
strcat(out, " function accepts");
139+
paramList();
140+
strcat(out, " returning");
141+
if (tokentype == ERROR)
142+
break;
143+
} else {
144+
strcat(out, " array");
145+
strcat(out, token);
146+
strcat(out, " of");
140147
}
148+
}
141149
}
142150

143151
void paramdcl(void)
@@ -154,9 +162,10 @@ void paramList(void)
154162
do {
155163
if (gettoken() == '\n') {
156164
printf("error: parameters syntax\n");
165+
tokentype = ERROR;
157166
continue;
158167
}
159-
// gettoken();
168+
160169
if (tokentype == NAME) {
161170
sprintf(paramDataType, " %s", token);
162171
paramdcl();
@@ -166,7 +175,7 @@ void paramList(void)
166175
if (tokentype == ',')
167176
strcat(out, " and" );
168177
}
169-
} while (tokentype != ')');
178+
} while (tokentype != ')' && tokentype != ERROR);
170179
}
171180

172181
/* convert declaration to words */
@@ -178,10 +187,9 @@ int main(void)
178187
if (EMPTY_LINE)
179188
continue; /* skip empty input lines */
180189
dcl();
181-
if (tokentype != '\n') {
190+
if (tokentype != '\n' || tokentype == ERROR)
182191
printf("syntax error\n");
183-
RECOVER;
184-
} else
192+
else
185193
printf("%s: %s %s\n", name, out, datatype);
186194
}
187195
return 0;

0 commit comments

Comments
 (0)