Blame intl/plural.y

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