diff libinterp/parse-tree/oct-parse.in.yy @ 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 77eff9c6fb09
children 1e8f8900a041
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); }
                 ;