Patch-ID: bash40-030
[bash.git] / lib / intl / plural.y
blob8b8cec7e83dddd62715346dfa4fdeac6a6a889a8
1 %{
2 /* plural.y - Expression parsing for plural form selection. */
4 /* Copyright (C) 2000, 2001, 2005-2009 Free Software Foundation, Inc.
5 Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
7 This file is part of GNU Bash.
9 Bash is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
14 Bash is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with Bash. If not, see <http://www.gnu.org/licenses/>.
23 /* The bison generated parser uses alloca. AIX 3 forces us to put this
24 declaration at the beginning of the file. The declaration in bison's
25 skeleton file comes too late. This must come before <config.h>
26 because <config.h> may include arbitrary system headers. */
27 #if defined _AIX && !defined __GNUC__
28 #pragma alloca
29 #endif
31 #ifdef HAVE_CONFIG_H
32 # include <config.h>
33 #endif
35 #include <stddef.h>
36 #include <stdlib.h>
37 #include "plural-exp.h"
39 /* The main function generated by the parser is called __gettextparse,
40 but we want it to be called PLURAL_PARSE. */
41 #ifndef _LIBC
42 # define __gettextparse PLURAL_PARSE
43 #endif
45 #define YYLEX_PARAM &((struct parse_args *) arg)->cp
46 #define YYPARSE_PARAM arg
48 %pure_parser
49 %expect 7
51 %union {
52 unsigned long int num;
53 enum operator op;
54 struct expression *exp;
58 /* Prototypes for local functions. */
59 static struct expression *new_exp PARAMS ((int nargs, enum operator op,
60 struct expression * const *args));
61 static inline struct expression *new_exp_0 PARAMS ((enum operator op));
62 static inline struct expression *new_exp_1 PARAMS ((enum operator op,
63 struct expression *right));
64 static struct expression *new_exp_2 PARAMS ((enum operator op,
65 struct expression *left,
66 struct expression *right));
67 static inline struct expression *new_exp_3 PARAMS ((enum operator op,
68 struct expression *bexp,
69 struct expression *tbranch,
70 struct expression *fbranch));
71 static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
72 static void yyerror PARAMS ((const char *str));
74 /* Allocation of expressions. */
76 static struct expression *
77 new_exp (nargs, op, args)
78 int nargs;
79 enum operator op;
80 struct expression * const *args;
82 int i;
83 struct expression *newp;
85 /* If any of the argument could not be malloc'ed, just return NULL. */
86 for (i = nargs - 1; i >= 0; i--)
87 if (args[i] == NULL)
88 goto fail;
90 /* Allocate a new expression. */
91 newp = (struct expression *) malloc (sizeof (*newp));
92 if (newp != NULL)
94 newp->nargs = nargs;
95 newp->operation = op;
96 for (i = nargs - 1; i >= 0; i--)
97 newp->val.args[i] = args[i];
98 return newp;
101 fail:
102 for (i = nargs - 1; i >= 0; i--)
103 FREE_EXPRESSION (args[i]);
105 return NULL;
108 static inline struct expression *
109 new_exp_0 (op)
110 enum operator op;
112 return new_exp (0, op, NULL);
115 static inline struct expression *
116 new_exp_1 (op, right)
117 enum operator op;
118 struct expression *right;
120 struct expression *args[1];
122 args[0] = right;
123 return new_exp (1, op, args);
126 static struct expression *
127 new_exp_2 (op, left, right)
128 enum operator op;
129 struct expression *left;
130 struct expression *right;
132 struct expression *args[2];
134 args[0] = left;
135 args[1] = right;
136 return new_exp (2, op, args);
139 static inline struct expression *
140 new_exp_3 (op, bexp, tbranch, fbranch)
141 enum operator op;
142 struct expression *bexp;
143 struct expression *tbranch;
144 struct expression *fbranch;
146 struct expression *args[3];
148 args[0] = bexp;
149 args[1] = tbranch;
150 args[2] = fbranch;
151 return new_exp (3, op, args);
156 /* This declares that all operators have the same associativity and the
157 precedence order as in C. See [Harbison, Steele: C, A Reference Manual].
158 There is no unary minus and no bitwise operators.
159 Operators with the same syntactic behaviour have been merged into a single
160 token, to save space in the array generated by bison. */
161 %right '?' /* ? */
162 %left '|' /* || */
163 %left '&' /* && */
164 %left EQUOP2 /* == != */
165 %left CMPOP2 /* < > <= >= */
166 %left ADDOP2 /* + - */
167 %left MULOP2 /* * / % */
168 %right '!' /* ! */
170 %token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2
171 %token <num> NUMBER
172 %type <exp> exp
176 start: exp
178 if ($1 == NULL)
179 YYABORT;
180 ((struct parse_args *) arg)->res = $1;
184 exp: exp '?' exp ':' exp
186 $$ = new_exp_3 (qmop, $1, $3, $5);
188 | exp '|' exp
190 $$ = new_exp_2 (lor, $1, $3);
192 | exp '&' exp
194 $$ = new_exp_2 (land, $1, $3);
196 | exp EQUOP2 exp
198 $$ = new_exp_2 ($2, $1, $3);
200 | exp CMPOP2 exp
202 $$ = new_exp_2 ($2, $1, $3);
204 | exp ADDOP2 exp
206 $$ = new_exp_2 ($2, $1, $3);
208 | exp MULOP2 exp
210 $$ = new_exp_2 ($2, $1, $3);
212 | '!' exp
214 $$ = new_exp_1 (lnot, $2);
216 | 'n'
218 $$ = new_exp_0 (var);
220 | NUMBER
222 if (($$ = new_exp_0 (num)) != NULL)
223 $$->val.num = $1;
225 | '(' exp ')'
227 $$ = $2;
233 void
234 internal_function
235 FREE_EXPRESSION (exp)
236 struct expression *exp;
238 if (exp == NULL)
239 return;
241 /* Handle the recursive case. */
242 switch (exp->nargs)
244 case 3:
245 FREE_EXPRESSION (exp->val.args[2]);
246 /* FALLTHROUGH */
247 case 2:
248 FREE_EXPRESSION (exp->val.args[1]);
249 /* FALLTHROUGH */
250 case 1:
251 FREE_EXPRESSION (exp->val.args[0]);
252 /* FALLTHROUGH */
253 default:
254 break;
257 free (exp);
261 static int
262 yylex (lval, pexp)
263 YYSTYPE *lval;
264 const char **pexp;
266 const char *exp = *pexp;
267 int result;
269 while (1)
271 if (exp[0] == '\0')
273 *pexp = exp;
274 return YYEOF;
277 if (exp[0] != ' ' && exp[0] != '\t')
278 break;
280 ++exp;
283 result = *exp++;
284 switch (result)
286 case '0': case '1': case '2': case '3': case '4':
287 case '5': case '6': case '7': case '8': case '9':
289 unsigned long int n = result - '0';
290 while (exp[0] >= '0' && exp[0] <= '9')
292 n *= 10;
293 n += exp[0] - '0';
294 ++exp;
296 lval->num = n;
297 result = NUMBER;
299 break;
301 case '=':
302 if (exp[0] == '=')
304 ++exp;
305 lval->op = equal;
306 result = EQUOP2;
308 else
309 result = YYERRCODE;
310 break;
312 case '!':
313 if (exp[0] == '=')
315 ++exp;
316 lval->op = not_equal;
317 result = EQUOP2;
319 break;
321 case '&':
322 case '|':
323 if (exp[0] == result)
324 ++exp;
325 else
326 result = YYERRCODE;
327 break;
329 case '<':
330 if (exp[0] == '=')
332 ++exp;
333 lval->op = less_or_equal;
335 else
336 lval->op = less_than;
337 result = CMPOP2;
338 break;
340 case '>':
341 if (exp[0] == '=')
343 ++exp;
344 lval->op = greater_or_equal;
346 else
347 lval->op = greater_than;
348 result = CMPOP2;
349 break;
351 case '*':
352 lval->op = mult;
353 result = MULOP2;
354 break;
356 case '/':
357 lval->op = divide;
358 result = MULOP2;
359 break;
361 case '%':
362 lval->op = module;
363 result = MULOP2;
364 break;
366 case '+':
367 lval->op = plus;
368 result = ADDOP2;
369 break;
371 case '-':
372 lval->op = minus;
373 result = ADDOP2;
374 break;
376 case 'n':
377 case '?':
378 case ':':
379 case '(':
380 case ')':
381 /* Nothing, just return the character. */
382 break;
384 case ';':
385 case '\n':
386 case '\0':
387 /* Be safe and let the user call this function again. */
388 --exp;
389 result = YYEOF;
390 break;
392 default:
393 result = YYERRCODE;
394 #if YYDEBUG != 0
395 --exp;
396 #endif
397 break;
400 *pexp = exp;
402 return result;
406 static void
407 yyerror (str)
408 const char *str;
410 /* Do nothing. We don't print error messages here. */