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