282
|
1
|
|
2 /* A Bison parser, made from parser.y
|
|
3 by GNU Bison version 1.28 */
|
|
4
|
|
5 #define YYBISON 1 /* Identify Bison output. */
|
|
6
|
|
7 #define NAME 257
|
|
8 #define NUMBER 258
|
|
9 #define NEG 259
|
|
10
|
|
11 #line 23 "parser.y"
|
|
12
|
|
13 #include <ctype.h>
|
|
14 #include <glib.h>
|
|
15 #include <locale.h>
|
|
16 #include <math.h>
|
|
17 #include <stdio.h>
|
|
18 #include <string.h>
|
|
19
|
|
20 #include "dict.h"
|
|
21 #include "execute.h"
|
|
22 #include "function.h"
|
|
23 #include "parser.h"
|
|
24 #include "storage.h"
|
|
25
|
|
26 #define YYPARSE_PARAM yyparam
|
|
27 #define YYLEX_PARAM yyparam
|
|
28
|
|
29 static gboolean expr_add_compile (expression_t *expr, symbol_dict_t *dict,
|
|
30 char *str);
|
|
31
|
|
32 #define GENERATE(str) if (!expr_add_compile (((parser_control *)yyparam)->expr, \
|
|
33 ((parser_control *)yyparam)->dict, str)) \
|
|
34 YYABORT;
|
|
35
|
|
36 #line 51 "parser.y"
|
|
37 typedef union {
|
|
38 char *s_value;
|
|
39 char c_value;
|
|
40 double d_value;
|
|
41 int i_value;
|
|
42 } YYSTYPE;
|
|
43 #include <stdio.h>
|
|
44
|
|
45 #ifndef __cplusplus
|
|
46 #ifndef __STDC__
|
|
47 #define const
|
|
48 #endif
|
|
49 #endif
|
|
50
|
|
51
|
|
52
|
|
53 #define YYFINAL 37
|
|
54 #define YYFLAG -32768
|
|
55 #define YYNTBASE 18
|
|
56
|
|
57 #define YYTRANSLATE(x) ((unsigned)(x) <= 259 ? yytranslate[x] : 22)
|
|
58
|
|
59 static const char yytranslate[] = { 0,
|
|
60 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
61 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
62 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
63 2, 2, 2, 2, 2, 2, 2, 2, 2, 14,
|
|
64 15, 8, 7, 13, 6, 2, 9, 2, 2, 2,
|
|
65 2, 2, 2, 2, 2, 2, 2, 2, 12, 17,
|
|
66 5, 16, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
67 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
68 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
69 2, 2, 2, 11, 2, 2, 2, 2, 2, 2,
|
|
70 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
71 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
72 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
73 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
74 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
75 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
76 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
77 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
78 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
79 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
80 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
81 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
82 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
83 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
84 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
85 2, 2, 2, 2, 2, 1, 3, 4, 10
|
|
86 };
|
|
87
|
|
88 #if YYDEBUG != 0
|
|
89 static const short yyprhs[] = { 0,
|
|
90 0, 1, 4, 5, 7, 10, 13, 15, 19, 21,
|
|
91 23, 27, 32, 36, 40, 44, 48, 52, 56, 59,
|
|
92 63
|
|
93 };
|
|
94
|
|
95 static const short yyrhs[] = { -1,
|
|
96 18, 19, 0, 0, 21, 0, 19, 12, 0, 1,
|
|
97 12, 0, 21, 0, 20, 13, 21, 0, 4, 0,
|
|
98 3, 0, 3, 5, 21, 0, 3, 14, 20, 15,
|
|
99 0, 21, 16, 21, 0, 21, 17, 21, 0, 21,
|
|
100 7, 21, 0, 21, 6, 21, 0, 21, 8, 21,
|
|
101 0, 21, 9, 21, 0, 6, 21, 0, 21, 11,
|
|
102 21, 0, 14, 21, 15, 0
|
|
103 };
|
|
104
|
|
105 #endif
|
|
106
|
|
107 #if YYDEBUG != 0
|
|
108 static const short yyrline[] = { 0,
|
|
109 73, 74, 78, 79, 81, 82, 86, 90, 95, 101,
|
|
110 107, 113, 120, 122, 125, 127, 129, 131, 133, 135,
|
|
111 137
|
|
112 };
|
|
113 #endif
|
|
114
|
|
115
|
|
116 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
|
|
117
|
|
118 static const char * const yytname[] = { "$","error","$undefined.","NAME","NUMBER",
|
|
119 "'='","'-'","'+'","'*'","'/'","NEG","'^'","';'","','","'('","')'","'>'","'<'",
|
|
120 "input","expression_list","argument_list","expression", NULL
|
|
121 };
|
|
122 #endif
|
|
123
|
|
124 static const short yyr1[] = { 0,
|
|
125 18, 18, 19, 19, 19, 19, 20, 20, 21, 21,
|
|
126 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
|
|
127 21
|
|
128 };
|
|
129
|
|
130 static const short yyr2[] = { 0,
|
|
131 0, 2, 0, 1, 2, 2, 1, 3, 1, 1,
|
|
132 3, 4, 3, 3, 3, 3, 3, 3, 2, 3,
|
|
133 3
|
|
134 };
|
|
135
|
|
136 static const short yydefact[] = { 1,
|
|
137 0, 0, 10, 9, 0, 0, 2, 4, 6, 0,
|
|
138 0, 19, 0, 5, 0, 0, 0, 0, 0, 0,
|
|
139 0, 11, 0, 7, 21, 16, 15, 17, 18, 20,
|
|
140 13, 14, 0, 12, 8, 0, 0
|
|
141 };
|
|
142
|
|
143 static const short yydefgoto[] = { 1,
|
|
144 7, 23, 8
|
|
145 };
|
|
146
|
|
147 static const short yypact[] = {-32768,
|
|
148 17, -8, 22,-32768, 47, 47, -3, 38,-32768, 47,
|
|
149 47, -9, 26,-32768, 47, 47, 47, 47, 47, 47,
|
|
150 47, 38, 9, 38,-32768, 48, 48, -9, -9, -9,
|
|
151 38, 38, 47,-32768, 38, 3,-32768
|
|
152 };
|
|
153
|
|
154 static const short yypgoto[] = {-32768,
|
|
155 -32768,-32768, -5
|
|
156 };
|
|
157
|
|
158
|
|
159 #define YYLAST 65
|
|
160
|
|
161
|
|
162 static const short yytable[] = { 12,
|
|
163 13, 19, 37, 9, 22, 24, 20, 21, 14, 26,
|
|
164 27, 28, 29, 30, 31, 32, 36, 2, 0, 3,
|
|
165 4, 33, 5, 34, 0, 0, 10, 35, -3, 0,
|
|
166 6, 15, 16, 17, 18, 11, 19, 0, 0, 0,
|
|
167 25, 20, 21, 15, 16, 17, 18, 0, 19, 3,
|
|
168 4, 0, 5, 20, 21, 17, 18, 0, 19, 0,
|
|
169 6, 0, 0, 20, 21
|
|
170 };
|
|
171
|
|
172 static const short yycheck[] = { 5,
|
|
173 6, 11, 0, 12, 10, 11, 16, 17, 12, 15,
|
|
174 16, 17, 18, 19, 20, 21, 0, 1, -1, 3,
|
|
175 4, 13, 6, 15, -1, -1, 5, 33, 12, -1,
|
|
176 14, 6, 7, 8, 9, 14, 11, -1, -1, -1,
|
|
177 15, 16, 17, 6, 7, 8, 9, -1, 11, 3,
|
|
178 4, -1, 6, 16, 17, 8, 9, -1, 11, -1,
|
|
179 14, -1, -1, 16, 17
|
|
180 };
|
|
181 #define YYPURE 1
|
|
182
|
|
183 /* -*-C-*- Note some compilers choke on comments on `#line' lines. */
|
|
184 #line 3 "/usr/share/misc/bison.simple"
|
|
185 /* This file comes from bison-1.28. */
|
|
186
|
|
187 /* Skeleton output parser for bison,
|
|
188 Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
|
|
189
|
|
190 This program is free software; you can redistribute it and/or modify
|
|
191 it under the terms of the GNU General Public License as published by
|
|
192 the Free Software Foundation; either version 2, or (at your option)
|
|
193 any later version.
|
|
194
|
|
195 This program is distributed in the hope that it will be useful,
|
|
196 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
197 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
198 GNU General Public License for more details.
|
|
199
|
|
200 You should have received a copy of the GNU General Public License
|
|
201 along with this program; if not, write to the Free Software
|
|
202 Foundation, Inc., 59 Temple Place - Suite 330,
|
|
203 Boston, MA 02111-1307, USA. */
|
|
204
|
|
205 /* As a special exception, when this file is copied by Bison into a
|
|
206 Bison output file, you may use that output file without restriction.
|
|
207 This special exception was added by the Free Software Foundation
|
|
208 in version 1.24 of Bison. */
|
|
209
|
|
210 /* This is the parser code that is written into each bison parser
|
|
211 when the %semantic_parser declaration is not specified in the grammar.
|
|
212 It was written by Richard Stallman by simplifying the hairy parser
|
|
213 used when %semantic_parser is specified. */
|
|
214
|
|
215 #ifndef YYSTACK_USE_ALLOCA
|
|
216 #ifdef alloca
|
|
217 #define YYSTACK_USE_ALLOCA
|
|
218 #else /* alloca not defined */
|
|
219 #ifdef __GNUC__
|
|
220 #define YYSTACK_USE_ALLOCA
|
|
221 #define alloca __builtin_alloca
|
|
222 #else /* not GNU C. */
|
|
223 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386))
|
|
224 #define YYSTACK_USE_ALLOCA
|
|
225 #include <alloca.h>
|
|
226 #else /* not sparc */
|
|
227 /* We think this test detects Watcom and Microsoft C. */
|
|
228 /* This used to test MSDOS, but that is a bad idea
|
|
229 since that symbol is in the user namespace. */
|
|
230 #if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__)
|
|
231 #if 0 /* No need for malloc.h, which pollutes the namespace;
|
|
232 instead, just don't use alloca. */
|
|
233 #include <malloc.h>
|
|
234 #endif
|
|
235 #else /* not MSDOS, or __TURBOC__ */
|
|
236 #if defined(_AIX)
|
|
237 /* I don't know what this was needed for, but it pollutes the namespace.
|
|
238 So I turned it off. rms, 2 May 1997. */
|
|
239 /* #include <malloc.h> */
|
|
240 #pragma alloca
|
|
241 #define YYSTACK_USE_ALLOCA
|
|
242 #else /* not MSDOS, or __TURBOC__, or _AIX */
|
|
243 #if 0
|
|
244 #ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up,
|
|
245 and on HPUX 10. Eventually we can turn this on. */
|
|
246 #define YYSTACK_USE_ALLOCA
|
|
247 #define alloca __builtin_alloca
|
|
248 #endif /* __hpux */
|
|
249 #endif
|
|
250 #endif /* not _AIX */
|
|
251 #endif /* not MSDOS, or __TURBOC__ */
|
|
252 #endif /* not sparc */
|
|
253 #endif /* not GNU C */
|
|
254 #endif /* alloca not defined */
|
|
255 #endif /* YYSTACK_USE_ALLOCA not defined */
|
|
256
|
|
257 #ifdef YYSTACK_USE_ALLOCA
|
|
258 #define YYSTACK_ALLOC alloca
|
|
259 #else
|
|
260 #define YYSTACK_ALLOC malloc
|
|
261 #endif
|
|
262
|
|
263 /* Note: there must be only one dollar sign in this file.
|
|
264 It is replaced by the list of actions, each action
|
|
265 as one case of the switch. */
|
|
266
|
|
267 #define yyerrok (yyerrstatus = 0)
|
|
268 #define yyclearin (yychar = YYEMPTY)
|
|
269 #define YYEMPTY -2
|
|
270 #define YYEOF 0
|
|
271 #define YYACCEPT goto yyacceptlab
|
|
272 #define YYABORT goto yyabortlab
|
|
273 #define YYERROR goto yyerrlab1
|
|
274 /* Like YYERROR except do call yyerror.
|
|
275 This remains here temporarily to ease the
|
|
276 transition to the new meaning of YYERROR, for GCC.
|
|
277 Once GCC version 2 has supplanted version 1, this can go. */
|
|
278 #define YYFAIL goto yyerrlab
|
|
279 #define YYRECOVERING() (!!yyerrstatus)
|
|
280 #define YYBACKUP(token, value) \
|
|
281 do \
|
|
282 if (yychar == YYEMPTY && yylen == 1) \
|
|
283 { yychar = (token), yylval = (value); \
|
|
284 yychar1 = YYTRANSLATE (yychar); \
|
|
285 YYPOPSTACK; \
|
|
286 goto yybackup; \
|
|
287 } \
|
|
288 else \
|
|
289 { yyerror ("syntax error: cannot back up"); YYERROR; } \
|
|
290 while (0)
|
|
291
|
|
292 #define YYTERROR 1
|
|
293 #define YYERRCODE 256
|
|
294
|
|
295 #ifndef YYPURE
|
|
296 #define YYLEX yylex()
|
|
297 #endif
|
|
298
|
|
299 #ifdef YYPURE
|
|
300 #ifdef YYLSP_NEEDED
|
|
301 #ifdef YYLEX_PARAM
|
|
302 #define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM)
|
|
303 #else
|
|
304 #define YYLEX yylex(&yylval, &yylloc)
|
|
305 #endif
|
|
306 #else /* not YYLSP_NEEDED */
|
|
307 #ifdef YYLEX_PARAM
|
|
308 #define YYLEX yylex(&yylval, YYLEX_PARAM)
|
|
309 #else
|
|
310 #define YYLEX yylex(&yylval)
|
|
311 #endif
|
|
312 #endif /* not YYLSP_NEEDED */
|
|
313 #endif
|
|
314
|
|
315 /* If nonreentrant, generate the variables here */
|
|
316
|
|
317 #ifndef YYPURE
|
|
318
|
|
319 int yychar; /* the lookahead symbol */
|
|
320 YYSTYPE yylval; /* the semantic value of the */
|
|
321 /* lookahead symbol */
|
|
322
|
|
323 #ifdef YYLSP_NEEDED
|
|
324 YYLTYPE yylloc; /* location data for the lookahead */
|
|
325 /* symbol */
|
|
326 #endif
|
|
327
|
|
328 int yynerrs; /* number of parse errors so far */
|
|
329 #endif /* not YYPURE */
|
|
330
|
|
331 #if YYDEBUG != 0
|
|
332 int yydebug; /* nonzero means print parse trace */
|
|
333 /* Since this is uninitialized, it does not stop multiple parsers
|
|
334 from coexisting. */
|
|
335 #endif
|
|
336
|
|
337 /* YYINITDEPTH indicates the initial size of the parser's stacks */
|
|
338
|
|
339 #ifndef YYINITDEPTH
|
|
340 #define YYINITDEPTH 200
|
|
341 #endif
|
|
342
|
|
343 /* YYMAXDEPTH is the maximum size the stacks can grow to
|
|
344 (effective only if the built-in stack extension method is used). */
|
|
345
|
|
346 #if YYMAXDEPTH == 0
|
|
347 #undef YYMAXDEPTH
|
|
348 #endif
|
|
349
|
|
350 #ifndef YYMAXDEPTH
|
|
351 #define YYMAXDEPTH 10000
|
|
352 #endif
|
|
353
|
|
354 /* Define __yy_memcpy. Note that the size argument
|
|
355 should be passed with type unsigned int, because that is what the non-GCC
|
|
356 definitions require. With GCC, __builtin_memcpy takes an arg
|
|
357 of type size_t, but it can handle unsigned int. */
|
|
358
|
|
359 #if __GNUC__ > 1 /* GNU C and GNU C++ define this. */
|
|
360 #define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT)
|
|
361 #else /* not GNU C or C++ */
|
|
362 #ifndef __cplusplus
|
|
363
|
|
364 /* This is the most reliable way to avoid incompatibilities
|
|
365 in available built-in functions on various systems. */
|
|
366 static void
|
|
367 __yy_memcpy (to, from, count)
|
|
368 char *to;
|
|
369 char *from;
|
|
370 unsigned int count;
|
|
371 {
|
|
372 register char *f = from;
|
|
373 register char *t = to;
|
|
374 register int i = count;
|
|
375
|
|
376 while (i-- > 0)
|
|
377 *t++ = *f++;
|
|
378 }
|
|
379
|
|
380 #else /* __cplusplus */
|
|
381
|
|
382 /* This is the most reliable way to avoid incompatibilities
|
|
383 in available built-in functions on various systems. */
|
|
384 static void
|
|
385 __yy_memcpy (char *to, char *from, unsigned int count)
|
|
386 {
|
|
387 register char *t = to;
|
|
388 register char *f = from;
|
|
389 register int i = count;
|
|
390
|
|
391 while (i-- > 0)
|
|
392 *t++ = *f++;
|
|
393 }
|
|
394
|
|
395 #endif
|
|
396 #endif
|
|
397
|
|
398 #line 217 "/usr/share/misc/bison.simple"
|
|
399
|
|
400 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
|
|
401 into yyparse. The argument should have type void *.
|
|
402 It should actually point to an object.
|
|
403 Grammar actions can access the variable by casting it
|
|
404 to the proper pointer type. */
|
|
405
|
|
406 #ifdef YYPARSE_PARAM
|
|
407 #ifdef __cplusplus
|
|
408 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
|
|
409 #define YYPARSE_PARAM_DECL
|
|
410 #else /* not __cplusplus */
|
|
411 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
|
|
412 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
|
|
413 #endif /* not __cplusplus */
|
|
414 #else /* not YYPARSE_PARAM */
|
|
415 #define YYPARSE_PARAM_ARG
|
|
416 #define YYPARSE_PARAM_DECL
|
|
417 #endif /* not YYPARSE_PARAM */
|
|
418
|
|
419 /* Prevent warning if -Wstrict-prototypes. */
|
|
420 #ifdef __GNUC__
|
|
421 #ifdef YYPARSE_PARAM
|
|
422 int yyparse (void *);
|
|
423 #else
|
|
424 int yyparse (void);
|
|
425 #endif
|
|
426 #endif
|
|
427
|
|
428 int
|
|
429 yyparse(YYPARSE_PARAM_ARG)
|
|
430 YYPARSE_PARAM_DECL
|
|
431 {
|
|
432 register int yystate;
|
|
433 register int yyn;
|
|
434 register short *yyssp;
|
|
435 register YYSTYPE *yyvsp;
|
|
436 int yyerrstatus; /* number of tokens to shift before error messages enabled */
|
|
437 int yychar1 = 0; /* lookahead token as an internal (translated) token number */
|
|
438
|
|
439 short yyssa[YYINITDEPTH]; /* the state stack */
|
|
440 YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */
|
|
441
|
|
442 short *yyss = yyssa; /* refer to the stacks thru separate pointers */
|
|
443 YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */
|
|
444
|
|
445 #ifdef YYLSP_NEEDED
|
|
446 YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */
|
|
447 YYLTYPE *yyls = yylsa;
|
|
448 YYLTYPE *yylsp;
|
|
449
|
|
450 #define YYPOPSTACK (yyvsp--, yyssp--, yylsp--)
|
|
451 #else
|
|
452 #define YYPOPSTACK (yyvsp--, yyssp--)
|
|
453 #endif
|
|
454
|
|
455 int yystacksize = YYINITDEPTH;
|
|
456 int yyfree_stacks = 0;
|
|
457
|
|
458 #ifdef YYPURE
|
|
459 int yychar;
|
|
460 YYSTYPE yylval;
|
|
461 int yynerrs;
|
|
462 #ifdef YYLSP_NEEDED
|
|
463 YYLTYPE yylloc;
|
|
464 #endif
|
|
465 #endif
|
|
466
|
|
467 YYSTYPE yyval; /* the variable used to return */
|
|
468 /* semantic values from the action */
|
|
469 /* routines */
|
|
470
|
|
471 int yylen;
|
|
472
|
|
473 #if YYDEBUG != 0
|
|
474 if (yydebug)
|
|
475 fprintf(stderr, "Starting parse\n");
|
|
476 #endif
|
|
477
|
|
478 yystate = 0;
|
|
479 yyerrstatus = 0;
|
|
480 yynerrs = 0;
|
|
481 yychar = YYEMPTY; /* Cause a token to be read. */
|
|
482
|
|
483 /* Initialize stack pointers.
|
|
484 Waste one element of value and location stack
|
|
485 so that they stay on the same level as the state stack.
|
|
486 The wasted elements are never initialized. */
|
|
487
|
|
488 yyssp = yyss - 1;
|
|
489 yyvsp = yyvs;
|
|
490 #ifdef YYLSP_NEEDED
|
|
491 yylsp = yyls;
|
|
492 #endif
|
|
493
|
|
494 /* Push a new state, which is found in yystate . */
|
|
495 /* In all cases, when you get here, the value and location stacks
|
|
496 have just been pushed. so pushing a state here evens the stacks. */
|
|
497 yynewstate:
|
|
498
|
|
499 *++yyssp = yystate;
|
|
500
|
|
501 if (yyssp >= yyss + yystacksize - 1)
|
|
502 {
|
|
503 /* Give user a chance to reallocate the stack */
|
|
504 /* Use copies of these so that the &'s don't force the real ones into memory. */
|
|
505 YYSTYPE *yyvs1 = yyvs;
|
|
506 short *yyss1 = yyss;
|
|
507 #ifdef YYLSP_NEEDED
|
|
508 YYLTYPE *yyls1 = yyls;
|
|
509 #endif
|
|
510
|
|
511 /* Get the current used size of the three stacks, in elements. */
|
|
512 int size = yyssp - yyss + 1;
|
|
513
|
|
514 #ifdef yyoverflow
|
|
515 /* Each stack pointer address is followed by the size of
|
|
516 the data in use in that stack, in bytes. */
|
|
517 #ifdef YYLSP_NEEDED
|
|
518 /* This used to be a conditional around just the two extra args,
|
|
519 but that might be undefined if yyoverflow is a macro. */
|
|
520 yyoverflow("parser stack overflow",
|
|
521 &yyss1, size * sizeof (*yyssp),
|
|
522 &yyvs1, size * sizeof (*yyvsp),
|
|
523 &yyls1, size * sizeof (*yylsp),
|
|
524 &yystacksize);
|
|
525 #else
|
|
526 yyoverflow("parser stack overflow",
|
|
527 &yyss1, size * sizeof (*yyssp),
|
|
528 &yyvs1, size * sizeof (*yyvsp),
|
|
529 &yystacksize);
|
|
530 #endif
|
|
531
|
|
532 yyss = yyss1; yyvs = yyvs1;
|
|
533 #ifdef YYLSP_NEEDED
|
|
534 yyls = yyls1;
|
|
535 #endif
|
|
536 #else /* no yyoverflow */
|
|
537 /* Extend the stack our own way. */
|
|
538 if (yystacksize >= YYMAXDEPTH)
|
|
539 {
|
|
540 yyerror("parser stack overflow");
|
|
541 if (yyfree_stacks)
|
|
542 {
|
|
543 free (yyss);
|
|
544 free (yyvs);
|
|
545 #ifdef YYLSP_NEEDED
|
|
546 free (yyls);
|
|
547 #endif
|
|
548 }
|
|
549 return 2;
|
|
550 }
|
|
551 yystacksize *= 2;
|
|
552 if (yystacksize > YYMAXDEPTH)
|
|
553 yystacksize = YYMAXDEPTH;
|
|
554 #ifndef YYSTACK_USE_ALLOCA
|
|
555 yyfree_stacks = 1;
|
|
556 #endif
|
|
557 yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp));
|
|
558 __yy_memcpy ((char *)yyss, (char *)yyss1,
|
|
559 size * (unsigned int) sizeof (*yyssp));
|
|
560 yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp));
|
|
561 __yy_memcpy ((char *)yyvs, (char *)yyvs1,
|
|
562 size * (unsigned int) sizeof (*yyvsp));
|
|
563 #ifdef YYLSP_NEEDED
|
|
564 yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp));
|
|
565 __yy_memcpy ((char *)yyls, (char *)yyls1,
|
|
566 size * (unsigned int) sizeof (*yylsp));
|
|
567 #endif
|
|
568 #endif /* no yyoverflow */
|
|
569
|
|
570 yyssp = yyss + size - 1;
|
|
571 yyvsp = yyvs + size - 1;
|
|
572 #ifdef YYLSP_NEEDED
|
|
573 yylsp = yyls + size - 1;
|
|
574 #endif
|
|
575
|
|
576 #if YYDEBUG != 0
|
|
577 if (yydebug)
|
|
578 fprintf(stderr, "Stack size increased to %d\n", yystacksize);
|
|
579 #endif
|
|
580
|
|
581 if (yyssp >= yyss + yystacksize - 1)
|
|
582 YYABORT;
|
|
583 }
|
|
584
|
|
585 #if YYDEBUG != 0
|
|
586 if (yydebug)
|
|
587 fprintf(stderr, "Entering state %d\n", yystate);
|
|
588 #endif
|
|
589
|
|
590 goto yybackup;
|
|
591 yybackup:
|
|
592
|
|
593 /* Do appropriate processing given the current state. */
|
|
594 /* Read a lookahead token if we need one and don't already have one. */
|
|
595 /* yyresume: */
|
|
596
|
|
597 /* First try to decide what to do without reference to lookahead token. */
|
|
598
|
|
599 yyn = yypact[yystate];
|
|
600 if (yyn == YYFLAG)
|
|
601 goto yydefault;
|
|
602
|
|
603 /* Not known => get a lookahead token if don't already have one. */
|
|
604
|
|
605 /* yychar is either YYEMPTY or YYEOF
|
|
606 or a valid token in external form. */
|
|
607
|
|
608 if (yychar == YYEMPTY)
|
|
609 {
|
|
610 #if YYDEBUG != 0
|
|
611 if (yydebug)
|
|
612 fprintf(stderr, "Reading a token: ");
|
|
613 #endif
|
|
614 yychar = YYLEX;
|
|
615 }
|
|
616
|
|
617 /* Convert token to internal form (in yychar1) for indexing tables with */
|
|
618
|
|
619 if (yychar <= 0) /* This means end of input. */
|
|
620 {
|
|
621 yychar1 = 0;
|
|
622 yychar = YYEOF; /* Don't call YYLEX any more */
|
|
623
|
|
624 #if YYDEBUG != 0
|
|
625 if (yydebug)
|
|
626 fprintf(stderr, "Now at end of input.\n");
|
|
627 #endif
|
|
628 }
|
|
629 else
|
|
630 {
|
|
631 yychar1 = YYTRANSLATE(yychar);
|
|
632
|
|
633 #if YYDEBUG != 0
|
|
634 if (yydebug)
|
|
635 {
|
|
636 fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
|
|
637 /* Give the individual parser a way to print the precise meaning
|
|
638 of a token, for further debugging info. */
|
|
639 #ifdef YYPRINT
|
|
640 YYPRINT (stderr, yychar, yylval);
|
|
641 #endif
|
|
642 fprintf (stderr, ")\n");
|
|
643 }
|
|
644 #endif
|
|
645 }
|
|
646
|
|
647 yyn += yychar1;
|
|
648 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
|
|
649 goto yydefault;
|
|
650
|
|
651 yyn = yytable[yyn];
|
|
652
|
|
653 /* yyn is what to do for this token type in this state.
|
|
654 Negative => reduce, -yyn is rule number.
|
|
655 Positive => shift, yyn is new state.
|
|
656 New state is final state => don't bother to shift,
|
|
657 just return success.
|
|
658 0, or most negative number => error. */
|
|
659
|
|
660 if (yyn < 0)
|
|
661 {
|
|
662 if (yyn == YYFLAG)
|
|
663 goto yyerrlab;
|
|
664 yyn = -yyn;
|
|
665 goto yyreduce;
|
|
666 }
|
|
667 else if (yyn == 0)
|
|
668 goto yyerrlab;
|
|
669
|
|
670 if (yyn == YYFINAL)
|
|
671 YYACCEPT;
|
|
672
|
|
673 /* Shift the lookahead token. */
|
|
674
|
|
675 #if YYDEBUG != 0
|
|
676 if (yydebug)
|
|
677 fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
|
|
678 #endif
|
|
679
|
|
680 /* Discard the token being shifted unless it is eof. */
|
|
681 if (yychar != YYEOF)
|
|
682 yychar = YYEMPTY;
|
|
683
|
|
684 *++yyvsp = yylval;
|
|
685 #ifdef YYLSP_NEEDED
|
|
686 *++yylsp = yylloc;
|
|
687 #endif
|
|
688
|
|
689 /* count tokens shifted since error; after three, turn off error status. */
|
|
690 if (yyerrstatus) yyerrstatus--;
|
|
691
|
|
692 yystate = yyn;
|
|
693 goto yynewstate;
|
|
694
|
|
695 /* Do the default action for the current state. */
|
|
696 yydefault:
|
|
697
|
|
698 yyn = yydefact[yystate];
|
|
699 if (yyn == 0)
|
|
700 goto yyerrlab;
|
|
701
|
|
702 /* Do a reduction. yyn is the number of a rule to reduce with. */
|
|
703 yyreduce:
|
|
704 yylen = yyr2[yyn];
|
|
705 if (yylen > 0)
|
|
706 yyval = yyvsp[1-yylen]; /* implement default value of the action */
|
|
707
|
|
708 #if YYDEBUG != 0
|
|
709 if (yydebug)
|
|
710 {
|
|
711 int i;
|
|
712
|
|
713 fprintf (stderr, "Reducing via rule %d (line %d), ",
|
|
714 yyn, yyrline[yyn]);
|
|
715
|
|
716 /* Print the symbols being reduced, and their result. */
|
|
717 for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
|
|
718 fprintf (stderr, "%s ", yytname[yyrhs[i]]);
|
|
719 fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
|
|
720 }
|
|
721 #endif
|
|
722
|
|
723
|
|
724 switch (yyn) {
|
|
725
|
|
726 case 4:
|
|
727 #line 80 "parser.y"
|
|
728 { ;
|
|
729 break;}
|
|
730 case 6:
|
|
731 #line 83 "parser.y"
|
|
732 { yyerrok; ;
|
|
733 break;}
|
|
734 case 7:
|
|
735 #line 88 "parser.y"
|
|
736 {
|
|
737 ;
|
|
738 break;}
|
|
739 case 8:
|
|
740 #line 91 "parser.y"
|
|
741 {
|
|
742 ;
|
|
743 break;}
|
|
744 case 9:
|
|
745 #line 96 "parser.y"
|
|
746 {
|
|
747 char *buf = g_strdup_printf ("c%f:", yyvsp[0].d_value);
|
|
748 GENERATE (buf);
|
|
749 g_free (buf);
|
|
750 ;
|
|
751 break;}
|
|
752 case 10:
|
|
753 #line 102 "parser.y"
|
|
754 {
|
|
755 char *buf = g_strdup_printf ("l%s:", yyvsp[0].s_value);
|
|
756 GENERATE (buf);
|
|
757 g_free (buf);
|
|
758 ;
|
|
759 break;}
|
|
760 case 11:
|
|
761 #line 108 "parser.y"
|
|
762 {
|
|
763 char *buf = g_strdup_printf ("s%s:", yyvsp[-2].s_value);
|
|
764 GENERATE (buf);
|
|
765 g_free (buf);
|
|
766 ;
|
|
767 break;}
|
|
768 case 12:
|
|
769 #line 114 "parser.y"
|
|
770 {
|
|
771 char *buf = g_strdup_printf ("f%s:", yyvsp[-3].s_value);
|
|
772 GENERATE (buf);
|
|
773 g_free (buf);
|
|
774 ;
|
|
775 break;}
|
|
776 case 13:
|
|
777 #line 121 "parser.y"
|
|
778 { GENERATE (">"); ;
|
|
779 break;}
|
|
780 case 14:
|
|
781 #line 123 "parser.y"
|
|
782 { GENERATE ("<"); ;
|
|
783 break;}
|
|
784 case 15:
|
|
785 #line 126 "parser.y"
|
|
786 { GENERATE ("+"); ;
|
|
787 break;}
|
|
788 case 16:
|
|
789 #line 128 "parser.y"
|
|
790 { GENERATE ("-"); ;
|
|
791 break;}
|
|
792 case 17:
|
|
793 #line 130 "parser.y"
|
|
794 { GENERATE ("*"); ;
|
|
795 break;}
|
|
796 case 18:
|
|
797 #line 132 "parser.y"
|
|
798 { GENERATE ("/"); ;
|
|
799 break;}
|
|
800 case 19:
|
|
801 #line 134 "parser.y"
|
|
802 { GENERATE ("n"); ;
|
|
803 break;}
|
|
804 case 20:
|
|
805 #line 136 "parser.y"
|
|
806 { GENERATE ("^"); ;
|
|
807 break;}
|
|
808 case 21:
|
|
809 #line 138 "parser.y"
|
|
810 { ;
|
|
811 break;}
|
|
812 }
|
|
813 /* the action file gets copied in in place of this dollarsign */
|
|
814 #line 543 "/usr/share/misc/bison.simple"
|
|
815
|
|
816 yyvsp -= yylen;
|
|
817 yyssp -= yylen;
|
|
818 #ifdef YYLSP_NEEDED
|
|
819 yylsp -= yylen;
|
|
820 #endif
|
|
821
|
|
822 #if YYDEBUG != 0
|
|
823 if (yydebug)
|
|
824 {
|
|
825 short *ssp1 = yyss - 1;
|
|
826 fprintf (stderr, "state stack now");
|
|
827 while (ssp1 != yyssp)
|
|
828 fprintf (stderr, " %d", *++ssp1);
|
|
829 fprintf (stderr, "\n");
|
|
830 }
|
|
831 #endif
|
|
832
|
|
833 *++yyvsp = yyval;
|
|
834
|
|
835 #ifdef YYLSP_NEEDED
|
|
836 yylsp++;
|
|
837 if (yylen == 0)
|
|
838 {
|
|
839 yylsp->first_line = yylloc.first_line;
|
|
840 yylsp->first_column = yylloc.first_column;
|
|
841 yylsp->last_line = (yylsp-1)->last_line;
|
|
842 yylsp->last_column = (yylsp-1)->last_column;
|
|
843 yylsp->text = 0;
|
|
844 }
|
|
845 else
|
|
846 {
|
|
847 yylsp->last_line = (yylsp+yylen-1)->last_line;
|
|
848 yylsp->last_column = (yylsp+yylen-1)->last_column;
|
|
849 }
|
|
850 #endif
|
|
851
|
|
852 /* Now "shift" the result of the reduction.
|
|
853 Determine what state that goes to,
|
|
854 based on the state we popped back to
|
|
855 and the rule number reduced by. */
|
|
856
|
|
857 yyn = yyr1[yyn];
|
|
858
|
|
859 yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
|
|
860 if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
|
|
861 yystate = yytable[yystate];
|
|
862 else
|
|
863 yystate = yydefgoto[yyn - YYNTBASE];
|
|
864
|
|
865 goto yynewstate;
|
|
866
|
|
867 yyerrlab: /* here on detecting error */
|
|
868
|
|
869 if (! yyerrstatus)
|
|
870 /* If not already recovering from an error, report this error. */
|
|
871 {
|
|
872 ++yynerrs;
|
|
873
|
|
874 #ifdef YYERROR_VERBOSE
|
|
875 yyn = yypact[yystate];
|
|
876
|
|
877 if (yyn > YYFLAG && yyn < YYLAST)
|
|
878 {
|
|
879 int size = 0;
|
|
880 char *msg;
|
|
881 int x, count;
|
|
882
|
|
883 count = 0;
|
|
884 /* Start X at -yyn if nec to avoid negative indexes in yycheck. */
|
|
885 for (x = (yyn < 0 ? -yyn : 0);
|
|
886 x < (sizeof(yytname) / sizeof(char *)); x++)
|
|
887 if (yycheck[x + yyn] == x)
|
|
888 size += strlen(yytname[x]) + 15, count++;
|
|
889 msg = (char *) malloc(size + 15);
|
|
890 if (msg != 0)
|
|
891 {
|
|
892 strcpy(msg, "parse error");
|
|
893
|
|
894 if (count < 5)
|
|
895 {
|
|
896 count = 0;
|
|
897 for (x = (yyn < 0 ? -yyn : 0);
|
|
898 x < (sizeof(yytname) / sizeof(char *)); x++)
|
|
899 if (yycheck[x + yyn] == x)
|
|
900 {
|
|
901 strcat(msg, count == 0 ? ", expecting `" : " or `");
|
|
902 strcat(msg, yytname[x]);
|
|
903 strcat(msg, "'");
|
|
904 count++;
|
|
905 }
|
|
906 }
|
|
907 yyerror(msg);
|
|
908 free(msg);
|
|
909 }
|
|
910 else
|
|
911 yyerror ("parse error; also virtual memory exceeded");
|
|
912 }
|
|
913 else
|
|
914 #endif /* YYERROR_VERBOSE */
|
|
915 yyerror("parse error");
|
|
916 }
|
|
917
|
|
918 goto yyerrlab1;
|
|
919 yyerrlab1: /* here on error raised explicitly by an action */
|
|
920
|
|
921 if (yyerrstatus == 3)
|
|
922 {
|
|
923 /* if just tried and failed to reuse lookahead token after an error, discard it. */
|
|
924
|
|
925 /* return failure if at end of input */
|
|
926 if (yychar == YYEOF)
|
|
927 YYABORT;
|
|
928
|
|
929 #if YYDEBUG != 0
|
|
930 if (yydebug)
|
|
931 fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
|
|
932 #endif
|
|
933
|
|
934 yychar = YYEMPTY;
|
|
935 }
|
|
936
|
|
937 /* Else will try to reuse lookahead token
|
|
938 after shifting the error token. */
|
|
939
|
|
940 yyerrstatus = 3; /* Each real token shifted decrements this */
|
|
941
|
|
942 goto yyerrhandle;
|
|
943
|
|
944 yyerrdefault: /* current state does not do anything special for the error token. */
|
|
945
|
|
946 #if 0
|
|
947 /* This is wrong; only states that explicitly want error tokens
|
|
948 should shift them. */
|
|
949 yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/
|
|
950 if (yyn) goto yydefault;
|
|
951 #endif
|
|
952
|
|
953 yyerrpop: /* pop the current state because it cannot handle the error token */
|
|
954
|
|
955 if (yyssp == yyss) YYABORT;
|
|
956 yyvsp--;
|
|
957 yystate = *--yyssp;
|
|
958 #ifdef YYLSP_NEEDED
|
|
959 yylsp--;
|
|
960 #endif
|
|
961
|
|
962 #if YYDEBUG != 0
|
|
963 if (yydebug)
|
|
964 {
|
|
965 short *ssp1 = yyss - 1;
|
|
966 fprintf (stderr, "Error: state stack now");
|
|
967 while (ssp1 != yyssp)
|
|
968 fprintf (stderr, " %d", *++ssp1);
|
|
969 fprintf (stderr, "\n");
|
|
970 }
|
|
971 #endif
|
|
972
|
|
973 yyerrhandle:
|
|
974
|
|
975 yyn = yypact[yystate];
|
|
976 if (yyn == YYFLAG)
|
|
977 goto yyerrdefault;
|
|
978
|
|
979 yyn += YYTERROR;
|
|
980 if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
|
|
981 goto yyerrdefault;
|
|
982
|
|
983 yyn = yytable[yyn];
|
|
984 if (yyn < 0)
|
|
985 {
|
|
986 if (yyn == YYFLAG)
|
|
987 goto yyerrpop;
|
|
988 yyn = -yyn;
|
|
989 goto yyreduce;
|
|
990 }
|
|
991 else if (yyn == 0)
|
|
992 goto yyerrpop;
|
|
993
|
|
994 if (yyn == YYFINAL)
|
|
995 YYACCEPT;
|
|
996
|
|
997 #if YYDEBUG != 0
|
|
998 if (yydebug)
|
|
999 fprintf(stderr, "Shifting error token, ");
|
|
1000 #endif
|
|
1001
|
|
1002 *++yyvsp = yylval;
|
|
1003 #ifdef YYLSP_NEEDED
|
|
1004 *++yylsp = yylloc;
|
|
1005 #endif
|
|
1006
|
|
1007 yystate = yyn;
|
|
1008 goto yynewstate;
|
|
1009
|
|
1010 yyacceptlab:
|
|
1011 /* YYACCEPT comes here. */
|
|
1012 if (yyfree_stacks)
|
|
1013 {
|
|
1014 free (yyss);
|
|
1015 free (yyvs);
|
|
1016 #ifdef YYLSP_NEEDED
|
|
1017 free (yyls);
|
|
1018 #endif
|
|
1019 }
|
|
1020 return 0;
|
|
1021
|
|
1022 yyabortlab:
|
|
1023 /* YYABORT comes here. */
|
|
1024 if (yyfree_stacks)
|
|
1025 {
|
|
1026 free (yyss);
|
|
1027 free (yyvs);
|
|
1028 #ifdef YYLSP_NEEDED
|
|
1029 free (yyls);
|
|
1030 #endif
|
|
1031 }
|
|
1032 return 1;
|
|
1033 }
|
|
1034 #line 141 "parser.y"
|
|
1035
|
|
1036 /* End of grammar */
|
|
1037
|
|
1038 /* Called by yyparse on error. */
|
|
1039 int yyerror (char *s) {
|
|
1040 /* Ignore errors, just print a warning. */
|
|
1041 g_warning ("%s\n", s);
|
|
1042 return 0;
|
|
1043 }
|
|
1044
|
|
1045 int yylex (YYSTYPE *yylval, void *yyparam) {
|
|
1046 int c;
|
|
1047 parser_control *pc = (parser_control *) yyparam;
|
|
1048
|
|
1049 /* Ignore whitespace, get first nonwhite character. */
|
|
1050 while ((c = fgetc (pc->input)) == ' ' || c == '\t' || c == '\n');
|
|
1051
|
|
1052 /* End of input ? */
|
|
1053 if (c == EOF)
|
|
1054 return 0;
|
|
1055
|
|
1056 /* Char starts a number => parse the number. */
|
|
1057 if (isdigit (c)) {
|
|
1058 ungetc (c, pc->input);/* Put the char back. */
|
|
1059 {
|
|
1060 char *old_locale, *saved_locale;
|
|
1061
|
|
1062 old_locale = setlocale (LC_ALL, NULL);
|
|
1063 saved_locale = g_strdup (old_locale);
|
|
1064 setlocale (LC_ALL, "C");
|
|
1065 fscanf (pc->input, "%lf", &yylval->d_value);
|
|
1066 setlocale (LC_ALL, saved_locale);
|
|
1067 g_free (saved_locale);
|
|
1068 }
|
|
1069 return NUMBER;
|
|
1070 }
|
|
1071
|
|
1072 /* Char starts an identifier => read the name. */
|
|
1073 if (isalpha (c)) {
|
|
1074 GString *sym_name;
|
|
1075
|
|
1076 sym_name = g_string_new (NULL);
|
|
1077
|
|
1078 do {
|
|
1079 sym_name = g_string_append_c (sym_name, c);
|
|
1080
|
|
1081 /* Get another character. */
|
|
1082 c = fgetc (pc->input);
|
|
1083 } while (c != EOF && isalnum (c));
|
|
1084
|
|
1085 ungetc (c, pc->input);
|
|
1086
|
|
1087 yylval->s_value = sym_name->str;
|
|
1088
|
|
1089 g_string_free (sym_name, FALSE);
|
|
1090
|
|
1091 return NAME;
|
|
1092 }
|
|
1093
|
|
1094 /* Any other character is a token by itself. */
|
|
1095 return c;
|
|
1096 }
|
|
1097
|
|
1098 static int load_name (char *str, char **name) {
|
|
1099 int count = 0;
|
|
1100 GString *new = g_string_new (NULL);
|
|
1101
|
|
1102 while (*str != 0 && *str != ':') {
|
|
1103 g_string_append_c (new, *str++);
|
|
1104 count++;
|
|
1105 }
|
|
1106
|
|
1107 *name = new->str;
|
|
1108 g_string_free (new, FALSE);
|
|
1109
|
|
1110 return count;
|
|
1111 }
|
|
1112
|
|
1113 static gboolean expr_add_compile (expression_t *expr, symbol_dict_t *dict,
|
|
1114 char *str) {
|
|
1115 char op;
|
|
1116 double dval;
|
|
1117 int i;
|
|
1118 char *name;
|
|
1119
|
|
1120 while ((op = *str++)) {
|
|
1121 switch (op) {
|
|
1122 case 'c': /* A constant. */
|
|
1123 store_byte (expr, 'c');
|
|
1124 sscanf (str, "%lf%n", &dval, &i);
|
|
1125 str += i;
|
|
1126 store_double (expr, dval);
|
|
1127 str++; /* Skip ';' */
|
|
1128 break;
|
|
1129
|
|
1130 case 'f': /* A function call. */
|
|
1131 store_byte (expr, 'f');
|
|
1132 str += load_name (str, &name);
|
|
1133 i = function_lookup (name);
|
|
1134 if (i < 0) return FALSE; /* Fail on error. */
|
|
1135 store_int (expr, i);
|
|
1136 g_free (name);
|
|
1137 str++; /* Skip ';' */
|
|
1138 break;
|
|
1139
|
|
1140 case 'l': /* Load a variable. */
|
|
1141 case 's': /* Store a variable. */
|
|
1142 store_byte (expr, op);
|
|
1143 str += load_name (str, &name);
|
|
1144 i = dict_lookup (dict, name);
|
|
1145 store_int (expr, i);
|
|
1146 g_free (name);
|
|
1147 str++; /* Skip ';' */
|
|
1148 break;
|
|
1149
|
|
1150 default: /* Copy verbatim. */
|
|
1151 store_byte (expr, op);
|
|
1152 break;
|
|
1153 }
|
|
1154 }
|
|
1155
|
|
1156 return TRUE;
|
|
1157 }
|
|
1158
|
|
1159 expression_t *expr_compile_string (const char* str, symbol_dict_t *dict) {
|
|
1160 parser_control pc;
|
|
1161 FILE *stream;
|
|
1162
|
|
1163 stream = fmemopen (str, strlen (str), "r");
|
|
1164
|
|
1165 pc.input = stream;
|
|
1166 pc.expr = expr_new ();
|
|
1167 pc.dict = dict;
|
|
1168
|
|
1169 if (yyparse (&pc) != 0) {
|
|
1170 /* Check for error. */
|
|
1171 expr_free (pc.expr);
|
|
1172 pc.expr = NULL;
|
|
1173 }
|
|
1174
|
|
1175 fclose (stream);
|
|
1176
|
|
1177 return pc.expr;
|
|
1178 }
|