| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 | 
							- %{
 
- /* Expression parsing for plural form selection.
 
-    Copyright (C) 2000-2001, 2003, 2005-2006 Free Software Foundation, Inc.
 
-    Written by Ulrich Drepper <drepper@cygnus.com>, 2000.
 
-    This program is free software; you can redistribute it and/or modify it
 
-    under the terms of the GNU Library General Public License as published
 
-    by the Free Software Foundation; either version 2, or (at your option)
 
-    any later version.
 
-    This program is distributed in the hope that it will be useful,
 
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
-    Library General Public License for more details.
 
-    You should have received a copy of the GNU Library General Public
 
-    License along with this program; if not, write to the Free Software
 
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
 
-    USA.  */
 
- /* For bison < 2.0, the bison generated parser uses alloca.  AIX 3 forces us
 
-    to put this declaration at the beginning of the file.  The declaration in
 
-    bison's skeleton file comes too late.  This must come before <config.h>
 
-    because <config.h> may include arbitrary system headers.
 
-    This can go away once the AM_INTL_SUBDIR macro requires bison >= 2.0.  */
 
- #if defined _AIX && !defined __GNUC__
 
-  #pragma alloca
 
- #endif
 
- #ifdef HAVE_CONFIG_H
 
- # include <config.h>
 
- #endif
 
- #include <stddef.h>
 
- #include <stdlib.h>
 
- #include <string.h>
 
- #include "plural-exp.h"
 
- /* The main function generated by the parser is called __gettextparse,
 
-    but we want it to be called PLURAL_PARSE.  */
 
- #ifndef _LIBC
 
- # define __gettextparse PLURAL_PARSE
 
- #endif
 
- #define YYLEX_PARAM	&((struct parse_args *) arg)->cp
 
- #define YYPARSE_PARAM	arg
 
- %}
 
- %pure_parser
 
- %expect 7
 
- %union {
 
-   unsigned long int num;
 
-   enum expression_operator op;
 
-   struct expression *exp;
 
- }
 
- %{
 
- /* Prototypes for local functions.  */
 
- static int yylex (YYSTYPE *lval, const char **pexp);
 
- static void yyerror (const char *str);
 
- /* Allocation of expressions.  */
 
- static struct expression *
 
- new_exp (int nargs, enum expression_operator op,
 
- 	 struct expression * const *args)
 
- {
 
-   int i;
 
-   struct expression *newp;
 
-   /* If any of the argument could not be malloc'ed, just return NULL.  */
 
-   for (i = nargs - 1; i >= 0; i--)
 
-     if (args[i] == NULL)
 
-       goto fail;
 
-   /* Allocate a new expression.  */
 
-   newp = (struct expression *) malloc (sizeof (*newp));
 
-   if (newp != NULL)
 
-     {
 
-       newp->nargs = nargs;
 
-       newp->operation = op;
 
-       for (i = nargs - 1; i >= 0; i--)
 
- 	newp->val.args[i] = args[i];
 
-       return newp;
 
-     }
 
-  fail:
 
-   for (i = nargs - 1; i >= 0; i--)
 
-     FREE_EXPRESSION (args[i]);
 
-   return NULL;
 
- }
 
- static inline struct expression *
 
- new_exp_0 (enum expression_operator op)
 
- {
 
-   return new_exp (0, op, NULL);
 
- }
 
- static inline struct expression *
 
- new_exp_1 (enum expression_operator op, struct expression *right)
 
- {
 
-   struct expression *args[1];
 
-   args[0] = right;
 
-   return new_exp (1, op, args);
 
- }
 
- static struct expression *
 
- new_exp_2 (enum expression_operator op, struct expression *left,
 
- 	   struct expression *right)
 
- {
 
-   struct expression *args[2];
 
-   args[0] = left;
 
-   args[1] = right;
 
-   return new_exp (2, op, args);
 
- }
 
- static inline struct expression *
 
- new_exp_3 (enum expression_operator op, struct expression *bexp,
 
- 	   struct expression *tbranch, struct expression *fbranch)
 
- {
 
-   struct expression *args[3];
 
-   args[0] = bexp;
 
-   args[1] = tbranch;
 
-   args[2] = fbranch;
 
-   return new_exp (3, op, args);
 
- }
 
- %}
 
- /* This declares that all operators have the same associativity and the
 
-    precedence order as in C.  See [Harbison, Steele: C, A Reference Manual].
 
-    There is no unary minus and no bitwise operators.
 
-    Operators with the same syntactic behaviour have been merged into a single
 
-    token, to save space in the array generated by bison.  */
 
- %right '?'		/*   ?		*/
 
- %left '|'		/*   ||		*/
 
- %left '&'		/*   &&		*/
 
- %left EQUOP2		/*   == !=	*/
 
- %left CMPOP2		/*   < > <= >=	*/
 
- %left ADDOP2		/*   + -	*/
 
- %left MULOP2		/*   * / %	*/
 
- %right '!'		/*   !		*/
 
- %token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2
 
- %token <num> NUMBER
 
- %type <exp> exp
 
- %%
 
- start:	  exp
 
- 	  {
 
- 	    if ($1 == NULL)
 
- 	      YYABORT;
 
- 	    ((struct parse_args *) arg)->res = $1;
 
- 	  }
 
- 	;
 
- exp:	  exp '?' exp ':' exp
 
- 	  {
 
- 	    $$ = new_exp_3 (qmop, $1, $3, $5);
 
- 	  }
 
- 	| exp '|' exp
 
- 	  {
 
- 	    $$ = new_exp_2 (lor, $1, $3);
 
- 	  }
 
- 	| exp '&' exp
 
