126226a97SJiri Olsa %option prefix="expr_" 226226a97SJiri Olsa %option reentrant 326226a97SJiri Olsa %option bison-bridge 426226a97SJiri Olsa 526226a97SJiri Olsa %{ 626226a97SJiri Olsa #include <linux/compiler.h> 726226a97SJiri Olsa #include "expr.h" 826226a97SJiri Olsa #include "expr-bison.h" 926226a97SJiri Olsa 1026226a97SJiri Olsa char *expr_get_text(yyscan_t yyscanner); 1126226a97SJiri Olsa YYSTYPE *expr_get_lval(yyscan_t yyscanner); 1226226a97SJiri Olsa 137db2fd0bSIan Rogers static double __value(YYSTYPE *yylval, char *str, int token) 1426226a97SJiri Olsa { 157db2fd0bSIan Rogers double num; 1626226a97SJiri Olsa 1726226a97SJiri Olsa errno = 0; 187db2fd0bSIan Rogers num = strtod(str, NULL); 1926226a97SJiri Olsa if (errno) 2026226a97SJiri Olsa return EXPR_ERROR; 2126226a97SJiri Olsa 2226226a97SJiri Olsa yylval->num = num; 2326226a97SJiri Olsa return token; 2426226a97SJiri Olsa } 2526226a97SJiri Olsa 267db2fd0bSIan Rogers static int value(yyscan_t scanner) 2726226a97SJiri Olsa { 2826226a97SJiri Olsa YYSTYPE *yylval = expr_get_lval(scanner); 2926226a97SJiri Olsa char *text = expr_get_text(scanner); 3026226a97SJiri Olsa 317db2fd0bSIan Rogers return __value(yylval, text, NUMBER); 3226226a97SJiri Olsa } 3326226a97SJiri Olsa 3426226a97SJiri Olsa /* 3526226a97SJiri Olsa * Allow @ instead of / to be able to specify pmu/event/ without 3626226a97SJiri Olsa * conflicts with normal division. 3726226a97SJiri Olsa */ 381e1a873dSKajol Jain static char *normalize(char *str, int runtime) 3926226a97SJiri Olsa { 4026226a97SJiri Olsa char *ret = str; 4126226a97SJiri Olsa char *dst = str; 4226226a97SJiri Olsa 4326226a97SJiri Olsa while (*str) { 44*ec5c5b3dSIan Rogers if (*str == '\\') 4526226a97SJiri Olsa *dst++ = *++str; 461e1a873dSKajol Jain else if (*str == '?') { 471e1a873dSKajol Jain char *paramval; 481e1a873dSKajol Jain int i = 0; 491e1a873dSKajol Jain int size = asprintf(¶mval, "%d", runtime); 501e1a873dSKajol Jain 511e1a873dSKajol Jain if (size < 0) 521e1a873dSKajol Jain *dst++ = '0'; 531e1a873dSKajol Jain else { 541e1a873dSKajol Jain while (i < size) 551e1a873dSKajol Jain *dst++ = paramval[i++]; 561e1a873dSKajol Jain free(paramval); 571e1a873dSKajol Jain } 581e1a873dSKajol Jain } 5926226a97SJiri Olsa else 6026226a97SJiri Olsa *dst++ = *str; 6126226a97SJiri Olsa str++; 6226226a97SJiri Olsa } 6326226a97SJiri Olsa 6426226a97SJiri Olsa *dst = 0x0; 6526226a97SJiri Olsa return ret; 6626226a97SJiri Olsa } 6726226a97SJiri Olsa 681e1a873dSKajol Jain static int str(yyscan_t scanner, int token, int runtime) 6926226a97SJiri Olsa { 7026226a97SJiri Olsa YYSTYPE *yylval = expr_get_lval(scanner); 7126226a97SJiri Olsa char *text = expr_get_text(scanner); 7226226a97SJiri Olsa 731e1a873dSKajol Jain yylval->str = normalize(strdup(text), runtime); 7426226a97SJiri Olsa if (!yylval->str) 7526226a97SJiri Olsa return EXPR_ERROR; 7626226a97SJiri Olsa 771e1a873dSKajol Jain yylval->str = normalize(yylval->str, runtime); 7826226a97SJiri Olsa return token; 7926226a97SJiri Olsa } 8026226a97SJiri Olsa %} 8126226a97SJiri Olsa 82a45badc7SIan Rogers number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+) 8326226a97SJiri Olsa 8426226a97SJiri Olsa sch [-,=] 8526226a97SJiri Olsa spec \\{sch} 861e1a873dSKajol Jain sym [0-9a-zA-Z_\.:@?]+ 875b3141d0SIan Rogers symbol ({spec}|{sym})+ 8826226a97SJiri Olsa 8926226a97SJiri Olsa %% 90871f9f59SJiri Olsa struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner); 91871f9f59SJiri Olsa 923e21a28aSIan Rogers d_ratio { return D_RATIO; } 9326226a97SJiri Olsa max { return MAX; } 9426226a97SJiri Olsa min { return MIN; } 9526226a97SJiri Olsa if { return IF; } 9626226a97SJiri Olsa else { return ELSE; } 9726226a97SJiri Olsa #smt_on { return SMT_ON; } 987db2fd0bSIan Rogers {number} { return value(yyscanner); } 991e1a873dSKajol Jain {symbol} { return str(yyscanner, ID, sctx->runtime); } 10026226a97SJiri Olsa "|" { return '|'; } 10126226a97SJiri Olsa "^" { return '^'; } 10226226a97SJiri Olsa "&" { return '&'; } 103ff1a12f9SIan Rogers "<" { return '<'; } 104ff1a12f9SIan Rogers ">" { return '>'; } 10526226a97SJiri Olsa "-" { return '-'; } 10626226a97SJiri Olsa "+" { return '+'; } 10726226a97SJiri Olsa "*" { return '*'; } 10826226a97SJiri Olsa "/" { return '/'; } 10926226a97SJiri Olsa "%" { return '%'; } 11026226a97SJiri Olsa "(" { return '('; } 11126226a97SJiri Olsa ")" { return ')'; } 11226226a97SJiri Olsa "," { return ','; } 11326226a97SJiri Olsa . { } 11426226a97SJiri Olsa %% 11526226a97SJiri Olsa 11626226a97SJiri Olsa int expr_wrap(void *scanner __maybe_unused) 11726226a97SJiri Olsa { 11826226a97SJiri Olsa return 1; 11926226a97SJiri Olsa } 120