From 3594391322954f6538087b1af480cf00fd8da2c8 Mon Sep 17 00:00:00 2001 From: sinanmohd Date: Sat, 8 Apr 2023 14:46:12 +0530 Subject: 5.18: improved k&r dcl programme 1) skip code comments (// and /**/) 2) skip empty lines 3) don't skip available token if error occurres the programme wont skip new line char anymore by overwrite it, this can cause it to get stuck at line 67 with a call to gettoken() --> getch() and mixing the current line with the next declaration(line) --- 5.18.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 5.18.c diff --git a/5.18.c b/5.18.c new file mode 100644 index 0000000..4e8f13a --- /dev/null +++ b/5.18.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include + +#define MAXTOKEN 100 +#define OUTLEN 1000 +#define MAXBUFF 100 + +enum { NAME, PARENS, BRACKETS }; +enum { NO, YES }; + +void err(char *s); +void errmsg(char *s); + +void dcl(void); +void dirdcl(void); + +int gettoken(void); +int tokentype; +int prevtoken; +char token[MAXTOKEN]; +char name[MAXTOKEN]; +char datatype[MAXTOKEN]; +char out[OUTLEN]; + +char buff[MAXBUFF]; +static size_t top; + +void errmsg(char *s) +{ + printf("err: %s\n", s); + prevtoken = YES; +} + +void err(char *s) +{ + printf("fatal error: %s\n", s); + exit(1); +} + +void dcl(void) +{ + int ns; + + for (ns = 0; gettoken() == '*';) + ns++; + dirdcl(); + while (ns-- > 0) + strcat(out, " pointer to"); +} + +void dirdcl(void) +{ + int type; + + if (tokentype == '(') { + dcl(); + if (tokentype != ')') + errmsg("missing )"); + } else if (tokentype == NAME) { + strcpy(name, token); + } else { + errmsg("expected name or (dcl)"); + } + + while ((type = gettoken()) == PARENS || type == BRACKETS) { + if (type == PARENS) { + strcat(out, " function returning"); + } else { + strcat(out, " array"); + strcat(out, token); + strcat(out, " of"); + } + } +} + +int gettoken(void) +{ + char c, *p = token; + char getch(void); + void ungetch(char); + + if (prevtoken == YES) { + prevtoken = NO; + return tokentype; + } + + while(isblank(c = getch())) + ; + + if (c == '/') { /* ignore comments */ + if ((c = getch()) == '/') { + while ((c = getch()) != '\n') + ; + } else if (c == '*') { + while (getch() != '*' || (c = getch()) != '/') + if (c == '*') + ungetch('*'); + return gettoken(); + } else { + ungetch(c); + c = '/'; + } + } + + if (c == '(') { + if ((c = getch()) == ')') { + strcpy(token, "()"); + return tokentype = PARENS; + } else { + ungetch(c); + return tokentype = '('; + } + } else if (c == '[') { + for (*p++ = '['; (*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 { + return tokentype = c; + } +} + +void ungetch(char c) +{ + if (top < MAXBUFF) + buff[top++] = c; + else + err("stack overflow"); +} + +char getch(void) +{ + return (top > 0) ? buff[--top] : getchar(); +} + +int main(void) +{ + while (gettoken() != EOF) { + if (tokentype == '\n') /* skip empty lines */ + continue; + strcpy(datatype, token); + out[0] = '\0'; + dcl(); + if (tokentype != '\n') + printf("synatx error\n"); + printf("%s: %s %s\n", name, out, datatype); + } + return 0; +} -- cgit v1.2.3