Update.
[glibc.git] / intl / plural.y
blobe85f7b8a65b88ccce66348c35accb190827baeb2
1 %{
2 /* Expression parsing for plural form selection.
3 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
4 Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
25 #include <stdlib.h>
26 #include "gettextP.h"
28 /* Names for the libintl functions are a problem. They must not clash
29 with existing names and they should follow ANSI C. But this source
30 code is also used in GNU C Library where the names have a __
31 prefix. So we have to make a difference here. */
32 #ifdef _LIBC
33 # define FREE_EXPRESSION __gettext_free_exp
34 #else
35 # define FREE_EXPRESSION gettext_free_exp__
36 # define __gettextparse gettextparse__
37 #endif
39 #define YYLEX_PARAM &((struct parse_args *) arg)->cp
40 #define YYPARSE_PARAM arg
42 %pure_parser
43 %expect 10
45 %union {
46 unsigned long int num;
47 enum operator op;
48 struct expression *exp;
52 /* Prototypes for local functions. */
53 static struct expression *new_exp PARAMS ((int nargs, enum operator op,
54 struct expression * const *args));
55 static inline struct expression *new_exp_0 PARAMS ((enum operator op));
56 static inline struct expression *new_exp_1 PARAMS ((enum operator op,
57 struct expression *right));
58 static struct expression *new_exp_2 PARAMS ((enum operator op,
59 struct expression *left,
60 struct expression *right));
61 static inline struct expression *new_exp_3 PARAMS ((enum operator op,
62 struct expression *bexp,
63 struct expression *tbranch,
64 struct expression *fbranch));
65 static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
66 static void yyerror PARAMS ((const char *str));
68 /* Allocation of expressions. */
70 static struct expression *
71 new_exp (nargs, op, args)
72 int nargs;
73 enum operator op;
74 struct expression * const *args;
76 int i;
77 struct expression *newp;
79 /* If any of the argument could not be malloc'ed, just return NULL. */
80 for (i = nargs - 1; i >= 0; i--)
81 if (args[i] == NULL)
82 goto fail;
84 /* Allocate a new expression. */
85 newp = (struct expression *) malloc (sizeof (*newp));
86 if (newp != NULL)
88 newp->nargs = nargs;
89 newp->operation = op;
90 for (i = nargs - 1; i >= 0; i--)
91 newp->val.args[i] = args[i];
92 return newp;
95 fail:
96 for (i = nargs - 1; i >= 0; i--)
97 FREE_EXPRESSION (args[i]);
99 return NULL;
102 static inline struct expression *
103 new_exp_0 (op)
104 enum operator op;
106 return new_exp (0, op, NULL);
109 static inline struct expression *
110 new_exp_1 (op, right)
111 enum operator op;
112 struct expression *right;
114 struct expression *args[1];
116 args[0] = right;
117 return new_exp (1, op, args);
120 static struct expression *
121 new_exp_2 (op, left, right)
122 enum operator op;
123 struct expression *left;
124 struct expression *right;
126 struct expression *args[2];
128 args[0] = left;
129 args[1] = right;
130 return new_exp (2, op, args);
133 static inline struct expression *
134 new_exp_3 (op, bexp, tbranch, fbranch)
135 enum operator op;
136 struct expression *bexp;
137 struct expression *tbranch;
138 struct expression *fbranch;
140 struct expression *args[3];
142 args[0] = bexp;
143 args[1] = tbranch;
144 args[2] = fbranch;
145 return new_exp (3, op, args);
150 /* This declares that all operators have the same associativity and the
151 precedence order as in C. See [Harbison, Steele: C, A Reference Manual].
152 There is no unary minus and no bitwise operators.
153 Operators with the same syntactic behaviour have been merged into a single
154 token, to save space in the array generated by bison. */
155 %right '?' /* ? */
156 %left '|' /* || */
157 %left '&' /* && */
158 %left EQUOP2 /* == != */
159 %left CMPOP2 /* < > <= >= */
160 %left ADDOP2 /* + - */
161 %left MULOP2 /* * / % */
162 %right '!' /* ! */
164 %token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2
165 %token <num> NUMBER
166 %type <exp> exp
170 start: exp
172 if ($1 == NULL)
173 YYABORT;
174 ((struct parse_args *) arg)->res = $1;
178 exp: exp '?' exp ':' exp
180 $$ = new_exp_3 (qmop, $1, $3, $5);
182 | exp '|' exp
184 $$ = new_exp_2 (lor, $1, $3);
186 | exp '&' exp
188 $$ = new_exp_2 (land, $1, $3);
190 | exp EQUOP2 exp
192 $$ = new_exp_2 ($2, $1, $3);
194 | exp CMPOP2 exp
196 $$ = new_exp_2 ($2, $1, $3);
198 | exp ADDOP2 exp
200 $$ = new_exp_2 ($2, $1, $3);
202 | exp MULOP2 exp
204 $$ = new_exp_2 ($2, $1, $3);
206 | '!' exp
208 $$ = new_exp_1 (lnot, $2);
210 | 'n'
212 $$ = new_exp_0 (var);
214 | NUMBER
216 if (($$ = new_exp_0 (num)) != NULL)
217 $$->val.num = $1;
219 | '(' exp ')'
221 $$ = $2;
227 void
228 internal_function
229 FREE_EXPRESSION (exp)
230 struct expression *exp;
232 if (exp == NULL)
233 return;
235 /* Handle the recursive case. */
236 switch (exp->nargs)
238 case 3:
239 FREE_EXPRESSION (exp->val.args[2]);
240 /* FALLTHROUGH */
241 case 2:
242 FREE_EXPRESSION (exp->val.args[1]);
243 /* FALLTHROUGH */
244 case 1:
245 FREE_EXPRESSION (exp->val.args[0]);
246 /* FALLTHROUGH */
247 default:
248 break;
251 free (exp);
255 static int
256 yylex (lval, pexp)
257 YYSTYPE *lval;
258 const char **pexp;
260 const char *exp = *pexp;
261 int result;
263 while (1)
265 if (exp[0] == '\0')
267 *pexp = exp;
268 return YYEOF;
271 if (exp[0] != ' ' && exp[0] != '\t')
272 break;
274 ++exp;
277 result = *exp++;
278 switch (result)
280 case '0': case '1': case '2': case '3': case '4':
281 case '5': case '6': case '7': case '8': case '9':
283 unsigned long int n = result - '0';
284 while (exp[0] >= '0' && exp[0] <= '9')
286 n *= 10;
287 n += exp[0] - '0';
288 ++exp;
290 lval->num = n;
291 result = NUMBER;
293 break;
295 case '=':
296 if (exp[0] == '=')
298 ++exp;
299 lval->op = equal;
300 result = EQUOP2;
302 else
303 result = YYERRCODE;
304 break;
306 case '!':
307 if (exp[0] == '=')
309 ++exp;
310 lval->op = not_equal;
311 result = EQUOP2;
313 break;
315 case '&':
316 case '|':
317 if (exp[0] == result)
318 ++exp;
319 else
320 result = YYERRCODE;
321 break;
323 case '<':
324 if (exp[0] == '=')
326 ++exp;
327 lval->op = less_or_equal;
329 else
330 lval->op = less_than;
331 result = CMPOP2;
332 break;
334 case '>':
335 if (exp[0] == '=')
337 ++exp;
338 lval->op = greater_or_equal;
340 else
341 lval->op = greater_than;
342 result = CMPOP2;
343 break;
345 case '*':
346 lval->op = mult;
347 result = MULOP2;
348 break;
350 case '/':
351 lval->op = divide;
352 result = MULOP2;
353 break;
355 case '%':
356 lval->op = module;
357 result = MULOP2;
358 break;
360 case '+':
361 lval->op = plus;
362 result = ADDOP2;
363 break;
365 case '-':
366 lval->op = minus;
367 result = ADDOP2;
368 break;
370 case 'n':
371 case '?':
372 case ':':
373 case '(':
374 case ')':
375 /* Nothing, just return the character. */
376 break;
378 case ';':
379 case '\n':
380 case '\0':
381 /* Be safe and let the user call this function again. */
382 --exp;
383 result = YYEOF;
384 break;
386 default:
387 result = YYERRCODE;
388 #if YYDEBUG != 0
389 --exp;
390 #endif
391 break;
394 *pexp = exp;
396 return result;
400 static void
401 yyerror (str)
402 const char *str;
404 /* Do nothing. We don't print error messages here. */