-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>
{
var, /* The variable "n". */
num, /* Decimal number. */
+ lnot, /* Logical NOT. */
mult, /* Multiplication. */
divide, /* Division. */
module, /* Module operation. */
{
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. */
%{
/* 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));
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
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
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)
return newp;
}
+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;
{
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:
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:
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)