From f100d8b192f6812e0ea7b4d22cf1d972cad83f40 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Thu, 14 Jun 2018 10:13:40 -0700 Subject: [PATCH] [flang] Issue 98, better error recovery for specification-part Original-commit: flang-compiler/f18@0b0812a82b15decf430de2c3ca991623cf53e5e2 Reviewed-on: https://github.com/flang-compiler/f18/pull/103 --- flang/lib/parser/grammar.h | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/flang/lib/parser/grammar.h b/flang/lib/parser/grammar.h index d81d436..31758ce 100644 --- a/flang/lib/parser/grammar.h +++ b/flang/lib/parser/grammar.h @@ -64,6 +64,15 @@ TYPE_CONTEXT_PARSER("declaration construct"_en_US, statement(indirect(Parser{})))), construct(declErrorRecovery))) +// R507 variant of declaration-construct for use in limitedSpecificationPart. +constexpr auto limitedDeclarationConstruct = + inContext("declaration construct"_en_US, + recovery( + first(construct(specificationConstruct), + construct(statement(indirect(dataStmt)))), + construct( + errorRecoveryStart >> stmtErrorRecovery))); + // R508 specification-construct -> // derived-type-def | enum-def | generic-stmt | interface-block | // parameter-stmt | procedure-declaration-stmt | @@ -251,6 +260,16 @@ TYPE_CONTEXT_PARSER("specification part"_en_US, many(statement(indirect(Parser{}))), implicitPart, many(declarationConstruct))) +// R504 variant for many contexts (modules, submodules, BLOCK DATA subprograms, +// and interfaces) which have constraints on their specification parts that +// preclude FORMAT, ENTRY, and statement functions, and benefit from +// specialized error recovery in the event of a spurious executable +// statement. +constexpr auto limitedSpecificationPart = inContext("specification part"_en_US, + construct(many(statement(indirect(Parser{}))), + many(statement(indirect(Parser{}))), implicitPart, + many(limitedDeclarationConstruct))); + // R505 implicit-part -> [implicit-part-stmt]... implicit-stmt // TODO: Can overshoot; any trailing PARAMETER, FORMAT, & ENTRY // statements after the last IMPLICIT should be transferred to the @@ -2910,7 +2929,7 @@ TYPE_CONTEXT_PARSER("END PROGRAM statement"_en_US, // module-stmt [specification-part] [module-subprogram-part] // end-module-stmt TYPE_CONTEXT_PARSER("module"_en_US, - construct(statement(Parser{}), specificationPart, + construct(statement(Parser{}), limitedSpecificationPart, maybe(Parser{}), unterminatedStatement(Parser{}))) @@ -2967,8 +2986,8 @@ TYPE_PARSER(construct(Parser{}) || // submodule-stmt [specification-part] [module-subprogram-part] // end-submodule-stmt TYPE_CONTEXT_PARSER("submodule"_en_US, - construct(statement(Parser{}), specificationPart, - maybe(Parser{}), + construct(statement(Parser{}), + limitedSpecificationPart, maybe(Parser{}), unterminatedStatement(Parser{}))) // R1417 submodule-stmt -> SUBMODULE ( parent-identifier ) submodule-name @@ -2986,7 +3005,8 @@ TYPE_CONTEXT_PARSER("END SUBMODULE statement"_en_US, // R1420 block-data -> block-data-stmt [specification-part] end-block-data-stmt TYPE_CONTEXT_PARSER("BLOCK DATA subprogram"_en_US, - construct(statement(Parser{}), specificationPart, + construct(statement(Parser{}), + limitedSpecificationPart, unterminatedStatement(Parser{}))) // R1421 block-data-stmt -> BLOCK DATA [block-data-name] @@ -3021,10 +3041,10 @@ TYPE_PARSER(construct("END INTERFACE" >> maybe(genericSpec))) TYPE_CONTEXT_PARSER("interface body"_en_US, construct( construct(statement(functionStmt), - indirect(specificationPart), statement(endFunctionStmt))) || - construct( - construct(statement(subroutineStmt), - indirect(specificationPart), statement(endSubroutineStmt)))) + indirect(limitedSpecificationPart), statement(endFunctionStmt))) || + construct(construct( + statement(subroutineStmt), indirect(limitedSpecificationPart), + statement(endSubroutineStmt)))) // R1507 specific-procedure -> procedure-name constexpr auto specificProcedure = name; -- 2.7.4