- 	  {
 
- 	    $$ = new_exp_2 (land, $1, $3);
 
- 	  }
 
- 	| exp EQUOP2 exp
 
- 	  {
 
- 	    $$ = new_exp_2 ($2, $1, $3);
 
- 	  }
 
- 	| exp CMPOP2 exp
 
- 	  {
 
- 	    $$ = new_exp_2 ($2, $1, $3);
 
- 	  }
 
- 	| exp ADDOP2 exp
 
- 	  {
 
- 	    $$ = new_exp_2 ($2, $1, $3);
 
- 	  }
 
- 	| exp MULOP2 exp
 
- 	  {
 
- 	    $$ = new_exp_2 ($2, $1, $3);
 
- 	  }
 
- 	| '!' exp
 
- 	  {
 
- 	    $$ = new_exp_1 (lnot, $2);
 
- 	  }
 
- 	| 'n'
 
- 	  {
 
- 	    $$ = new_exp_0 (var);
 
- 	  }
 
- 	| NUMBER
 
- 	  {
 
- 	    if (($$ = new_exp_0 (num)) != NULL)
 
- 	      $$->val.num = $1;
 
- 	  }
 
- 	| '(' exp ')'
 
- 	  {
 
- 	    $$ = $2;
 
- 	  }
 
- 	;
 
- %%
 
- void
 
- internal_function
 
- FREE_EXPRESSION (struct expression *exp)
 
- {
 
-   if (exp == NULL)
 
-     return;
 
-   /* Handle the recursive case.  */
 
-   switch (exp->nargs)
 
-     {
 
-     case 3:
 
-       FREE_EXPRESSION (exp->val.args[2]);
 
-       /* FALLTHROUGH */
 
-     case 2:
 
-       FREE_EXPRESSION (exp->val.args[1]);
 
-       /* FALLTHROUGH */
 
-     case 1:
 
-       FREE_EXPRESSION (exp->val.args[0]);
 
-       /* FALLTHROUGH */
 
-     default:
 
-       break;
 
-     }
 
-   free (exp);
 
- }
 
- static int
 
- yylex (YYSTYPE *lval, const char **pexp)
 
- {
 
-   const char *exp = *pexp;
 
-   int result;
 
-   while (1)
 
-     {
 
-       if (exp[0] == '\0')
 
- 	{
 
- 	  *pexp = exp;
 
- 	  return YYEOF;
 
- 	}
 
-       if (exp[0] != ' ' && exp[0] != '\t')
 
- 	break;
 
-       ++exp;
 
-     }
 
-   result = *exp++;
 
-   switch (result)
 
-     {
 
-     case '0': case '1': case '2': case '3': case '4':
 
-     case '5': case '6': case '7': case '8': case '9':
 
-       {
 
- 	unsigned long int n = result - '0';
 
- 	while (exp[0] >= '0' && exp[0] <= '9')
 
- 	  {
 
- 	    n *= 10;
 
- 	    n += exp[0] - '0';
 
- 	    ++exp;
 
- 	  }
 
- 	lval->num = n;
 
- 	result = NUMBER;
 
-       }
 
-       break;
 
-     case '=':
 
-       if (exp[0] == '=')
 
- 	{
 
- 	  ++exp;
 
- 	  lval->op = equal;
 
- 	  result = EQUOP2;
 
- 	}
 
-       else
 
- 	result = YYERRCODE;
 
-       break;
 
-     case '!':
 
-       if (exp[0] == '=')
 
- 	{
 
- 	  ++exp;
 
- 	  lval->op = not_equal;
 
- 	  result = EQUOP2;
 
- 	}
 
-       break;
 
-     case '&':
 
-     case '|':
 
-       if (exp[0] == result)
 
- 	++exp;
 
-       else
 
- 	result = YYERRCODE;
 
-       break;
 
-     case '<':
 
-       if (exp[0] == '=')
 
- 	{
 
- 	  ++exp;
 
- 	  lval->op = less_or_equal;
 
- 	}
 
-       else
 
- 	lval->op = less_than;
 
-       result = CMPOP2;
 
-       break;
 
-     case '>':
 
-       if (exp[0] == '=')
 
- 	{
 
- 	  ++exp;
 
- 	  lval->op = greater_or_equal;
 
- 	}
 
-       else
 
- 	lval->op = greater_than;
 
-       result = CMPOP2;
 
-       break;
 
-     case '*':
 
-       lval->op = mult;
 
-       result = MULOP2;
 
-       break;
 
-     case '/':
 
-       lval->op = divide;
 
-       result = MULOP2;
 
-       break;
 
-     case '%':
 
-       lval->op = module;
 
-       result = MULOP2;
 
-       break;
 
-     case '+':
 
-       lval->op = plus;
 
-       result = ADDOP2;
 
-       break;
 
-     case '-':
 
-       lval->op = minus;
 
-       result = ADDOP2;
 
-       break;
 
-     case 'n':
 
-     case '?':
 
-     case ':':
 
-     case '(':
 
-     case ')':
 
-       /* Nothing, just return the character.  */
 
-       break;
 
-     case ';':
 
-     case '\n':
 
-     case '\0':
 
-       /* Be safe and let the user call this function again.  */
 
-       --exp;
 
-       result = YYEOF;
 
-       break;
 
-     default:
 
-       result = YYERRCODE;
 
- #if YYDEBUG != 0
 
-       --exp;
 
- #endif
 
-       break;
 
-     }
 
-   *pexp = exp;
 
-   return result;
 
- }
 
- static void
 
- yyerror (const char *str)
 
- {
 
-   /* Do nothing.  We don't print error messages here.  */
 
- }
 
 
  |