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 13*7db2fd0bSIan Rogers static double __value(YYSTYPE *yylval, char *str, int token) 1426226a97SJiri Olsa { 15*7db2fd0bSIan Rogers double num; 1626226a97SJiri Olsa 1726226a97SJiri Olsa errno = 0; 18*7db2fd0bSIan 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 26*7db2fd0bSIan 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 31*7db2fd0bSIan 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) { 4426226a97SJiri Olsa if (*str == '@') 4526226a97SJiri Olsa *dst++ = '/'; 4626226a97SJiri Olsa else if (*str == '\\') 4726226a97SJiri Olsa *dst++ = *++str; 481e1a873dSKajol Jain else if (*str == '?') { 491e1a873dSKajol Jain char *paramval; 501e1a873dSKajol Jain int i = 0; 511e1a873dSKajol Jain int size = asprintf(¶mval, "%d", runtime); 521e1a873dSKajol Jain 531e1a873dSKajol Jain if (size < 0) 541e1a873dSKajol Jain *dst++ = '0'; 551e1a873dSKajol Jain else { 561e1a873dSKajol Jain while (i < size) 571e1a873dSKajol Jain *dst++ = paramval[i++]; 581e1a873dSKajol Jain free(paramval); 591e1a873dSKajol Jain } 601e1a873dSKajol Jain } 6126226a97SJiri Olsa else 6226226a97SJiri Olsa *dst++ = *str; 6326226a97SJiri Olsa str++; 6426226a97SJiri Olsa } 6526226a97SJiri Olsa 6626226a97SJiri Olsa *dst = 0x0; 6726226a97SJiri Olsa return ret; 6826226a97SJiri Olsa } 6926226a97SJiri Olsa 701e1a873dSKajol Jain static int str(yyscan_t scanner, int token, int runtime) 7126226a97SJiri Olsa { 7226226a97SJiri Olsa YYSTYPE *yylval = expr_get_lval(scanner); 7326226a97SJiri Olsa char *text = expr_get_text(scanner); 7426226a97SJiri Olsa 751e1a873dSKajol Jain yylval->str = normalize(strdup(text), runtime); 7626226a97SJiri Olsa if (!yylval->str) 7726226a97SJiri Olsa return EXPR_ERROR; 7826226a97SJiri Olsa 791e1a873dSKajol Jain yylval->str = normalize(yylval->str, runtime); 8026226a97SJiri Olsa return token; 8126226a97SJiri Olsa } 8226226a97SJiri Olsa %} 8326226a97SJiri Olsa 84*7db2fd0bSIan Rogers number [0-9]*\.?[0-9]+ 8526226a97SJiri Olsa 8626226a97SJiri Olsa sch [-,=] 8726226a97SJiri Olsa spec \\{sch} 881e1a873dSKajol Jain sym [0-9a-zA-Z_\.:@?]+ 895b3141d0SIan Rogers symbol ({spec}|{sym})+ 9026226a97SJiri Olsa 9126226a97SJiri Olsa %% 92871f9f59SJiri Olsa struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner); 93871f9f59SJiri Olsa 9426226a97SJiri Olsa { 95871f9f59SJiri Olsa int start_token = sctx->start_token; 9626226a97SJiri Olsa 97871f9f59SJiri Olsa if (sctx->start_token) { 98871f9f59SJiri Olsa sctx->start_token = 0; 9926226a97SJiri Olsa return start_token; 10026226a97SJiri Olsa } 10126226a97SJiri Olsa } 10226226a97SJiri Olsa 10326226a97SJiri Olsa max { return MAX; } 10426226a97SJiri Olsa min { return MIN; } 10526226a97SJiri Olsa if { return IF; } 10626226a97SJiri Olsa else { return ELSE; } 10726226a97SJiri Olsa #smt_on { return SMT_ON; } 108*7db2fd0bSIan Rogers {number} { return value(yyscanner); } 1091e1a873dSKajol Jain {symbol} { return str(yyscanner, ID, sctx->runtime); } 11026226a97SJiri Olsa "|" { return '|'; } 11126226a97SJiri Olsa "^" { return '^'; } 11226226a97SJiri Olsa "&" { return '&'; } 11326226a97SJiri Olsa "-" { return '-'; } 11426226a97SJiri Olsa "+" { return '+'; } 11526226a97SJiri Olsa "*" { return '*'; } 11626226a97SJiri Olsa "/" { return '/'; } 11726226a97SJiri Olsa "%" { return '%'; } 11826226a97SJiri Olsa "(" { return '('; } 11926226a97SJiri Olsa ")" { return ')'; } 12026226a97SJiri Olsa "," { return ','; } 12126226a97SJiri Olsa . { } 12226226a97SJiri Olsa %% 12326226a97SJiri Olsa 12426226a97SJiri Olsa int expr_wrap(void *scanner __maybe_unused) 12526226a97SJiri Olsa { 12626226a97SJiri Olsa return 1; 12726226a97SJiri Olsa } 128