Commit a2f29587 by Roger Sayle Committed by Roger Sayle

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
parent 7d34a5a9
2004-05-25 Roger Sayle <roger@eyesopen.com>
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 <paul@codesourcery.com> 2004-05-25 Paul Brook <paul@codesourcery.com>
* expr.c (check_inquiry): Remove bogus tests. * expr.c (check_inquiry): Remove bogus tests.
......
...@@ -222,6 +222,38 @@ match_level_1 (gfc_expr ** result) ...@@ -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 static match
match_mult_operand (gfc_expr ** result) match_mult_operand (gfc_expr ** result)
{ {
...@@ -241,7 +273,7 @@ match_mult_operand (gfc_expr ** result) ...@@ -241,7 +273,7 @@ match_mult_operand (gfc_expr ** result)
where = *gfc_current_locus (); where = *gfc_current_locus ();
m = match_mult_operand (&exp); m = match_ext_mult_operand (&exp);
if (m == MATCH_NO) if (m == MATCH_NO)
gfc_error ("Expected exponent in expression at %C"); gfc_error ("Expected exponent in expression at %C");
if (m != MATCH_YES) if (m != MATCH_YES)
...@@ -266,6 +298,46 @@ match_mult_operand (gfc_expr ** result) ...@@ -266,6 +298,46 @@ match_mult_operand (gfc_expr ** result)
static match 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) match_add_operand (gfc_expr ** result)
{ {
gfc_expr *all, *e, *total; gfc_expr *all, *e, *total;
...@@ -295,7 +367,7 @@ match_add_operand (gfc_expr ** result) ...@@ -295,7 +367,7 @@ match_add_operand (gfc_expr ** result)
where = *gfc_current_locus (); where = *gfc_current_locus ();
m = match_mult_operand (&e); m = match_ext_mult_operand (&e);
if (m == MATCH_NO) if (m == MATCH_NO)
{ {
gfc_set_locus (&old_loc); gfc_set_locus (&old_loc);
...@@ -329,15 +401,43 @@ match_add_operand (gfc_expr ** result) ...@@ -329,15 +401,43 @@ match_add_operand (gfc_expr ** result)
} }
static int static match
match_add_op (void) match_ext_add_operand (gfc_expr ** result)
{ {
gfc_expr *all, *e;
locus where;
match m;
int i;
if (next_operator (INTRINSIC_MINUS)) where = *gfc_current_locus ();
return -1; i = match_add_op ();
if (next_operator (INTRINSIC_PLUS))
return 1; if (i == 0)
return 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) ...@@ -354,12 +454,17 @@ match_level_2 (gfc_expr ** result)
where = *gfc_current_locus (); where = *gfc_current_locus ();
i = match_add_op (); i = match_add_op ();
m = match_add_operand (&e); if (i != 0)
if (i != 0 && m == MATCH_NO) {
m = match_ext_add_operand (&e);
if (m == MATCH_NO)
{ {
gfc_error (expression_syntax); gfc_error (expression_syntax);
m = MATCH_ERROR; m = MATCH_ERROR;
} }
}
else
m = match_add_operand (&e);
if (m != MATCH_YES) if (m != MATCH_YES)
return m; return m;
...@@ -391,7 +496,7 @@ match_level_2 (gfc_expr ** result) ...@@ -391,7 +496,7 @@ match_level_2 (gfc_expr ** result)
if (i == 0) if (i == 0)
break; break;
m = match_add_operand (&e); m = match_ext_add_operand (&e);
if (m == MATCH_NO) if (m == MATCH_NO)
gfc_error (expression_syntax); gfc_error (expression_syntax);
if (m != MATCH_YES) if (m != MATCH_YES)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment