plural.y revision 1.8 1 1.1 mrg %{
2 1.1 mrg /* Expression parsing for plural form selection.
3 1.8 mrg Copyright (C) 2000-2020 Free Software Foundation, Inc.
4 1.1 mrg Written by Ulrich Drepper <drepper (at) cygnus.com>, 2000.
5 1.1 mrg
6 1.1 mrg This program is free software; you can redistribute it and/or modify it
7 1.1 mrg under the terms of the GNU Library General Public License as published
8 1.1 mrg by the Free Software Foundation; either version 2, or (at your option)
9 1.1 mrg any later version.
10 1.1 mrg
11 1.1 mrg This program is distributed in the hope that it will be useful,
12 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 1.1 mrg Library General Public License for more details.
15 1.1 mrg
16 1.1 mrg You should have received a copy of the GNU Library General Public
17 1.1 mrg License along with this program; if not, write to the Free Software
18 1.1 mrg Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
19 1.1 mrg USA. */
20 1.1 mrg
21 1.1 mrg /* The bison generated parser uses alloca. AIX 3 forces us to put this
22 1.1 mrg declaration at the beginning of the file. The declaration in bison's
23 1.1 mrg skeleton file comes too late. This must come before <config.h>
24 1.1 mrg because <config.h> may include arbitrary system headers. */
25 1.1 mrg #if defined _AIX && !defined __GNUC__
26 1.1 mrg #pragma alloca
27 1.1 mrg #endif
28 1.1 mrg
29 1.1 mrg #ifdef HAVE_CONFIG_H
30 1.1 mrg # include <config.h>
31 1.1 mrg #endif
32 1.1 mrg
33 1.1 mrg #include <stddef.h>
34 1.1 mrg #include <stdlib.h>
35 1.1 mrg #include "plural-exp.h"
36 1.1 mrg
37 1.1 mrg /* The main function generated by the parser is called __gettextparse,
38 1.1 mrg but we want it to be called PLURAL_PARSE. */
39 1.1 mrg #ifndef _LIBC
40 1.1 mrg # define __gettextparse PLURAL_PARSE
41 1.1 mrg #endif
42 1.1 mrg
43 1.8 mrg #ifndef USE_BISON3
44 1.1 mrg #define YYLEX_PARAM &((struct parse_args *) arg)->cp
45 1.1 mrg #define YYPARSE_PARAM arg
46 1.8 mrg #endif
47 1.1 mrg %}
48 1.1 mrg %pure_parser
49 1.8 mrg /* BISON3 %parse-param {struct parse_args *arg} */
50 1.8 mrg /* BISON3 %lex-param {struct parse_args *arg} */
51 1.8 mrg /* BISON3 %define api.pure full */
52 1.1 mrg %expect 7
53 1.1 mrg
54 1.1 mrg %union {
55 1.1 mrg unsigned long int num;
56 1.1 mrg enum operator op;
57 1.1 mrg struct expression *exp;
58 1.1 mrg }
59 1.1 mrg
60 1.1 mrg %{
61 1.1 mrg /* Prototypes for local functions. */
62 1.1 mrg static struct expression *new_exp PARAMS ((int nargs, enum operator op,
63 1.1 mrg struct expression * const *args));
64 1.1 mrg static inline struct expression *new_exp_0 PARAMS ((enum operator op));
65 1.1 mrg static inline struct expression *new_exp_1 PARAMS ((enum operator op,
66 1.1 mrg struct expression *right));
67 1.1 mrg static struct expression *new_exp_2 PARAMS ((enum operator op,
68 1.1 mrg struct expression *left,
69 1.1 mrg struct expression *right));
70 1.1 mrg static inline struct expression *new_exp_3 PARAMS ((enum operator op,
71 1.1 mrg struct expression *bexp,
72 1.1 mrg struct expression *tbranch,
73 1.1 mrg struct expression *fbranch));
74 1.8 mrg #ifdef USE_BISON3
75 1.8 mrg static int yylex PARAMS ((YYSTYPE *lval, struct parse_args *arg));
76 1.8 mrg static void yyerror PARAMS ((struct parse_args *arg, const char *str));
77 1.8 mrg #else
78 1.1 mrg static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
79 1.1 mrg static void yyerror PARAMS ((const char *str));
80 1.8 mrg #endif
81 1.1 mrg
82 1.1 mrg /* Allocation of expressions. */
83 1.1 mrg
84 1.1 mrg static struct expression *
85 1.1 mrg new_exp (nargs, op, args)
86 1.1 mrg int nargs;
87 1.1 mrg enum operator op;
88 1.1 mrg struct expression * const *args;
89 1.1 mrg {
90 1.1 mrg int i;
91 1.1 mrg struct expression *newp;
92 1.1 mrg
93 1.1 mrg /* If any of the argument could not be malloc'ed, just return NULL. */
94 1.1 mrg for (i = nargs - 1; i >= 0; i--)
95 1.1 mrg if (args[i] == NULL)
96 1.1 mrg goto fail;
97 1.1 mrg
98 1.1 mrg /* Allocate a new expression. */
99 1.1 mrg newp = (struct expression *) malloc (sizeof (*newp));
100 1.1 mrg if (newp != NULL)
101 1.1 mrg {
102 1.1 mrg newp->nargs = nargs;
103 1.1 mrg newp->operation = op;
104 1.1 mrg for (i = nargs - 1; i >= 0; i--)
105 1.1 mrg newp->val.args[i] = args[i];
106 1.1 mrg return newp;
107 1.1 mrg }
108 1.1 mrg
109 1.1 mrg fail:
110 1.1 mrg for (i = nargs - 1; i >= 0; i--)
111 1.1 mrg FREE_EXPRESSION (args[i]);
112 1.1 mrg
113 1.1 mrg return NULL;
114 1.1 mrg }
115 1.1 mrg
116 1.1 mrg static inline struct expression *
117 1.1 mrg new_exp_0 (op)
118 1.1 mrg enum operator op;
119 1.1 mrg {
120 1.1 mrg return new_exp (0, op, NULL);
121 1.1 mrg }
122 1.1 mrg
123 1.1 mrg static inline struct expression *
124 1.1 mrg new_exp_1 (op, right)
125 1.1 mrg enum operator op;
126 1.1 mrg struct expression *right;
127 1.1 mrg {
128 1.1 mrg struct expression *args[1];
129 1.1 mrg
130 1.1 mrg args[0] = right;
131 1.1 mrg return new_exp (1, op, args);
132 1.1 mrg }
133 1.1 mrg
134 1.1 mrg static struct expression *
135 1.1 mrg new_exp_2 (op, left, right)
136 1.1 mrg enum operator op;
137 1.1 mrg struct expression *left;
138 1.1 mrg struct expression *right;
139 1.1 mrg {
140 1.1 mrg struct expression *args[2];
141 1.1 mrg
142 1.1 mrg args[0] = left;
143 1.1 mrg args[1] = right;
144 1.1 mrg return new_exp (2, op, args);
145 1.1 mrg }
146 1.1 mrg
147 1.1 mrg static inline struct expression *
148 1.1 mrg new_exp_3 (op, bexp, tbranch, fbranch)
149 1.1 mrg enum operator op;
150 1.1 mrg struct expression *bexp;
151 1.1 mrg struct expression *tbranch;
152 1.1 mrg struct expression *fbranch;
153 1.1 mrg {
154 1.1 mrg struct expression *args[3];
155 1.1 mrg
156 1.1 mrg args[0] = bexp;
157 1.1 mrg args[1] = tbranch;
158 1.1 mrg args[2] = fbranch;
159 1.1 mrg return new_exp (3, op, args);
160 1.1 mrg }
161 1.1 mrg
162 1.1 mrg %}
163 1.1 mrg
164 1.1 mrg /* This declares that all operators have the same associativity and the
165 1.1 mrg precedence order as in C. See [Harbison, Steele: C, A Reference Manual].
166 1.1 mrg There is no unary minus and no bitwise operators.
167 1.1 mrg Operators with the same syntactic behaviour have been merged into a single
168 1.1 mrg token, to save space in the array generated by bison. */
169 1.1 mrg %right '?' /* ? */
170 1.1 mrg %left '|' /* || */
171 1.1 mrg %left '&' /* && */
172 1.1 mrg %left EQUOP2 /* == != */
173 1.1 mrg %left CMPOP2 /* < > <= >= */
174 1.1 mrg %left ADDOP2 /* + - */
175 1.1 mrg %left MULOP2 /* * / % */
176 1.1 mrg %right '!' /* ! */
177 1.1 mrg
178 1.1 mrg %token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2
179 1.1 mrg %token <num> NUMBER
180 1.1 mrg %type <exp> exp
181 1.1 mrg
182 1.1 mrg %%
183 1.1 mrg
184 1.1 mrg start: exp
185 1.1 mrg {
186 1.1 mrg if ($1 == NULL)
187 1.1 mrg YYABORT;
188 1.1 mrg ((struct parse_args *) arg)->res = $1;
189 1.1 mrg }
190 1.1 mrg ;
191 1.1 mrg
192 1.1 mrg exp: exp '?' exp ':' exp
193 1.1 mrg {
194 1.1 mrg $$ = new_exp_3 (qmop, $1, $3, $5);
195 1.1 mrg }
196 1.1 mrg | exp '|' exp
197 1.1 mrg {
198 1.1 mrg $$ = new_exp_2 (lor, $1, $3);
199 1.1 mrg }
200 1.1 mrg | exp '&' exp
201 1.1 mrg {
202 1.1 mrg $$ = new_exp_2 (land, $1, $3);
203 1.1 mrg }
204 1.1 mrg | exp EQUOP2 exp
205 1.1 mrg {
206 1.1 mrg $$ = new_exp_2 ($2, $1, $3);
207 1.1 mrg }
208 1.1 mrg | exp CMPOP2 exp
209 1.1 mrg {
210 1.1 mrg $$ = new_exp_2 ($2, $1, $3);
211 1.1 mrg }
212 1.1 mrg | exp ADDOP2 exp
213 1.1 mrg {
214 1.1 mrg $$ = new_exp_2 ($2, $1, $3);
215 1.1 mrg }
216 1.1 mrg | exp MULOP2 exp
217 1.1 mrg {
218 1.1 mrg $$ = new_exp_2 ($2, $1, $3);
219 1.1 mrg }
220 1.1 mrg | '!' exp
221 1.1 mrg {
222 1.1 mrg $$ = new_exp_1 (lnot, $2);
223 1.1 mrg }
224 1.1 mrg | 'n'
225 1.1 mrg {
226 1.1 mrg $$ = new_exp_0 (var);
227 1.1 mrg }
228 1.1 mrg | NUMBER
229 1.1 mrg {
230 1.1 mrg if (($$ = new_exp_0 (num)) != NULL)
231 1.1 mrg $$->val.num = $1;
232 1.1 mrg }
233 1.1 mrg | '(' exp ')'
234 1.1 mrg {
235 1.1 mrg $$ = $2;
236 1.1 mrg }
237 1.1 mrg ;
238 1.1 mrg
239 1.1 mrg %%
240 1.1 mrg
241 1.1 mrg void
242 1.1 mrg internal_function
243 1.1 mrg FREE_EXPRESSION (exp)
244 1.1 mrg struct expression *exp;
245 1.1 mrg {
246 1.1 mrg if (exp == NULL)
247 1.1 mrg return;
248 1.1 mrg
249 1.1 mrg /* Handle the recursive case. */
250 1.1 mrg switch (exp->nargs)
251 1.1 mrg {
252 1.1 mrg case 3:
253 1.1 mrg FREE_EXPRESSION (exp->val.args[2]);
254 1.1 mrg /* FALLTHROUGH */
255 1.1 mrg case 2:
256 1.1 mrg FREE_EXPRESSION (exp->val.args[1]);
257 1.1 mrg /* FALLTHROUGH */
258 1.1 mrg case 1:
259 1.1 mrg FREE_EXPRESSION (exp->val.args[0]);
260 1.1 mrg /* FALLTHROUGH */
261 1.1 mrg default:
262 1.1 mrg break;
263 1.1 mrg }
264 1.1 mrg
265 1.1 mrg free (exp);
266 1.1 mrg }
267 1.1 mrg
268 1.1 mrg
269 1.8 mrg #ifdef USE_BISON3
270 1.8 mrg static int
271 1.8 mrg yylex (lval, arg)
272 1.8 mrg YYSTYPE *lval;
273 1.8 mrg struct parse_args *arg;
274 1.8 mrg {
275 1.8 mrg const char **pexp = &arg->cp;
276 1.8 mrg #else
277 1.1 mrg static int
278 1.1 mrg yylex (lval, pexp)
279 1.1 mrg YYSTYPE *lval;
280 1.1 mrg const char **pexp;
281 1.1 mrg {
282 1.8 mrg #endif
283 1.1 mrg const char *exp = *pexp;
284 1.1 mrg int result;
285 1.1 mrg
286 1.1 mrg while (1)
287 1.1 mrg {
288 1.1 mrg if (exp[0] == '\0')
289 1.1 mrg {
290 1.1 mrg *pexp = exp;
291 1.1 mrg return YYEOF;
292 1.1 mrg }
293 1.1 mrg
294 1.1 mrg if (exp[0] != ' ' && exp[0] != '\t')
295 1.1 mrg break;
296 1.1 mrg
297 1.1 mrg ++exp;
298 1.1 mrg }
299 1.1 mrg
300 1.1 mrg result = *exp++;
301 1.1 mrg switch (result)
302 1.1 mrg {
303 1.1 mrg case '0': case '1': case '2': case '3': case '4':
304 1.1 mrg case '5': case '6': case '7': case '8': case '9':
305 1.1 mrg {
306 1.1 mrg unsigned long int n = result - '0';
307 1.1 mrg while (exp[0] >= '0' && exp[0] <= '9')
308 1.1 mrg {
309 1.1 mrg n *= 10;
310 1.1 mrg n += exp[0] - '0';
311 1.1 mrg ++exp;
312 1.1 mrg }
313 1.1 mrg lval->num = n;
314 1.1 mrg result = NUMBER;
315 1.1 mrg }
316 1.1 mrg break;
317 1.1 mrg
318 1.1 mrg case '=':
319 1.1 mrg if (exp[0] == '=')
320 1.1 mrg {
321 1.1 mrg ++exp;
322 1.1 mrg lval->op = equal;
323 1.1 mrg result = EQUOP2;
324 1.1 mrg }
325 1.1 mrg else
326 1.1 mrg result = YYERRCODE;
327 1.1 mrg break;
328 1.1 mrg
329 1.1 mrg case '!':
330 1.1 mrg if (exp[0] == '=')
331 1.1 mrg {
332 1.1 mrg ++exp;
333 1.1 mrg lval->op = not_equal;
334 1.1 mrg result = EQUOP2;
335 1.1 mrg }
336 1.1 mrg break;
337 1.1 mrg
338 1.1 mrg case '&':
339 1.1 mrg case '|':
340 1.1 mrg if (exp[0] == result)
341 1.1 mrg ++exp;
342 1.1 mrg else
343 1.1 mrg result = YYERRCODE;
344 1.1 mrg break;
345 1.1 mrg
346 1.1 mrg case '<':
347 1.1 mrg if (exp[0] == '=')
348 1.1 mrg {
349 1.1 mrg ++exp;
350 1.1 mrg lval->op = less_or_equal;
351 1.1 mrg }
352 1.1 mrg else
353 1.1 mrg lval->op = less_than;
354 1.1 mrg result = CMPOP2;
355 1.1 mrg break;
356 1.1 mrg
357 1.1 mrg case '>':
358 1.1 mrg if (exp[0] == '=')
359 1.1 mrg {
360 1.1 mrg ++exp;
361 1.1 mrg lval->op = greater_or_equal;
362 1.1 mrg }
363 1.1 mrg else
364 1.1 mrg lval->op = greater_than;
365 1.1 mrg result = CMPOP2;
366 1.1 mrg break;
367 1.1 mrg
368 1.1 mrg case '*':
369 1.1 mrg lval->op = mult;
370 1.1 mrg result = MULOP2;
371 1.1 mrg break;
372 1.1 mrg
373 1.1 mrg case '/':
374 1.1 mrg lval->op = divide;
375 1.1 mrg result = MULOP2;
376 1.1 mrg break;
377 1.1 mrg
378 1.1 mrg case '%':
379 1.1 mrg lval->op = module;
380 1.1 mrg result = MULOP2;
381 1.1 mrg break;
382 1.1 mrg
383 1.1 mrg case '+':
384 1.1 mrg lval->op = plus;
385 1.1 mrg result = ADDOP2;
386 1.1 mrg break;
387 1.1 mrg
388 1.1 mrg case '-':
389 1.1 mrg lval->op = minus;
390 1.1 mrg result = ADDOP2;
391 1.1 mrg break;
392 1.1 mrg
393 1.1 mrg case 'n':
394 1.1 mrg case '?':
395 1.1 mrg case ':':
396 1.1 mrg case '(':
397 1.1 mrg case ')':
398 1.1 mrg /* Nothing, just return the character. */
399 1.1 mrg break;
400 1.1 mrg
401 1.1 mrg case ';':
402 1.1 mrg case '\n':
403 1.1 mrg case '\0':
404 1.1 mrg /* Be safe and let the user call this function again. */
405 1.1 mrg --exp;
406 1.1 mrg result = YYEOF;
407 1.1 mrg break;
408 1.1 mrg
409 1.1 mrg default:
410 1.1 mrg result = YYERRCODE;
411 1.1 mrg #if YYDEBUG != 0
412 1.1 mrg --exp;
413 1.1 mrg #endif
414 1.1 mrg break;
415 1.1 mrg }
416 1.1 mrg
417 1.1 mrg *pexp = exp;
418 1.1 mrg
419 1.1 mrg return result;
420 1.1 mrg }
421 1.1 mrg
422 1.1 mrg
423 1.8 mrg #ifdef USE_BISON3
424 1.8 mrg static void
425 1.8 mrg yyerror (arg, str)
426 1.8 mrg struct parse_args *arg;
427 1.8 mrg #else
428 1.1 mrg static void
429 1.1 mrg yyerror (str)
430 1.8 mrg #endif
431 1.1 mrg const char *str;
432 1.1 mrg {
433 1.1 mrg /* Do nothing. We don't print error messages here. */
434 1.1 mrg }
435