bool

simple boolean algebra solver
Log | Files | Refs

commit b30dc248b357b4afd8055d55e704bf2447140d15
Author: thing1 <l.standen@posteo.com>
Date:   Tue, 14 Oct 2025 23:31:14 +0100

init commit

Diffstat:
A.gitignore | 4++++
AMakefile | 17+++++++++++++++++
Abool.l | 10++++++++++
Abool.y | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexpr.c | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aexpr.h | 4++++
Atest.bool | 1+
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)