5 WSKAŹNIKI I TABLICE
int gettoken (void); int tokentype; char token[MAXTOKEN]; char name[MAXTOKEN]; char datatype[MAXTOKEN]; char out[1000];
/* typ ostatniego leksemu */
/* tekst ostatniego leksemu */
I* nazwa występująca w deklaracji */ /* typ danych: char, int itp. */
/* wyjściowy opis słowny */
main() /*dcl: zamień deklaracje C na opis słowny */
while (gettoken () != EOF) { /* pierwszy leksem w wierszu */ strcpy(datatype, token); /* jest typem* danych */ out[0] = ’\0’;
dcl(); /* analiza składniowa reszty wiersza */ if (tokentype != ’\n’)
printffbłąd składniowy\n"); printf(”%s: %s %s\n”, name, out, datatype);
return 0;
Podczas czytania z wejścia funkcja gettoken najpierw pomija odstępy i znaki tabulacji, a potem buduje kolejny leksem; „leksemem” jest tu nazwa, para nawiasów okrągłych, para nawiasów kwadratowych ewentualnie zawierających liczbę, a także każd) inny pojedynczy znak.
int gettoken(void) /* podaj następny leksem */
int c, getch(void);
void ungetch(int);
char *p = token;
while ((c = getch()) == ” || c == ’\t’)
if (c == •(’) (
if ((c = getch()) == ’)■) { strcpy(token,
return tokentype = PARENS;
} else { ungetch(c); return tokentype = ’(’;
}
12 SKOMPLIKOWANE DEKLARACJE___
powered by
Mi siol
} else if (c == '[*) {
for (*p++ = c; (*p-H- = getch()) != ■]■;
*P = ’\0’;
return tokentype = BRACKETS;
} else if (isalpha (c)) {
for (*p-H- = c; isalnum(c = getch());)
*p++ = c;
*P = ’\0’; ungetch(c);
return tokentype = NAME;
} else
return tokentype = c;
Funkcje getch i ungetch omówiliśmy w rozdz. 4.
Działanie odwrotne jest łatwiejsze, zwłaszcza jeśli nie przejmujemy się nadmiarowymi nawiasami. Program undcl zamienia opis słowny deklaracji, powiedzmy „X jest funkcją zwracającą wskaźnik do tablicy wskaźników do funkcji zwracających char”, co możemy wyrazić tak:
x() * [] * () char
na deklarację w języku C
char (*(*x ())[])()
Skrócona składnia danych na wejściu pozwala nam ponownie skorzystać z funkcji gettoken. Program undcl używa więc tych samych zmiennych zewnętrznych co dcl.
I* undcl: zamień opis słowny na deklarację */ main()
{
int type;
char temp[MAXTOKEN];
while (gettoken() != EOF) { strcpyfout, token); while ((type = gettoken()) 1= ’\n’)
if (type == PARENS 11 type == BRACKETS) strcat(out, token); else if (type == ’*’) {
sprintf(temp, "(*%s)", out); strcpy(out, temp);
171