aboutsummaryrefslogtreecommitdiff
path: root/src/parser.y
diff options
context:
space:
mode:
authorThomas Voss <mail@thomasvoss.com> 2024-09-04 19:10:47 +0200
committerThomas Voss <mail@thomasvoss.com> 2024-09-04 19:10:47 +0200
commit581f61a8ddf535175b03749b215ade43f3fa28c5 (patch)
tree44f0cb985d2a717c257347301ecc3d43d98ecfff /src/parser.y
parentada93069cb5fb292bfb5f3b8a22ba6221e55d7b5 (diff)
Support multiple eqns per table
Diffstat (limited to 'src/parser.y')
-rw-r--r--src/parser.y60
1 files changed, 35 insertions, 25 deletions
diff --git a/src/parser.y b/src/parser.y
index e77af6f..e424068 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -6,10 +6,10 @@
#include "lexer.h"
#include "parser.h"
+#include "wrapper.h"
static ast_t mkunop(int, ast_t);
static ast_t mkbinop(int, ast_t, ast_t);
-static void *xmalloc(size_t);
static void yyerror(const char *);
extern const char *current_file;
@@ -20,8 +20,9 @@ extern const char *current_file;
}
%union {
- char ch;
- ast_t ast;
+ char ch;
+ ast_t ast;
+ asts_t asts;
}
%define parse.error verbose
@@ -33,7 +34,8 @@ extern const char *current_file;
%token NOT AND OR XOR IMPL
%token EQUIV OPAR CPAR EOL
%token<ch> IDENT
-%type<ast> line exp
+%type<ast> expr
+%type<asts> line exprs
%left OR
%left AND
@@ -46,34 +48,51 @@ extern const char *current_file;
input:
%empty
| input line {
- if ($2.eqn != NULL)
+ if ($2.len > 0)
astprocess($2);
}
;
line:
- EOL { $$.eqn = NULL; }
- | exp eol { $$ = $1; }
+ EOL { $$.len = 0; }
+ | exprs eol { $$ = $1; }
;
-eol: EOL | YYEOF;
+exprs:
+ expr {
+ $$.len = 1;
+ $$.cap = 8;
+ $$.buf = xmalloc(sizeof(*$$.buf) * $$.cap);
+ $$.buf[0] = $1;
+ }
+ | exprs '|' expr {
+ $$ = $1;
+ if ($$.len == $$.cap) {
+ $$.cap *= 2;
+ $$.buf = xrealloc($$.buf, sizeof(*$$.buf) * $$.cap);
+ }
+ $$.buf[$$.len++] = $3;
+ }
+ ;
-exp:
+expr:
IDENT {
$$.eqn = xmalloc(sizeof(eqn_t));
$$.eqn->type = IDENT;
$$.eqn->ch = $1;
$$.vars = 1 << (islower($1) ? $1-'a'+26 : $1-'A');
}
- | NOT exp { $$ = mkunop(NOT, $2); }
- | OPAR exp CPAR { $$ = mkunop(OPAR, $2); }
- | exp AND exp { $$ = mkbinop(AND, $1, $3); }
- | exp OR exp { $$ = mkbinop(OR, $1, $3); }
- | exp XOR exp { $$ = mkbinop(XOR, $1, $3); }
- | exp IMPL exp { $$ = mkbinop(IMPL, $1, $3); }
- | exp EQUIV exp { $$ = mkbinop(EQUIV, $1, $3); }
+ | NOT expr { $$ = mkunop(NOT, $2); }
+ | OPAR expr CPAR { $$ = mkunop(OPAR, $2); }
+ | expr AND expr { $$ = mkbinop(AND, $1, $3); }
+ | expr OR expr { $$ = mkbinop(OR, $1, $3); }
+ | expr XOR expr { $$ = mkbinop(XOR, $1, $3); }
+ | expr IMPL expr { $$ = mkbinop(IMPL, $1, $3); }
+ | expr EQUIV expr { $$ = mkbinop(EQUIV, $1, $3); }
;
+eol: EOL | YYEOF;
+
%%
ast_t
@@ -101,15 +120,6 @@ mkbinop(int op, ast_t lhs, ast_t rhs)
return a;
}
-void *
-xmalloc(size_t n)
-{
- void *p = malloc(n);
- if (p == NULL)
- err(1, "malloc");
- return p;
-}
-
void
yyerror(const char *s)
{