aboutsummaryrefslogtreecommitdiff
path: root/5.18.c
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 /5.18.c
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)
Diffstat (limited to '5.18.c')
-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;
+}