[flang] better program unit END statement error recovery
authorpeter klausler <pklausler@nvidia.com>
Mon, 30 Jul 2018 22:31:06 +0000 (15:31 -0700)
committerpeter klausler <pklausler@nvidia.com>
Mon, 30 Jul 2018 22:31:06 +0000 (15:31 -0700)
Original-commit: flang-compiler/f18@62799c88ff86bfa5d193e8efff20c26d3093a016
Reviewed-on: https://github.com/flang-compiler/f18/pull/156
Tree-same-pre-rewrite: false

flang/lib/parser/grammar.h
flang/lib/parser/stmt-parser.h

index aa85cbc..d47a4dd 100644 (file)
@@ -694,11 +694,6 @@ TYPE_PARSER(construct<PrivateOrSequence>(Parser<PrivateStmt>{}) ||
     construct<PrivateOrSequence>(Parser<SequenceStmt>{}))
 
 // R730 end-type-stmt -> END TYPE [type-name]
-constexpr auto missingOptionalName{defaulted(cut >> maybe(name))};
-constexpr auto noNameEnd{"END" >> missingOptionalName};
-constexpr auto bareEnd{noNameEnd / lookAhead(endOfStmt)};
-constexpr auto endStmtErrorRecovery{
-    ("END"_tok / SkipPast<'\n'>{} || consumedAllInput) >> missingOptionalName};
 TYPE_PARSER(construct<EndTypeStmt>(
     recovery("END TYPE" >> maybe(name), endStmtErrorRecovery)))
 
@@ -2980,8 +2975,8 @@ TYPE_CONTEXT_PARSER("PROGRAM statement"_en_US,
 
 // R1403 end-program-stmt -> END [PROGRAM [program-name]]
 TYPE_CONTEXT_PARSER("END PROGRAM statement"_en_US,
-    construct<EndProgramStmt>(recovery(
-        "END PROGRAM" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
+    construct<EndProgramStmt>(recovery("END PROGRAM" >> maybe(name) || bareEnd,
+        unterminatedEndStmtErrorRecovery)))
 
 // R1404 module ->
 //         module-stmt [specification-part] [module-subprogram-part]
@@ -2997,8 +2992,8 @@ TYPE_CONTEXT_PARSER(
 
 // R1406 end-module-stmt -> END [MODULE [module-name]]
 TYPE_CONTEXT_PARSER("END MODULE statement"_en_US,
-    construct<EndModuleStmt>(
-        recovery("END MODULE" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
+    construct<EndModuleStmt>(recovery("END MODULE" >> maybe(name) || bareEnd,
+        unterminatedEndStmtErrorRecovery)))
 
 // R1407 module-subprogram-part -> contains-stmt [module-subprogram]...
 TYPE_CONTEXT_PARSER("module subprogram part"_en_US,
@@ -3058,8 +3053,9 @@ TYPE_PARSER(construct<ParentIdentifier>(name, maybe(":" >> name)))
 
 // R1419 end-submodule-stmt -> END [SUBMODULE [submodule-name]]
 TYPE_CONTEXT_PARSER("END SUBMODULE statement"_en_US,
-    construct<EndSubmoduleStmt>(recovery(
-        "END SUBMODULE" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
+    construct<EndSubmoduleStmt>(
+        recovery("END SUBMODULE" >> maybe(name) || bareEnd,
+            unterminatedEndStmtErrorRecovery)))
 
 // R1420 block-data -> block-data-stmt [specification-part] end-block-data-stmt
 TYPE_CONTEXT_PARSER("BLOCK DATA subprogram"_en_US,
@@ -3073,8 +3069,9 @@ TYPE_CONTEXT_PARSER("BLOCK DATA statement"_en_US,
 
 // R1422 end-block-data-stmt -> END [BLOCK DATA [block-data-name]]
 TYPE_CONTEXT_PARSER("END BLOCK DATA statement"_en_US,
-    construct<EndBlockDataStmt>(recovery(
-        "END BLOCK DATA" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
+    construct<EndBlockDataStmt>(
+        recovery("END BLOCK DATA" >> maybe(name) || bareEnd,
+            unterminatedEndStmtErrorRecovery)))
 
 // R1501 interface-block ->
 //         interface-stmt [interface-specification]... end-interface-stmt
@@ -3257,7 +3254,8 @@ TYPE_PARSER(construct<Suffix>(
 
 // R1533 end-function-stmt -> END [FUNCTION [function-name]]
 TYPE_PARSER(construct<EndFunctionStmt>(
-    recovery("END FUNCTION" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
+    recovery("END FUNCTION" >> maybe(name) || bareEnd,
+        unterminatedEndStmtErrorRecovery)))
 
 // R1534 subroutine-subprogram ->
 //         subroutine-stmt [specification-part] [execution-part]
@@ -3282,7 +3280,8 @@ TYPE_PARSER(construct<DummyArg>(name) || construct<DummyArg>(star))
 
 // R1537 end-subroutine-stmt -> END [SUBROUTINE [subroutine-name]]
 TYPE_PARSER(construct<EndSubroutineStmt>(
-    recovery("END SUBROUTINE" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
+    recovery("END SUBROUTINE" >> maybe(name) || bareEnd,
+        unterminatedEndStmtErrorRecovery)))
 
 // R1538 separate-module-subprogram ->
 //         mp-subprogram-stmt [specification-part] [execution-part]
@@ -3298,8 +3297,9 @@ TYPE_CONTEXT_PARSER("MODULE PROCEDURE statement"_en_US,
 
 // R1540 end-mp-subprogram-stmt -> END [PROCEDURE [procedure-name]]
 TYPE_CONTEXT_PARSER("END PROCEDURE statement"_en_US,
-    construct<EndMpSubprogramStmt>(recovery(
-        "END PROCEDURE" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
+    construct<EndMpSubprogramStmt>(
+        recovery("END PROCEDURE" >> maybe(name) || bareEnd,
+            unterminatedEndStmtErrorRecovery)))
 
 // R1541 entry-stmt -> ENTRY entry-name [( [dummy-arg-list] ) [suffix]]
 TYPE_PARSER(
index d65602e..fa080b2 100644 (file)
@@ -80,5 +80,14 @@ constexpr auto executionPartErrorRecovery{stmtErrorRecoveryStart >>
     !"TYPE IS"_tok >> !"CLASS"_tok >> !"RANK"_tok >>
     !("!$OMP "_sptok >> "END"_tok) >> skipBadLine};
 
+// END statement error recovery
+constexpr auto missingOptionalName{defaulted(cut >> maybe(name))};
+constexpr auto noNameEnd{"END" >> missingOptionalName};
+constexpr auto bareEnd{noNameEnd / lookAhead(endOfStmt)};
+constexpr auto endStmtErrorRecovery{
+    ("END"_tok / SkipPast<'\n'>{} || consumedAllInput) >> missingOptionalName};
+constexpr auto unterminatedEndStmtErrorRecovery{
+    ("END"_tok / SkipTo<'\n'>{} || consumedAllInput) >> missingOptionalName};
+
 }  // namespace Fortran::parser
 #endif  // FORTRAN_PARSER_STMT_PARSER_H_