From efd4210b802c0b06823a3eae5024992aba152c44 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Fri, 16 Mar 2001 17:33:21 +0000 Subject: Fix the plural expression grammar, again. --- intl/plural.y | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 11 deletions(-) (limited to 'intl/plural.y') 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 NUMBER %type 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) -- cgit v1.1