1 %option prefix="expr_" 2 %option reentrant 3 %option bison-bridge 4 5 %{ 6 #include <linux/compiler.h> 7 #include "expr.h" 8 #include "expr-bison.h" 9 10 char *expr_get_text(yyscan_t yyscanner); 11 YYSTYPE *expr_get_lval(yyscan_t yyscanner); 12 13 static double __value(YYSTYPE *yylval, char *str, int token) 14 { 15 double num; 16 17 errno = 0; 18 num = strtod(str, NULL); 19 if (errno) 20 return EXPR_ERROR; 21 22 yylval->num = num; 23 return token; 24 } 25 26 static int value(yyscan_t scanner) 27 { 28 YYSTYPE *yylval = expr_get_lval(scanner); 29 char *text = expr_get_text(scanner); 30 31 return __value(yylval, text, NUMBER); 32 } 33 34 /* 35 * Allow @ instead of / to be able to specify pmu/event/ without 36 * conflicts with normal division. 37 */ 38 static char *normalize(char *str, int runtime) 39 { 40 char *ret = str; 41 char *dst = str; 42 43 while (*str) { 44 if (*str == '\\') 45 *dst++ = *++str; 46 else if (*str == '?') { 47 char *paramval; 48 int i = 0; 49 int size = asprintf(¶mval, "%d", runtime); 50 51 if (size < 0) 52 *dst++ = '0'; 53 else { 54 while (i < size) 55 *dst++ = paramval[i++]; 56 free(paramval); 57 } 58 } 59 else 60 *dst++ = *str; 61 str++; 62 } 63 64 *dst = 0x0; 65 return ret; 66 } 67 68 static int str(yyscan_t scanner, int token, int runtime) 69 { 70 YYSTYPE *yylval = expr_get_lval(scanner); 71 char *text = expr_get_text(scanner); 72 73 yylval->str = normalize(strdup(text), runtime); 74 if (!yylval->str) 75 return EXPR_ERROR; 76 77 yylval->str = normalize(yylval->str, runtime); 78 return token; 79 } 80 %} 81 82 number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+) 83 84 sch [-,=] 85 spec \\{sch} 86 sym [0-9a-zA-Z_\.:@?]+ 87 symbol ({spec}|{sym})+ 88 89 %% 90 struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner); 91 92 d_ratio { return D_RATIO; } 93 max { return MAX; } 94 min { return MIN; } 95 if { return IF; } 96 else { return ELSE; } 97 #smt_on { return SMT_ON; } 98 {number} { return value(yyscanner); } 99 {symbol} { return str(yyscanner, ID, sctx->runtime); } 100 "|" { return '|'; } 101 "^" { return '^'; } 102 "&" { return '&'; } 103 "<" { return '<'; } 104 ">" { return '>'; } 105 "-" { return '-'; } 106 "+" { return '+'; } 107 "*" { return '*'; } 108 "/" { return '/'; } 109 "%" { return '%'; } 110 "(" { return '('; } 111 ")" { return ')'; } 112 "," { return ','; } 113 . { } 114 %% 115 116 int expr_wrap(void *scanner __maybe_unused) 117 { 118 return 1; 119 } 120