Blame intl/plural.y

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