home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / gettext / intl / plural.y < prev    next >
Encoding:
Lex Description  |  2010-09-19  |  7.4 KB  |  386 lines

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