#include #include "utils.h" #define MAXTOKEN 100 enum { NAME, PARENS, BRACKETS }; void dcl(void); void dirdcl(void); int gettoken(void); int istype(char *s); int tokentype; char token[MAXTOKEN]; char name[MAXTOKEN][MAXTOKEN]; char out[1000]; int error; int namei; int main() { int i; char datatype[MAXTOKEN][MAXTOKEN]; while (gettoken() != EOF) { for (i = 0; istype(token); i++) { strcpy(datatype[i], token); gettoken(); } strcpy(datatype[i], "\0"); out[0] = '\0'; error = 0; namei = 0; dcl(); if (tokentype != '\n' || error) { printf("syntax error\n\n"); while (tokentype != '\n') gettoken(); } printf("%s: %s", name[0], out); for (i = 0; strcom(datatype[i], "\0"); i++) printf(" %s", datatype[i]); printf("\n\n"); } return 0; } /* main() */ void dcl(void) { int ns; for (ns = 0; tokentype == '*'; gettoken()) ns++; dirdcl(); while (ns-- > 0) strcat(out, " pointer to"); } /* dcl() */ void dirdcl(void) { int i; char datatype[MAXTOKEN][MAXTOKEN]; if (tokentype == '(') { gettoken(); dcl(); if (tokentype != ')') { printf("error: missing )\n"); error = 1; return; } gettoken(); } else if (tokentype == NAME) { strcpy(name[namei++], token); if (namei == MAXTOKEN) { printf("error: too many names\n"); error = 1; return; } gettoken(); } else { printf("error: expected name or (dcl)\n"); error = 1; return; } while (tokentype == PARENS || tokentype == BRACKETS || tokentype == '(') { if (tokentype == PARENS) { strcat(out, " function returning"); } else if (tokentype == BRACKETS) { strcat(out, " array"); strcat(out, token); strcat(out, " of"); } else { /* we got ourselves some ARGUMENTS! */ gettoken(); strcat(out, " function taking"); for (i = 0; istype(token); i++) { strcpy(datatype[i], token); gettoken(); } strcpy(datatype[i], "\0"); dcl(); for (i = 0; strcom(datatype[i], "\0"); i++) { strcat(out, " "); strcat(out, datatype[i]); } while (tokentype == ',') { gettoken(); strcat(out, " and taking"); for (i = 0; istype(token); i++) { strcpy(datatype[i], token); gettoken(); } strcpy(datatype[i], "\0"); dcl(); for (i = 0; strcom(datatype[i], "\0"); i++) { strcat(out, " "); strcat(out, datatype[i]); } } if (tokentype != ')') { printf("error: expected ) not present\n"); printf("K&R ATE MY BALLS!\n"); error = 1; return; } strcat(out, " and returning"); } gettoken(); } } /* dirdcl() */ int gettoken(void) { int c; char *p = token; while ((c = getch()) == ' ' || c == '\t'); if (c == '(') { while ((c = getch()) == ' '); /* skip spaces */ if (c == ')') { strcpy(token, "()"); return tokentype = PARENS; } else { ungetch(c); strcpy(token, "("); 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 { sprintf(token, "%c", c); return tokentype = c; } } /* gettoken() */ /* makes sure s is a type-qualifier or type-specifier */ int istype(char *s) { int i; /* valid type specifiers */ const char *types[] = { "char", "int", "float", "double", "long", "struct", "const", "register", "auto", "short", "union", "static", "volatile", "signed", "unsigned", "extern", "void", "EOF" }; for (i = 0; strcom((char *)types[i], "EOF"); i++) { if (!strcom((char *)types[i], s)) return 1; } return 0; } /* istype() */