fio: update FSF address
[fio.git] / exp / expression-parser.l
1 %{
2
3 /*
4  * (C) Copyright 2014, Stephen M. Cameron.
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License version 2 as
8  *  published by the Free Software Foundation.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #include <stdio.h>
22 #include <string.h>
23 #include "y.tab.h"
24
25 #define YYSTYPE PARSER_VALUE_TYPE
26
27 extern int lexer_input(char *buffer, unsigned int *nbytes, int buffersize);
28
29 #undef YY_INPUT
30 #define YY_INPUT(buffer, bytes_read, bytes_requested)                   \
31 ({                                                                      \
32         int __ret;                                                      \
33         unsigned int __bread = bytes_read;                              \
34         __ret = lexer_input((buffer), &__bread, (bytes_requested));     \
35         bytes_read = __bread;                                           \
36         __ret;                                                          \
37 })
38
39 extern int yyerror(long long *result, double *dresult,
40                 int *has_error, int *units_specified, const char *msg);
41
42 static void __attribute__((unused)) yyunput(int c, char *buf_ptr);
43 static int __attribute__((unused)) input(void);
44
45 /* set by parser -- this is another thing which makes the parser thread-unsafe :(. */
46 int lexer_value_is_time = 0; /* for determining if "m" suffix means mega- or minutes */
47
48 #define set_suffix_value(yylval, i_val, d_val, has_d_val) \
49         (yylval).v.dval = (d_val); \
50         (yylval).v.ival = (i_val); \
51         (yylval).v.has_dval = (has_d_val); \
52         (yylval).v.has_error = 0;
53
54 %}
55
56 %%
57
58
59 [kK]|[kK][bB]   {
60                         set_suffix_value(yylval, 1024, 1024.0, 0);
61                         return SUFFIX;
62                 }
63 [Mm][bB]        {
64                         set_suffix_value(yylval, 1024 * 1024, 1024.0 * 1024.0, 0);
65                         return SUFFIX;
66                 }
67 [mM][sS]        {
68                         set_suffix_value(yylval, 1000, 1000.0, 1);
69                         return SUFFIX;
70                 }
71 [uU][sS]        {
72                         set_suffix_value(yylval, 1, 1.0, 1);
73                         return SUFFIX;
74                 }
75 [gG]|[Gg][Bb]   {
76                         set_suffix_value(yylval, 1024LL * 1024 * 1024, 1024.0 * 1024.0 * 1024, 0);
77                         return SUFFIX;
78                 }
79 [tT]|[tT][bB]   {       
80                         set_suffix_value(yylval, 1024LL * 1024 * 1024 * 1024,
81                                                 1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024, 0);
82                         return SUFFIX;
83                 }
84 [pP]|[pP][bB]   {       
85                         set_suffix_value(yylval, 1024LL * 1024 * 1024 * 1024 * 1024,
86                                         1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0, 0);
87                         return SUFFIX;
88                 }
89 [kK][iI][Bb]    {
90                         set_suffix_value(yylval, 1000LL, 1000.0, 0);
91                         return SUFFIX;
92                 }
93 [mM][Ii][bB]    {
94                         set_suffix_value(yylval, 1000000LL, 1000000.0 , 0);
95                         return SUFFIX;
96                 }
97 [gG][iI][Bb]    {
98                         set_suffix_value(yylval, 1000000000LL, 1000000000.0 , 0);
99                         return SUFFIX;
100                 }
101 [pP][iI][Bb]    {       
102                         set_suffix_value(yylval, 1000000000000LL, 1000000000000.0 , 0);
103                         return SUFFIX;
104                 }
105 [sS]            {
106                         set_suffix_value(yylval, 1000000LL, 1000000.0 , 0);
107                         return SUFFIX;
108                 }
109 [mM]            {
110                         if (!lexer_value_is_time) {
111                                 set_suffix_value(yylval, 1024 * 1024, 1024.0 * 1024.0, 0);
112                         } else {
113                                 set_suffix_value(yylval, 60LL * 1000000LL, 60.0 * 1000000.0, 0);
114                         }
115                         return SUFFIX;
116                 }
117 [dD]            {
118                         set_suffix_value(yylval, 60LL * 60LL * 24LL * 1000000LL,
119                                                 60.0 * 60.0 * 24.0 * 1000000.0, 0);
120                         return SUFFIX;
121                 }
122 [hH]            {       
123                         set_suffix_value(yylval, 60LL * 60LL * 1000000LL,
124                                         60.0 * 60.0 * 1000000.0, 0);
125                         return SUFFIX;
126                 }
127 [ \t] ; /* ignore whitespace */
128 [#:,].* ; /* ignore comments, and everything after colons and commas */
129 [0-9]*[.][0-9]+|[0-9]*[.]?[0-9]+[eE][-+]*[0-9]+ {
130                         int rc;
131                         double dval;
132
133                         rc = sscanf(yytext, "%lf", &dval);
134                         if (rc == 1) {
135                                 yylval.v.dval = dval;
136                                 yylval.v.ival = (long long) dval;
137                                 yylval.v.has_dval = 1;
138                                 yylval.v.has_error = 0;
139                                 return NUMBER;
140                         } else {
141                                 yyerror(0, 0, 0, 0, "bad number\n");
142                                 yylval.v.has_error = 1;
143                                 return NUMBER;
144                         }
145                 }
146 0x[0-9a-fA-F]+ {
147                 int rc, intval;
148                 rc = sscanf(yytext, "%x", &intval);
149                 if (rc == 1) {
150                         yylval.v.ival = intval;
151                         yylval.v.dval = (double) intval;
152                         yylval.v.has_dval = 0;
153                         yylval.v.has_error = 0;
154                         return NUMBER;
155                 } else {
156                         yyerror(0, 0, 0, 0, "bad number\n");
157                         yylval.v.has_error = 1;
158                         return NUMBER;
159                 }
160         }
161 [0-9]+  {
162                 int rc, intval;
163                 rc = sscanf(yytext, "%d", &intval);
164                 if (rc == 1) {
165                         yylval.v.ival = intval;
166                         yylval.v.dval = (double) intval;
167                         yylval.v.has_dval = 0;
168                         yylval.v.has_error = 0;
169                         return NUMBER;
170                 } else {
171                         yyerror(0, 0, 0, 0, "bad number\n");
172                         yylval.v.has_error = 1;
173                         return NUMBER;
174                 }
175         }
176 \n      return 0;
177 [+-/*()^%]      return yytext[0];
178
179 .       {
180                 yylval.v.has_error = 1;
181                 return NUMBER;  
182         }
183 %%
184