at v5.8-rc2 2.2 kB view raw
1/* Simple expression parser */ 2%{ 3#define YYDEBUG 1 4#include <stdio.h> 5#include "util.h" 6#include "util/debug.h" 7#include <stdlib.h> // strtod() 8#define IN_EXPR_Y 1 9#include "expr.h" 10#include "smt.h" 11#include <string.h> 12 13%} 14 15%define api.pure full 16 17%parse-param { double *final_val } 18%parse-param { struct expr_parse_ctx *ctx } 19%parse-param {void *scanner} 20%lex-param {void* scanner} 21 22%union { 23 double num; 24 char *str; 25} 26 27%token EXPR_PARSE EXPR_OTHER EXPR_ERROR 28%token <num> NUMBER 29%token <str> ID 30%destructor { free ($$); } <str> 31%token MIN MAX IF ELSE SMT_ON 32%left MIN MAX IF 33%left '|' 34%left '^' 35%left '&' 36%left '-' '+' 37%left '*' '/' '%' 38%left NEG NOT 39%type <num> expr if_expr 40 41%{ 42static void expr_error(double *final_val __maybe_unused, 43 struct expr_parse_ctx *ctx __maybe_unused, 44 void *scanner, 45 const char *s) 46{ 47 pr_debug("%s\n", s); 48} 49 50%} 51%% 52 53start: 54EXPR_PARSE all_expr 55| 56EXPR_OTHER all_other 57 58all_other: all_other other 59| 60 61other: ID 62{ 63 expr__add_id(ctx, $1, 0.0); 64} 65| 66MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')' | ',' 67 68 69all_expr: if_expr { *final_val = $1; } 70 ; 71 72if_expr: 73 expr IF expr ELSE expr { $$ = $3 ? $1 : $5; } 74 | expr 75 ; 76 77expr: NUMBER 78 | ID { if (expr__get_id(ctx, $1, &$$)) { 79 pr_debug("%s not found\n", $1); 80 free($1); 81 YYABORT; 82 } 83 free($1); 84 } 85 | expr '|' expr { $$ = (long)$1 | (long)$3; } 86 | expr '&' expr { $$ = (long)$1 & (long)$3; } 87 | expr '^' expr { $$ = (long)$1 ^ (long)$3; } 88 | expr '+' expr { $$ = $1 + $3; } 89 | expr '-' expr { $$ = $1 - $3; } 90 | expr '*' expr { $$ = $1 * $3; } 91 | expr '/' expr { if ($3 == 0) { 92 pr_debug("division by zero\n"); 93 YYABORT; 94 } 95 $$ = $1 / $3; 96 } 97 | expr '%' expr { if ((long)$3 == 0) { 98 pr_debug("division by zero\n"); 99 YYABORT; 100 } 101 $$ = (long)$1 % (long)$3; 102 } 103 | '-' expr %prec NEG { $$ = -$2; } 104 | '(' if_expr ')' { $$ = $2; } 105 | MIN '(' expr ',' expr ')' { $$ = $3 < $5 ? $3 : $5; } 106 | MAX '(' expr ',' expr ')' { $$ = $3 > $5 ? $3 : $5; } 107 | SMT_ON { $$ = smt_on() > 0; } 108 ; 109 110%%