164ab3302SCarolineConcatto //===-- lib/Parser/program-parsers.cpp ------------------------------------===// 264ab3302SCarolineConcatto // 364ab3302SCarolineConcatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 464ab3302SCarolineConcatto // See https://llvm.org/LICENSE.txt for license information. 564ab3302SCarolineConcatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 664ab3302SCarolineConcatto // 764ab3302SCarolineConcatto //===----------------------------------------------------------------------===// 864ab3302SCarolineConcatto 964ab3302SCarolineConcatto // Per-type parsers for program units 1064ab3302SCarolineConcatto 1164ab3302SCarolineConcatto #include "basic-parsers.h" 1264ab3302SCarolineConcatto #include "expr-parsers.h" 1364ab3302SCarolineConcatto #include "misc-parsers.h" 1464ab3302SCarolineConcatto #include "stmt-parser.h" 1564ab3302SCarolineConcatto #include "token-parsers.h" 1664ab3302SCarolineConcatto #include "type-parser-implementation.h" 1764ab3302SCarolineConcatto #include "flang/Parser/characters.h" 1864ab3302SCarolineConcatto #include "flang/Parser/parse-tree.h" 1964ab3302SCarolineConcatto 2064ab3302SCarolineConcatto namespace Fortran::parser { 2164ab3302SCarolineConcatto 2299a0a12aSPeter Klausler // R1530 function-stmt -> 2399a0a12aSPeter Klausler // [prefix] FUNCTION function-name ( [dummy-arg-name-list] ) [suffix] 2499a0a12aSPeter Klausler // R1526 prefix -> prefix-spec [prefix-spec]... 2599a0a12aSPeter Klausler // R1531 dummy-arg-name -> name 2699a0a12aSPeter Klausler 2799a0a12aSPeter Klausler static constexpr auto validFunctionStmt{ 2899a0a12aSPeter Klausler construct<FunctionStmt>(many(prefixSpec), "FUNCTION" >> name, 2999a0a12aSPeter Klausler parenthesized(optionalList(name)), maybe(suffix)) / 3099a0a12aSPeter Klausler atEndOfStmt || 3199a0a12aSPeter Klausler construct<FunctionStmt>(many(prefixSpec), "FUNCTION" >> name / atEndOfStmt, 3299a0a12aSPeter Klausler // PGI & Intel accept "FUNCTION F" 3399a0a12aSPeter Klausler extension<LanguageFeature::OmitFunctionDummies>( 3499a0a12aSPeter Klausler "nonstandard usage: FUNCTION statement without dummy argument list"_port_en_US, 3599a0a12aSPeter Klausler pure<std::list<Name>>()), 3699a0a12aSPeter Klausler pure<std::optional<Suffix>>())}; 3799a0a12aSPeter Klausler 3899a0a12aSPeter Klausler // function-stmt with error recovery -- used in interfaces and internal 3999a0a12aSPeter Klausler // subprograms, but not at the top level, where REALFUNCTIONF and 4099a0a12aSPeter Klausler // INTEGERPUREELEMENTALFUNCTIONG(10) might appear as the first statement 4199a0a12aSPeter Klausler // of a main program. 4299a0a12aSPeter Klausler TYPE_PARSER(validFunctionStmt || 4399a0a12aSPeter Klausler construct<FunctionStmt>(many(prefixSpec), "FUNCTION" >> name, 4499a0a12aSPeter Klausler defaulted(parenthesized(optionalList(name))), maybe(suffix)) / 4599a0a12aSPeter Klausler checkEndOfKnownStmt) 4699a0a12aSPeter Klausler 4764ab3302SCarolineConcatto // R502 program-unit -> 4864ab3302SCarolineConcatto // main-program | external-subprogram | module | submodule | block-data 4964ab3302SCarolineConcatto // R503 external-subprogram -> function-subprogram | subroutine-subprogram 5064ab3302SCarolineConcatto // N.B. "module" must precede "external-subprogram" in this sequence of 5164ab3302SCarolineConcatto // alternatives to avoid ambiguity with the MODULE keyword prefix that 5264ab3302SCarolineConcatto // they recognize. I.e., "modulesubroutinefoo" should start a module 5364ab3302SCarolineConcatto // "subroutinefoo", not a subroutine "foo" with the MODULE prefix. The 5464ab3302SCarolineConcatto // ambiguity is exacerbated by the extension that accepts a function 5564ab3302SCarolineConcatto // statement without an otherwise empty list of dummy arguments. That 5664ab3302SCarolineConcatto // MODULE prefix is disallowed by a constraint (C1547) in this context, 5764ab3302SCarolineConcatto // so the standard language is not ambiguous, but disabling its misrecognition 58619b5bfcSPeter Klausler // here would require context-sensitive keyword recognition or variant parsers 59619b5bfcSPeter Klausler // for several productions; giving the "module" production priority here is a 60619b5bfcSPeter Klausler // cleaner solution, though regrettably subtle. 61619b5bfcSPeter Klausler // Enforcing C1547 is done in semantics. 6213cee14bSpeter klausler static constexpr auto programUnit{ 6313cee14bSpeter klausler construct<ProgramUnit>(indirect(Parser<Module>{})) || 6464ab3302SCarolineConcatto construct<ProgramUnit>(indirect(subroutineSubprogram)) || 6564ab3302SCarolineConcatto construct<ProgramUnit>(indirect(Parser<Submodule>{})) || 6664ab3302SCarolineConcatto construct<ProgramUnit>(indirect(Parser<BlockData>{})) || 6799a0a12aSPeter Klausler lookAhead(validFunctionStmt) >> 6899a0a12aSPeter Klausler construct<ProgramUnit>(indirect(functionSubprogram)) || 6913cee14bSpeter klausler construct<ProgramUnit>(indirect(Parser<MainProgram>{}))}; 7013cee14bSpeter klausler static constexpr auto normalProgramUnit{StartNewSubprogram{} >> programUnit / 7113cee14bSpeter klausler skipMany(";"_tok) / space / recovery(endOfLine, SkipPast<'\n'>{})}; 7213cee14bSpeter klausler static constexpr auto globalCompilerDirective{ 7313cee14bSpeter klausler construct<ProgramUnit>(indirect(compilerDirective))}; 7413cee14bSpeter klausler 7582867439SValentin Clement (バレンタイン クレメン) static constexpr auto globalOpenACCCompilerDirective{ 7682867439SValentin Clement (バレンタイン クレメン) construct<ProgramUnit>(indirect(skipStuffBeforeStatement >> 7782867439SValentin Clement (バレンタイン クレメン) "!$ACC "_sptok >> Parser<OpenACCRoutineConstruct>{}))}; 7882867439SValentin Clement (バレンタイン クレメン) 7913cee14bSpeter klausler // R501 program -> program-unit [program-unit]... 8013cee14bSpeter klausler // This is the top-level production for the Fortran language. 8113cee14bSpeter klausler // F'2018 6.3.1 defines a program unit as a sequence of one or more lines, 8213cee14bSpeter klausler // implying that a line can't be part of two distinct program units. 8313cee14bSpeter klausler // Consequently, a program unit END statement should be the last statement 8413cee14bSpeter klausler // on its line. We parse those END statements via unterminatedStatement() 8513cee14bSpeter klausler // and then skip over the end of the line here. 862d8b6a47SPeter Klausler TYPE_PARSER( 872d8b6a47SPeter Klausler construct<Program>(extension<LanguageFeature::EmptySourceFile>( 882d8b6a47SPeter Klausler "nonstandard usage: empty source file"_port_en_US, 892d8b6a47SPeter Klausler skipStuffBeforeStatement >> !nextCh >> 902d8b6a47SPeter Klausler pure<std::list<ProgramUnit>>()) || 9182867439SValentin Clement (バレンタイン クレメン) some(globalCompilerDirective || globalOpenACCCompilerDirective || 9282867439SValentin Clement (バレンタイン クレメン) normalProgramUnit) / 9313cee14bSpeter klausler skipStuffBeforeStatement)) 9464ab3302SCarolineConcatto 9564ab3302SCarolineConcatto // R507 declaration-construct -> 9664ab3302SCarolineConcatto // specification-construct | data-stmt | format-stmt | 9764ab3302SCarolineConcatto // entry-stmt | stmt-function-stmt 9864ab3302SCarolineConcatto // N.B. These parsers incorporate recognition of some other statements that 9964ab3302SCarolineConcatto // may have been misplaced in the sequence of statements that are acceptable 10064ab3302SCarolineConcatto // as a specification part in order to improve error recovery. 10164ab3302SCarolineConcatto // Also note that many instances of specification-part in the standard grammar 10264ab3302SCarolineConcatto // are in contexts that impose constraints on the kinds of statements that 10364ab3302SCarolineConcatto // are allowed, and so we have a variant production for declaration-construct 10464ab3302SCarolineConcatto // that implements those constraints. 105010c55bfSPeter Klausler constexpr auto actionStmtLookAhead{first(actionStmt >> ok, 106010c55bfSPeter Klausler // Also accept apparent action statements with errors if they might be 107010c55bfSPeter Klausler // first in the execution part 108010c55bfSPeter Klausler "ALLOCATE ("_tok, "CALL" >> name >> "("_tok, "GO TO"_tok, "OPEN ("_tok, 109010c55bfSPeter Klausler "PRINT"_tok / space / !"("_tok, "READ ("_tok, "WRITE ("_tok)}; 110010c55bfSPeter Klausler constexpr auto execPartLookAhead{first(actionStmtLookAhead >> ok, 111010c55bfSPeter Klausler openaccConstruct >> ok, openmpConstruct >> ok, "ASSOCIATE ("_tok, 112010c55bfSPeter Klausler "BLOCK"_tok, "SELECT"_tok, "CHANGE TEAM"_sptok, "CRITICAL"_tok, "DO"_tok, 113010c55bfSPeter Klausler "IF ("_tok, "WHERE ("_tok, "FORALL ("_tok, "!$CUF"_tok)}; 11464ab3302SCarolineConcatto constexpr auto declErrorRecovery{ 11564ab3302SCarolineConcatto stmtErrorRecoveryStart >> !execPartLookAhead >> skipStmtErrorRecovery}; 11664ab3302SCarolineConcatto constexpr auto misplacedSpecificationStmt{Parser<UseStmt>{} >> 11764ab3302SCarolineConcatto fail<DeclarationConstruct>("misplaced USE statement"_err_en_US) || 11864ab3302SCarolineConcatto Parser<ImportStmt>{} >> 11964ab3302SCarolineConcatto fail<DeclarationConstruct>( 12064ab3302SCarolineConcatto "IMPORT statements must follow any USE statements and precede all other declarations"_err_en_US) || 12164ab3302SCarolineConcatto Parser<ImplicitStmt>{} >> 12264ab3302SCarolineConcatto fail<DeclarationConstruct>( 12364ab3302SCarolineConcatto "IMPLICIT statements must follow USE and IMPORT and precede all other declarations"_err_en_US)}; 12464ab3302SCarolineConcatto 125fffbabfdSPeter Klausler TYPE_CONTEXT_PARSER("declaration construct"_en_US, 12664ab3302SCarolineConcatto first(construct<DeclarationConstruct>(specificationConstruct), 12764ab3302SCarolineConcatto construct<DeclarationConstruct>(statement(indirect(dataStmt))), 128fffbabfdSPeter Klausler construct<DeclarationConstruct>(statement(indirect(formatStmt))), 12964ab3302SCarolineConcatto construct<DeclarationConstruct>(statement(indirect(entryStmt))), 13064ab3302SCarolineConcatto construct<DeclarationConstruct>( 13164ab3302SCarolineConcatto statement(indirect(Parser<StmtFunctionStmt>{}))), 132fffbabfdSPeter Klausler misplacedSpecificationStmt)) 133fffbabfdSPeter Klausler 134fffbabfdSPeter Klausler constexpr auto recoveredDeclarationConstruct{ 135fffbabfdSPeter Klausler recovery(withMessage("expected declaration construct"_err_en_US, 136fffbabfdSPeter Klausler declarationConstruct), 137fffbabfdSPeter Klausler construct<DeclarationConstruct>(declErrorRecovery))}; 138fffbabfdSPeter Klausler 139fffbabfdSPeter Klausler // R504 specification-part -> 140fffbabfdSPeter Klausler // [use-stmt]... [import-stmt]... [implicit-part] 141fffbabfdSPeter Klausler // [declaration-construct]... 142fffbabfdSPeter Klausler TYPE_CONTEXT_PARSER("specification part"_en_US, 143fffbabfdSPeter Klausler construct<SpecificationPart>(many(openaccDeclarativeConstruct), 144fffbabfdSPeter Klausler many(openmpDeclarativeConstruct), many(indirect(compilerDirective)), 145fffbabfdSPeter Klausler many(statement(indirect(Parser<UseStmt>{}))), 146fffbabfdSPeter Klausler many(unambiguousStatement(indirect(Parser<ImportStmt>{}))), 147fffbabfdSPeter Klausler implicitPart, many(recoveredDeclarationConstruct))) 14864ab3302SCarolineConcatto 14964ab3302SCarolineConcatto // R507 variant of declaration-construct for use in limitedSpecificationPart. 15064ab3302SCarolineConcatto constexpr auto invalidDeclarationStmt{formatStmt >> 15164ab3302SCarolineConcatto fail<DeclarationConstruct>( 15264ab3302SCarolineConcatto "FORMAT statements are not permitted in this specification part"_err_en_US) || 15364ab3302SCarolineConcatto entryStmt >> 15464ab3302SCarolineConcatto fail<DeclarationConstruct>( 15564ab3302SCarolineConcatto "ENTRY statements are not permitted in this specification part"_err_en_US)}; 15664ab3302SCarolineConcatto 15764ab3302SCarolineConcatto constexpr auto limitedDeclarationConstruct{recovery( 15864ab3302SCarolineConcatto withMessage("expected declaration construct"_err_en_US, 15964ab3302SCarolineConcatto inContext("declaration construct"_en_US, 16064ab3302SCarolineConcatto first(construct<DeclarationConstruct>(specificationConstruct), 16164ab3302SCarolineConcatto construct<DeclarationConstruct>(statement(indirect(dataStmt))), 16264ab3302SCarolineConcatto misplacedSpecificationStmt, invalidDeclarationStmt))), 16364ab3302SCarolineConcatto construct<DeclarationConstruct>( 16464ab3302SCarolineConcatto stmtErrorRecoveryStart >> skipStmtErrorRecovery))}; 16564ab3302SCarolineConcatto 16664ab3302SCarolineConcatto // R504 variant for many contexts (modules, submodules, BLOCK DATA subprograms, 16764ab3302SCarolineConcatto // and interfaces) which have constraints on their specification parts that 16864ab3302SCarolineConcatto // preclude FORMAT, ENTRY, and statement functions, and benefit from 16964ab3302SCarolineConcatto // specialized error recovery in the event of a spurious executable 17064ab3302SCarolineConcatto // statement. 17164ab3302SCarolineConcatto constexpr auto limitedSpecificationPart{inContext("specification part"_en_US, 1720a90ffa7SValentin Clement construct<SpecificationPart>(many(openaccDeclarativeConstruct), 173cf715717STim Keith many(openmpDeclarativeConstruct), many(indirect(compilerDirective)), 17464ab3302SCarolineConcatto many(statement(indirect(Parser<UseStmt>{}))), 17564ab3302SCarolineConcatto many(unambiguousStatement(indirect(Parser<ImportStmt>{}))), 17664ab3302SCarolineConcatto implicitPart, many(limitedDeclarationConstruct)))}; 17764ab3302SCarolineConcatto 17864ab3302SCarolineConcatto // R508 specification-construct -> 17964ab3302SCarolineConcatto // derived-type-def | enum-def | generic-stmt | interface-block | 18064ab3302SCarolineConcatto // parameter-stmt | procedure-declaration-stmt | 18164ab3302SCarolineConcatto // other-specification-stmt | type-declaration-stmt 18264ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("specification construct"_en_US, 18364ab3302SCarolineConcatto first(construct<SpecificationConstruct>(indirect(Parser<DerivedTypeDef>{})), 18464ab3302SCarolineConcatto construct<SpecificationConstruct>(indirect(Parser<EnumDef>{})), 18564ab3302SCarolineConcatto construct<SpecificationConstruct>( 18664ab3302SCarolineConcatto statement(indirect(Parser<GenericStmt>{}))), 18764ab3302SCarolineConcatto construct<SpecificationConstruct>(indirect(interfaceBlock)), 18864ab3302SCarolineConcatto construct<SpecificationConstruct>(statement(indirect(parameterStmt))), 18964ab3302SCarolineConcatto construct<SpecificationConstruct>( 19064ab3302SCarolineConcatto statement(indirect(oldParameterStmt))), 19164ab3302SCarolineConcatto construct<SpecificationConstruct>( 19264ab3302SCarolineConcatto statement(indirect(Parser<ProcedureDeclarationStmt>{}))), 19364ab3302SCarolineConcatto construct<SpecificationConstruct>( 19464ab3302SCarolineConcatto statement(Parser<OtherSpecificationStmt>{})), 19564ab3302SCarolineConcatto construct<SpecificationConstruct>( 19664ab3302SCarolineConcatto statement(indirect(typeDeclarationStmt))), 19764ab3302SCarolineConcatto construct<SpecificationConstruct>(indirect(Parser<StructureDef>{})), 1980a90ffa7SValentin Clement construct<SpecificationConstruct>( 1990a90ffa7SValentin Clement indirect(openaccDeclarativeConstruct)), 20064ab3302SCarolineConcatto construct<SpecificationConstruct>(indirect(openmpDeclarativeConstruct)), 20164ab3302SCarolineConcatto construct<SpecificationConstruct>(indirect(compilerDirective)))) 20264ab3302SCarolineConcatto 20364ab3302SCarolineConcatto // R513 other-specification-stmt -> 20464ab3302SCarolineConcatto // access-stmt | allocatable-stmt | asynchronous-stmt | bind-stmt | 20564ab3302SCarolineConcatto // codimension-stmt | contiguous-stmt | dimension-stmt | external-stmt | 20664ab3302SCarolineConcatto // intent-stmt | intrinsic-stmt | namelist-stmt | optional-stmt | 20764ab3302SCarolineConcatto // pointer-stmt | protected-stmt | save-stmt | target-stmt | 2084ad72793SPeter Klausler // volatile-stmt | value-stmt | common-stmt | equivalence-stmt | 2094ad72793SPeter Klausler // (CUDA) CUDA-attributes-stmt 21064ab3302SCarolineConcatto TYPE_PARSER(first( 21164ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<AccessStmt>{})), 21264ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<AllocatableStmt>{})), 21364ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<AsynchronousStmt>{})), 21464ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<BindStmt>{})), 21564ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<CodimensionStmt>{})), 21664ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<ContiguousStmt>{})), 21764ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<DimensionStmt>{})), 21864ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<ExternalStmt>{})), 21964ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<IntentStmt>{})), 22064ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<IntrinsicStmt>{})), 22164ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<NamelistStmt>{})), 22264ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<OptionalStmt>{})), 22364ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<PointerStmt>{})), 22464ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<ProtectedStmt>{})), 22564ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<SaveStmt>{})), 22664ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<TargetStmt>{})), 22764ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<ValueStmt>{})), 22864ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<VolatileStmt>{})), 22964ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<CommonStmt>{})), 23064ab3302SCarolineConcatto construct<OtherSpecificationStmt>(indirect(Parser<EquivalenceStmt>{})), 2314ad72793SPeter Klausler construct<OtherSpecificationStmt>(indirect(Parser<BasedPointerStmt>{})), 2324ad72793SPeter Klausler construct<OtherSpecificationStmt>(indirect(Parser<CUDAAttributesStmt>{})))) 23364ab3302SCarolineConcatto 23464ab3302SCarolineConcatto // R1401 main-program -> 23564ab3302SCarolineConcatto // [program-stmt] [specification-part] [execution-part] 23664ab3302SCarolineConcatto // [internal-subprogram-part] end-program-stmt 23764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("main program"_en_US, 23864ab3302SCarolineConcatto construct<MainProgram>(maybe(statement(Parser<ProgramStmt>{})), 23964ab3302SCarolineConcatto specificationPart, executionPart, maybe(internalSubprogramPart), 24064ab3302SCarolineConcatto unterminatedStatement(Parser<EndProgramStmt>{}))) 24164ab3302SCarolineConcatto 24264ab3302SCarolineConcatto // R1402 program-stmt -> PROGRAM program-name 24364ab3302SCarolineConcatto // PGI allows empty parentheses after the name. 24464ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("PROGRAM statement"_en_US, 24564ab3302SCarolineConcatto construct<ProgramStmt>("PROGRAM" >> name / 24664ab3302SCarolineConcatto maybe(extension<LanguageFeature::ProgramParentheses>( 2472d8b6a47SPeter Klausler "nonstandard usage: parentheses in PROGRAM statement"_port_en_US, 24864ab3302SCarolineConcatto parenthesized(ok))))) 24964ab3302SCarolineConcatto 25064ab3302SCarolineConcatto // R1403 end-program-stmt -> END [PROGRAM [program-name]] 25164ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("END PROGRAM statement"_en_US, 252b5aea329SPeter Klausler construct<EndProgramStmt>( 253b5aea329SPeter Klausler recovery("END" >> defaulted("PROGRAM" >> maybe(name)) / atEndOfStmt, 254b5aea329SPeter Klausler progUnitEndStmtErrorRecovery))) 25564ab3302SCarolineConcatto 25664ab3302SCarolineConcatto // R1404 module -> 25764ab3302SCarolineConcatto // module-stmt [specification-part] [module-subprogram-part] 25864ab3302SCarolineConcatto // end-module-stmt 25964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("module"_en_US, 26064ab3302SCarolineConcatto construct<Module>(statement(Parser<ModuleStmt>{}), limitedSpecificationPart, 26164ab3302SCarolineConcatto maybe(Parser<ModuleSubprogramPart>{}), 26264ab3302SCarolineConcatto unterminatedStatement(Parser<EndModuleStmt>{}))) 26364ab3302SCarolineConcatto 26464ab3302SCarolineConcatto // R1405 module-stmt -> MODULE module-name 26564ab3302SCarolineConcatto TYPE_CONTEXT_PARSER( 26664ab3302SCarolineConcatto "MODULE statement"_en_US, construct<ModuleStmt>("MODULE" >> name)) 26764ab3302SCarolineConcatto 26864ab3302SCarolineConcatto // R1406 end-module-stmt -> END [MODULE [module-name]] 26964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("END MODULE statement"_en_US, 270b5aea329SPeter Klausler construct<EndModuleStmt>( 271b5aea329SPeter Klausler recovery("END" >> defaulted("MODULE" >> maybe(name)) / atEndOfStmt, 272b5aea329SPeter Klausler progUnitEndStmtErrorRecovery))) 27364ab3302SCarolineConcatto 27464ab3302SCarolineConcatto // R1407 module-subprogram-part -> contains-stmt [module-subprogram]... 27564ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("module subprogram part"_en_US, 27664ab3302SCarolineConcatto construct<ModuleSubprogramPart>(statement(containsStmt), 27764ab3302SCarolineConcatto many(StartNewSubprogram{} >> Parser<ModuleSubprogram>{}))) 27864ab3302SCarolineConcatto 27964ab3302SCarolineConcatto // R1408 module-subprogram -> 28064ab3302SCarolineConcatto // function-subprogram | subroutine-subprogram | 28164ab3302SCarolineConcatto // separate-module-subprogram 28264ab3302SCarolineConcatto TYPE_PARSER(construct<ModuleSubprogram>(indirect(functionSubprogram)) || 28364ab3302SCarolineConcatto construct<ModuleSubprogram>(indirect(subroutineSubprogram)) || 2847c1b2898SPeter Klausler construct<ModuleSubprogram>(indirect(Parser<SeparateModuleSubprogram>{})) || 2857c1b2898SPeter Klausler construct<ModuleSubprogram>(indirect(compilerDirective))) 28664ab3302SCarolineConcatto 28764ab3302SCarolineConcatto // R1410 module-nature -> INTRINSIC | NON_INTRINSIC 28864ab3302SCarolineConcatto constexpr auto moduleNature{ 28964ab3302SCarolineConcatto "INTRINSIC" >> pure(UseStmt::ModuleNature::Intrinsic) || 29064ab3302SCarolineConcatto "NON_INTRINSIC" >> pure(UseStmt::ModuleNature::Non_Intrinsic)}; 29164ab3302SCarolineConcatto 29264ab3302SCarolineConcatto // R1409 use-stmt -> 29364ab3302SCarolineConcatto // USE [[, module-nature] ::] module-name [, rename-list] | 29464ab3302SCarolineConcatto // USE [[, module-nature] ::] module-name , ONLY : [only-list] 29564ab3302SCarolineConcatto // N.B. Lookahead to the end of the statement is necessary to resolve 29664ab3302SCarolineConcatto // ambiguity with assignments and statement function definitions that 29764ab3302SCarolineConcatto // begin with the letters "USE". 29864ab3302SCarolineConcatto TYPE_PARSER(construct<UseStmt>("USE" >> optionalBeforeColons(moduleNature), 29964ab3302SCarolineConcatto name, ", ONLY :" >> optionalList(Parser<Only>{})) || 30064ab3302SCarolineConcatto construct<UseStmt>("USE" >> optionalBeforeColons(moduleNature), name, 30164ab3302SCarolineConcatto defaulted("," >> 30264ab3302SCarolineConcatto nonemptyList("expected renamings"_err_en_US, Parser<Rename>{})) / 30364ab3302SCarolineConcatto lookAhead(endOfStmt))) 30464ab3302SCarolineConcatto 30564ab3302SCarolineConcatto // R1411 rename -> 30664ab3302SCarolineConcatto // local-name => use-name | 30764ab3302SCarolineConcatto // OPERATOR ( local-defined-operator ) => 30864ab3302SCarolineConcatto // OPERATOR ( use-defined-operator ) 30964ab3302SCarolineConcatto TYPE_PARSER(construct<Rename>("OPERATOR (" >> 31064ab3302SCarolineConcatto construct<Rename::Operators>( 31164ab3302SCarolineConcatto definedOpName / ") => OPERATOR (", definedOpName / ")")) || 31264ab3302SCarolineConcatto construct<Rename>(construct<Rename::Names>(name, "=>" >> name))) 31364ab3302SCarolineConcatto 31464ab3302SCarolineConcatto // R1412 only -> generic-spec | only-use-name | rename 31564ab3302SCarolineConcatto // R1413 only-use-name -> use-name 3169a883bfaSpeter klausler // N.B. generic-spec and only-use-name are ambiguous; resolved with symbols 31764ab3302SCarolineConcatto TYPE_PARSER(construct<Only>(Parser<Rename>{}) || 3189a883bfaSpeter klausler construct<Only>(indirect(genericSpec)) || construct<Only>(name)) 31964ab3302SCarolineConcatto 32064ab3302SCarolineConcatto // R1416 submodule -> 32164ab3302SCarolineConcatto // submodule-stmt [specification-part] [module-subprogram-part] 32264ab3302SCarolineConcatto // end-submodule-stmt 32364ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("submodule"_en_US, 32464ab3302SCarolineConcatto construct<Submodule>(statement(Parser<SubmoduleStmt>{}), 32564ab3302SCarolineConcatto limitedSpecificationPart, maybe(Parser<ModuleSubprogramPart>{}), 32664ab3302SCarolineConcatto unterminatedStatement(Parser<EndSubmoduleStmt>{}))) 32764ab3302SCarolineConcatto 32864ab3302SCarolineConcatto // R1417 submodule-stmt -> SUBMODULE ( parent-identifier ) submodule-name 32964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SUBMODULE statement"_en_US, 33064ab3302SCarolineConcatto construct<SubmoduleStmt>( 33164ab3302SCarolineConcatto "SUBMODULE" >> parenthesized(Parser<ParentIdentifier>{}), name)) 33264ab3302SCarolineConcatto 33364ab3302SCarolineConcatto // R1418 parent-identifier -> ancestor-module-name [: parent-submodule-name] 33464ab3302SCarolineConcatto TYPE_PARSER(construct<ParentIdentifier>(name, maybe(":" >> name))) 33564ab3302SCarolineConcatto 33664ab3302SCarolineConcatto // R1419 end-submodule-stmt -> END [SUBMODULE [submodule-name]] 33764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("END SUBMODULE statement"_en_US, 33864ab3302SCarolineConcatto construct<EndSubmoduleStmt>( 339b5aea329SPeter Klausler recovery("END" >> defaulted("SUBMODULE" >> maybe(name)) / atEndOfStmt, 34064ab3302SCarolineConcatto progUnitEndStmtErrorRecovery))) 34164ab3302SCarolineConcatto 34264ab3302SCarolineConcatto // R1420 block-data -> block-data-stmt [specification-part] end-block-data-stmt 34364ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("BLOCK DATA subprogram"_en_US, 34464ab3302SCarolineConcatto construct<BlockData>(statement(Parser<BlockDataStmt>{}), 34564ab3302SCarolineConcatto limitedSpecificationPart, 34664ab3302SCarolineConcatto unterminatedStatement(Parser<EndBlockDataStmt>{}))) 34764ab3302SCarolineConcatto 34864ab3302SCarolineConcatto // R1421 block-data-stmt -> BLOCK DATA [block-data-name] 34964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("BLOCK DATA statement"_en_US, 35064ab3302SCarolineConcatto construct<BlockDataStmt>("BLOCK DATA" >> maybe(name))) 35164ab3302SCarolineConcatto 35264ab3302SCarolineConcatto // R1422 end-block-data-stmt -> END [BLOCK DATA [block-data-name]] 35364ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("END BLOCK DATA statement"_en_US, 35464ab3302SCarolineConcatto construct<EndBlockDataStmt>( 355b5aea329SPeter Klausler recovery("END" >> defaulted("BLOCK DATA" >> maybe(name)) / atEndOfStmt, 35664ab3302SCarolineConcatto progUnitEndStmtErrorRecovery))) 35764ab3302SCarolineConcatto 35864ab3302SCarolineConcatto // R1501 interface-block -> 35964ab3302SCarolineConcatto // interface-stmt [interface-specification]... end-interface-stmt 36064ab3302SCarolineConcatto TYPE_PARSER(construct<InterfaceBlock>(statement(Parser<InterfaceStmt>{}), 36164ab3302SCarolineConcatto many(Parser<InterfaceSpecification>{}), 36264ab3302SCarolineConcatto statement(Parser<EndInterfaceStmt>{}))) 36364ab3302SCarolineConcatto 36464ab3302SCarolineConcatto // R1502 interface-specification -> interface-body | procedure-stmt 36564ab3302SCarolineConcatto TYPE_PARSER(construct<InterfaceSpecification>(Parser<InterfaceBody>{}) || 36664ab3302SCarolineConcatto construct<InterfaceSpecification>(statement(Parser<ProcedureStmt>{}))) 36764ab3302SCarolineConcatto 36864ab3302SCarolineConcatto // R1503 interface-stmt -> INTERFACE [generic-spec] | ABSTRACT INTERFACE 36964ab3302SCarolineConcatto TYPE_PARSER(construct<InterfaceStmt>("INTERFACE" >> maybe(genericSpec)) || 37064ab3302SCarolineConcatto construct<InterfaceStmt>(construct<Abstract>("ABSTRACT INTERFACE"_sptok))) 37164ab3302SCarolineConcatto 37264ab3302SCarolineConcatto // R1504 end-interface-stmt -> END INTERFACE [generic-spec] 373619b5bfcSPeter Klausler TYPE_PARSER( 374619b5bfcSPeter Klausler construct<EndInterfaceStmt>(recovery("END INTERFACE" >> maybe(genericSpec), 375619b5bfcSPeter Klausler constructEndStmtErrorRecovery >> pure<std::optional<GenericSpec>>()))) 37664ab3302SCarolineConcatto 37764ab3302SCarolineConcatto // R1505 interface-body -> 37864ab3302SCarolineConcatto // function-stmt [specification-part] end-function-stmt | 37964ab3302SCarolineConcatto // subroutine-stmt [specification-part] end-subroutine-stmt 38064ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("interface body"_en_US, 38164ab3302SCarolineConcatto construct<InterfaceBody>( 38264ab3302SCarolineConcatto construct<InterfaceBody::Function>(statement(functionStmt), 38364ab3302SCarolineConcatto indirect(limitedSpecificationPart), statement(endFunctionStmt))) || 38464ab3302SCarolineConcatto construct<InterfaceBody>(construct<InterfaceBody::Subroutine>( 38564ab3302SCarolineConcatto statement(subroutineStmt), indirect(limitedSpecificationPart), 38664ab3302SCarolineConcatto statement(endSubroutineStmt)))) 38764ab3302SCarolineConcatto 38864ab3302SCarolineConcatto // R1507 specific-procedure -> procedure-name 38964ab3302SCarolineConcatto constexpr auto specificProcedures{ 39064ab3302SCarolineConcatto nonemptyList("expected specific procedure names"_err_en_US, name)}; 39164ab3302SCarolineConcatto 39264ab3302SCarolineConcatto // R1506 procedure-stmt -> [MODULE] PROCEDURE [::] specific-procedure-list 39364ab3302SCarolineConcatto TYPE_PARSER(construct<ProcedureStmt>("MODULE PROCEDURE"_sptok >> 39464ab3302SCarolineConcatto pure(ProcedureStmt::Kind::ModuleProcedure), 39564ab3302SCarolineConcatto maybe("::"_tok) >> specificProcedures) || 39664ab3302SCarolineConcatto construct<ProcedureStmt>( 39764ab3302SCarolineConcatto "PROCEDURE" >> pure(ProcedureStmt::Kind::Procedure), 39864ab3302SCarolineConcatto maybe("::"_tok) >> specificProcedures)) 39964ab3302SCarolineConcatto 40064ab3302SCarolineConcatto // R1508 generic-spec -> 40164ab3302SCarolineConcatto // generic-name | OPERATOR ( defined-operator ) | 40264ab3302SCarolineConcatto // ASSIGNMENT ( = ) | defined-io-generic-spec 40364ab3302SCarolineConcatto // R1509 defined-io-generic-spec -> 40464ab3302SCarolineConcatto // READ ( FORMATTED ) | READ ( UNFORMATTED ) | 40564ab3302SCarolineConcatto // WRITE ( FORMATTED ) | WRITE ( UNFORMATTED ) 40664ab3302SCarolineConcatto TYPE_PARSER(sourced(first(construct<GenericSpec>("OPERATOR" >> 40764ab3302SCarolineConcatto parenthesized(Parser<DefinedOperator>{})), 40864ab3302SCarolineConcatto construct<GenericSpec>( 40964ab3302SCarolineConcatto construct<GenericSpec::Assignment>("ASSIGNMENT ( = )"_tok)), 41064ab3302SCarolineConcatto construct<GenericSpec>( 41164ab3302SCarolineConcatto construct<GenericSpec::ReadFormatted>("READ ( FORMATTED )"_tok)), 41264ab3302SCarolineConcatto construct<GenericSpec>( 41364ab3302SCarolineConcatto construct<GenericSpec::ReadUnformatted>("READ ( UNFORMATTED )"_tok)), 41464ab3302SCarolineConcatto construct<GenericSpec>( 41564ab3302SCarolineConcatto construct<GenericSpec::WriteFormatted>("WRITE ( FORMATTED )"_tok)), 41664ab3302SCarolineConcatto construct<GenericSpec>( 41764ab3302SCarolineConcatto construct<GenericSpec::WriteUnformatted>("WRITE ( UNFORMATTED )"_tok)), 41864ab3302SCarolineConcatto construct<GenericSpec>(name)))) 41964ab3302SCarolineConcatto 42064ab3302SCarolineConcatto // R1510 generic-stmt -> 42164ab3302SCarolineConcatto // GENERIC [, access-spec] :: generic-spec => specific-procedure-list 42264ab3302SCarolineConcatto TYPE_PARSER(construct<GenericStmt>("GENERIC" >> maybe("," >> accessSpec), 42364ab3302SCarolineConcatto "::" >> genericSpec, "=>" >> specificProcedures)) 42464ab3302SCarolineConcatto 42564ab3302SCarolineConcatto // R1511 external-stmt -> EXTERNAL [::] external-name-list 42664ab3302SCarolineConcatto TYPE_PARSER( 42764ab3302SCarolineConcatto "EXTERNAL" >> maybe("::"_tok) >> construct<ExternalStmt>(listOfNames)) 42864ab3302SCarolineConcatto 42964ab3302SCarolineConcatto // R1512 procedure-declaration-stmt -> 43064ab3302SCarolineConcatto // PROCEDURE ( [proc-interface] ) [[, proc-attr-spec]... ::] 43164ab3302SCarolineConcatto // proc-decl-list 43264ab3302SCarolineConcatto TYPE_PARSER("PROCEDURE" >> 43364ab3302SCarolineConcatto construct<ProcedureDeclarationStmt>(parenthesized(maybe(procInterface)), 43464ab3302SCarolineConcatto optionalListBeforeColons(Parser<ProcAttrSpec>{}), 43564ab3302SCarolineConcatto nonemptyList("expected procedure declarations"_err_en_US, procDecl))) 43664ab3302SCarolineConcatto 43764ab3302SCarolineConcatto // R1513 proc-interface -> interface-name | declaration-type-spec 43864ab3302SCarolineConcatto // R1516 interface-name -> name 43964ab3302SCarolineConcatto // N.B. Simple names of intrinsic types (e.g., "REAL") are not 44064ab3302SCarolineConcatto // ambiguous here - they take precedence over derived type names 44164ab3302SCarolineConcatto // thanks to C1516. 44264ab3302SCarolineConcatto TYPE_PARSER( 44364ab3302SCarolineConcatto construct<ProcInterface>(declarationTypeSpec / lookAhead(")"_tok)) || 44464ab3302SCarolineConcatto construct<ProcInterface>(name)) 44564ab3302SCarolineConcatto 44664ab3302SCarolineConcatto // R1514 proc-attr-spec -> 44764ab3302SCarolineConcatto // access-spec | proc-language-binding-spec | INTENT ( intent-spec ) | 44864ab3302SCarolineConcatto // OPTIONAL | POINTER | PROTECTED | SAVE 44964ab3302SCarolineConcatto TYPE_PARSER(construct<ProcAttrSpec>(accessSpec) || 45064ab3302SCarolineConcatto construct<ProcAttrSpec>(languageBindingSpec) || 45164ab3302SCarolineConcatto construct<ProcAttrSpec>("INTENT" >> parenthesized(intentSpec)) || 45264ab3302SCarolineConcatto construct<ProcAttrSpec>(optional) || construct<ProcAttrSpec>(pointer) || 45364ab3302SCarolineConcatto construct<ProcAttrSpec>(protectedAttr) || construct<ProcAttrSpec>(save)) 45464ab3302SCarolineConcatto 45564ab3302SCarolineConcatto // R1515 proc-decl -> procedure-entity-name [=> proc-pointer-init] 45664ab3302SCarolineConcatto TYPE_PARSER(construct<ProcDecl>(name, maybe("=>" >> Parser<ProcPointerInit>{}))) 45764ab3302SCarolineConcatto 45864ab3302SCarolineConcatto // R1517 proc-pointer-init -> null-init | initial-proc-target 45964ab3302SCarolineConcatto // R1518 initial-proc-target -> procedure-name 46064ab3302SCarolineConcatto TYPE_PARSER( 46164ab3302SCarolineConcatto construct<ProcPointerInit>(nullInit) || construct<ProcPointerInit>(name)) 46264ab3302SCarolineConcatto 46364ab3302SCarolineConcatto // R1519 intrinsic-stmt -> INTRINSIC [::] intrinsic-procedure-name-list 46464ab3302SCarolineConcatto TYPE_PARSER( 46564ab3302SCarolineConcatto "INTRINSIC" >> maybe("::"_tok) >> construct<IntrinsicStmt>(listOfNames)) 46664ab3302SCarolineConcatto 4674ad72793SPeter Klausler // R1520 function-reference -> procedure-designator 4684ad72793SPeter Klausler // ( [actual-arg-spec-list] ) 46964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("function reference"_en_US, 4704ad72793SPeter Klausler sourced(construct<FunctionReference>( 4714ad72793SPeter Klausler construct<Call>(Parser<ProcedureDesignator>{}, 47264ab3302SCarolineConcatto parenthesized(optionalList(actualArgSpec))))) / 47364ab3302SCarolineConcatto !"["_tok) 47464ab3302SCarolineConcatto 4754ad72793SPeter Klausler // R1521 call-stmt -> CALL procedure-designator [chevrons] 4764ad72793SPeter Klausler /// [( [actual-arg-spec-list] )] 477*fe5a64d1SValentin Clement (バレンタイン クレメン) // (CUDA) chevrons -> <<< * | scalar-expr, scalar-expr [, scalar-int-expr 4784ad72793SPeter Klausler // [, scalar-int-expr ] ] >>> 479*fe5a64d1SValentin Clement (バレンタイン クレメン) constexpr auto starOrExpr{ 480*fe5a64d1SValentin Clement (バレンタイン クレメン) construct<CallStmt::StarOrExpr>("*" >> pure<std::optional<ScalarExpr>>() || 481*fe5a64d1SValentin Clement (バレンタイン クレメン) applyFunction(presentOptional<ScalarExpr>, scalarExpr))}; 4824ad72793SPeter Klausler TYPE_PARSER(extension<LanguageFeature::CUDA>( 483*fe5a64d1SValentin Clement (バレンタイン クレメン) "<<<" >> construct<CallStmt::Chevrons>(starOrExpr, ", " >> scalarExpr, 4844ad72793SPeter Klausler maybe("," >> scalarIntExpr), maybe("," >> scalarIntExpr)) / 4854ad72793SPeter Klausler ">>>")) 486010c55bfSPeter Klausler constexpr auto actualArgSpecList{optionalList(actualArgSpec)}; 487010c55bfSPeter Klausler TYPE_CONTEXT_PARSER("CALL statement"_en_US, 488010c55bfSPeter Klausler construct<CallStmt>( 4894ad72793SPeter Klausler sourced(construct<CallStmt>("CALL" >> Parser<ProcedureDesignator>{}, 490010c55bfSPeter Klausler maybe(Parser<CallStmt::Chevrons>{}) / space, 491010c55bfSPeter Klausler "(" >> actualArgSpecList / ")" || 492010c55bfSPeter Klausler lookAhead(endOfStmt) >> defaulted(actualArgSpecList))))) 49364ab3302SCarolineConcatto 49464ab3302SCarolineConcatto // R1522 procedure-designator -> 49564ab3302SCarolineConcatto // procedure-name | proc-component-ref | data-ref % binding-name 49664ab3302SCarolineConcatto TYPE_PARSER(construct<ProcedureDesignator>(Parser<ProcComponentRef>{}) || 49764ab3302SCarolineConcatto construct<ProcedureDesignator>(name)) 49864ab3302SCarolineConcatto 49964ab3302SCarolineConcatto // R1523 actual-arg-spec -> [keyword =] actual-arg 50064ab3302SCarolineConcatto TYPE_PARSER(construct<ActualArgSpec>( 50164ab3302SCarolineConcatto maybe(keyword / "=" / !"="_ch), Parser<ActualArg>{})) 50264ab3302SCarolineConcatto 50364ab3302SCarolineConcatto // R1524 actual-arg -> 50464ab3302SCarolineConcatto // expr | variable | procedure-name | proc-component-ref | 50564ab3302SCarolineConcatto // alt-return-spec 50664ab3302SCarolineConcatto // N.B. the "procedure-name" and "proc-component-ref" alternatives can't 50764ab3302SCarolineConcatto // yet be distinguished from "variable", many instances of which can't be 50864ab3302SCarolineConcatto // distinguished from "expr" anyway (to do so would misparse structure 50964ab3302SCarolineConcatto // constructors and function calls as array elements). 51064ab3302SCarolineConcatto // Semantics sorts it all out later. 51164ab3302SCarolineConcatto TYPE_PARSER(construct<ActualArg>(expr) || 51264ab3302SCarolineConcatto construct<ActualArg>(Parser<AltReturnSpec>{}) || 5132d8b6a47SPeter Klausler extension<LanguageFeature::PercentRefAndVal>( 5142d8b6a47SPeter Klausler "nonstandard usage: %REF"_port_en_US, 515930c2d91SPeter Klausler construct<ActualArg>( 516930c2d91SPeter Klausler construct<ActualArg::PercentRef>("%REF" >> parenthesized(expr)))) || 5172d8b6a47SPeter Klausler extension<LanguageFeature::PercentRefAndVal>( 5182d8b6a47SPeter Klausler "nonstandard usage: %VAL"_port_en_US, 5192d8b6a47SPeter Klausler construct<ActualArg>( 52064ab3302SCarolineConcatto construct<ActualArg::PercentVal>("%VAL" >> parenthesized(expr))))) 52164ab3302SCarolineConcatto 52264ab3302SCarolineConcatto // R1525 alt-return-spec -> * label 52364ab3302SCarolineConcatto TYPE_PARSER(construct<AltReturnSpec>(star >> label)) 52464ab3302SCarolineConcatto 52564ab3302SCarolineConcatto // R1527 prefix-spec -> 52664ab3302SCarolineConcatto // declaration-type-spec | ELEMENTAL | IMPURE | MODULE | 5274ad72793SPeter Klausler // NON_RECURSIVE | PURE | RECURSIVE | 5284ad72793SPeter Klausler // (CUDA) ATTRIBUTES ( (DEVICE | GLOBAL | GRID_GLOBAL | HOST)... ) | 5294ad72793SPeter Klausler // LAUNCH_BOUNDS(expr-list) | CLUSTER_DIMS(expr-list) 5304ad72793SPeter Klausler TYPE_PARSER(first("DEVICE" >> pure(common::CUDASubprogramAttrs::Device), 5314ad72793SPeter Klausler "GLOBAL" >> pure(common::CUDASubprogramAttrs::Global), 5324ad72793SPeter Klausler "GRID_GLOBAL" >> pure(common::CUDASubprogramAttrs::Grid_Global), 5334ad72793SPeter Klausler "HOST" >> pure(common::CUDASubprogramAttrs::Host))) 53464ab3302SCarolineConcatto TYPE_PARSER(first(construct<PrefixSpec>(declarationTypeSpec), 53564ab3302SCarolineConcatto construct<PrefixSpec>(construct<PrefixSpec::Elemental>("ELEMENTAL"_tok)), 53664ab3302SCarolineConcatto construct<PrefixSpec>(construct<PrefixSpec::Impure>("IMPURE"_tok)), 53764ab3302SCarolineConcatto construct<PrefixSpec>(construct<PrefixSpec::Module>("MODULE"_tok)), 53864ab3302SCarolineConcatto construct<PrefixSpec>( 53964ab3302SCarolineConcatto construct<PrefixSpec::Non_Recursive>("NON_RECURSIVE"_tok)), 54064ab3302SCarolineConcatto construct<PrefixSpec>(construct<PrefixSpec::Pure>("PURE"_tok)), 5414ad72793SPeter Klausler construct<PrefixSpec>(construct<PrefixSpec::Recursive>("RECURSIVE"_tok)), 5424ad72793SPeter Klausler extension<LanguageFeature::CUDA>( 5434ad72793SPeter Klausler construct<PrefixSpec>(construct<PrefixSpec::Attributes>("ATTRIBUTES" >> 5444ad72793SPeter Klausler parenthesized( 5454ad72793SPeter Klausler optionalList(Parser<common::CUDASubprogramAttrs>{}))))), 5464ad72793SPeter Klausler extension<LanguageFeature::CUDA>(construct<PrefixSpec>( 5474ad72793SPeter Klausler construct<PrefixSpec::Launch_Bounds>("LAUNCH_BOUNDS" >> 5484ad72793SPeter Klausler parenthesized(nonemptyList( 5494ad72793SPeter Klausler "expected launch bounds"_err_en_US, scalarIntConstantExpr))))), 5504ad72793SPeter Klausler extension<LanguageFeature::CUDA>(construct<PrefixSpec>( 5514ad72793SPeter Klausler construct<PrefixSpec::Cluster_Dims>("CLUSTER_DIMS" >> 5524ad72793SPeter Klausler parenthesized(nonemptyList("expected cluster dimensions"_err_en_US, 5534ad72793SPeter Klausler scalarIntConstantExpr))))))) 55464ab3302SCarolineConcatto 55564ab3302SCarolineConcatto // R1529 function-subprogram -> 55664ab3302SCarolineConcatto // function-stmt [specification-part] [execution-part] 55764ab3302SCarolineConcatto // [internal-subprogram-part] end-function-stmt 55864ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("FUNCTION subprogram"_en_US, 55964ab3302SCarolineConcatto construct<FunctionSubprogram>(statement(functionStmt), specificationPart, 56064ab3302SCarolineConcatto executionPart, maybe(internalSubprogramPart), 56164ab3302SCarolineConcatto unterminatedStatement(endFunctionStmt))) 56264ab3302SCarolineConcatto 56364ab3302SCarolineConcatto // R1532 suffix -> 56464ab3302SCarolineConcatto // proc-language-binding-spec [RESULT ( result-name )] | 56564ab3302SCarolineConcatto // RESULT ( result-name ) [proc-language-binding-spec] 56664ab3302SCarolineConcatto TYPE_PARSER(construct<Suffix>( 56764ab3302SCarolineConcatto languageBindingSpec, maybe("RESULT" >> parenthesized(name))) || 56864ab3302SCarolineConcatto construct<Suffix>( 56964ab3302SCarolineConcatto "RESULT" >> parenthesized(name), maybe(languageBindingSpec))) 57064ab3302SCarolineConcatto 57164ab3302SCarolineConcatto // R1533 end-function-stmt -> END [FUNCTION [function-name]] 572b5aea329SPeter Klausler TYPE_PARSER(construct<EndFunctionStmt>( 573b5aea329SPeter Klausler recovery("END" >> defaulted("FUNCTION" >> maybe(name)) / atEndOfStmt, 574b5aea329SPeter Klausler progUnitEndStmtErrorRecovery))) 57564ab3302SCarolineConcatto 57664ab3302SCarolineConcatto // R1534 subroutine-subprogram -> 57764ab3302SCarolineConcatto // subroutine-stmt [specification-part] [execution-part] 57864ab3302SCarolineConcatto // [internal-subprogram-part] end-subroutine-stmt 57964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SUBROUTINE subprogram"_en_US, 58064ab3302SCarolineConcatto construct<SubroutineSubprogram>(statement(subroutineStmt), 58164ab3302SCarolineConcatto specificationPart, executionPart, maybe(internalSubprogramPart), 58264ab3302SCarolineConcatto unterminatedStatement(endSubroutineStmt))) 58364ab3302SCarolineConcatto 58464ab3302SCarolineConcatto // R1535 subroutine-stmt -> 58564ab3302SCarolineConcatto // [prefix] SUBROUTINE subroutine-name [( [dummy-arg-list] ) 58664ab3302SCarolineConcatto // [proc-language-binding-spec]] 58764ab3302SCarolineConcatto TYPE_PARSER( 58899a0a12aSPeter Klausler (construct<SubroutineStmt>(many(prefixSpec), "SUBROUTINE" >> name, 58999a0a12aSPeter Klausler !"("_tok >> pure<std::list<DummyArg>>(), 59099a0a12aSPeter Klausler pure<std::optional<LanguageBindingSpec>>()) || 59164ab3302SCarolineConcatto construct<SubroutineStmt>(many(prefixSpec), "SUBROUTINE" >> name, 59299a0a12aSPeter Klausler defaulted(parenthesized(optionalList(dummyArg))), 59399a0a12aSPeter Klausler maybe(languageBindingSpec))) / 59499a0a12aSPeter Klausler checkEndOfKnownStmt) 59564ab3302SCarolineConcatto 59664ab3302SCarolineConcatto // R1536 dummy-arg -> dummy-arg-name | * 59764ab3302SCarolineConcatto TYPE_PARSER(construct<DummyArg>(name) || construct<DummyArg>(star)) 59864ab3302SCarolineConcatto 59964ab3302SCarolineConcatto // R1537 end-subroutine-stmt -> END [SUBROUTINE [subroutine-name]] 600b5aea329SPeter Klausler TYPE_PARSER(construct<EndSubroutineStmt>( 601b5aea329SPeter Klausler recovery("END" >> defaulted("SUBROUTINE" >> maybe(name)) / atEndOfStmt, 602b5aea329SPeter Klausler progUnitEndStmtErrorRecovery))) 60364ab3302SCarolineConcatto 60464ab3302SCarolineConcatto // R1538 separate-module-subprogram -> 60564ab3302SCarolineConcatto // mp-subprogram-stmt [specification-part] [execution-part] 60664ab3302SCarolineConcatto // [internal-subprogram-part] end-mp-subprogram-stmt 60764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("separate module subprogram"_en_US, 60864ab3302SCarolineConcatto construct<SeparateModuleSubprogram>(statement(Parser<MpSubprogramStmt>{}), 60964ab3302SCarolineConcatto specificationPart, executionPart, maybe(internalSubprogramPart), 61064ab3302SCarolineConcatto statement(Parser<EndMpSubprogramStmt>{}))) 61164ab3302SCarolineConcatto 61264ab3302SCarolineConcatto // R1539 mp-subprogram-stmt -> MODULE PROCEDURE procedure-name 61364ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("MODULE PROCEDURE statement"_en_US, 61464ab3302SCarolineConcatto construct<MpSubprogramStmt>("MODULE PROCEDURE"_sptok >> name)) 61564ab3302SCarolineConcatto 61664ab3302SCarolineConcatto // R1540 end-mp-subprogram-stmt -> END [PROCEDURE [procedure-name]] 61764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("END PROCEDURE statement"_en_US, 61864ab3302SCarolineConcatto construct<EndMpSubprogramStmt>( 619b5aea329SPeter Klausler recovery("END" >> defaulted("PROCEDURE" >> maybe(name)) / atEndOfStmt, 62064ab3302SCarolineConcatto progUnitEndStmtErrorRecovery))) 62164ab3302SCarolineConcatto 62264ab3302SCarolineConcatto // R1541 entry-stmt -> ENTRY entry-name [( [dummy-arg-list] ) [suffix]] 62364ab3302SCarolineConcatto TYPE_PARSER( 62464ab3302SCarolineConcatto "ENTRY" >> (construct<EntryStmt>(name, 62564ab3302SCarolineConcatto parenthesized(optionalList(dummyArg)), maybe(suffix)) || 62664ab3302SCarolineConcatto construct<EntryStmt>(name, construct<std::list<DummyArg>>(), 62764ab3302SCarolineConcatto construct<std::optional<Suffix>>()))) 62864ab3302SCarolineConcatto 62964ab3302SCarolineConcatto // R1542 return-stmt -> RETURN [scalar-int-expr] 63064ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("RETURN statement"_en_US, 63164ab3302SCarolineConcatto construct<ReturnStmt>("RETURN" >> maybe(scalarIntExpr))) 63264ab3302SCarolineConcatto 63364ab3302SCarolineConcatto // R1543 contains-stmt -> CONTAINS 63464ab3302SCarolineConcatto TYPE_PARSER(construct<ContainsStmt>("CONTAINS"_tok)) 63564ab3302SCarolineConcatto 63664ab3302SCarolineConcatto // R1544 stmt-function-stmt -> 63764ab3302SCarolineConcatto // function-name ( [dummy-arg-name-list] ) = scalar-expr 63864ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("statement function definition"_en_US, 63964ab3302SCarolineConcatto construct<StmtFunctionStmt>( 64064ab3302SCarolineConcatto name, parenthesized(optionalList(name)), "=" >> scalar(expr))) 6411f879005STim Keith } // namespace Fortran::parser 642