| Ilya Zakharevich on Tue, 5 Dec 2000 17:18:43 -0500 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| 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
subexpressions-with-preferences. So instead of
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)); }
| term ADDOP term
{ $$ = newBINOP($2, 0, $1, scalar($3)); }
| '(' expr ')' { $$ = sawparens($2); }
(with an appropiate precedences of assignment, power, multiplication
and addition) have it:
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); }
term2 : term ADDOP term
{ $$ = 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