18c2ecf20Sopenharmony_ci%option prefix="expr_" 28c2ecf20Sopenharmony_ci%option reentrant 38c2ecf20Sopenharmony_ci%option bison-bridge 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci%{ 68c2ecf20Sopenharmony_ci#include <linux/compiler.h> 78c2ecf20Sopenharmony_ci#include "expr.h" 88c2ecf20Sopenharmony_ci#include "expr-bison.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_cichar *expr_get_text(yyscan_t yyscanner); 118c2ecf20Sopenharmony_ciYYSTYPE *expr_get_lval(yyscan_t yyscanner); 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_cistatic double __value(YYSTYPE *yylval, char *str, int token) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci double num; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci errno = 0; 188c2ecf20Sopenharmony_ci num = strtod(str, NULL); 198c2ecf20Sopenharmony_ci if (errno) 208c2ecf20Sopenharmony_ci return EXPR_ERROR; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci yylval->num = num; 238c2ecf20Sopenharmony_ci return token; 248c2ecf20Sopenharmony_ci} 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_cistatic int value(yyscan_t scanner) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci YYSTYPE *yylval = expr_get_lval(scanner); 298c2ecf20Sopenharmony_ci char *text = expr_get_text(scanner); 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci return __value(yylval, text, NUMBER); 328c2ecf20Sopenharmony_ci} 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci/* 358c2ecf20Sopenharmony_ci * Allow @ instead of / to be able to specify pmu/event/ without 368c2ecf20Sopenharmony_ci * conflicts with normal division. 378c2ecf20Sopenharmony_ci */ 388c2ecf20Sopenharmony_cistatic char *normalize(char *str, int runtime) 398c2ecf20Sopenharmony_ci{ 408c2ecf20Sopenharmony_ci char *ret = str; 418c2ecf20Sopenharmony_ci char *dst = str; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci while (*str) { 448c2ecf20Sopenharmony_ci if (*str == '@') 458c2ecf20Sopenharmony_ci *dst++ = '/'; 468c2ecf20Sopenharmony_ci else if (*str == '\\') 478c2ecf20Sopenharmony_ci *dst++ = *++str; 488c2ecf20Sopenharmony_ci else if (*str == '?') { 498c2ecf20Sopenharmony_ci char *paramval; 508c2ecf20Sopenharmony_ci int i = 0; 518c2ecf20Sopenharmony_ci int size = asprintf(¶mval, "%d", runtime); 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci if (size < 0) 548c2ecf20Sopenharmony_ci *dst++ = '0'; 558c2ecf20Sopenharmony_ci else { 568c2ecf20Sopenharmony_ci while (i < size) 578c2ecf20Sopenharmony_ci *dst++ = paramval[i++]; 588c2ecf20Sopenharmony_ci free(paramval); 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci } 618c2ecf20Sopenharmony_ci else 628c2ecf20Sopenharmony_ci *dst++ = *str; 638c2ecf20Sopenharmony_ci str++; 648c2ecf20Sopenharmony_ci } 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci *dst = 0x0; 678c2ecf20Sopenharmony_ci return ret; 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic int str(yyscan_t scanner, int token, int runtime) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci YYSTYPE *yylval = expr_get_lval(scanner); 738c2ecf20Sopenharmony_ci char *text = expr_get_text(scanner); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci yylval->str = normalize(strdup(text), runtime); 768c2ecf20Sopenharmony_ci if (!yylval->str) 778c2ecf20Sopenharmony_ci return EXPR_ERROR; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci yylval->str = normalize(yylval->str, runtime); 808c2ecf20Sopenharmony_ci return token; 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci%} 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_cinumber ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+) 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cisch [-,=] 878c2ecf20Sopenharmony_cispec \\{sch} 888c2ecf20Sopenharmony_cisym [0-9a-zA-Z_\.:@?]+ 898c2ecf20Sopenharmony_cisymbol ({spec}|{sym})+ 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci%% 928c2ecf20Sopenharmony_ci struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci { 958c2ecf20Sopenharmony_ci int start_token = sctx->start_token; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci if (sctx->start_token) { 988c2ecf20Sopenharmony_ci sctx->start_token = 0; 998c2ecf20Sopenharmony_ci return start_token; 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci } 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cid_ratio { return D_RATIO; } 1048c2ecf20Sopenharmony_cimax { return MAX; } 1058c2ecf20Sopenharmony_cimin { return MIN; } 1068c2ecf20Sopenharmony_ciif { return IF; } 1078c2ecf20Sopenharmony_cielse { return ELSE; } 1088c2ecf20Sopenharmony_ci#smt_on { return SMT_ON; } 1098c2ecf20Sopenharmony_ci{number} { return value(yyscanner); } 1108c2ecf20Sopenharmony_ci{symbol} { return str(yyscanner, ID, sctx->runtime); } 1118c2ecf20Sopenharmony_ci"|" { return '|'; } 1128c2ecf20Sopenharmony_ci"^" { return '^'; } 1138c2ecf20Sopenharmony_ci"&" { return '&'; } 1148c2ecf20Sopenharmony_ci"<" { return '<'; } 1158c2ecf20Sopenharmony_ci">" { return '>'; } 1168c2ecf20Sopenharmony_ci"-" { return '-'; } 1178c2ecf20Sopenharmony_ci"+" { return '+'; } 1188c2ecf20Sopenharmony_ci"*" { return '*'; } 1198c2ecf20Sopenharmony_ci"/" { return '/'; } 1208c2ecf20Sopenharmony_ci"%" { return '%'; } 1218c2ecf20Sopenharmony_ci"(" { return '('; } 1228c2ecf20Sopenharmony_ci")" { return ')'; } 1238c2ecf20Sopenharmony_ci"," { return ','; } 1248c2ecf20Sopenharmony_ci. { } 1258c2ecf20Sopenharmony_ci%% 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ciint expr_wrap(void *scanner __maybe_unused) 1288c2ecf20Sopenharmony_ci{ 1298c2ecf20Sopenharmony_ci return 1; 1308c2ecf20Sopenharmony_ci} 131