From: Roger Sayle Date: Wed, 26 May 2004 02:35:29 +0000 (+0000) Subject: re PR fortran/13912 (Does not accept consecutive arithmetic operators (*-)) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a2f29587957bf9f1853b9eeba2b05492c9b7150a;p=gcc.git re PR fortran/13912 (Does not accept consecutive arithmetic operators (*-)) PR fortran/13912 * matchexp.c: Allow unary operators after arithmetic operators as a GNU extension. (match_ext_mult_operand, match_ext_add_operand): New functions. (match_mult_operand): Tweak to call match_ext_mult_operand. (match_add_operand): Tweak to call match_ext_mult_operand. (match_level_2): Rearrange to call match_ext_add_operand. From-SVN: r82277 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index c9a4f7decd5..74228782f57 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2004-05-25 Roger Sayle + + PR fortran/13912 + * matchexp.c: Allow unary operators after arithmetic operators + as a GNU extension. + (match_ext_mult_operand, match_ext_add_operand): New functions. + (match_mult_operand): Tweak to call match_ext_mult_operand. + (match_add_operand): Tweak to call match_ext_mult_operand. + (match_level_2): Rearrange to call match_ext_add_operand. + 2004-05-25 Paul Brook * expr.c (check_inquiry): Remove bogus tests. diff --git a/gcc/fortran/matchexp.c b/gcc/fortran/matchexp.c index f0c227f95b8..539a91a31c1 100644 --- a/gcc/fortran/matchexp.c +++ b/gcc/fortran/matchexp.c @@ -222,6 +222,38 @@ match_level_1 (gfc_expr ** result) } +/* As a GNU extension we support an expanded level-2 expression syntax. + Via this extension we support (arbitrary) nesting of unary plus and + minus operations following unary and binary operators, such as **. + The grammar of section 7.1.1.3 is effectively rewitten as: + + R704 mult-operand is level-1-expr [ power-op ext-mult-operand ] + R704' ext-mult-operand is add-op ext-mult-operand + or mult-operand + R705 add-operand is add-operand mult-op ext-mult-operand + or mult-operand + R705' ext-add-operand is add-op ext-add-operand + or add-operand + R706 level-2-expr is [ level-2-expr ] add-op ext-add-operand + or add-operand + */ + +static match match_ext_mult_operand (gfc_expr ** result); +static match match_ext_add_operand (gfc_expr ** result); + + +static int +match_add_op (void) +{ + + if (next_operator (INTRINSIC_MINUS)) + return -1; + if (next_operator (INTRINSIC_PLUS)) + return 1; + return 0; +} + + static match match_mult_operand (gfc_expr ** result) { @@ -241,7 +273,7 @@ match_mult_operand (gfc_expr ** result) where = *gfc_current_locus (); - m = match_mult_operand (&exp); + m = match_ext_mult_operand (&exp); if (m == MATCH_NO) gfc_error ("Expected exponent in expression at %C"); if (m != MATCH_YES) @@ -265,6 +297,46 @@ match_mult_operand (gfc_expr ** result) } +static match +match_ext_mult_operand (gfc_expr ** result) +{ + gfc_expr *all, *e; + locus where; + match m; + int i; + + where = *gfc_current_locus (); + i = match_add_op (); + + if (i == 0) + return match_mult_operand (result); + + if (gfc_notify_std (GFC_STD_GNU, "Extension: Unary operator following" + " arithmetic operator (use parentheses) at %C") + == FAILURE) + return MATCH_ERROR; + + m = match_ext_mult_operand (&e); + if (m != MATCH_YES) + return m; + + if (i == -1) + all = gfc_uminus (e); + else + all = gfc_uplus (e); + + if (all == NULL) + { + gfc_free_expr (e); + return MATCH_ERROR; + } + + all->where = where; + *result = all; + return MATCH_YES; +} + + static match match_add_operand (gfc_expr ** result) { @@ -295,7 +367,7 @@ match_add_operand (gfc_expr ** result) where = *gfc_current_locus (); - m = match_mult_operand (&e); + m = match_ext_mult_operand (&e); if (m == MATCH_NO) { gfc_set_locus (&old_loc); @@ -329,15 +401,43 @@ match_add_operand (gfc_expr ** result) } -static int -match_add_op (void) +static match +match_ext_add_operand (gfc_expr ** result) { + gfc_expr *all, *e; + locus where; + match m; + int i; - if (next_operator (INTRINSIC_MINUS)) - return -1; - if (next_operator (INTRINSIC_PLUS)) - return 1; - return 0; + where = *gfc_current_locus (); + i = match_add_op (); + + if (i == 0) + return match_add_operand (result); + + if (gfc_notify_std (GFC_STD_GNU, "Extension: Unary operator following" + " arithmetic operator (use parentheses) at %C") + == FAILURE) + return MATCH_ERROR; + + m = match_ext_add_operand (&e); + if (m != MATCH_YES) + return m; + + if (i == -1) + all = gfc_uminus (e); + else + all = gfc_uplus (e); + + if (all == NULL) + { + gfc_free_expr (e); + return MATCH_ERROR; + } + + all->where = where; + *result = all; + return MATCH_YES; } @@ -354,12 +454,17 @@ match_level_2 (gfc_expr ** result) where = *gfc_current_locus (); i = match_add_op (); - m = match_add_operand (&e); - if (i != 0 && m == MATCH_NO) + if (i != 0) { - gfc_error (expression_syntax); - m = MATCH_ERROR; + m = match_ext_add_operand (&e); + if (m == MATCH_NO) + { + gfc_error (expression_syntax); + m = MATCH_ERROR; + } } + else + m = match_add_operand (&e); if (m != MATCH_YES) return m; @@ -391,7 +496,7 @@ match_level_2 (gfc_expr ** result) if (i == 0) break; - m = match_add_operand (&e); + m = match_ext_add_operand (&e); if (m == MATCH_NO) gfc_error (expression_syntax); if (m != MATCH_YES)