diff options
author | sinanmohd <sinan@firemail.cc> | 2023-04-08 14:46:12 +0530 |
---|---|---|
committer | sinanmohd <sinan@firemail.cc> | 2023-04-08 14:46:12 +0530 |
commit | 3594391322954f6538087b1af480cf00fd8da2c8 (patch) | |
tree | 61c89cd18d6c5b80d8652dfd0898d9168f9d9ae9 | |
parent | b81fb4214a8055588048b0fb392a0b2b9157a286 (diff) |
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)
-rw-r--r-- | 5.18.c | 157 |
1 files changed, 157 insertions, 0 deletions
@@ -0,0 +1,157 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> + +#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; +} |