[flang] Even better program unit END statement error recovery.
authorpeter klausler <pklausler@nvidia.com>
Mon, 30 Jul 2018 23:33:55 +0000 (16:33 -0700)
committerpeter klausler <pklausler@nvidia.com>
Mon, 30 Jul 2018 23:33:55 +0000 (16:33 -0700)
Original-commit: flang-compiler/f18@31f456ebc5c7ec1040776ac234f75c344021193f
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 d47a4dd..a694f9b 100644 (file)
@@ -2975,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,
-        unterminatedEndStmtErrorRecovery)))
+    construct<EndProgramStmt>(recovery(
+        "END PROGRAM" >> maybe(name) || bareEnd, progUnitEndStmtErrorRecovery)))
 
 // R1404 module ->
 //         module-stmt [specification-part] [module-subprogram-part]
@@ -2992,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,
-        unterminatedEndStmtErrorRecovery)))
+    construct<EndModuleStmt>(recovery(
+        "END MODULE" >> maybe(name) || bareEnd, progUnitEndStmtErrorRecovery)))
 
 // R1407 module-subprogram-part -> contains-stmt [module-subprogram]...
 TYPE_CONTEXT_PARSER("module subprogram part"_en_US,
@@ -3055,7 +3055,7 @@ TYPE_PARSER(construct<ParentIdentifier>(name, maybe(":" >> name)))
 TYPE_CONTEXT_PARSER("END SUBMODULE statement"_en_US,
     construct<EndSubmoduleStmt>(
         recovery("END SUBMODULE" >> maybe(name) || bareEnd,
-            unterminatedEndStmtErrorRecovery)))
+            progUnitEndStmtErrorRecovery)))
 
 // R1420 block-data -> block-data-stmt [specification-part] end-block-data-stmt
 TYPE_CONTEXT_PARSER("BLOCK DATA subprogram"_en_US,
@@ -3071,7 +3071,7 @@ TYPE_CONTEXT_PARSER("BLOCK DATA statement"_en_US,
 TYPE_CONTEXT_PARSER("END BLOCK DATA statement"_en_US,
     construct<EndBlockDataStmt>(
         recovery("END BLOCK DATA" >> maybe(name) || bareEnd,
-            unterminatedEndStmtErrorRecovery)))
+            progUnitEndStmtErrorRecovery)))
 
 // R1501 interface-block ->
 //         interface-stmt [interface-specification]... end-interface-stmt
@@ -3253,9 +3253,8 @@ TYPE_PARSER(construct<Suffix>(
         "RESULT" >> parenthesized(name), maybe(languageBindingSpec)))
 
 // R1533 end-function-stmt -> END [FUNCTION [function-name]]
-TYPE_PARSER(construct<EndFunctionStmt>(
-    recovery("END FUNCTION" >> maybe(name) || bareEnd,
-        unterminatedEndStmtErrorRecovery)))
+TYPE_PARSER(construct<EndFunctionStmt>(recovery(
+    "END FUNCTION" >> maybe(name) || bareEnd, progUnitEndStmtErrorRecovery)))
 
 // R1534 subroutine-subprogram ->
 //         subroutine-stmt [specification-part] [execution-part]
@@ -3279,9 +3278,8 @@ TYPE_PARSER(
 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,
-        unterminatedEndStmtErrorRecovery)))
+TYPE_PARSER(construct<EndSubroutineStmt>(recovery(
+    "END SUBROUTINE" >> maybe(name) || bareEnd, progUnitEndStmtErrorRecovery)))
 
 // R1538 separate-module-subprogram ->
 //         mp-subprogram-stmt [specification-part] [execution-part]
@@ -3299,7 +3297,7 @@ TYPE_CONTEXT_PARSER("MODULE PROCEDURE statement"_en_US,
 TYPE_CONTEXT_PARSER("END PROCEDURE statement"_en_US,
     construct<EndMpSubprogramStmt>(
         recovery("END PROCEDURE" >> maybe(name) || bareEnd,
-            unterminatedEndStmtErrorRecovery)))
+            progUnitEndStmtErrorRecovery)))
 
 // R1541 entry-stmt -> ENTRY entry-name [( [dummy-arg-list] ) [suffix]]
 TYPE_PARSER(
index fa080b2..e1d84a9 100644 (file)
@@ -85,9 +85,11 @@ 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};
+    ("END"_tok >> SkipPast<'\n'>{} || consumedAllInput) >> missingOptionalName};
+constexpr auto progUnitEndStmtErrorRecovery{
+    (many(!"END"_tok >> SkipPast<'\n'>{}) >>
+        ("END"_tok >> SkipTo<'\n'>{} || consumedAllInput)) >>
+    missingOptionalName};
 
 }  // namespace Fortran::parser
 #endif  // FORTRAN_PARSER_STMT_PARSER_H_