aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsinanmohd <sinan@firemail.cc>2023-04-22 17:46:20 +0530
committersinanmohd <sinan@firemail.cc>2023-04-23 21:30:25 +0530
commit2f3d854c1226108907651a8fcf9228767eee9742 (patch)
treea5ba21f54083291fcc2fb57b5ff676d94883afee
parentc14dab7f3a1cf72619fadce9b81b55426dc0b32e (diff)
5.20: initial commit
-rw-r--r--5.20/Makefile13
-rw-r--r--5.20/dcl.c72
-rw-r--r--5.20/dcl.h9
-rw-r--r--5.20/err.c16
-rw-r--r--5.20/err.h2
-rw-r--r--5.20/getch.c22
-rw-r--r--5.20/getch.h2
-rw-r--r--5.20/main.c33
-rw-r--r--5.20/token.c117
-rw-r--r--5.20/token.h17
10 files changed, 303 insertions, 0 deletions
diff --git a/5.20/Makefile b/5.20/Makefile
new file mode 100644
index 0000000..dec76b9
--- /dev/null
+++ b/5.20/Makefile
@@ -0,0 +1,13 @@
+objects = main.o token.o getch.o err.o dcl.o
+
+dcl : $(objects)
+ cc -o dcl $(objects)
+
+main.o token.o : getch.h
+main.o : dcl.h
+dcl.o err.o main.o : token.h
+getch.o dcl.o : err.h
+
+.PHONY : clean
+clean :
+ rm dcl $(objects)
diff --git a/5.20/dcl.c b/5.20/dcl.c
new file mode 100644
index 0000000..e504919
--- /dev/null
+++ b/5.20/dcl.c
@@ -0,0 +1,72 @@
+#include <stdio.h>
+#include <string.h>
+#include "token.h"
+#include "err.h"
+#include "dcl.h"
+
+char out[OUTLEN];
+char name[MAXTOKEN];
+
+void dcl(void)
+{
+ int ns;
+
+ for (ns = 0; gettoken() == '*';)
+ ns++;
+ dirdcl();
+ while (ns-- > 0)
+ strncat(out, " pointer to", OUTLEN - 1);
+}
+
+void dirdcl(void)
+{
+ int type;
+
+ if (tokentype == '(') {
+ dcl();
+ if (tokentype != ')')
+ warn("missing )");
+ } else if (tokentype == ')' || tokentype == ',') {
+ prevtoken = YES;
+ } else if (tokentype == NAME) {
+ strcpy(name, token);
+ } else {
+ warn("expected () or name or (dcl)");
+ }
+
+ while ((type = gettoken()) == PARENS || type == BRACKETS ||
+ type == '(' || type == ',') {
+ if (type == PARENS) {
+ strncat(out, " function returning", OUTLEN - 1);
+ } else if (type == '(') {
+ strncat(out, " function expecting", OUTLEN - 1);
+ parmdcl();
+ strncat(out, " and returning", OUTLEN - 1);
+ } else if (type == ',') {
+ parmdcl();
+ strncat(out, ",", OUTLEN - 1);
+ } else {
+ strncat(out, " array", OUTLEN - 1);
+ strncat(out, token, OUTLEN - 1);
+ strncat(out, " of", OUTLEN - 1);
+ }
+ }
+
+ if (tokentype == '\n')
+ prevtoken = YES;
+}
+
+void parmdcl(void)
+{
+ char parmdt[MAXTOKEN];
+ parmdt[0] = '\0';
+
+ while (gettoken() == NAME && isdatatyp()) {
+ strncat(parmdt, " ", MAXTOKEN - 1);
+ strncat(parmdt, token, MAXTOKEN - 1);
+ }
+
+ prevtoken = YES;
+ dcl();
+ strncat(out, parmdt, OUTLEN - 1);
+}
diff --git a/5.20/dcl.h b/5.20/dcl.h
new file mode 100644
index 0000000..697cf76
--- /dev/null
+++ b/5.20/dcl.h
@@ -0,0 +1,9 @@
+#define OUTLEN 1000
+#define MAXTOKEN 100
+
+void dcl(void);
+void dirdcl(void);
+void parmdcl(void);
+
+extern char out[OUTLEN];
+extern char name[MAXTOKEN];
diff --git a/5.20/err.c b/5.20/err.c
new file mode 100644
index 0000000..005fdad
--- /dev/null
+++ b/5.20/err.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "err.h"
+#include "token.h"
+
+void err(char *s)
+{
+ printf("eror: %s\n", s);
+ exit(1);
+}
+
+void warn(char *s)
+{
+ printf("warn: %s\n", s);
+ prevtoken = YES;
+}
diff --git a/5.20/err.h b/5.20/err.h
new file mode 100644
index 0000000..72dee29
--- /dev/null
+++ b/5.20/err.h
@@ -0,0 +1,2 @@
+void err(char *s);
+void warn(char *s);
diff --git a/5.20/getch.c b/5.20/getch.c
new file mode 100644
index 0000000..e41671e
--- /dev/null
+++ b/5.20/getch.c
@@ -0,0 +1,22 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include "err.h"
+#include "getch.h"
+
+#define MAXBUFF 100
+
+char buff[MAXBUFF];
+static size_t top;
+
+void ungetch(char c)
+{
+ if (top < MAXBUFF)
+ buff[top++] = c;
+ else
+ err("buff: stack overflow");
+}
+
+char getch(void)
+{
+ return (top > 0) ? buff[--top] : getchar();
+}
diff --git a/5.20/getch.h b/5.20/getch.h
new file mode 100644
index 0000000..cbfe8ad
--- /dev/null
+++ b/5.20/getch.h
@@ -0,0 +1,2 @@
+void ungetch(char c);
+char getch(void);
diff --git a/5.20/main.c b/5.20/main.c
new file mode 100644
index 0000000..6338524
--- /dev/null
+++ b/5.20/main.c
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <string.h>
+#include "token.h"
+#include "getch.h"
+#include "dcl.h"
+
+char datatype[MAXTOKEN];
+
+int main(void)
+{
+ while (gettoken() != EOF) {
+ if (tokentype == '\n') /* skip empty lines */
+ continue;
+
+ datatype[0] = '\0';
+ do {
+ strcat(datatype, token);
+ strcat(datatype, " ");
+ } while (gettoken() == NAME && isdatatyp());
+ prevtoken = YES;
+
+ if (tokentype == EOF)
+ break;
+
+ out[0] = '\0';
+ dcl();
+ if (tokentype != '\n')
+ printf("synatx error\n");
+ printf("%s: %s %s\n", name, out, datatype);
+ }
+
+ return 0;
+}
diff --git a/5.20/token.c b/5.20/token.c
new file mode 100644
index 0000000..0a69b09
--- /dev/null
+++ b/5.20/token.c
@@ -0,0 +1,117 @@
+#include <string.h>
+#include <ctype.h>
+#include "getch.h"
+#include "token.h"
+#include "err.h"
+
+#define ARR_SIZE(X) sizeof(X)/sizeof(X[0])
+
+char tokentype;
+char token[MAXTOKEN];
+char prevtoken;
+
+char *typqual[] = {
+ "const",
+ "volatile"
+};
+
+char *storspec[] = {
+ "auto",
+ "extern",
+ "register",
+ "static"
+};
+
+char *datatyp[] = {
+ "char",
+ "int",
+ "long",
+ "short",
+ "signed",
+ "unsigned",
+ "void"
+};
+
+
+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;
+ }
+}
+
+int peaktoken()
+{
+ char type;
+
+ if (prevtoken == YES)
+ err("prevtoken overflow");
+ type = gettoken();
+ prevtoken = YES;
+ return type;
+}
+
+int isdatatyp(void)
+{
+ int i, len;
+
+ for (i = 0, len = ARR_SIZE(typqual); i < len; ++i)
+ if(!strcmp(token, typqual[i]))
+ return 1;
+
+ for (i = 0, len = ARR_SIZE(storspec); i < len; ++i)
+ if(!strcmp(token, storspec[i]))
+ return 1;
+
+ for (i = 0, len = ARR_SIZE(datatyp); i < len; ++i)
+ if(!strcmp(token, datatyp[i]))
+ return 1;
+
+ return 0;
+}
diff --git a/5.20/token.h b/5.20/token.h
new file mode 100644
index 0000000..327b1e7
--- /dev/null
+++ b/5.20/token.h
@@ -0,0 +1,17 @@
+#ifndef TOKEN_H
+
+#define MAXTOKEN 100
+
+enum { NAME, PARENS, BRACKETS };
+enum { NO, YES };
+
+int gettoken(void);
+int peaktoken(void);
+int isdatatyp(void);
+
+extern char tokentype;
+extern char token[MAXTOKEN];
+extern char prevtoken;
+
+#define TOKEN_H
+#endif