plural.y
上传用户:riyaled888
上传日期:2009-03-27
资源大小:7338k
文件大小:8k
源码类别:

多媒体

开发平台:

MultiPlatform

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