2 Copyright (C) 2000-2024 Free Software Foundation, Inc.
3 Contributed by Andy Vaught
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
28 static const char expression_syntax
[] = N_("Syntax error in expression at %C");
31 /* Match a user-defined operator name. This is a normal name with a
32 few restrictions. The error_flag controls whether an error is
33 raised if 'true' or 'false' are used or not. */
36 gfc_match_defined_op_name (char *result
, int error_flag
)
38 static const char * const badops
[] = {
39 "and", "or", "not", "eqv", "neqv", "eq", "ne", "ge", "le", "lt", "gt",
43 char name
[GFC_MAX_SYMBOL_LEN
+ 1];
48 old_loc
= gfc_current_locus
;
50 m
= gfc_match (" . %n .", name
);
54 /* .true. and .false. have interpretations as constants. Trying to
55 use these as operators will fail at a later time. */
57 if (strcmp (name
, "true") == 0 || strcmp (name
, "false") == 0)
61 gfc_current_locus
= old_loc
;
65 for (i
= 0; badops
[i
]; i
++)
66 if (strcmp (badops
[i
], name
) == 0)
69 for (i
= 0; name
[i
]; i
++)
70 if (!ISALPHA (name
[i
]))
72 gfc_error ("Bad character %qc in OPERATOR name at %C", name
[i
]);
76 strcpy (result
, name
);
80 gfc_error ("The name %qs cannot be used as a defined operator at %C",
83 gfc_current_locus
= old_loc
;
88 /* Match a user defined operator. The symbol found must be an
92 match_defined_operator (gfc_user_op
**result
)
94 char name
[GFC_MAX_SYMBOL_LEN
+ 1];
97 m
= gfc_match_defined_op_name (name
, 0);
101 *result
= gfc_get_uop (name
);
106 /* Check to see if the given operator is next on the input. If this
107 is not the case, the parse pointer remains where it was. */
110 next_operator (gfc_intrinsic_op t
)
115 old_loc
= gfc_current_locus
;
116 if (gfc_match_intrinsic_op (&u
) == MATCH_YES
&& t
== u
)
119 gfc_current_locus
= old_loc
;
124 /* Call the INTRINSIC_PARENTHESES function. This is both
125 used explicitly, as below, or by resolve.cc to generate
129 gfc_get_parentheses (gfc_expr
*e
)
133 e2
= gfc_get_operator_expr (&e
->where
, INTRINSIC_PARENTHESES
, e
, NULL
);
136 e2
->corank
= e
->corank
;
142 /* Match a primary expression. */
145 match_primary (gfc_expr
**result
)
150 m
= gfc_match_literal_constant (result
, 0);
154 m
= gfc_match_array_constructor (result
);
158 m
= gfc_match_rvalue (result
);
162 /* Match an expression in parentheses. */
163 if (gfc_match_char ('(') != MATCH_YES
)
166 m
= gfc_match_expr (&e
);
169 if (m
== MATCH_ERROR
)
172 m
= gfc_match_char (')');
174 gfc_error ("Expected a right parenthesis in expression at %C");
176 /* Now we have the expression inside the parentheses, build the
177 expression pointing to it. By 7.1.7.2, any expression in
178 parentheses shall be treated as a data entity. */
179 *result
= gfc_get_parentheses (e
);
183 gfc_free_expr (*result
);
190 gfc_error (expression_syntax
);
195 /* Match a level 1 expression. */
198 match_level_1 (gfc_expr
**result
)
205 gfc_gobble_whitespace ();
206 where
= gfc_current_locus
;
208 m
= match_defined_operator (&uop
);
209 if (m
== MATCH_ERROR
)
212 m
= match_primary (&e
);
220 f
= gfc_get_operator_expr (&where
, INTRINSIC_USER
, e
, NULL
);
221 f
->value
.op
.uop
= uop
;
229 /* As a GNU extension we support an expanded level-2 expression syntax.
230 Via this extension we support (arbitrary) nesting of unary plus and
231 minus operations following unary and binary operators, such as **.
232 The grammar of section 7.1.1.3 is effectively rewritten as:
234 R704 mult-operand is level-1-expr [ power-op ext-mult-operand ]
235 R704' ext-mult-operand is add-op ext-mult-operand
237 R705 add-operand is add-operand mult-op ext-mult-operand
239 R705' ext-add-operand is add-op ext-add-operand
241 R706 level-2-expr is [ level-2-expr ] add-op ext-add-operand
245 static match
match_ext_mult_operand (gfc_expr
**result
);
246 static match
match_ext_add_operand (gfc_expr
**result
);
251 if (next_operator (INTRINSIC_MINUS
))
253 if (next_operator (INTRINSIC_PLUS
))
260 match_mult_operand (gfc_expr
**result
)
262 /* Workaround -Wmaybe-uninitialized false positive during
263 profiledbootstrap by initializing them. */
264 gfc_expr
*e
= NULL
, *exp
, *r
;
268 m
= match_level_1 (&e
);
272 if (!next_operator (INTRINSIC_POWER
))
278 where
= gfc_current_locus
;
280 m
= match_ext_mult_operand (&exp
);
282 gfc_error ("Expected exponent in expression at %C");
289 r
= gfc_power (e
, exp
);
305 match_ext_mult_operand (gfc_expr
**result
)
312 where
= gfc_current_locus
;
316 return match_mult_operand (result
);
318 if (gfc_notification_std (GFC_STD_GNU
) == ERROR
)
320 gfc_error ("Extension: Unary operator following "
321 "arithmetic operator (use parentheses) at %C");
325 gfc_warning (0, "Extension: Unary operator following "
326 "arithmetic operator (use parentheses) at %C");
328 m
= match_ext_mult_operand (&e
);
333 all
= gfc_uminus (e
);
350 match_add_operand (gfc_expr
**result
)
352 gfc_expr
*all
, *e
, *total
;
353 locus where
, old_loc
;
357 m
= match_mult_operand (&all
);
363 /* Build up a string of products or quotients. */
365 old_loc
= gfc_current_locus
;
367 if (next_operator (INTRINSIC_TIMES
))
371 if (next_operator (INTRINSIC_DIVIDE
))
372 i
= INTRINSIC_DIVIDE
;
377 where
= gfc_current_locus
;
379 m
= match_ext_mult_operand (&e
);
382 gfc_current_locus
= old_loc
;
386 if (m
== MATCH_ERROR
)
392 if (i
== INTRINSIC_TIMES
)
393 total
= gfc_multiply (all
, e
);
395 total
= gfc_divide (all
, e
);
414 match_ext_add_operand (gfc_expr
**result
)
421 where
= gfc_current_locus
;
425 return match_add_operand (result
);
427 if (gfc_notification_std (GFC_STD_GNU
) == ERROR
)
429 gfc_error ("Extension: Unary operator following "
430 "arithmetic operator (use parentheses) at %C");
434 gfc_warning (0, "Extension: Unary operator following "
435 "arithmetic operator (use parentheses) at %C");
437 m
= match_ext_add_operand (&e
);
442 all
= gfc_uminus (e
);
458 /* Match a level 2 expression. */
461 match_level_2 (gfc_expr
**result
)
463 gfc_expr
*all
, *e
, *total
;
468 where
= gfc_current_locus
;
473 m
= match_ext_add_operand (&e
);
476 gfc_error (expression_syntax
);
481 m
= match_add_operand (&e
);
491 all
= gfc_uminus (e
);
504 /* Append add-operands to the sum. */
508 where
= gfc_current_locus
;
513 m
= match_ext_add_operand (&e
);
515 gfc_error (expression_syntax
);
523 total
= gfc_subtract (all
, e
);
525 total
= gfc_add (all
, e
);
543 /* Match a level three expression. */
546 match_level_3 (gfc_expr
**result
)
548 gfc_expr
*all
, *e
, *total
= NULL
;
552 m
= match_level_2 (&all
);
558 if (!next_operator (INTRINSIC_CONCAT
))
561 where
= gfc_current_locus
;
563 m
= match_level_2 (&e
);
565 gfc_error (expression_syntax
);
572 total
= gfc_concat (all
, e
);
589 /* Match a level 4 expression. */
592 match_level_4 (gfc_expr
**result
)
594 gfc_expr
*left
, *right
, *r
;
600 m
= match_level_3 (&left
);
604 old_loc
= gfc_current_locus
;
606 if (gfc_match_intrinsic_op (&i
) != MATCH_YES
)
612 if (i
!= INTRINSIC_EQ
&& i
!= INTRINSIC_NE
&& i
!= INTRINSIC_GE
613 && i
!= INTRINSIC_LE
&& i
!= INTRINSIC_LT
&& i
!= INTRINSIC_GT
614 && i
!= INTRINSIC_EQ_OS
&& i
!= INTRINSIC_NE_OS
&& i
!= INTRINSIC_GE_OS
615 && i
!= INTRINSIC_LE_OS
&& i
!= INTRINSIC_LT_OS
&& i
!= INTRINSIC_GT_OS
)
617 gfc_current_locus
= old_loc
;
622 where
= gfc_current_locus
;
624 m
= match_level_3 (&right
);
626 gfc_error (expression_syntax
);
629 gfc_free_expr (left
);
636 case INTRINSIC_EQ_OS
:
637 r
= gfc_eq (left
, right
, i
);
641 case INTRINSIC_NE_OS
:
642 r
= gfc_ne (left
, right
, i
);
646 case INTRINSIC_LT_OS
:
647 r
= gfc_lt (left
, right
, i
);
651 case INTRINSIC_LE_OS
:
652 r
= gfc_le (left
, right
, i
);
656 case INTRINSIC_GT_OS
:
657 r
= gfc_gt (left
, right
, i
);
661 case INTRINSIC_GE_OS
:
662 r
= gfc_ge (left
, right
, i
);
666 gfc_internal_error ("match_level_4(): Bad operator");
671 gfc_free_expr (left
);
672 gfc_free_expr (right
);
684 match_and_operand (gfc_expr
**result
)
691 i
= next_operator (INTRINSIC_NOT
);
692 where
= gfc_current_locus
;
694 m
= match_level_4 (&e
);
717 match_or_operand (gfc_expr
**result
)
719 gfc_expr
*all
, *e
, *total
;
723 m
= match_and_operand (&all
);
729 if (!next_operator (INTRINSIC_AND
))
731 where
= gfc_current_locus
;
733 m
= match_and_operand (&e
);
735 gfc_error (expression_syntax
);
742 total
= gfc_and (all
, e
);
760 match_equiv_operand (gfc_expr
**result
)
762 gfc_expr
*all
, *e
, *total
;
766 m
= match_or_operand (&all
);
772 if (!next_operator (INTRINSIC_OR
))
774 where
= gfc_current_locus
;
776 m
= match_or_operand (&e
);
778 gfc_error (expression_syntax
);
785 total
= gfc_or (all
, e
);
802 /* Match a level 5 expression. */
805 match_level_5 (gfc_expr
**result
)
807 gfc_expr
*all
, *e
, *total
;
812 m
= match_equiv_operand (&all
);
818 if (next_operator (INTRINSIC_EQV
))
822 if (next_operator (INTRINSIC_NEQV
))
828 where
= gfc_current_locus
;
830 m
= match_equiv_operand (&e
);
832 gfc_error (expression_syntax
);
839 if (i
== INTRINSIC_EQV
)
840 total
= gfc_eqv (all
, e
);
842 total
= gfc_neqv (all
, e
);
860 /* Match an expression. At this level, we are stringing together
861 level 5 expressions separated by binary operators. */
864 gfc_match_expr (gfc_expr
**result
)
871 m
= match_level_5 (&all
);
878 m
= match_defined_operator (&uop
);
881 if (m
== MATCH_ERROR
)
887 where
= gfc_current_locus
;
889 m
= match_level_5 (&e
);
891 gfc_error (expression_syntax
);
898 all
= gfc_get_operator_expr (&where
, INTRINSIC_USER
, all
, e
);
899 all
->value
.op
.uop
= uop
;