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