~ubuntu-branches/ubuntu/hardy/minicom/hardy

« back to all changes in this revision

Viewing changes to intl/plural.y

  • Committer: Bazaar Package Importer
  • Author(s): Martin A. Godisch
  • Date: 2006-10-27 05:41:23 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20061027054123-9cyfsdx649zetdrv
Tags: 2.2-3
* Added upstream NEWS file, closes: #394827.
* Fixed spelling errors, closes: #395449.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 <config.h>
24
 
   because <config.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 <config.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 10
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
 
}