Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e704ec7

Browse files
rewrite
Simplified the code and used the revised error recovery approach from 5-18.
1 parent 3c6c063 commit e704ec7

File tree

1 file changed

+79
-78
lines changed

1 file changed

+79
-78
lines changed

‎chapter05/5-19.c

Lines changed: 79 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,125 @@
11
/*
22
* Exercise 5-19. Modify undcl so that it does not add redundant parentheses to
33
* declaration.
4+
*
45
* By Faisal Saadatmand
5-
* */
6+
*/
67

8+
#include <ctype.h>
79
#include <stdio.h>
810
#include <string.h>
9-
#include <ctype.h>
10-
11-
#define MAXTOKEN 100
12-
#define BUFSIZE 100
1311

14-
#define SKIP_BLANKS(c) while (((c) = getch()) == ' ' || (c) == '\t')
12+
#define BUFSIZE 100
13+
#define MAXLEN 1000
14+
#define MAXTOKEN 100
1515

1616
enum { NAME, PARENS, BRACKETS };
17+
enum { GOOD, FAIL };
1718

1819
/* functions */
19-
int gettoken(void);
20-
int getch(void);
21-
void ungetch(int);
20+
void undcl(void);
21+
int gettoken();
2222

2323
/* globals */
24-
char token[MAXTOKEN]; /* last token string */
25-
int tokentype; /* type of last token */
26-
char name[MAXTOKEN]; /* identifier name */
27-
char out[1000];
28-
int buf[BUFSIZE]; /* buffer from ungetch */
29-
int bufp; /* next free position in buf */
30-
int pushedEOF; /* signals EOF has been pushed-back */
31-
32-
/* gettoekn: return next token */
33-
int gettoken(void)
34-
{
35-
int c, getch(void);
36-
void ungetch(int);
37-
char *p = token;
38-
39-
SKIP_BLANKS(c);
40-
41-
if (c == '(') {
42-
SKIP_BLANKS(c); /* allow spaces in parens */
43-
if (c == ')') {
44-
strcpy(token, "()");
45-
return tokentype = PARENS;
46-
} else {
47-
ungetch(c);
48-
return tokentype = '(';
49-
}
50-
} else if (c == '[') {
51-
for (*p++ = c; (*p = getch()) != ']'; p++)
52-
if (*p == '\n') /* error check: missing ']' */
53-
return *p;
54-
*++p = '0円';
55-
return tokentype = BRACKETS;
56-
} else if (isalpha(c)) {
57-
for (*p++ = c; isalnum(c = getch()); p++)
58-
*p = c;
59-
*p = '0円';
60-
ungetch(c);
61-
return tokentype = NAME;
62-
} else
63-
return tokentype = c;
64-
}
24+
int buf[BUFSIZE]; /* buffer from ungetch */
25+
int bufp = 0; /* next free position in buf */
26+
int tokentype; /* type of last token */
27+
char token[MAXTOKEN]; /* last token string */
28+
char name[MAXTOKEN]; /* identifier name */
29+
char datatype[MAXTOKEN]; /* data type = char, int, etc. */
30+
char out[MAXLEN]; /* composed output string */
31+
char state; /* flag to propagate the current state of parsing */
6532

6633
/* getch: get a (possibly pushed back) character */
6734
int getch(void)
6835
{
69-
return (bufp > 0) ? buf[--bufp] : (pushedEOF) ? EOF : getchar();
36+
return (bufp > 0) ? buf[--bufp] : getchar();
7037
}
7138

7239
/* ungerch: push character back on input */
7340
void ungetch(int c)
7441
{
75-
if (c == EOF) {
76-
pushedEOF = 1;
77-
return;
78-
}
79-
8042
if (bufp >= BUFSIZE)
8143
printf("ungetch: too many characters\n");
8244
else
8345
buf[bufp++] = c;
8446
}
8547

48+
/* needsParens: check if the next token is a parenthesis or a bracket */
49+
int needsParens()
50+
{
51+
void ungettokken(int);
52+
int nextType;
53+
54+
nextType = gettoken(); /* peek ahead */
55+
state = FAIL; /* signal token push back */
56+
return nextType == PARENS || nextType == BRACKETS;
57+
}
58+
8659
/* undcl: convert word descriptions to declarations */
8760
void undcl(void)
8861
{
89-
int type, is_dcl, error;
90-
char temp[1100]; /* increased size to avoid potential overflow */
62+
int type;
63+
char temp[MAXTOKEN];
9164

92-
is_dcl = error = 0;
93-
strcpy(out, token);
94-
while ((type = gettoken()) != '\n') {
95-
if (type == PARENS || type == BRACKETS) {
96-
if (is_dcl) { /* check if previous token is the start of dcl */
97-
sprintf(temp, "(%s)", out);
98-
strcpy(out, temp);
99-
is_dcl = 0;
100-
}
65+
while ((type = gettoken()) != '\n')
66+
if (type == PARENS || type == BRACKETS)
10167
strcat(out, token);
102-
} else if (type == '*') {
103-
sprintf(temp, "*%s", out);
68+
else if (type == '*') {
69+
sprintf(temp, needsParens() ? "(*%s)" : "*%s", out);
10470
strcpy(out, temp);
105-
is_dcl = 1;
10671
} else if (type == NAME) {
10772
sprintf(temp, "%s %s", token, out);
10873
strcpy(out, temp);
109-
} else {
74+
} else
11075
printf("invalid input at %s\n", token);
111-
error = 1;
76+
}
77+
78+
/* gettoken: return next token */
79+
int gettoken(void)
80+
{
81+
int c, getch(void);
82+
void ungetch(int);
83+
char *p = token;
84+
85+
if (state == FAIL) {
86+
state = GOOD;
87+
return tokentype; /* push back the previous token */
88+
}
89+
while ((c = getch()) == ' ' || c == '\t')
90+
;
91+
if (c == '(') {
92+
if ((c = getch()) == ')') {
93+
strcpy(token, "()");
94+
return tokentype = PARENS;
11295
}
96+
ungetch(c);
97+
return tokentype = '(';
98+
}
99+
if (c == '[') {
100+
for (*p++ = c; (*p++ = getch()) != ']'; )
101+
;
102+
*p = '0円';
103+
return tokentype = BRACKETS;
113104
}
114-
if (!error)
115-
printf("%s\n", out);
105+
if (isalpha(c)) {
106+
for (*p++ = c; isalnum(c = getch()); )
107+
*p++ = c;
108+
*p = '0円';
109+
ungetch(c);
110+
return tokentype = NAME;
111+
}
112+
return tokentype = c;
116113
}
117114

118-
int main(void)
115+
int main(void)
119116
{
120-
while (gettoken() != EOF)
121-
if (tokentype != '\n') /* skip empty input lines */
122-
undcl();
117+
while (gettoken() != EOF) { /* first token on line */
118+
if (tokentype == '\n') /* skip empty input lines */
119+
continue;
120+
strcpy(out, token); /* is the datatype */
121+
undcl();
122+
printf("%s\n", out);
123+
}
123124
return 0;
124125
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /