1 %option prefix="expr_" 1 %option prefix="expr_" 2 %option reentrant 2 %option reentrant 3 %option bison-bridge 3 %option bison-bridge 4 4 5 %{ 5 %{ 6 #include <linux/compiler.h> 6 #include <linux/compiler.h> 7 #include "expr.h" 7 #include "expr.h" 8 #include "expr-bison.h" 8 #include "expr-bison.h" 9 #include <math.h> 9 #include <math.h> 10 10 11 char *expr_get_text(yyscan_t yyscanner); 11 char *expr_get_text(yyscan_t yyscanner); 12 YYSTYPE *expr_get_lval(yyscan_t yyscanner); 12 YYSTYPE *expr_get_lval(yyscan_t yyscanner); 13 13 14 static double __value(YYSTYPE *yylval, char *s 14 static double __value(YYSTYPE *yylval, char *str, int token) 15 { 15 { 16 double num; 16 double num; 17 17 18 errno = 0; 18 errno = 0; 19 num = strtod(str, NULL); 19 num = strtod(str, NULL); 20 if (errno) 20 if (errno) 21 return EXPR_ERROR; 21 return EXPR_ERROR; 22 22 23 yylval->num = num; 23 yylval->num = num; 24 return token; 24 return token; 25 } 25 } 26 26 27 static int value(yyscan_t scanner) 27 static int value(yyscan_t scanner) 28 { 28 { 29 YYSTYPE *yylval = expr_get_lval(scanne 29 YYSTYPE *yylval = expr_get_lval(scanner); 30 char *text = expr_get_text(scanner); 30 char *text = expr_get_text(scanner); 31 31 32 return __value(yylval, text, NUMBER); 32 return __value(yylval, text, NUMBER); 33 } 33 } 34 34 35 /* 35 /* 36 * Allow @ instead of / to be able to specify 36 * Allow @ instead of / to be able to specify pmu/event/ without 37 * conflicts with normal division. 37 * conflicts with normal division. 38 */ 38 */ 39 static char *normalize(char *str, int runtime) 39 static char *normalize(char *str, int runtime) 40 { 40 { 41 char *ret = str; 41 char *ret = str; 42 char *dst = str; 42 char *dst = str; 43 43 44 while (*str) { 44 while (*str) { 45 if (*str == '\\') { !! 45 if (*str == '\\') 46 *dst++ = *++str; 46 *dst++ = *++str; 47 if (!*str) << 48 break; << 49 } << 50 else if (*str == '?') { 47 else if (*str == '?') { 51 char *paramval; 48 char *paramval; 52 int i = 0; 49 int i = 0; 53 int size = asprintf(&p 50 int size = asprintf(¶mval, "%d", runtime); 54 51 55 if (size < 0) 52 if (size < 0) 56 *dst++ = '0'; 53 *dst++ = '0'; 57 else { 54 else { 58 while (i < siz 55 while (i < size) 59 *dst++ 56 *dst++ = paramval[i++]; 60 free(paramval) 57 free(paramval); 61 } 58 } 62 } 59 } 63 else 60 else 64 *dst++ = *str; 61 *dst++ = *str; 65 str++; 62 str++; 66 } 63 } 67 64 68 *dst = 0x0; 65 *dst = 0x0; 69 return ret; 66 return ret; 70 } 67 } 71 68 72 static int str(yyscan_t scanner, int token, in 69 static int str(yyscan_t scanner, int token, int runtime) 73 { 70 { 74 YYSTYPE *yylval = expr_get_lval(scanne 71 YYSTYPE *yylval = expr_get_lval(scanner); 75 char *text = expr_get_text(scanner); 72 char *text = expr_get_text(scanner); 76 73 77 yylval->str = normalize(strdup(text), 74 yylval->str = normalize(strdup(text), runtime); 78 if (!yylval->str) 75 if (!yylval->str) 79 return EXPR_ERROR; 76 return EXPR_ERROR; 80 77 81 yylval->str = normalize(yylval->str, r 78 yylval->str = normalize(yylval->str, runtime); 82 return token; 79 return token; 83 } 80 } 84 81 85 static int literal(yyscan_t scanner, const str !! 82 static int literal(yyscan_t scanner) 86 { 83 { 87 YYSTYPE *yylval = expr_get_lval(scanne 84 YYSTYPE *yylval = expr_get_lval(scanner); 88 85 89 yylval->num = expr__get_literal(expr_g !! 86 yylval->num = expr__get_literal(expr_get_text(scanner)); 90 if (isnan(yylval->num)) { !! 87 if (isnan(yylval->num)) 91 if (!sctx->is_test) !! 88 return EXPR_ERROR; 92 return EXPR_ERROR; << 93 yylval->num = 1; << 94 } << 95 return LITERAL; << 96 } << 97 << 98 static int nan_value(yyscan_t scanner) << 99 { << 100 YYSTYPE *yylval = expr_get_lval(scanne << 101 89 102 yylval->num = NAN; !! 90 return LITERAL; 103 return NUMBER; << 104 } 91 } 105 %} 92 %} 106 93 107 number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9 !! 94 number ([0-9]+\.?[0-9]*|[0-9]*\.?[0-9]+) 108 95 109 sch [-,=] 96 sch [-,=] 110 spec \\{sch} 97 spec \\{sch} 111 sym [0-9a-zA-Z_\.:@?]+ 98 sym [0-9a-zA-Z_\.:@?]+ 112 symbol ({spec}|{sym})+ 99 symbol ({spec}|{sym})+ 113 literal #[0-9a-zA-Z_\.\-]+ 100 literal #[0-9a-zA-Z_\.\-]+ 114 101 115 %% 102 %% 116 struct expr_scanner_ctx *sctx = expr_g 103 struct expr_scanner_ctx *sctx = expr_get_extra(yyscanner); 117 104 118 d_ratio { return D_RATIO; } 105 d_ratio { return D_RATIO; } 119 max { return MAX; } 106 max { return MAX; } 120 min { return MIN; } 107 min { return MIN; } 121 if { return IF; } 108 if { return IF; } 122 else { return ELSE; } 109 else { return ELSE; } 123 source_count { return SOURCE_COUNT; } 110 source_count { return SOURCE_COUNT; } 124 has_event { return HAS_EVENT; } !! 111 {literal} { return literal(yyscanner); } 125 strcmp_cpuid_str { return STRCMP_CPUID_ << 126 NaN { return nan_value(yyscanner); << 127 {literal} { return literal(yyscanner, sc << 128 {number} { return value(yyscanner); } 112 {number} { return value(yyscanner); } 129 {symbol} { return str(yyscanner, ID, sc 113 {symbol} { return str(yyscanner, ID, sctx->runtime); } 130 "|" { return '|'; } 114 "|" { return '|'; } 131 "^" { return '^'; } 115 "^" { return '^'; } 132 "&" { return '&'; } 116 "&" { return '&'; } 133 "<" { return '<'; } 117 "<" { return '<'; } 134 ">" { return '>'; } 118 ">" { return '>'; } 135 "-" { return '-'; } 119 "-" { return '-'; } 136 "+" { return '+'; } 120 "+" { return '+'; } 137 "*" { return '*'; } 121 "*" { return '*'; } 138 "/" { return '/'; } 122 "/" { return '/'; } 139 "%" { return '%'; } 123 "%" { return '%'; } 140 "(" { return '('; } 124 "(" { return '('; } 141 ")" { return ')'; } 125 ")" { return ')'; } 142 "," { return ','; } 126 "," { return ','; } 143 . { } 127 . { } 144 %% 128 %% 145 129 146 int expr_wrap(void *scanner __maybe_unused) 130 int expr_wrap(void *scanner __maybe_unused) 147 { 131 { 148 return 1; 132 return 1; 149 } 133 }
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.