@@ -72,23 +72,39 @@ static void reject_statement (void);
7272 input with the passed string. If this succeeds, we call the
7373 keyword-dependent matching function that will match the rest of the
7474 statement. For single keywords, the matching subroutine is
75- gfc_match_eos(). */
75+ gfc_match_eos().
76+
77+ If NO_SUBSTRING, the keyword must be followed by a character not
78+ permitted in a name (for free form); EOF is not handled here. Due
79+ to fixed-form Fortran, longer keywords still need to be matched
80+ before shorter substrings.
81+
82+ If REJECT_STMT_ON_ERROR is false, it is assumed that no error
83+ recovery handling is needed. */
7684
7785static match
78- match_word (const char *str, match (*subr) (void ), locus *old_locus)
86+ match_word (const char *str, match (*subr) (void ), locus *old_locus,
87+ bool no_substring = false, bool reject_stmt_on_error = true)
7988{
8089 match m;
90+ char c;
8191
8292 if (str != NULL )
8393 {
8494 m = gfc_match (str);
8595 if (m != MATCH_YES )
8696 return m;
97+ if (no_substring && gfc_current_form == FORM_FREE
98+ && ((c = gfc_peek_ascii_char ()) == ' _' || c == ' $' || ISALNUM (c)))
99+ {
100+ gfc_current_locus = *old_locus;
101+ return MATCH_NO ;
102+ }
87103 }
88104
89105 m = (*subr) ();
90106
91- if (m != MATCH_YES )
107+ if (m == MATCH_NO || (reject_stmt_on_error && m == MATCH_ERROR ) )
92108 {
93109 gfc_current_locus = *old_locus;
94110 reject_statement ();
@@ -99,24 +115,33 @@ match_word (const char *str, match (*subr) (void), locus *old_locus)
99115
100116
101117/* Like match_word, but if str is matched, set a flag that it
102- was matched. */
118+ was matched. Note that reject_statement() is not called if
119+ SUBR returned a match error - and no substring matching is
120+ assumed. */
103121static match
104122match_word_omp_simd (const char *str, match (*subr) (void ), locus *old_locus,
105123 bool *simd_matched)
106124{
107125 match m;
126+ char c;
108127
109128 if (str != NULL )
110129 {
111130 m = gfc_match (str);
112131 if (m != MATCH_YES )
113132 return m;
133+ if (gfc_current_form == FORM_FREE
134+ && ((c = gfc_peek_ascii_char ()) == ' _' || c == ' $' || ISALNUM (c)))
135+ {
136+ gfc_current_locus = *old_locus;
137+ return MATCH_NO ;
138+ }
114139 *simd_matched = true ;
115140 }
116141
117142 m = (*subr) ();
118143
119- if (m != MATCH_YES )
144+ if (m == MATCH_NO )
120145 {
121146 gfc_current_locus = *old_locus;
122147 reject_statement ();
@@ -677,21 +702,20 @@ decode_statement (void)
677702}
678703
679704/* Like match and if spec_only, goto do_spec_only without actually
680- matching. */
681- /* If the directive matched but the clauses failed, do not start
682- matching the next directive in the same switch statement. */
683- #define matcha (keyword, subr, st ) \
684- do { \
685- match m2; \
686- if (spec_only && gfc_match (keyword) == MATCH_YES ) \
687- goto do_spec_only; \
688- else if ((m2 = match_word (keyword, subr, &old_locus)) \
689- == MATCH_YES ) \
690- return st; \
691- else if (m2 == MATCH_ERROR ) \
692- goto error_handling; \
693- else \
694- undo_new_statement (); \
705+ matching. If the directive matched but the parsing then failed,
706+ do not start matching the next directive in the same switch statement. */
707+ #define matcha (keyword, subr, st ) \
708+ do { \
709+ match m2; \
710+ if (spec_only && gfc_match (keyword) == MATCH_YES ) \
711+ goto do_spec_only; \
712+ else if ((m2 = match_word (keyword, subr, &old_locus, true , \
713+ false )) == MATCH_YES ) \
714+ return st; \
715+ else if (m2 == MATCH_ERROR ) \
716+ goto error_handling; \
717+ else \
718+ undo_new_statement (); \
695719 } while (0 )
696720
697721static gfc_statement
@@ -745,7 +769,7 @@ decode_oacc_directive (void)
745769 break ;
746770 case ' d' :
747771 matcha (" data" , gfc_match_oacc_data, ST_OACC_DATA );
748- match (" declare" , gfc_match_oacc_declare, ST_OACC_DECLARE );
772+ matcha (" declare" , gfc_match_oacc_declare, ST_OACC_DECLARE );
749773 break ;
750774 case ' e' :
751775 matcha (" end atomic" , gfc_match_omp_eos_error, ST_OACC_END_ATOMIC );
@@ -791,17 +815,19 @@ decode_oacc_directive (void)
791815 break ;
792816 }
793817
794- /* Directive not found or stored an error message.
795- Check and give up. */
818+ /* Directive not found. */
819+ gfc_error_now (" Unclassifiable OpenACC directive at %C" );
820+ goto recover;
796821
822+ /* Directive found but failed with an error, possibly with
823+ a stored an error message. */
797824 error_handling:
798825 if (gfc_error_check () == 0 )
799- gfc_error_now (" Unclassifiable OpenACC directive at %C" );
826+ gfc_error_now (" Syntax error in statement at %C" );
800827
828+ recover:
801829 reject_statement ();
802-
803830 gfc_error_recovery ();
804-
805831 return ST_NONE ;
806832
807833 do_spec_only:
@@ -812,6 +838,8 @@ decode_oacc_directive (void)
812838 return ST_GET_FCN_CHARACTERISTICS ;
813839}
814840
841+ #undef matcha
842+
815843/* Checks for the ST_OMP_ALLOCATE. First, check whether all list items
816844 are allocatables/pointers - and if so, assume it is associated with a Fortran
817845 ALLOCATE stmt. If not, do some initial parsing-related checks and append
@@ -911,23 +939,23 @@ check_omp_allocate_stmt (locus *loc)
911939 and if spec_only, goto do_spec_only without actually matching. */
912940/* If the directive matched but the clauses failed, do not start
913941 matching the next directive in the same switch statement. */
914- #define matcho (keyword, subr, st ) \
915- do { \
916- match m2; \
917- if (!flag_openmp) \
918- ; \
919- else if (spec_only && gfc_match (keyword) == MATCH_YES ) \
920- goto do_spec_only; \
921- else if ((m2 = match_word (keyword, subr, &old_locus)) \
922- == MATCH_YES ) \
923- { \
924- ret = st; \
925- goto finish; \
926- } \
927- else if (m2 == MATCH_ERROR ) \
928- goto error_handling; \
929- else \
930- undo_new_statement (); \
942+ #define matcho (keyword, subr, st ) \
943+ do { \
944+ match m2; \
945+ if (!flag_openmp) \
946+ ; \
947+ else if (spec_only && gfc_match (keyword) == MATCH_YES ) \
948+ goto do_spec_only; \
949+ else if ((m2 = match_word (keyword, subr, &old_locus, true , \
950+ false )) == MATCH_YES ) \
951+ { \
952+ ret = st; \
953+ goto finish; \
954+ } \
955+ else if (m2 == MATCH_ERROR ) \
956+ goto error_handling; \
957+ else \
958+ undo_new_statement (); \
931959 } while (0 )
932960
933961/* Like match, but set a flag simd_matched if keyword matched. */
@@ -947,21 +975,21 @@ check_omp_allocate_stmt (locus *loc)
947975 } while (0 )
948976
949977/* Like match, but don't match anything if not -fopenmp. */
950- #define matchdo (keyword, subr, st ) \
951- do { \
952- match m2; \
953- if (!flag_openmp) \
954- ; \
955- else if ((m2 = match_word (keyword, subr, &old_locus)) \
956- == MATCH_YES ) \
957- { \
958- ret = st; \
959- goto finish; \
960- } \
961- else if (m2 == MATCH_ERROR ) \
962- goto error_handling; \
963- else \
964- undo_new_statement (); \
978+ #define matchdo (keyword, subr, st ) \
979+ do { \
980+ match m2; \
981+ if (!flag_openmp) \
982+ ; \
983+ else if ((m2 = match_word (keyword, subr, &old_locus, true , \
984+ false )) == MATCH_YES ) \
985+ { \
986+ ret = st; \
987+ goto finish; \
988+ } \
989+ else if (m2 == MATCH_ERROR ) \
990+ goto error_handling; \
991+ else \
992+ undo_new_statement (); \
965993 } while (0 )
966994
967995static gfc_statement
@@ -1330,17 +1358,20 @@ decode_omp_directive (void)
13301358 break ;
13311359 }
13321360
1333- /* All else has failed, so give up. See if any of the matchers has
1334- stored an error message of some sort. Don't error out if
1335- not -fopenmp and simd_matched is false, i.e. if a directive other
1336- than one marked with match has been seen. */
1361+ /* Directive not found. Don't error out if not -fopenmp and
1362+ simd_matched is false, i.e. if a directive other than one marked
1363+ with match has been seen. */
1364+ if (flag_openmp || simd_matched)
1365+ gfc_error_now (" Unclassifiable OpenMP directive at %C" );
1366+ goto recover;
13371367
13381368 error_handling:
1339- if (flag_openmp || simd_matched)
1340- {
1341- if (!gfc_error_check ())
1342- gfc_error_now (" Unclassifiable OpenMP directive at %C" );
1343- }
1369+ /* Directive found but failed with an error, possibly with
1370+ a stored an error message. */
1371+ if ((flag_openmp || simd_matched) && gfc_error_check () == 0 )
1372+ gfc_error_now (" Syntax error in statement at %C" );
1373+
1374+ recover:
13441375
13451376 /* If parsing a metadirective, let the caller deal with the cleanup. */
13461377 if (gfc_matching_omp_context_selector)
@@ -1467,6 +1498,11 @@ decode_omp_directive (void)
14671498 return ST_GET_FCN_CHARACTERISTICS ;
14681499}
14691500
1501+ #undef matchs
1502+ #undef matcho
1503+ #undef matchds
1504+ #undef matchdo
1505+
14701506gfc_statement
14711507match_omp_directive (void )
14721508{
0 commit comments