commit c6cc2ba557076fd1385da67a6381e3a427a2124b
Author: thing1 <thing1@seacrossedlovers.xyz>
Date: Wed, 19 Nov 2025 21:38:32 +0000
init commit
Diffstat:
| A | .gitignore | | | 2 | ++ |
| A | Makefile | | | 12 | ++++++++++++ |
| A | lexer.c | | | 62 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | lexer.h | | | 29 | +++++++++++++++++++++++++++++ |
| A | note.md | | | 99 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | spl.c | | | 68 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 272 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+*.o
+spl
diff --git a/Makefile b/Makefile
@@ -0,0 +1,12 @@
+CFLAGS=-ggdb
+
+SRC = spl.c lexer.c
+OBJ = ${SRC:.c=.o}
+EXEC = spl
+
+${EXEC}: ${OBJ}
+
+${OBJ}: ${SRC}
+
+clean:
+ rm -rf ${OBJ} ${EXEC}
diff --git a/lexer.c b/lexer.c
@@ -0,0 +1,62 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "lexer.h"
+
+void
+lexErr(lex *l) {
+ fprintf(stderr, "unexpected token '%c'\n", *l->ptr);
+ exit(1);
+}
+
+int
+lexNum(lex *l) {
+ int n = atoi(l->ptr);
+ while (isdigit(*l->ptr))
+ l->ptr++;
+ return n;
+}
+
+tok
+next(lex *l) {
+ tok t = {0};
+ switch (*l->ptr) {
+ case 0:
+ t.op = LEOF;
+ return t;
+
+ case '\n': case ' ': case '\t': case '\v':
+ l->ptr++;
+ return next(l);
+
+ case ADD: case SUB: case MUL: case DIV:
+ t.op = *l->ptr++;
+ return t;
+ }
+ if (isdigit(*l->ptr)) {
+ t.op = INT;
+ t.n = lexNum(l);
+ }
+ else lexErr(l);
+
+ return t;
+}
+
+void
+printTok(tok *t) {
+ switch (t->op) {
+ case INT: printf("INT: %d\n", t->n); break;
+ case LEOF: printf("$\n"); break;
+ case ADD: printf("ADD\n"); break;
+ case SUB: printf("SUB\n"); break;
+ case MUL: printf("MUL\n"); break;
+ case DIV: printf("DIV\n"); break;
+ }
+}
+
+lex
+mklexer(char *input) {
+ lex l = (lex){input, input};
+ return l;
+}
diff --git a/lexer.h b/lexer.h
@@ -0,0 +1,29 @@
+#ifndef __LEXER_H_
+#define __LEXER_H_
+
+enum ops {
+ NOP = 0,
+ INT = -1,
+ ADD = '+',
+ SUB = '-',
+ MUL = '*',
+ DIV = '/',
+ LEOF = '$',
+};
+
+typedef struct tok {
+ short op;
+ int n;
+} tok;
+
+typedef struct lex {
+ char *input, *ptr;
+} lex;
+
+void lexErr(lex *l);
+int lexNum(lex *l);
+tok next(lex *l);
+void printTok(tok *t);
+lex mklexer(char *input);
+
+#endif
diff --git a/note.md b/note.md
@@ -0,0 +1,99 @@
+pivot parser
+============
+
+a parser could work like so
+
+2 + 4 * 3 - 1 = 13
+
+loop through all tokens and find the first token with the lowest presidence
+
+2 + 4 * 3 - 1
+ ^
+
+split the list
+
+2
++
+4 * 3 - 1
+
+repeat
+
+4 * 3
+-
+1
+
+4
+*
+3
+
+assemble the tree
+
+ +
+ / \
+ 2 -
+ / \
+ * 1
+ / \
+ 4 3
+
+2 + ((4 * 3) - 1)
+2 + (12 - 1)
+2 + 11
+13
+
+another example
+
+4 * 2 + (4 - 1) = 11
+
+4 * 2
++
+(4 - 1)
+
+4
+*
+2
+
+ +
+ / \
+ * (4 - 1)
+ / \
+ 4 2
+
+4 - 1
+
+4
+-
+1
+
+ +
+ / \
+ * \
+ / \ \
+ 4 2 \
+ -
+ / \
+ 4 1
+
+(4 * 2) + (4 - 1)
+8 + 3
+11
+
+
+func(a) * (10 - 4)
+
+func(a)
+*
+(10 - 4)
+
+ *
+ / \
+ func(a) \
+ (10 - 4)
+
+ *
+ / \
+ func(a) -
+ / \
+ 10 4
+
+func(a) * (10 - 4)
diff --git a/spl.c b/spl.c
@@ -0,0 +1,68 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "lexer.h"
+
+typedef struct rexpr {
+ char op;
+
+ struct rexpr *expr[2];
+ int n[2];
+} rexpr;
+
+void
+parserErr(const char *msg) {
+ fprintf(stderr, "%s\n", msg);
+ exit(1);
+}
+
+int
+getpres(rexpr r) {
+ switch (r.op) {
+ case INT: return 0;
+
+ case ADD: return 1;
+ case SUB: return 1;
+
+ case MUL: return 2;
+ case DIV: return 2;
+
+ case LEOF: return -1;
+ }
+}
+
+int
+isop(tok t) {
+ return (t.op == ADD || t.op == SUB || t.op == MUL || t.op == DIV);
+}
+
+rexpr *
+parseRexpr(lex *l) {
+ rexpr *e = malloc(sizeof(rexpr)), *e2;
+ tok t1 = next(l), t2 = next(l);
+
+ if (t1.op != INT)
+ parserErr("Expected INT in rexpr");
+ e->n[0] = t1.n;
+ if (isop(t2)) {
+ e->op = t2.op;
+ e2 = parseRexpr(l);
+ if (e2->op == INT) e->n[1] = e2->n[0];
+ else e->expr[1] = e2;
+ }
+ else if (t2.op == LEOF) {
+ e->op = INT;
+ return e;
+ }
+ else
+ parserErr("Unexpected token in rexpr");
+}
+
+int
+main() {
+ lex l = mklexer("5 + 2");
+
+ rexpr *e = parseRexpr(&l);
+
+}