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