1 %{
2
3 #define USE_PURE_PARSER
4
5 #ifdef USE_PURE_PARSER
6 #define YY_DECL int yylex (YYSTYPE *lvalp)
7 #define YY_LVALP lvalp
8 #else
9 #define YY_LVALP (&yylval)
10 #endif
11
12 /* get current pos (offset from start of line) */
13 #define YY_USER_ACTION lex_pos=yy_bp - YY_CURRENT_BUFFER->yy_ch_buf;
14
15 #include <stdio.h>
16 #include <string.h>
17 #include <stdlib.h>
18
19 #include "eval.h"
20 #include "evaltype.h"
21 #include "evalparse.h"
22
23 static int lex_pos;
24
char2int(char a,int base)25 static int char2int(char a, int base)
26 {
27 int i;
28 if ((a>='A') && (a<='Z')) {
29 i=a-'A'+10;
30 } else if ((a>='a') && (a<='z')) {
31 i=a-'a'+10;
32 } else if ((a>='0') && (a<='9')) {
33 i=a-'0';
34 } else return -1;
35 if (i>=base) return -1;
36 return i;
37 }
38
parse_float(eval_scalar * f,char * fpn)39 static int parse_float(eval_scalar *f, char *fpn)
40 {
41 char *end;
42 double d;
43 d=strtod(fpn, &end);
44 if (*end == 0) {
45 f->type=SCALAR_FLOAT;
46 f->scalar.floatnum.value=d;
47 return 1;
48 }
49 return 0;
50 }
51
parse_integer(eval_scalar * i,char * num,int base,int lenmod)52 static int parse_integer(eval_scalar *i, char *num, int base, int lenmod)
53 {
54 uint64 k = 0;
55 int l = strlen(num) + lenmod;
56 while (l--) {
57 int c=char2int(*num, base);
58 if (c==-1) return 0;
59 k *= base;
60 k += c;
61 num++;
62 }
63 i->type=SCALAR_INT;
64 i->scalar.integer.value=k;
65 i->scalar.integer.type=TYPE_UNKNOWN;
66 return 1;
67 }
68
parse_cstring(eval_scalar * r,char * s,int len)69 static int parse_cstring(eval_scalar *r, char *s, int len)
70 {
71 char *result;
72
73 int alloclen = len;
74 if (alloclen < 1) alloclen = 1;
75
76 r->type = SCALAR_STR;
77 r->scalar.str.value = (char*)malloc(alloclen);
78 if (!r->scalar.str.value) return 0;
79
80 result = r->scalar.str.value;
81
82 // may not end with '\\'
83 if (len && s[len-1] == '\\') return 0;
84
85 while (s && *s && len) {
86 if (*s == '\\') {
87 s++;len--;if (!len) break;
88 switch (*s) {
89 case '0':
90 *result++='\0';
91 break;
92 case 'a':
93 *result++='\a';
94 break;
95 case 'b':
96 *result++='\b';
97 break;
98 case 'e':
99 *result++='\e';
100 break;
101 case 'f':
102 *result++='\f';
103 break;
104 case 'n':
105 *result++='\n';
106 break;
107 case 'r':
108 *result++='\r';
109 break;
110 case 't':
111 *result++='\t';
112 break;
113 case 'v':
114 *result++='\v';
115 break;
116 case '\"':
117 *result++='"';
118 break;
119 case '\\':
120 *result++='\\';
121 break;
122 case 'x': {
123 int p, q;
124 s++;len--;if (!len) break;
125 p=char2int(*s, 16);
126 if (p==-1) return 0;
127 s++;len--;if (!len) break;
128 q=char2int(*s, 16);
129 if (q==-1) return 0;
130 *result++=(char)p*16+q;
131 break;
132 }
133 default:
134 *result++='\\';
135 if (len) *result++=*s;
136 break;
137 }
138 } else {
139 *result++ = *s;
140 }
141 s++;len--;
142 }
143
144 r->scalar.str.len=result-r->scalar.str.value;
145
146 return 1;
147 }
148
parse_pstring(eval_scalar * s,char * cstr,int len)149 static int parse_pstring(eval_scalar *s, char *cstr, int len)
150 {
151 int alloclen=len;
152 if (!len) alloclen=1;
153
154 s->type=SCALAR_STR;
155 s->scalar.str.value=(char*)malloc(alloclen);
156 memcpy(s->scalar.str.value, cstr, len);
157 s->scalar.str.len=len;
158 return 1;
159 }
160
lex_current_buffer()161 void *lex_current_buffer()
162 {
163 return (void*)YY_CURRENT_BUFFER;
164 }
165
lex_current_buffer_pos()166 int lex_current_buffer_pos()
167 {
168 return lex_pos;
169 }
170
lex_switch_buffer(void * buffer)171 void lex_switch_buffer(void *buffer)
172 {
173 yy_switch_to_buffer(buffer);
174 }
175
lex_delete_buffer(void * buffer)176 void lex_delete_buffer(void *buffer)
177 {
178 yy_delete_buffer(buffer);
179 }
180
lex_scan_string_buffer(const char * str)181 void *lex_scan_string_buffer(const char *str)
182 {
183 return yy_scan_string(str);
184 }
185
186 /*
187 */
188 %}
189
190 %option noyywrap
191
192 %%
193
194 [ \t]+ /* nop */
195 \"(\\\"|[^"])*\" if (parse_cstring(&YY_LVALP->scalar, yytext+1, strlen(yytext+1)-1)) return EVAL_STR;
196 '[^']*' if (parse_pstring(&YY_LVALP->scalar, yytext+1, strlen(yytext+1)-1)) return EVAL_STR;
197 lt return EVAL_STR_LT;
198 le return EVAL_STR_LE;
199 gt return EVAL_STR_GT;
200 ge return EVAL_STR_GE;
201 eq return EVAL_STR_EQ;
202 ne return EVAL_STR_NE;
203 \*\* return EVAL_POW;
204 \<\< return EVAL_SHL;
205 \>\> return EVAL_SHR;
206 \< return EVAL_LT;
207 \<\= return EVAL_LE;
208 \> return EVAL_GT;
209 \>\= return EVAL_GE;
210 \=\= return EVAL_EQ;
211 \!\= return EVAL_NE;
212 \&\& return EVAL_LAND;
213 \|\| return EVAL_LOR;
214 \^\^ return EVAL_LXOR;
215 [$@a-zA-Z_][a-zA-Z0-9_]* YY_LVALP->ident=strdup(yytext); return EVAL_IDENT;
216 [0-9]+\.[0-9]+([eE][+-]?[0-9]+)? if (parse_float(&YY_LVALP->scalar, yytext)) return EVAL_FLOAT;
217 [0-9]+ if (parse_integer(&YY_LVALP->scalar, yytext, 10, 0)) return EVAL_INT;
218 0x[0-9a-fA-F]+ if (parse_integer(&YY_LVALP->scalar, yytext+2, 16, 0)) return EVAL_INT;
219 [0-9][0-9a-fA-F]*h if (parse_integer(&YY_LVALP->scalar, yytext, 16, -1)) return EVAL_INT;
220 [0-9]+d if (parse_integer(&YY_LVALP->scalar, yytext, 10, -1)) return EVAL_INT;
221 [0-7]+o if (parse_integer(&YY_LVALP->scalar, yytext, 8, -1)) return EVAL_INT;
222 [0-1]+b if (parse_integer(&YY_LVALP->scalar, yytext, 2, -1)) return EVAL_INT;
223 . return *yytext;
224 \n return '\n';
225
226 %%
227