From 6135c20380e8651892f2ef70d42251c7bdae4bd9 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Mon, 30 Jul 2018 15:31:06 -0700 Subject: [PATCH] [flang] better program unit END statement error recovery 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 | 34 +++++++++++++++++----------------- flang/lib/parser/stmt-parser.h | 9 +++++++++ 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/flang/lib/parser/grammar.h b/flang/lib/parser/grammar.h index aa85cbc..d47a4dd 100644 --- a/flang/lib/parser/grammar.h +++ b/flang/lib/parser/grammar.h @@ -694,11 +694,6 @@ TYPE_PARSER(construct(Parser{}) || construct(Parser{})) // 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( 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(recovery( - "END PROGRAM" >> maybe(name) || bareEnd, endStmtErrorRecovery))) + construct(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( - recovery("END MODULE" >> maybe(name) || bareEnd, endStmtErrorRecovery))) + construct(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(name, maybe(":" >> name))) // R1419 end-submodule-stmt -> END [SUBMODULE [submodule-name]] TYPE_CONTEXT_PARSER("END SUBMODULE statement"_en_US, - construct(recovery( - "END SUBMODULE" >> maybe(name) || bareEnd, endStmtErrorRecovery))) + construct( + 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(recovery( - "END BLOCK DATA" >> maybe(name) || bareEnd, endStmtErrorRecovery))) + construct( + 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( // R1533 end-function-stmt -> END [FUNCTION [function-name]] TYPE_PARSER(construct( - 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(name) || construct(star)) // R1537 end-subroutine-stmt -> END [SUBROUTINE [subroutine-name]] TYPE_PARSER(construct( - 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(recovery( - "END PROCEDURE" >> maybe(name) || bareEnd, endStmtErrorRecovery))) + construct( + recovery("END PROCEDURE" >> maybe(name) || bareEnd, + unterminatedEndStmtErrorRecovery))) // R1541 entry-stmt -> ENTRY entry-name [( [dummy-arg-list] ) [suffix]] TYPE_PARSER( diff --git a/flang/lib/parser/stmt-parser.h b/flang/lib/parser/stmt-parser.h index d65602e..fa080b2 100644 --- a/flang/lib/parser/stmt-parser.h +++ b/flang/lib/parser/stmt-parser.h @@ -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_ -- 2.7.4