Ilya Zakharevich on Tue, 5 Dec 2000 17:18:43 -0500

 Re: inequalities

```On Tue, Dec 05, 2000 at 08:03:19PM +0100, Bill Allombert wrote:
> > I don't think that
> >   (a<b)<c
> > should necessarily give a warning; I think it would be nice if
> >   a<b<c
> > gave a warning.

> The problem is that the (yacc) parser eats up the parens,
> so after parsing, there is no way to tell the difference.

But it is *your* grammar, not yacc's one, right?  So change it.  ;-)

Here is what I wrote in my "Programming and math" interview (plug:
http://www.math.ohio-state.edu/~ilya/interview/www-perl-com.html):

Another pragmatically controlled thing may be an introduction
of a "floating precedence" of operators. Obviously, one cannot
design a precedence table with 20 or so levels of precedence
which gives an "intuitively obvious" or "natural" parsing of
parentheses-less expressions. A solution I can see is to make
some operators have a range of precedence, and warn/die on
expressions which do not have the same interpretation when the
precedences of operators move in these ranges. (Think of A & B
|| C.) (I confess that I do not know how to do it with yacc, so
this may be not so minor.)

At that time I did not know how to implement it with yacc, but now I
think I do.  Just make the production rules produce

term	:	term ASSIGNOP term
{ \$\$ = newASSIGNOP(OPf_STACKED, \$1, \$2, \$3); }
|	term POWOP term
{ \$\$ = newBINOP(\$2, 0, scalar(\$1), scalar(\$3)); }
|	term MULOP term
{ \$\$ = newBINOP(\$2, 0, \$1, scalar(\$3)); }
{ \$\$ = newBINOP(\$2, 0, \$1, scalar(\$3)); }
| '(' expr ')'  { \$\$ = sawparens(\$2); }

(with an appropiate precedences of assignment, power, multiplication

term : term1 | term2_or_more

term2_or_more : term2 | term3_or_more

term3_or_more : term3 | term4_or_more

term4_or_more : term4 | term5

term1	:	term ASSIGNOP term
{ \$\$ = newASSIGNOP(OPf_STACKED, \$1, \$2, \$3); }

{ \$\$ = newASSIGNOP(OPf_STACKED, \$1, \$2, \$3); }

term3	:	term MULOP term
{ \$\$ = newASSIGNOP(OPf_STACKED, \$1, \$2, \$3); }

term4	:	term POWOP term
{ \$\$ = newASSIGNOP(OPf_STACKED, \$1, \$2, \$3); }

term5	:	'(' term ')'
{ \$\$ = sawparens(\$2); }

[So far it is a 1-to-1 translation of the older syntax.]

But now you can add "the sliding precedence".  Suppose you want to
make the precedence of MULOP slide between 3 and 4 (so it cannot be
used with POWOP without parentheses).  Then you change the POWOP rule to

term3 :       term5 MULOP term5
{ \$\$ = newASSIGNOP(OPf_STACKED, \$1, \$2, \$3); }

|	term MULOP term
{ Report_error();
\$\$ = newASSIGNOP(OPf_STACKED, \$1, \$2, \$3); }

I did not try to implement it, but I think it would work.

Ilya
```