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