"Fossies" - the Fresh Open Source Software Archive

Member "tin-2.6.2/intl/plural.y" (23 Aug 2021, 8375 Bytes) of package /linux/misc/tin-2.6.2.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Bison source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

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