at v5.13 2.3 kB view raw
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 10char *expr_get_text(yyscan_t yyscanner); 11YYSTYPE *expr_get_lval(yyscan_t yyscanner); 12 13static 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 26static 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 */ 38static 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(&paramval, "%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 70static 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 84number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+) 85 86sch [-,=] 87spec \\{sch} 88sym [0-9a-zA-Z_\.:@?]+ 89symbol ({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 103d_ratio { return D_RATIO; } 104max { return MAX; } 105min { return MIN; } 106if { return IF; } 107else { 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 127int expr_wrap(void *scanner __maybe_unused) 128{ 129 return 1; 130}