Mercurial > hg > octave-nkf
changeset 17622:fd712a12fe53
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.
author | Axel Mathéi <axel.mathei@gmail.com> |
---|---|
date | Thu, 10 Oct 2013 12:15:18 -0400 |
parents | d41c8f96ed06 |
children | 7b305b36b87e |
files | libinterp/parse-tree/oct-parse.in.yy test/parser.tst |
diffstat | 2 files changed, 61 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.in.yy +++ b/libinterp/parse-tree/oct-parse.in.yy @@ -238,7 +238,7 @@ %type <tree_matrix_type> matrix_rows %type <tree_cell_type> cell_rows %type <tree_expression_type> matrix cell -%type <tree_expression_type> primary_expr oper_expr +%type <tree_expression_type> primary_expr oper_expr power_expr %type <tree_expression_type> simple_expr colon_expr assign_expr expression %type <tree_identifier_type> identifier fcn_name magic_tilde %type <tree_identifier_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); } ;
--- a/test/parser.tst +++ b/test/parser.tst @@ -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);