plural.y 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. %{
  2. /* Expression parsing for plural form selection.
  3. Copyright (C) 2000-2020 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
  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. #ifndef USE_BISON3
  36. #define YYLEX_PARAM &((struct parse_args *) arg)->cp
  37. #define YYPARSE_PARAM arg
  38. #endif
  39. %}
  40. %pure_parser
  41. /* BISON3 %parse-param {struct parse_args *arg} */
  42. /* BISON3 %lex-param {struct parse_args *arg} */
  43. /* BISON3 %define api.pure full */
  44. %expect 7
  45. %union {
  46. unsigned long int num;
  47. enum operator op;
  48. struct expression *exp;
  49. }
  50. %{
  51. /* Prototypes for local functions. */
  52. static struct expression *new_exp PARAMS ((int nargs, enum operator op,
  53. struct expression * const *args));
  54. static inline struct expression *new_exp_0 PARAMS ((enum operator op));
  55. static inline struct expression *new_exp_1 PARAMS ((enum operator op,
  56. struct expression *right));
  57. static struct expression *new_exp_2 PARAMS ((enum operator op,
  58. struct expression *left,
  59. struct expression *right));
  60. static inline struct expression *new_exp_3 PARAMS ((enum operator op,
  61. struct expression *bexp,
  62. struct expression *tbranch,
  63. struct expression *fbranch));
  64. #ifdef USE_BISON3
  65. static int yylex PARAMS ((YYSTYPE *lval, struct parse_args *arg));
  66. static void yyerror PARAMS ((struct parse_args *arg, const char *str));
  67. #else
  68. static int yylex PARAMS ((YYSTYPE *lval, const char **pexp));
  69. static void yyerror PARAMS ((const char *str));
  70. #endif
  71. /* Allocation of expressions. */
  72. static struct expression *
  73. new_exp (nargs, op, args)
  74. int nargs;
  75. enum operator op;
  76. struct expression * const *args;
  77. {
  78. int i;
  79. struct expression *newp;
  80. /* If any of the argument could not be malloc'ed, just return NULL. */
  81. for (i = nargs - 1; i >= 0; i--)
  82. if (args[i] == NULL)
  83. goto fail;
  84. /* Allocate a new expression. */
  85. newp = (struct expression *) malloc (sizeof (*newp));
  86. if (newp != NULL)
  87. {
  88. newp->nargs = nargs;
  89. newp->operation = op;
  90. for (i = nargs - 1; i >= 0; i--)
  91. newp->val.args[i] = args[i];
  92. return newp;
  93. }
  94. fail:
  95. for (i = nargs - 1; i >= 0; i--)
  96. FREE_EXPRESSION (args[i]);
  97. return NULL;
  98. }
  99. static inline struct expression *
  100. new_exp_0 (op)
  101. enum operator op;
  102. {
  103. return new_exp (0, op, NULL);
  104. }
  105. static inline struct expression *
  106. new_exp_1 (op, right)
  107. enum operator op;
  108. struct expression *right;
  109. {
  110. struct expression *args[1];
  111. args[0] = right;
  112. return new_exp (1, op, args);
  113. }
  114. static struct expression *
  115. new_exp_2 (op, left, right)
  116. enum operator op;
  117. struct expression *left;
  118. struct expression *right;
  119. {
  120. struct expression *args[2];
  121. args[0] = left;
  122. args[1] = right;
  123. return new_exp (2, op, args);
  124. }
  125. static inline struct expression *
  126. new_exp_3 (op, bexp, tbranch, fbranch)
  127. enum operator op;
  128. struct expression *bexp;
  129. struct expression *tbranch;
  130. struct expression *fbranch;
  131. {
  132. struct expression *args[3];
  133. args[0] = bexp;
  134. args[1] = tbranch;
  135. args[2] = fbranch;
  136. return new_exp (3, op, args);
  137. }
  138. %}
  139. /* This declares that all operators have the same associativity and the
  140. precedence order as in C. See [Harbison, Steele: C, A Reference Manual].
  141. There is no unary minus and no bitwise operators.
  142. Operators with the same syntactic behaviour have been merged into a single
  143. token, to save space in the array generated by bison. */
  144. %right '?' /* ? */
  145. %left '|' /* || */
  146. %left '&' /* && */
  147. %left EQUOP2 /* == != */
  148. %left CMPOP2 /* < > <= >= */
  149. %left ADDOP2 /* + - */
  150. %left MULOP2 /* * / % */
  151. %right '!' /* ! */
  152. %token <op> EQUOP2 CMPOP2 ADDOP2 MULOP2
  153. %token <num> NUMBER
  154. %type <exp> exp
  155. %%
  156. start: exp
  157. {
  158. if ($1 == NULL)
  159. YYABORT;
  160. ((struct parse_args *) arg)->res = $1;
  161. }
  162. ;
  163. exp: exp '?' exp ':' exp
  164. {
  165. $$ = new_exp_3 (qmop, $1, $3, $5);
  166. }
  167. | exp '|' exp
  168. {
  169. $$ = new_exp_2 (lor, $1, $3);
  170. }
  171. | exp '&' exp
  172. {
  173. $$ = new_exp_2 (land, $1, $3);
  174. }
  175. | exp EQUOP2 exp
  176. {
  177. $$ = new_exp_2 ($2, $1, $3);
  178. }
  179. | exp CMPOP2 exp
  180. {
  181. $$ = new_exp_2 ($2, $1, $3);
  182. }
  183. | exp ADDOP2 exp
  184. {
  185. $$ = new_exp_2 ($2, $1, $3);
  186. }
  187. | exp MULOP2 exp
  188. {
  189. $$ = new_exp_2 ($2, $1, $3);
  190. }
  191. | '!' exp
  192. {
  193. $$ = new_exp_1 (lnot, $2);
  194. }
  195. | 'n'
  196. {
  197. $$ = new_exp_0 (var);
  198. }
  199. | NUMBER
  200. {
  201. if (($$ = new_exp_0 (num)) != NULL)
  202. $$->val.num = $1;
  203. }
  204. | '(' exp ')'
  205. {
  206. $$ = $2;
  207. }
  208. ;
  209. %%
  210. void
  211. internal_function
  212. FREE_EXPRESSION (exp)
  213. struct expression *exp;
  214. {
  215. if (exp == NULL)
  216. return;
  217. /* Handle the recursive case. */
  218. switch (exp->nargs)
  219. {
  220. case 3:
  221. FREE_EXPRESSION (exp->val.args[2]);
  222. /* FALLTHROUGH */
  223. case 2:
  224. FREE_EXPRESSION (exp->val.args[1]);
  225. /* FALLTHROUGH */
  226. case 1:
  227. FREE_EXPRESSION (exp->val.args[0]);
  228. /* FALLTHROUGH */
  229. default:
  230. break;
  231. }
  232. free (exp);
  233. }
  234. #ifdef USE_BISON3
  235. static int
  236. yylex (lval, arg)
  237. YYSTYPE *lval;
  238. struct parse_args *arg;
  239. {
  240. const char **pexp = &arg->cp;
  241. #else
  242. static int
  243. yylex (lval, pexp)
  244. YYSTYPE *lval;
  245. const char **pexp;
  246. {
  247. #endif
  248. const char *exp = *pexp;
  249. int result;
  250. while (1)
  251. {
  252. if (exp[0] == '\0')
  253. {
  254. *pexp = exp;
  255. return YYEOF;
  256. }
  257. if (exp[0] != ' ' && exp[0] != '\t')
  258. break;
  259. ++exp;
  260. }
  261. result = *exp++;
  262. switch (result)
  263. {
  264. case '0': case '1': case '2': case '3': case '4':
  265. case '5': case '6': case '7': case '8': case '9':
  266. {
  267. unsigned long int n = result - '0';
  268. while (exp[0] >= '0' && exp[0] <= '9')
  269. {
  270. n *= 10;
  271. n += exp[0] - '0';
  272. ++exp;
  273. }
  274. lval->num = n;
  275. result = NUMBER;
  276. }
  277. break;
  278. case '=':
  279. if (exp[0] == '=')
  280. {
  281. ++exp;
  282. lval->op = equal;
  283. result = EQUOP2;
  284. }
  285. else
  286. result = YYERRCODE;
  287. break;
  288. case '!':
  289. if (exp[0] == '=')
  290. {
  291. ++exp;
  292. lval->op = not_equal;
  293. result = EQUOP2;
  294. }
  295. break;
  296. case '&':
  297. case '|':
  298. if (exp[0] == result)
  299. ++exp;
  300. else
  301. result = YYERRCODE;
  302. break;
  303. case '<':
  304. if (exp[0] == '=')
  305. {
  306. ++exp;
  307. lval->op = less_or_equal;
  308. }
  309. else
  310. lval->op = less_than;
  311. result = CMPOP2;
  312. break;
  313. case '>':
  314. if (exp[0] == '=')
  315. {
  316. ++exp;
  317. lval->op = greater_or_equal;
  318. }
  319. else
  320. lval->op = greater_than;
  321. result = CMPOP2;
  322. break;
  323. case '*':
  324. lval->op = mult;
  325. result = MULOP2;
  326. break;
  327. case '/':
  328. lval->op = divide;
  329. result = MULOP2;
  330. break;
  331. case '%':
  332. lval->op = module;
  333. result = MULOP2;
  334. break;
  335. case '+':
  336. lval->op = plus;
  337. result = ADDOP2;
  338. break;
  339. case '-':
  340. lval->op = minus;
  341. result = ADDOP2;
  342. break;
  343. case 'n':
  344. case '?':
  345. case ':':
  346. case '(':
  347. case ')':
  348. /* Nothing, just return the character. */
  349. break;
  350. case ';':
  351. case '\n':
  352. case '\0':
  353. /* Be safe and let the user call this function again. */
  354. --exp;
  355. result = YYEOF;
  356. break;
  357. default:
  358. result = YYERRCODE;
  359. #if YYDEBUG != 0
  360. --exp;
  361. #endif
  362. break;
  363. }
  364. *pexp = exp;
  365. return result;
  366. }
  367. #ifdef USE_BISON3
  368. static void
  369. yyerror (arg, str)
  370. struct parse_args *arg;
  371. #else
  372. static void
  373. yyerror (str)
  374. #endif
  375. const char *str;
  376. {
  377. /* Do nothing. We don't print error messages here. */
  378. }