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++ = '/'; 46 else if (*str == '\\') 47 *dst++ = *++str; 48 else if (*str == '?') { 49 char *paramval; 50 int i = 0; 51 int size = asprintf(¶mval, "%d", runtime); 52 53 if (size < 0) 54 *dst++ = '0'; 55 else { 56 while (i < size) 57 *dst++ = paramval[i++]; 58 free(paramval); 59 } 60 } 61 else 62 *dst++ = *str; 63 str++; 64 } 65 66 *dst = 0x0; 67 return ret; 68 } 69 70 static int str(yyscan_t scanner, int token, int runtime) 71 { 72 YYSTYPE *yylval = expr_get_lval(scanner); 73 char *text = expr_get_text(scanner); 74 75 yylval->str = normalize(strdup(text), runtime); 76 if (!yylval->str) 77 return EXPR_ERROR; 78 79 yylval->str = normalize(yylval->str, runtime); 80 return token; 81 } 82 %} 83 84 number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+) 85 86 sch [-,=] 87 spec \\{sch} 88 sym [0-9a-zA-Z_\.:@?]+ 89 symbol ({spec}|{sym})+ 90 91 %% 92 struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner); 93 94 { 95 int start_token = sctx->start_token; 96 97 if (sctx->start_token) { 98 sctx->start_token = 0; 99 return start_token; 100 } 101 } 102 103 d_ratio { return D_RATIO; } 104 max { return MAX; } 105 min { return MIN; } 106 if { return IF; } 107 else { return ELSE; } 108 #smt_on { return SMT_ON; } 109 {number} { return value(yyscanner); } 110 {symbol} { return str(yyscanner, ID, sctx->runtime); } 111 "|" { return '|'; } 112 "^" { return '^'; } 113 "&" { return '&'; } 114 "<" { return '<'; } 115 ">" { return '>'; } 116 "-" { return '-'; } 117 "+" { return '+'; } 118 "*" { return '*'; } 119 "/" { return '/'; } 120 "%" { return '%'; } 121 "(" { return '('; } 122 ")" { return ')'; } 123 "," { return ','; } 124 . { } 125 %% 126 127 int expr_wrap(void *scanner __maybe_unused) 128 { 129 return 1; 130 } 131