# HG changeset patch # User Axel Mathéi # Date 1381421718 14400 # Node ID fd712a12fe53aa2b262fdd788b71017a5f007a0f # Parent d41c8f96ed0653fe2639a1bab3e7fa8a4ed8f362 compatibility for power operator precedence and direction (bug #33304) * oct-parse.in.yy (power_expr): New non-terminal. (oper_expr): Use it for the RHS of POW and EPOW operators. * parser.tst: New tests. diff -r d41c8f96ed06 -r fd712a12fe53 libinterp/parse-tree/oct-parse.in.yy --- a/libinterp/parse-tree/oct-parse.in.yy Wed Oct 09 22:38:43 2013 -0400 +++ b/libinterp/parse-tree/oct-parse.in.yy Thu Oct 10 12:15:18 2013 -0400 @@ -238,7 +238,7 @@ %type matrix_rows %type cell_rows %type matrix cell -%type primary_expr oper_expr +%type primary_expr oper_expr power_expr %type simple_expr colon_expr assign_expr expression %type identifier fcn_name magic_tilde %type superclass_identifier meta_identifier @@ -598,9 +598,9 @@ { $$ = parser.make_prefix_op ('+', $2, $1); } | '-' oper_expr %prec UNARY { $$ = parser.make_prefix_op ('-', $2, $1); } - | oper_expr POW oper_expr + | oper_expr POW power_expr { $$ = parser.make_binary_op (POW, $1, $2, $3); } - | oper_expr EPOW oper_expr + | oper_expr EPOW power_expr { $$ = parser.make_binary_op (EPOW, $1, $2, $3); } | oper_expr '+' oper_expr { $$ = parser.make_binary_op ('+', $1, $2, $3); } @@ -624,6 +624,52 @@ { $$ = parser.make_binary_op (ELEFTDIV, $1, $2, $3); } ; +power_expr : primary_expr + { $$ = $1; } + | power_expr PLUS_PLUS + { $$ = parser.make_postfix_op (PLUS_PLUS, $1, $2); } + | power_expr MINUS_MINUS + { $$ = parser.make_postfix_op (MINUS_MINUS, $1, $2); } + | power_expr '(' ')' + { + $$ = parser.make_index_expression ($1, 0, '('); + if (! $$) + ABORT_PARSE; + } + | power_expr '(' arg_list ')' + { + $$ = parser.make_index_expression ($1, $3, '('); + if (! $$) + ABORT_PARSE; + } + | power_expr '{' '}' + { + $$ = parser.make_index_expression ($1, 0, '{'); + if (! $$) + ABORT_PARSE; + } + | power_expr '{' arg_list '}' + { + $$ = parser.make_index_expression ($1, $3, '{'); + if (! $$) + ABORT_PARSE; + } + | power_expr indirect_ref_op STRUCT_ELT + { $$ = parser.make_indirect_ref ($1, $3->text ()); } + | power_expr indirect_ref_op '(' expression ')' + { $$ = parser.make_indirect_ref ($1, $4); } + | PLUS_PLUS power_expr %prec POW + { $$ = parser.make_prefix_op (PLUS_PLUS, $2, $1); } + | MINUS_MINUS power_expr %prec POW + { $$ = parser.make_prefix_op (MINUS_MINUS, $2, $1); } + | EXPR_NOT power_expr %prec POW + { $$ = parser.make_prefix_op (EXPR_NOT, $2, $1); } + | '+' power_expr %prec POW + { $$ = parser.make_prefix_op ('+', $2, $1); } + | '-' power_expr %prec POW + { $$ = parser.make_prefix_op ('-', $2, $1); } + ; + colon_expr : colon_expr1 { $$ = parser.finish_colon_expression ($1); } ; diff -r d41c8f96ed06 -r fd712a12fe53 test/parser.tst --- a/test/parser.tst Wed Oct 09 22:38:43 2013 -0400 +++ b/test/parser.tst Thu Oct 10 12:15:18 2013 -0400 @@ -80,7 +80,19 @@ ## Level 11 (transpose and exponentiation) %!test +%! a = 2; +%! assert (2 ^a++, 4) +%! assert (a, 3) +%! assert (2 ^--a ^2, 16) +%! assert (a, 2) +%! assert (2 ^++a, 8) +%! assert (a, 3) +%! assert (a' ^2, 9) +%! assert (2 ^sin(0), 1) %! assert (-2 ^2, -4); +%! assert (2 ^+1 ^3, 8) +%! assert (2 ^-1 ^3, 0.125) +%! assert (2 ^~0 ^2, 4) %! assert (!0 ^0, false); %! assert (2*3 ^2, 18); %! assert (2+3 ^2, 11);