aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--5.19.c144
-rw-r--r--5.19/Makefile12
-rw-r--r--5.19/err.c9
-rw-r--r--5.19/err.h1
-rw-r--r--5.19/getch.c22
-rw-r--r--5.19/getch.h2
-rw-r--r--5.19/main.c46
-rw-r--r--5.19/token.c72
-rw-r--r--5.19/token.h14
9 files changed, 322 insertions, 0 deletions
diff --git a/5.19.c b/5.19.c
new file mode 100644
index 0000000..8709df7
--- /dev/null
+++ b/5.19.c
@@ -0,0 +1,144 @@
+#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);
+
+int gettoken(void);
+int peaktoken(void);
+char tokentype;
+char token[MAXTOKEN];
+char prevtoken;
+char out[OUTLEN];
+
+char buff[MAXBUFF];
+static size_t top;
+
+
+void err(char *s)
+{
+ printf("fatal error: %s\n", s);
+ exit(1);
+}
+
+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("buff: stack overflow");
+}
+
+char getch(void)
+{
+ return (top > 0) ? buff[--top] : getchar();
+}
+
+int peaktoken()
+{
+ char type;
+
+ type = gettoken();
+ prevtoken = YES;
+ return type;
+}
+
+int main(void)
+{
+ int err;
+ char type;
+ char temp[OUTLEN + MAXTOKEN];
+
+ while (gettoken() != EOF) {
+ err = 0;
+ strcpy(out, token);
+ while ((type = gettoken()) != '\n') {
+ if (type == PARENS || type == BRACKETS ) {
+ strcat(out, token);
+ } else if (type == '*') {
+ if ((type = peaktoken()) == PARENS ||
+ type == BRACKETS)
+ sprintf(temp, "(*%s)", out);
+ else
+ sprintf(temp, "*%s", out);
+ strcpy(out, temp);
+ } else if (type == NAME) {
+ sprintf(temp, "%s %s", token, out);
+ out[0] = '\0'; /* rust sisters btfo */
+ strncat(out, temp, OUTLEN - 1);
+ } else {
+ err = 1;
+ printf("err: invalid input at %s\n", token);
+ while ((type = gettoken()) != '\n')
+ ;
+ ungetch('\n');
+ }
+ }
+
+ if (!err)
+ printf("%s\n", out);
+ }
+
+ return 0;
+}
diff --git a/5.19/Makefile b/5.19/Makefile
new file mode 100644
index 0000000..5152fbe
--- /dev/null
+++ b/5.19/Makefile
@@ -0,0 +1,12 @@
+objects = main.o token.o getch.o err.o
+
+undcl : $(objects)
+ cc -o undcl $(objects)
+
+main.o token.o : getch.h
+main.o : token.h
+getch.o : err.h
+
+.PHONY : clean
+clean :
+ rm undcl $(objects)
diff --git a/5.19/err.c b/5.19/err.c
new file mode 100644
index 0000000..0bc092c
--- /dev/null
+++ b/5.19/err.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "err.h"
+
+void err(char *s)
+{
+ printf("fatal error: %s\n", s);
+ exit(1);
+}
diff --git a/5.19/err.h b/5.19/err.h
new file mode 100644
index 0000000..1fa2cfc
--- /dev/null
+++ b/5.19/err.h
@@ -0,0 +1 @@
+void err(char *s);
diff --git a/5.19/getch.c b/5.19/getch.c
new file mode 100644
index 0000000..e41671e
--- /dev/null
+++ b/5.19/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.19/getch.h b/5.19/getch.h
new file mode 100644
index 0000000..cbfe8ad
--- /dev/null
+++ b/5.19/getch.h
@@ -0,0 +1,2 @@
+void ungetch(char c);
+char getch(void);
diff --git a/5.19/main.c b/5.19/main.c
new file mode 100644
index 0000000..3e1d2e9
--- /dev/null
+++ b/5.19/main.c
@@ -0,0 +1,46 @@
+#include <stdio.h>
+#include <string.h>
+#include "token.h"
+#include "getch.h"
+
+#define OUTLEN 1000
+
+char out[OUTLEN];
+
+int main(void)
+{
+ int errstat;
+ char temp[OUTLEN + MAXTOKEN], type;
+
+ while (gettoken() != EOF) {
+ errstat = 0;
+ strcpy(out, token);
+ while ((type = gettoken()) != '\n') {
+ if (type == PARENS || type == BRACKETS ) {
+ strcat(out, token);
+ } else if (type == '*') {
+ if ((type = peaktoken()) == PARENS ||
+ type == BRACKETS)
+ sprintf(temp, "(*%s)", out);
+ else
+ sprintf(temp, "*%s", out);
+ strcpy(out, temp);
+ } else if (type == NAME) {
+ sprintf(temp, "%s %s", token, out);
+ out[0] = '\0'; /* rust sisters btfo */
+ strncat(out, temp, OUTLEN - 1);
+ } else {
+ errstat = 1;
+ printf("err: invalid input at %s\n", token);
+ while ((type = gettoken()) != '\n')
+ ;
+ ungetch('\n');
+ }
+ }
+
+ if (!errstat)
+ printf("%s\n", out);
+ }
+
+ return 0;
+}
diff --git a/5.19/token.c b/5.19/token.c
new file mode 100644
index 0000000..7f4d555
--- /dev/null
+++ b/5.19/token.c
@@ -0,0 +1,72 @@
+#include <string.h>
+#include <ctype.h>
+#include "getch.h"
+#include "token.h"
+
+enum { NO, YES };
+
+char tokentype;
+char token[MAXTOKEN];
+char prevtoken;
+
+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;
+
+ type = gettoken();
+ prevtoken = YES;
+ return type;
+}
diff --git a/5.19/token.h b/5.19/token.h
new file mode 100644
index 0000000..32a910a
--- /dev/null
+++ b/5.19/token.h
@@ -0,0 +1,14 @@
+#ifndef TOKEN_H
+
+#define MAXTOKEN 100
+
+enum { NAME, PARENS, BRACKETS };
+
+int gettoken(void);
+int peaktoken(void);
+
+extern char tokentype;
+extern char token[MAXTOKEN];
+
+#define TOKEN_H
+#endif