at v5.12 2.5 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 13static double d_ratio(double val0, double val1) 14{ 15 if (val1 == 0) { 16 return 0; 17 } 18 return val0 / val1; 19} 20 21%} 22 23%define api.pure full 24 25%parse-param { double *final_val } 26%parse-param { struct expr_parse_ctx *ctx } 27%parse-param {void *scanner} 28%lex-param {void* scanner} 29 30%union { 31 double num; 32 char *str; 33} 34 35%token EXPR_PARSE EXPR_OTHER EXPR_ERROR 36%token <num> NUMBER 37%token <str> ID 38%destructor { free ($$); } <str> 39%token MIN MAX IF ELSE SMT_ON D_RATIO 40%left MIN MAX IF 41%left '|' 42%left '^' 43%left '&' 44%left '<' '>' 45%left '-' '+' 46%left '*' '/' '%' 47%left NEG NOT 48%type <num> expr if_expr 49 50%{ 51static void expr_error(double *final_val __maybe_unused, 52 struct expr_parse_ctx *ctx __maybe_unused, 53 void *scanner, 54 const char *s) 55{ 56 pr_debug("%s\n", s); 57} 58 59%} 60%% 61 62start: 63EXPR_PARSE all_expr 64| 65EXPR_OTHER all_other 66 67all_other: all_other other 68| 69 70other: ID 71{ 72 expr__add_id(ctx, $1); 73} 74| 75MIN | MAX | IF | ELSE | SMT_ON | NUMBER | '|' | '^' | '&' | '-' | '+' | '*' | '/' | '%' | '(' | ')' | ',' 76| 77'<' | '>' | D_RATIO 78 79all_expr: if_expr { *final_val = $1; } 80 ; 81 82if_expr: 83 expr IF expr ELSE expr { $$ = $3 ? $1 : $5; } 84 | expr 85 ; 86 87expr: NUMBER 88 | ID { 89 struct expr_id_data *data; 90 91 if (expr__resolve_id(ctx, $1, &data)) { 92 free($1); 93 YYABORT; 94 } 95 96 $$ = expr_id_data__value(data); 97 free($1); 98 } 99 | expr '|' expr { $$ = (long)$1 | (long)$3; } 100 | expr '&' expr { $$ = (long)$1 & (long)$3; } 101 | expr '^' expr { $$ = (long)$1 ^ (long)$3; } 102 | expr '<' expr { $$ = $1 < $3; } 103 | expr '>' expr { $$ = $1 > $3; } 104 | expr '+' expr { $$ = $1 + $3; } 105 | expr '-' expr { $$ = $1 - $3; } 106 | expr '*' expr { $$ = $1 * $3; } 107 | expr '/' expr { if ($3 == 0) { 108 pr_debug("division by zero\n"); 109 YYABORT; 110 } 111 $$ = $1 / $3; 112 } 113 | expr '%' expr { if ((long)$3 == 0) { 114 pr_debug("division by zero\n"); 115 YYABORT; 116 } 117 $$ = (long)$1 % (long)$3; 118 } 119 | '-' expr %prec NEG { $$ = -$2; } 120 | '(' if_expr ')' { $$ = $2; } 121 | MIN '(' expr ',' expr ')' { $$ = $3 < $5 ? $3 : $5; } 122 | MAX '(' expr ',' expr ')' { $$ = $3 > $5 ? $3 : $5; } 123 | SMT_ON { $$ = smt_on() > 0; } 124 | D_RATIO '(' expr ',' expr ')' { $$ = d_ratio($3,$5); } 125 ; 126 127%%