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