aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsinanmohd <sinan@firemail.cc>2023-04-08 14:46:12 +0530
committersinanmohd <sinan@firemail.cc>2023-04-08 14:46:12 +0530
commit3594391322954f6538087b1af480cf00fd8da2c8 (patch)
tree61c89cd18d6c5b80d8652dfd0898d9168f9d9ae9
parentb81fb4214a8055588048b0fb392a0b2b9157a286 (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.c157
1 files changed, 157 insertions, 0 deletions
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 <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;
+}