commit b30dc248b357b4afd8055d55e704bf2447140d15
Author: thing1 <l.standen@posteo.com>
Date: Tue, 14 Oct 2025 23:31:14 +0100
init commit
Diffstat:
7 files changed, 155 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,4 @@
+lex.yy.*
+y.*
+bool
+
diff --git a/Makefile b/Makefile
@@ -0,0 +1,17 @@
+CFLAGS=-ggdb
+LIBS=-lfl
+
+all: expr
+
+lexer: bool.l
+ lex bool.l
+
+parser: bool.y
+ yacc -d bool.y
+
+expr: parser lexer expr.c
+ cc expr.c lex.yy.c y.tab.c -o bool ${LIBS} ${CFLAGS}
+
+clean:
+ rm -rf lex.yy.* y.* bool
+
diff --git a/bool.l b/bool.l
@@ -0,0 +1,10 @@
+%{
+#include "y.tab.h"
+%}
+%%
+
+\t|\n {;}
+[A-Z] { yylval.sym = yytext[0]; return SYMBOL; }
+. { return yytext[0]; }
+
+%%
diff --git a/bool.y b/bool.y
@@ -0,0 +1,57 @@
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include "expr.h"
+
+extern int yylex();
+int yyerror(const char *);
+btree *program;
+char vars[26] = {0};
+
+btree *
+mkbtree(char op, btree *left, btree *right) {
+ btree *bin = malloc(sizeof(btree));
+ bin->op = op;
+ bin->left = left;
+ bin->right = right;
+ return bin;
+}
+
+%}
+
+%union {
+ struct btree *tree;
+ char sym;
+}
+
+%token <sym> SYMBOL
+
+%type <tree> expr
+%type <tree> symbol
+
+%left '+'
+%left '.'
+%left '!'
+%left '(' ')'
+
+%%
+
+prog : expr {program = $1;}
+
+expr : expr '.' expr {$$ = mkbtree('.', $1, $3);}
+ | expr '+' expr {$$ = mkbtree('+', $1, $3);}
+ | '!' expr {$$ = mkbtree('!', $2, NULL);}
+ | '(' expr ')' {$$ = $2;}
+ | symbol
+ ;
+
+symbol : SYMBOL {$$ = mkbtree($1, NULL, NULL); vars[$1 - 65] = $1;}
+ ;
+
+%%
+
+int
+yyerror(const char *s) {
+ fprintf(stderr, "error: %s\n", s);
+ return 1;
+}
diff --git a/expr.c b/expr.c
@@ -0,0 +1,62 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include "expr.h"
+
+extern FILE *yyin;
+extern void yyparse();
+extern btree *program;
+extern char vars[26];
+bool vals[26];
+
+void
+flush() {
+ while (getchar() != '\n') ;
+}
+
+bool
+eval(btree *p) {
+ bool l, r;
+ switch (p->op) {
+ case '.':
+ l = eval(p->left);
+ r = eval(p->right);
+ return l && r;
+ case '+':
+ l = eval(p->left);
+ r = eval(p->right);
+ return l || r;
+ case '!':
+ l = eval(p->left);
+ return !l;
+ default:
+ return vals[p->op - 65];
+ }
+}
+
+int
+main(int argc, char **argv) {
+ yyin = stdin;
+ if (argc > 1)
+ yyin = fopen(argv[1], "r");
+ if (!yyin) {
+ fprintf(stderr, "failed to open file, using stdin\n");
+ yyin = stdin;
+ }
+
+ yyparse();
+
+ for (int i = 0; i < 26; i++) {
+ if (vars[i]) {
+ printf("%c = ", vars[i]);
+ scanf("%d", &vals[i]);
+ flush();
+ }
+ }
+
+ bool res = eval(program);
+
+ printf("res = %s\n", (res) ? "true" : "false");
+
+ fclose(yyin);
+ return 0;
+}
diff --git a/expr.h b/expr.h
@@ -0,0 +1,4 @@
+typedef struct btree {
+ char op;
+ struct btree *left, *right;
+} btree;
diff --git a/test.bool b/test.bool
@@ -0,0 +1 @@
+!(A.B+C)