diff options
author | Bruno Haible <bruno@clisp.org> | 2001-03-16 17:33:21 +0000 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2001-03-16 17:33:21 +0000 |
commit | efd4210b802c0b06823a3eae5024992aba152c44 (patch) | |
tree | 5ab9f40cc451ed6de47d860bd3f3a0254ccc7798 /intl | |
parent | f22951d28a5a24cd261761496cca26e8689eb2a2 (diff) | |
download | external_gettext-efd4210b802c0b06823a3eae5024992aba152c44.zip external_gettext-efd4210b802c0b06823a3eae5024992aba152c44.tar.gz external_gettext-efd4210b802c0b06823a3eae5024992aba152c44.tar.bz2 |
Fix the plural expression grammar, again.
Diffstat (limited to 'intl')
-rw-r--r-- | intl/ChangeLog | 16 | ||||
-rw-r--r-- | intl/dcigettext.c | 2 | ||||
-rw-r--r-- | intl/gettextP.h | 5 | ||||
-rw-r--r-- | intl/plural.y | 72 |
4 files changed, 78 insertions, 17 deletions
diff --git a/intl/ChangeLog b/intl/ChangeLog index 095a17b..13579ad 100644 --- a/intl/ChangeLog +++ b/intl/ChangeLog @@ -1,11 +1,15 @@ -2001-03-12 Bruno Haible <haible@clisp.cons.org> - - * gettextP.h (struct expression): Add operators less_than, - greater_than, less_or_equal, greater_or_equal. - * plural.y ('<', '>', LE, GE): New operators. +2001-03-16 Bruno Haible <haible@clisp.cons.org> + + * gettextP.h (struct expression): Add operators lnot, less_than, + greater_than, less_or_equal, greater_or_equal. Add args1 to union. + * plural.y ('?' ':'): Make right-associative. + ('<', '>', LE, GE, '!'): New operators. + (EQ): Renamed from '='. + (NE): Renamed from '!'. (exp): Add rules with these operators. + (new_exp_1): New function. (FREE_EXPRESSION): Recognize these operators. - (yylex): Don't skip "\\n". Recognize '<', '>', LE, GE operators. + (yylex): Don't skip "\\n". Recognize '<', '>', LE, GE, '!' operators. * dcigettext.c (plural_eval): Recognize these operators. 2001-03-10 Bruno Haible <haible@clisp.cons.org> diff --git a/intl/dcigettext.c b/intl/dcigettext.c index 982689b..ba93fb3 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -994,6 +994,8 @@ plural_eval (pexp, n) return n; case num: return pexp->val.num; + case lnot: + return ! plural_eval (pexp->val.args1.right, n); case mult: return (plural_eval (pexp->val.args2.left, n) * plural_eval (pexp->val.args2.right, n)); diff --git a/intl/gettextP.h b/intl/gettextP.h index 0c8520c..715b04d 100644 --- a/intl/gettextP.h +++ b/intl/gettextP.h @@ -79,6 +79,7 @@ struct expression { var, /* The variable "n". */ num, /* Decimal number. */ + lnot, /* Logical NOT. */ mult, /* Multiplication. */ divide, /* Division. */ module, /* Module operation. */ @@ -99,6 +100,10 @@ struct expression unsigned long int num; /* Number value for `num'. */ struct { + struct expression *right; /* Subexpression in unary operation. */ + } args1; + struct + { struct expression *left; /* Left expression in binary operation. */ struct expression *right; /* Right expression in binary operation. */ } args2; diff --git a/intl/plural.y b/intl/plural.y index f835fa5..20fb60c 100644 --- a/intl/plural.y +++ b/intl/plural.y @@ -49,6 +49,8 @@ %{ /* Prototypes for local functions. */ static struct expression *new_exp_0 PARAMS ((enum operator op)); +static 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)); @@ -60,15 +62,17 @@ static int yylex PARAMS ((YYSTYPE *lval, const char **pexp)); static void yyerror PARAMS ((const char *str)); %} -/* This declares that all operators are left-associative, and that the - precedence order is the same as in C. There is no unary minus. */ -%left '?' /* ? */ +/* This declares that all operators have the same associativity and the + precedence order as in C. See [Harbison, Steele: C, A Reference Manual]. + There is no unary minus and no bitwise operators. */ +%right '?' /* ? */ %left '|' /* || */ %left '&' /* && */ -%left '=', '!' /* == != */ -%nonassoc '<', '>', LE, GE /* < > <= >= */ +%left EQ, NE /* == != */ +%left '<', '>', LE, GE /* < > <= >= */ %left '+', '-' /* + - */ %left '*', '/', '%' /* * / % */ +%right '!' /* ! */ %token <num> NUMBER %type <exp> exp @@ -96,12 +100,12 @@ exp: exp '?' exp ':' exp if (($$ = new_exp_2 (land, $1, $3)) == NULL) YYABORT } - | exp '=' exp + | exp EQ exp { if (($$ = new_exp_2 (equal, $1, $3)) == NULL) YYABORT } - | exp '!' exp + | exp NE exp { if (($$ = new_exp_2 (not_equal, $1, $3)) == NULL) YYABORT @@ -151,6 +155,11 @@ exp: exp '?' exp ':' exp if (($$ = new_exp_2 (module, $1, $3)) == NULL) YYABORT } + | '!' exp + { + if (($$ = new_exp_1 (lnot, $2)) == NULL) + YYABORT + } | 'n' { if (($$ = new_exp_0 (var)) == NULL) @@ -183,6 +192,29 @@ new_exp_0 (op) } static struct expression * +new_exp_1 (op, right) + enum operator op; + struct expression *right; +{ + struct expression *newp = NULL; + + if (right != NULL) + newp = (struct expression *) malloc (sizeof (*newp)); + + if (newp != NULL) + { + newp->operation = op; + newp->val.args1.right = right; + } + else + { + FREE_EXPRESSION (right); + } + + return newp; +} + +static struct expression * new_exp_2 (op, left, right) enum operator op; struct expression *left; @@ -250,7 +282,10 @@ FREE_EXPRESSION (exp) { case qmop: FREE_EXPRESSION (exp->val.args3.fbranch); - /* FALLTHROUGH */ + /* FREE_EXPRESSION (exp->val.args3.tbranch); */ + /* FREE_EXPRESSION (exp->val.args3.bexp); */ + /* break; */ + /* instead: FALLTHROUGH */ case mult: case divide: @@ -266,7 +301,12 @@ FREE_EXPRESSION (exp) case land: case lor: FREE_EXPRESSION (exp->val.args2.right); - FREE_EXPRESSION (exp->val.args2.left); + /* FREE_EXPRESSION (exp->val.args2.left); */ + /* break; */ + /* instead: FALLTHROUGH */ + + case lnot: + FREE_EXPRESSION (exp->val.args1.right); break; default: @@ -318,13 +358,23 @@ yylex (lval, pexp) break; case '=': - case '!': if (exp[0] == '=') - ++exp; + { + ++exp; + result = EQ; + } else result = YYERRCODE; break; + case '!': + if (exp[0] == '=') + { + ++exp; + result = NE; + } + break; + case '&': case '|': if (exp[0] == result) |