xref: /llvm-project/flang/lib/Parser/executable-parsers.cpp (revision be6bc6a1e5beb84984b8e1419393c80a3fe2d3d8)
164ab3302SCarolineConcatto //===-- lib/Parser/executable-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 executable statements
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 
2264ab3302SCarolineConcatto // Fortran allows the statement with the corresponding label at the end of
2364ab3302SCarolineConcatto // a do-construct that begins with an old-style label-do-stmt to be a
2464ab3302SCarolineConcatto // new-style END DO statement; e.g., DO 10 I=1,N; ...; 10 END DO.  Usually,
2564ab3302SCarolineConcatto // END DO statements appear only at the ends of do-constructs that begin
2664ab3302SCarolineConcatto // with a nonlabel-do-stmt, so care must be taken to recognize this case and
2764ab3302SCarolineConcatto // essentially treat them like CONTINUE statements.
2864ab3302SCarolineConcatto 
2964ab3302SCarolineConcatto // R514 executable-construct ->
3064ab3302SCarolineConcatto //        action-stmt | associate-construct | block-construct |
3164ab3302SCarolineConcatto //        case-construct | change-team-construct | critical-construct |
3264ab3302SCarolineConcatto //        do-construct | if-construct | select-rank-construct |
334ad72793SPeter Klausler //        select-type-construct | where-construct | forall-construct |
344ad72793SPeter Klausler // (CUDA) CUF-kernel-do-construct
354ad72793SPeter Klausler constexpr auto executableConstruct{first(
364ad72793SPeter Klausler     construct<ExecutableConstruct>(CapturedLabelDoStmt{}),
3764ab3302SCarolineConcatto     construct<ExecutableConstruct>(EndDoStmtForCapturedLabelDoStmt{}),
3864ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(Parser<DoConstruct>{})),
3964ab3302SCarolineConcatto     // Attempt DO statements before assignment statements for better
4064ab3302SCarolineConcatto     // error messages in cases like "DO10I=1,(error)".
4164ab3302SCarolineConcatto     construct<ExecutableConstruct>(statement(actionStmt)),
4264ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(Parser<AssociateConstruct>{})),
4364ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(Parser<BlockConstruct>{})),
4464ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(Parser<CaseConstruct>{})),
4564ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(Parser<ChangeTeamConstruct>{})),
4664ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(Parser<CriticalConstruct>{})),
4764ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(Parser<IfConstruct>{})),
4864ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(Parser<SelectRankConstruct>{})),
4964ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(Parser<SelectTypeConstruct>{})),
5064ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(whereConstruct)),
5164ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(forallConstruct)),
5264ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(ompEndLoopDirective)),
5364ab3302SCarolineConcatto     construct<ExecutableConstruct>(indirect(openmpConstruct)),
54561a3697SValentin Clement     construct<ExecutableConstruct>(indirect(Parser<OpenACCConstruct>{})),
554ad72793SPeter Klausler     construct<ExecutableConstruct>(indirect(compilerDirective)),
564ad72793SPeter Klausler     construct<ExecutableConstruct>(indirect(Parser<CUFKernelDoConstruct>{})))};
5764ab3302SCarolineConcatto 
5864ab3302SCarolineConcatto // R510 execution-part-construct ->
5964ab3302SCarolineConcatto //        executable-construct | format-stmt | entry-stmt | data-stmt
6064ab3302SCarolineConcatto // Extension (PGI/Intel): also accept NAMELIST in execution part
6164ab3302SCarolineConcatto constexpr auto obsoleteExecutionPartConstruct{recovery(ignoredStatementPrefix >>
6264ab3302SCarolineConcatto         fail<ExecutionPartConstruct>(
6364ab3302SCarolineConcatto             "obsolete legacy extension is not supported"_err_en_US),
6464ab3302SCarolineConcatto     construct<ExecutionPartConstruct>(construct<ErrorRecovery>(ok /
6564ab3302SCarolineConcatto         statement("REDIMENSION" >> name /
6664ab3302SCarolineConcatto                 parenthesized(nonemptyList(Parser<AllocateShapeSpec>{}))))))};
6764ab3302SCarolineConcatto 
6864ab3302SCarolineConcatto TYPE_PARSER(recovery(
6964ab3302SCarolineConcatto     CONTEXT_PARSER("execution part construct"_en_US,
7064ab3302SCarolineConcatto         first(construct<ExecutionPartConstruct>(executableConstruct),
71fffbabfdSPeter Klausler             construct<ExecutionPartConstruct>(statement(indirect(formatStmt))),
72fffbabfdSPeter Klausler             construct<ExecutionPartConstruct>(statement(indirect(entryStmt))),
73fffbabfdSPeter Klausler             construct<ExecutionPartConstruct>(statement(indirect(dataStmt))),
7464ab3302SCarolineConcatto             extension<LanguageFeature::ExecutionPartNamelist>(
752d8b6a47SPeter Klausler                 "nonstandard usage: NAMELIST in execution part"_port_en_US,
7664ab3302SCarolineConcatto                 construct<ExecutionPartConstruct>(
7764ab3302SCarolineConcatto                     statement(indirect(Parser<NamelistStmt>{})))),
78fffbabfdSPeter Klausler             obsoleteExecutionPartConstruct,
79fffbabfdSPeter Klausler             lookAhead(declarationConstruct) >> SkipTo<'\n'>{} >>
80fffbabfdSPeter Klausler                 fail<ExecutionPartConstruct>(
81fffbabfdSPeter Klausler                     "misplaced declaration in the execution part"_err_en_US))),
8264ab3302SCarolineConcatto     construct<ExecutionPartConstruct>(executionPartErrorRecovery)))
8364ab3302SCarolineConcatto 
8464ab3302SCarolineConcatto // R509 execution-part -> executable-construct [execution-part-construct]...
8564ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("execution part"_en_US,
8664ab3302SCarolineConcatto     construct<ExecutionPart>(many(executionPartConstruct)))
8764ab3302SCarolineConcatto 
8864ab3302SCarolineConcatto // R515 action-stmt ->
8964ab3302SCarolineConcatto //        allocate-stmt | assignment-stmt | backspace-stmt | call-stmt |
9064ab3302SCarolineConcatto //        close-stmt | continue-stmt | cycle-stmt | deallocate-stmt |
9164ab3302SCarolineConcatto //        endfile-stmt | error-stop-stmt | event-post-stmt | event-wait-stmt |
9264ab3302SCarolineConcatto //        exit-stmt | fail-image-stmt | flush-stmt | form-team-stmt |
93a2d7af75SKatherine Rasmussen //        goto-stmt | if-stmt | inquire-stmt | lock-stmt | notify-wait-stmt |
94a2d7af75SKatherine Rasmussen //        nullify-stmt | open-stmt | pointer-assignment-stmt | print-stmt |
95a2d7af75SKatherine Rasmussen //        read-stmt | return-stmt | rewind-stmt | stop-stmt | sync-all-stmt |
9664ab3302SCarolineConcatto //        sync-images-stmt | sync-memory-stmt | sync-team-stmt | unlock-stmt |
9764ab3302SCarolineConcatto //        wait-stmt | where-stmt | write-stmt | computed-goto-stmt | forall-stmt
9864ab3302SCarolineConcatto // R1159 continue-stmt -> CONTINUE
9964ab3302SCarolineConcatto // R1163 fail-image-stmt -> FAIL IMAGE
10064ab3302SCarolineConcatto TYPE_PARSER(first(construct<ActionStmt>(indirect(Parser<AllocateStmt>{})),
10164ab3302SCarolineConcatto     construct<ActionStmt>(indirect(assignmentStmt)),
10264ab3302SCarolineConcatto     construct<ActionStmt>(indirect(pointerAssignmentStmt)),
10364ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<BackspaceStmt>{})),
10464ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<CallStmt>{})),
10564ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<CloseStmt>{})),
10664ab3302SCarolineConcatto     construct<ActionStmt>(construct<ContinueStmt>("CONTINUE"_tok)),
10764ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<CycleStmt>{})),
10864ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<DeallocateStmt>{})),
10964ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<EndfileStmt>{})),
11064ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<EventPostStmt>{})),
11164ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<EventWaitStmt>{})),
11264ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<ExitStmt>{})),
11364ab3302SCarolineConcatto     construct<ActionStmt>(construct<FailImageStmt>("FAIL IMAGE"_sptok)),
11464ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<FlushStmt>{})),
11564ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<FormTeamStmt>{})),
11664ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<GotoStmt>{})),
11764ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<IfStmt>{})),
11864ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<InquireStmt>{})),
11964ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<LockStmt>{})),
120a2d7af75SKatherine Rasmussen     construct<ActionStmt>(indirect(Parser<NotifyWaitStmt>{})),
12164ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<NullifyStmt>{})),
12264ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<OpenStmt>{})),
12364ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<PrintStmt>{})),
12464ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<ReadStmt>{})),
12564ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<ReturnStmt>{})),
12664ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<RewindStmt>{})),
12764ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<StopStmt>{})), // & error-stop-stmt
12864ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<SyncAllStmt>{})),
12964ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<SyncImagesStmt>{})),
13064ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<SyncMemoryStmt>{})),
13164ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<SyncTeamStmt>{})),
13264ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<UnlockStmt>{})),
13364ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<WaitStmt>{})),
13464ab3302SCarolineConcatto     construct<ActionStmt>(indirect(whereStmt)),
13564ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<WriteStmt>{})),
13664ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<ComputedGotoStmt>{})),
13764ab3302SCarolineConcatto     construct<ActionStmt>(indirect(forallStmt)),
13864ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<ArithmeticIfStmt>{})),
13964ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<AssignStmt>{})),
14064ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<AssignedGotoStmt>{})),
14164ab3302SCarolineConcatto     construct<ActionStmt>(indirect(Parser<PauseStmt>{}))))
14264ab3302SCarolineConcatto 
14364ab3302SCarolineConcatto // R1102 associate-construct -> associate-stmt block end-associate-stmt
14464ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("ASSOCIATE construct"_en_US,
14564ab3302SCarolineConcatto     construct<AssociateConstruct>(statement(Parser<AssociateStmt>{}), block,
14664ab3302SCarolineConcatto         statement(Parser<EndAssociateStmt>{})))
14764ab3302SCarolineConcatto 
14864ab3302SCarolineConcatto // R1103 associate-stmt ->
14964ab3302SCarolineConcatto //        [associate-construct-name :] ASSOCIATE ( association-list )
15064ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("ASSOCIATE statement"_en_US,
15164ab3302SCarolineConcatto     construct<AssociateStmt>(maybe(name / ":"),
15264ab3302SCarolineConcatto         "ASSOCIATE" >> parenthesized(nonemptyList(Parser<Association>{}))))
15364ab3302SCarolineConcatto 
15464ab3302SCarolineConcatto // R1104 association -> associate-name => selector
15564ab3302SCarolineConcatto TYPE_PARSER(construct<Association>(name, "=>" >> selector))
15664ab3302SCarolineConcatto 
15764ab3302SCarolineConcatto // R1105 selector -> expr | variable
15864ab3302SCarolineConcatto TYPE_PARSER(construct<Selector>(variable) / lookAhead(","_tok || ")"_tok) ||
15964ab3302SCarolineConcatto     construct<Selector>(expr))
16064ab3302SCarolineConcatto 
16164ab3302SCarolineConcatto // R1106 end-associate-stmt -> END ASSOCIATE [associate-construct-name]
162619b5bfcSPeter Klausler TYPE_PARSER(construct<EndAssociateStmt>(recovery(
163619b5bfcSPeter Klausler     "END ASSOCIATE" >> maybe(name), namedConstructEndStmtErrorRecovery)))
16464ab3302SCarolineConcatto 
16564ab3302SCarolineConcatto // R1107 block-construct ->
16664ab3302SCarolineConcatto //         block-stmt [block-specification-part] block end-block-stmt
16764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("BLOCK construct"_en_US,
16864ab3302SCarolineConcatto     construct<BlockConstruct>(statement(Parser<BlockStmt>{}),
16964ab3302SCarolineConcatto         Parser<BlockSpecificationPart>{}, // can be empty
17064ab3302SCarolineConcatto         block, statement(Parser<EndBlockStmt>{})))
17164ab3302SCarolineConcatto 
17264ab3302SCarolineConcatto // R1108 block-stmt -> [block-construct-name :] BLOCK
17364ab3302SCarolineConcatto TYPE_PARSER(construct<BlockStmt>(maybe(name / ":") / "BLOCK"))
17464ab3302SCarolineConcatto 
17564ab3302SCarolineConcatto // R1109 block-specification-part ->
17664ab3302SCarolineConcatto //         [use-stmt]... [import-stmt]... [implicit-part]
17764ab3302SCarolineConcatto //         [[declaration-construct]... specification-construct]
17864ab3302SCarolineConcatto // C1107 prohibits COMMON, EQUIVALENCE, INTENT, NAMELIST, OPTIONAL, VALUE,
17964ab3302SCarolineConcatto // and statement function definitions.  C1108 prohibits SAVE /common/.
18064ab3302SCarolineConcatto // C1570 indirectly prohibits ENTRY.  These constraints are best enforced later.
18164ab3302SCarolineConcatto // The odd grammar rule above would have the effect of forcing any
18264ab3302SCarolineConcatto // trailing FORMAT and DATA statements after the last specification-construct
18364ab3302SCarolineConcatto // to be recognized as part of the block-construct's block part rather than
18464ab3302SCarolineConcatto // its block-specification-part, a distinction without any apparent difference.
18564ab3302SCarolineConcatto TYPE_PARSER(construct<BlockSpecificationPart>(specificationPart))
18664ab3302SCarolineConcatto 
18764ab3302SCarolineConcatto // R1110 end-block-stmt -> END BLOCK [block-construct-name]
18864ab3302SCarolineConcatto TYPE_PARSER(construct<EndBlockStmt>(
189619b5bfcSPeter Klausler     recovery("END BLOCK" >> maybe(name), namedConstructEndStmtErrorRecovery)))
19064ab3302SCarolineConcatto 
19164ab3302SCarolineConcatto // R1111 change-team-construct -> change-team-stmt block end-change-team-stmt
19264ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("CHANGE TEAM construct"_en_US,
19364ab3302SCarolineConcatto     construct<ChangeTeamConstruct>(statement(Parser<ChangeTeamStmt>{}), block,
19464ab3302SCarolineConcatto         statement(Parser<EndChangeTeamStmt>{})))
19564ab3302SCarolineConcatto 
19664ab3302SCarolineConcatto // R1112 change-team-stmt ->
19764ab3302SCarolineConcatto //         [team-construct-name :] CHANGE TEAM
19864ab3302SCarolineConcatto //         ( team-value [, coarray-association-list] [, sync-stat-list] )
19964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("CHANGE TEAM statement"_en_US,
20064ab3302SCarolineConcatto     construct<ChangeTeamStmt>(maybe(name / ":"),
20164ab3302SCarolineConcatto         "CHANGE TEAM"_sptok >> "("_tok >> teamValue,
20264ab3302SCarolineConcatto         defaulted("," >> nonemptyList(Parser<CoarrayAssociation>{})),
20364ab3302SCarolineConcatto         defaulted("," >> nonemptyList(statOrErrmsg))) /
20464ab3302SCarolineConcatto         ")")
20564ab3302SCarolineConcatto 
20664ab3302SCarolineConcatto // R1113 coarray-association -> codimension-decl => selector
20764ab3302SCarolineConcatto TYPE_PARSER(
20864ab3302SCarolineConcatto     construct<CoarrayAssociation>(Parser<CodimensionDecl>{}, "=>" >> selector))
20964ab3302SCarolineConcatto 
21064ab3302SCarolineConcatto // R1114 end-change-team-stmt ->
21164ab3302SCarolineConcatto //         END TEAM [( [sync-stat-list] )] [team-construct-name]
21264ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("END TEAM statement"_en_US,
21364ab3302SCarolineConcatto     construct<EndChangeTeamStmt>(
21464ab3302SCarolineConcatto         "END TEAM" >> defaulted(parenthesized(optionalList(statOrErrmsg))),
21564ab3302SCarolineConcatto         maybe(name)))
21664ab3302SCarolineConcatto 
21764ab3302SCarolineConcatto // R1117 critical-stmt ->
21864ab3302SCarolineConcatto //         [critical-construct-name :] CRITICAL [( [sync-stat-list] )]
21964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("CRITICAL statement"_en_US,
22064ab3302SCarolineConcatto     construct<CriticalStmt>(maybe(name / ":"),
22164ab3302SCarolineConcatto         "CRITICAL" >> defaulted(parenthesized(optionalList(statOrErrmsg)))))
22264ab3302SCarolineConcatto 
22364ab3302SCarolineConcatto // R1116 critical-construct -> critical-stmt block end-critical-stmt
22464ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("CRITICAL construct"_en_US,
22564ab3302SCarolineConcatto     construct<CriticalConstruct>(statement(Parser<CriticalStmt>{}), block,
22664ab3302SCarolineConcatto         statement(Parser<EndCriticalStmt>{})))
22764ab3302SCarolineConcatto 
22864ab3302SCarolineConcatto // R1118 end-critical-stmt -> END CRITICAL [critical-construct-name]
229619b5bfcSPeter Klausler TYPE_PARSER(construct<EndCriticalStmt>(recovery(
230619b5bfcSPeter Klausler     "END CRITICAL" >> maybe(name), namedConstructEndStmtErrorRecovery)))
23164ab3302SCarolineConcatto 
23264ab3302SCarolineConcatto // R1119 do-construct -> do-stmt block end-do
23364ab3302SCarolineConcatto // R1120 do-stmt -> nonlabel-do-stmt | label-do-stmt
23464ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("DO construct"_en_US,
23564ab3302SCarolineConcatto     construct<DoConstruct>(
23664ab3302SCarolineConcatto         statement(Parser<NonLabelDoStmt>{}) / EnterNonlabelDoConstruct{}, block,
23764ab3302SCarolineConcatto         statement(Parser<EndDoStmt>{}) / LeaveDoConstruct{}))
23864ab3302SCarolineConcatto 
23964ab3302SCarolineConcatto // R1125 concurrent-header ->
24064ab3302SCarolineConcatto //         ( [integer-type-spec ::] concurrent-control-list
24164ab3302SCarolineConcatto //         [, scalar-mask-expr] )
24264ab3302SCarolineConcatto TYPE_PARSER(parenthesized(construct<ConcurrentHeader>(
24364ab3302SCarolineConcatto     maybe(integerTypeSpec / "::"), nonemptyList(Parser<ConcurrentControl>{}),
24464ab3302SCarolineConcatto     maybe("," >> scalarLogicalExpr))))
24564ab3302SCarolineConcatto 
24664ab3302SCarolineConcatto // R1126 concurrent-control ->
24764ab3302SCarolineConcatto //         index-name = concurrent-limit : concurrent-limit [: concurrent-step]
24864ab3302SCarolineConcatto // R1127 concurrent-limit -> scalar-int-expr
24964ab3302SCarolineConcatto // R1128 concurrent-step -> scalar-int-expr
25064ab3302SCarolineConcatto TYPE_PARSER(construct<ConcurrentControl>(name / "=", scalarIntExpr / ":",
25164ab3302SCarolineConcatto     scalarIntExpr, maybe(":" >> scalarIntExpr)))
25264ab3302SCarolineConcatto 
25364ab3302SCarolineConcatto // R1130 locality-spec ->
25464ab3302SCarolineConcatto //         LOCAL ( variable-name-list ) | LOCAL_INIT ( variable-name-list ) |
2553af717d6Skhaki3 //         REDUCE ( reduce-operation : variable-name-list ) |
25664ab3302SCarolineConcatto //         SHARED ( variable-name-list ) | DEFAULT ( NONE )
25764ab3302SCarolineConcatto TYPE_PARSER(construct<LocalitySpec>(construct<LocalitySpec::Local>(
25864ab3302SCarolineConcatto                 "LOCAL" >> parenthesized(listOfNames))) ||
25964ab3302SCarolineConcatto     construct<LocalitySpec>(construct<LocalitySpec::LocalInit>(
26064ab3302SCarolineConcatto         "LOCAL_INIT"_sptok >> parenthesized(listOfNames))) ||
2613af717d6Skhaki3     construct<LocalitySpec>(construct<LocalitySpec::Reduce>(
2623af717d6Skhaki3         "REDUCE (" >> Parser<LocalitySpec::Reduce::Operator>{} / ":",
2633af717d6Skhaki3         listOfNames / ")")) ||
26464ab3302SCarolineConcatto     construct<LocalitySpec>(construct<LocalitySpec::Shared>(
26564ab3302SCarolineConcatto         "SHARED" >> parenthesized(listOfNames))) ||
26664ab3302SCarolineConcatto     construct<LocalitySpec>(
26764ab3302SCarolineConcatto         construct<LocalitySpec::DefaultNone>("DEFAULT ( NONE )"_tok)))
26864ab3302SCarolineConcatto 
26964ab3302SCarolineConcatto // R1123 loop-control ->
27064ab3302SCarolineConcatto //         [,] do-variable = scalar-int-expr , scalar-int-expr
27164ab3302SCarolineConcatto //           [, scalar-int-expr] |
27264ab3302SCarolineConcatto //         [,] WHILE ( scalar-logical-expr ) |
27364ab3302SCarolineConcatto //         [,] CONCURRENT concurrent-header concurrent-locality
27464ab3302SCarolineConcatto // R1129 concurrent-locality -> [locality-spec]...
27564ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("loop control"_en_US,
27664ab3302SCarolineConcatto     maybe(","_tok) >>
27764ab3302SCarolineConcatto         (construct<LoopControl>(loopBounds(scalarExpr)) ||
27864ab3302SCarolineConcatto             construct<LoopControl>(
27964ab3302SCarolineConcatto                 "WHILE" >> parenthesized(scalarLogicalExpr)) ||
28064ab3302SCarolineConcatto             construct<LoopControl>(construct<LoopControl::Concurrent>(
28164ab3302SCarolineConcatto                 "CONCURRENT" >> concurrentHeader,
28264ab3302SCarolineConcatto                 many(Parser<LocalitySpec>{})))))
28364ab3302SCarolineConcatto 
284*be6bc6a1SPeter Klausler // "DO" is a valid statement, so the loop control is optional; but for
285*be6bc6a1SPeter Klausler // better recovery from errors in the loop control, don't parse a
286*be6bc6a1SPeter Klausler // DO statement with a bad loop control as a DO statement that has
287*be6bc6a1SPeter Klausler // no loop control and is followed by garbage.
288*be6bc6a1SPeter Klausler static constexpr auto loopControlOrEndOfStmt{
289*be6bc6a1SPeter Klausler     construct<std::optional<LoopControl>>(Parser<LoopControl>{}) ||
290*be6bc6a1SPeter Klausler     lookAhead(";\n"_ch) >> construct<std::optional<LoopControl>>()};
291*be6bc6a1SPeter Klausler 
29264ab3302SCarolineConcatto // R1121 label-do-stmt -> [do-construct-name :] DO label [loop-control]
29381d04709SPeter Klausler // A label-do-stmt with a do-construct-name is parsed as a nonlabel-do-stmt
29481d04709SPeter Klausler // with an optional label.
29564ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("label DO statement"_en_US,
296*be6bc6a1SPeter Klausler     construct<LabelDoStmt>("DO" >> label, loopControlOrEndOfStmt))
29764ab3302SCarolineConcatto 
29864ab3302SCarolineConcatto // R1122 nonlabel-do-stmt -> [do-construct-name :] DO [loop-control]
29964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("nonlabel DO statement"_en_US,
30081d04709SPeter Klausler     construct<NonLabelDoStmt>(
301*be6bc6a1SPeter Klausler         name / ":", "DO" >> maybe(label), loopControlOrEndOfStmt) ||
30281d04709SPeter Klausler         construct<NonLabelDoStmt>(construct<std::optional<Name>>(),
303*be6bc6a1SPeter Klausler             construct<std::optional<Label>>(), "DO" >> loopControlOrEndOfStmt))
30464ab3302SCarolineConcatto 
30564ab3302SCarolineConcatto // R1132 end-do-stmt -> END DO [do-construct-name]
30664ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("END DO statement"_en_US,
30764ab3302SCarolineConcatto     construct<EndDoStmt>(
308619b5bfcSPeter Klausler         recovery("END DO" >> maybe(name), namedConstructEndStmtErrorRecovery)))
30964ab3302SCarolineConcatto 
31064ab3302SCarolineConcatto // R1133 cycle-stmt -> CYCLE [do-construct-name]
31164ab3302SCarolineConcatto TYPE_CONTEXT_PARSER(
31264ab3302SCarolineConcatto     "CYCLE statement"_en_US, construct<CycleStmt>("CYCLE" >> maybe(name)))
31364ab3302SCarolineConcatto 
31464ab3302SCarolineConcatto // R1134 if-construct ->
31564ab3302SCarolineConcatto //         if-then-stmt block [else-if-stmt block]...
31664ab3302SCarolineConcatto //         [else-stmt block] end-if-stmt
31764ab3302SCarolineConcatto // R1135 if-then-stmt -> [if-construct-name :] IF ( scalar-logical-expr )
31864ab3302SCarolineConcatto // THEN R1136 else-if-stmt ->
31964ab3302SCarolineConcatto //         ELSE IF ( scalar-logical-expr ) THEN [if-construct-name]
32064ab3302SCarolineConcatto // R1137 else-stmt -> ELSE [if-construct-name]
32164ab3302SCarolineConcatto // R1138 end-if-stmt -> END IF [if-construct-name]
32264ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("IF construct"_en_US,
32364ab3302SCarolineConcatto     construct<IfConstruct>(
32464ab3302SCarolineConcatto         statement(construct<IfThenStmt>(maybe(name / ":"),
32560b67302SPeter Klausler             "IF" >> parenthesized(scalarLogicalExpr) /
32660b67302SPeter Klausler                     recovery("THEN"_tok, lookAhead(endOfStmt)))),
32764ab3302SCarolineConcatto         block,
32864ab3302SCarolineConcatto         many(construct<IfConstruct::ElseIfBlock>(
32964ab3302SCarolineConcatto             unambiguousStatement(construct<ElseIfStmt>(
33064ab3302SCarolineConcatto                 "ELSE IF" >> parenthesized(scalarLogicalExpr),
3310061e681Speter klausler                 recovery("THEN"_tok, ok) >> maybe(name))),
33264ab3302SCarolineConcatto             block)),
33364ab3302SCarolineConcatto         maybe(construct<IfConstruct::ElseBlock>(
33464ab3302SCarolineConcatto             statement(construct<ElseStmt>("ELSE" >> maybe(name))), block)),
335619b5bfcSPeter Klausler         statement(construct<EndIfStmt>(recovery(
336619b5bfcSPeter Klausler             "END IF" >> maybe(name), namedConstructEndStmtErrorRecovery)))))
33764ab3302SCarolineConcatto 
33864ab3302SCarolineConcatto // R1139 if-stmt -> IF ( scalar-logical-expr ) action-stmt
33964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("IF statement"_en_US,
34064ab3302SCarolineConcatto     construct<IfStmt>("IF" >> parenthesized(scalarLogicalExpr),
34164ab3302SCarolineConcatto         unlabeledStatement(actionStmt)))
34264ab3302SCarolineConcatto 
34364ab3302SCarolineConcatto // R1140 case-construct ->
34464ab3302SCarolineConcatto //         select-case-stmt [case-stmt block]... end-select-stmt
34564ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SELECT CASE construct"_en_US,
34664ab3302SCarolineConcatto     construct<CaseConstruct>(statement(Parser<SelectCaseStmt>{}),
34764ab3302SCarolineConcatto         many(construct<CaseConstruct::Case>(
34864ab3302SCarolineConcatto             unambiguousStatement(Parser<CaseStmt>{}), block)),
34964ab3302SCarolineConcatto         statement(endSelectStmt)))
35064ab3302SCarolineConcatto 
35164ab3302SCarolineConcatto // R1141 select-case-stmt -> [case-construct-name :] SELECT CASE ( case-expr
35264ab3302SCarolineConcatto // ) R1144 case-expr -> scalar-expr
35364ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SELECT CASE statement"_en_US,
35464ab3302SCarolineConcatto     construct<SelectCaseStmt>(
35564ab3302SCarolineConcatto         maybe(name / ":"), "SELECT CASE" >> parenthesized(scalar(expr))))
35664ab3302SCarolineConcatto 
35764ab3302SCarolineConcatto // R1142 case-stmt -> CASE case-selector [case-construct-name]
35864ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("CASE statement"_en_US,
35964ab3302SCarolineConcatto     construct<CaseStmt>("CASE" >> Parser<CaseSelector>{}, maybe(name)))
36064ab3302SCarolineConcatto 
36164ab3302SCarolineConcatto // R1143 end-select-stmt -> END SELECT [case-construct-name]
36264ab3302SCarolineConcatto // R1151 end-select-rank-stmt -> END SELECT [select-construct-name]
36364ab3302SCarolineConcatto // R1155 end-select-type-stmt -> END SELECT [select-construct-name]
36464ab3302SCarolineConcatto TYPE_PARSER(construct<EndSelectStmt>(
365619b5bfcSPeter Klausler     recovery("END SELECT" >> maybe(name), namedConstructEndStmtErrorRecovery)))
36664ab3302SCarolineConcatto 
36764ab3302SCarolineConcatto // R1145 case-selector -> ( case-value-range-list ) | DEFAULT
36864ab3302SCarolineConcatto constexpr auto defaultKeyword{construct<Default>("DEFAULT"_tok)};
36964ab3302SCarolineConcatto TYPE_PARSER(parenthesized(construct<CaseSelector>(
37064ab3302SCarolineConcatto                 nonemptyList(Parser<CaseValueRange>{}))) ||
37164ab3302SCarolineConcatto     construct<CaseSelector>(defaultKeyword))
37264ab3302SCarolineConcatto 
37364ab3302SCarolineConcatto // R1147 case-value -> scalar-constant-expr
37464ab3302SCarolineConcatto constexpr auto caseValue{scalar(constantExpr)};
37564ab3302SCarolineConcatto 
37664ab3302SCarolineConcatto // R1146 case-value-range ->
37764ab3302SCarolineConcatto //         case-value | case-value : | : case-value | case-value : case-value
37864ab3302SCarolineConcatto TYPE_PARSER(construct<CaseValueRange>(construct<CaseValueRange::Range>(
37964ab3302SCarolineConcatto                 construct<std::optional<CaseValue>>(caseValue),
38064ab3302SCarolineConcatto                 ":" >> maybe(caseValue))) ||
38164ab3302SCarolineConcatto     construct<CaseValueRange>(
38264ab3302SCarolineConcatto         construct<CaseValueRange::Range>(construct<std::optional<CaseValue>>(),
38364ab3302SCarolineConcatto             ":" >> construct<std::optional<CaseValue>>(caseValue))) ||
38464ab3302SCarolineConcatto     construct<CaseValueRange>(caseValue))
38564ab3302SCarolineConcatto 
38664ab3302SCarolineConcatto // R1148 select-rank-construct ->
38764ab3302SCarolineConcatto //         select-rank-stmt [select-rank-case-stmt block]...
38864ab3302SCarolineConcatto //         end-select-rank-stmt
38964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SELECT RANK construct"_en_US,
39064ab3302SCarolineConcatto     construct<SelectRankConstruct>(statement(Parser<SelectRankStmt>{}),
39164ab3302SCarolineConcatto         many(construct<SelectRankConstruct::RankCase>(
39264ab3302SCarolineConcatto             unambiguousStatement(Parser<SelectRankCaseStmt>{}), block)),
39364ab3302SCarolineConcatto         statement(endSelectStmt)))
39464ab3302SCarolineConcatto 
39564ab3302SCarolineConcatto // R1149 select-rank-stmt ->
39664ab3302SCarolineConcatto //         [select-construct-name :] SELECT RANK
39764ab3302SCarolineConcatto //         ( [associate-name =>] selector )
39864ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SELECT RANK statement"_en_US,
39964ab3302SCarolineConcatto     construct<SelectRankStmt>(maybe(name / ":"),
40064ab3302SCarolineConcatto         "SELECT RANK"_sptok >> "("_tok >> maybe(name / "=>"), selector / ")"))
40164ab3302SCarolineConcatto 
40264ab3302SCarolineConcatto // R1150 select-rank-case-stmt ->
40364ab3302SCarolineConcatto //         RANK ( scalar-int-constant-expr ) [select-construct-name] |
40464ab3302SCarolineConcatto //         RANK ( * ) [select-construct-name] |
40564ab3302SCarolineConcatto //         RANK DEFAULT [select-construct-name]
40664ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("RANK case statement"_en_US,
40764ab3302SCarolineConcatto     "RANK" >> (construct<SelectRankCaseStmt>(
40864ab3302SCarolineConcatto                   parenthesized(construct<SelectRankCaseStmt::Rank>(
40964ab3302SCarolineConcatto                                     scalarIntConstantExpr) ||
41064ab3302SCarolineConcatto                       construct<SelectRankCaseStmt::Rank>(star)) ||
41164ab3302SCarolineConcatto                       construct<SelectRankCaseStmt::Rank>(defaultKeyword),
41264ab3302SCarolineConcatto                   maybe(name))))
41364ab3302SCarolineConcatto 
41464ab3302SCarolineConcatto // R1152 select-type-construct ->
41564ab3302SCarolineConcatto //         select-type-stmt [type-guard-stmt block]... end-select-type-stmt
41664ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SELECT TYPE construct"_en_US,
41764ab3302SCarolineConcatto     construct<SelectTypeConstruct>(statement(Parser<SelectTypeStmt>{}),
41864ab3302SCarolineConcatto         many(construct<SelectTypeConstruct::TypeCase>(
41964ab3302SCarolineConcatto             unambiguousStatement(Parser<TypeGuardStmt>{}), block)),
42064ab3302SCarolineConcatto         statement(endSelectStmt)))
42164ab3302SCarolineConcatto 
42264ab3302SCarolineConcatto // R1153 select-type-stmt ->
42364ab3302SCarolineConcatto //         [select-construct-name :] SELECT TYPE
42464ab3302SCarolineConcatto //         ( [associate-name =>] selector )
42564ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SELECT TYPE statement"_en_US,
42664ab3302SCarolineConcatto     construct<SelectTypeStmt>(maybe(name / ":"),
42764ab3302SCarolineConcatto         "SELECT TYPE (" >> maybe(name / "=>"), selector / ")"))
42864ab3302SCarolineConcatto 
42964ab3302SCarolineConcatto // R1154 type-guard-stmt ->
43064ab3302SCarolineConcatto //         TYPE IS ( type-spec ) [select-construct-name] |
43164ab3302SCarolineConcatto //         CLASS IS ( derived-type-spec ) [select-construct-name] |
43264ab3302SCarolineConcatto //         CLASS DEFAULT [select-construct-name]
43364ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("type guard statement"_en_US,
43464ab3302SCarolineConcatto     construct<TypeGuardStmt>("TYPE IS"_sptok >>
43564ab3302SCarolineConcatto                 parenthesized(construct<TypeGuardStmt::Guard>(typeSpec)) ||
43664ab3302SCarolineConcatto             "CLASS IS"_sptok >> parenthesized(construct<TypeGuardStmt::Guard>(
43764ab3302SCarolineConcatto                                     derivedTypeSpec)) ||
43864ab3302SCarolineConcatto             construct<TypeGuardStmt::Guard>("CLASS" >> defaultKeyword),
43964ab3302SCarolineConcatto         maybe(name)))
44064ab3302SCarolineConcatto 
44164ab3302SCarolineConcatto // R1156 exit-stmt -> EXIT [construct-name]
44264ab3302SCarolineConcatto TYPE_CONTEXT_PARSER(
44364ab3302SCarolineConcatto     "EXIT statement"_en_US, construct<ExitStmt>("EXIT" >> maybe(name)))
44464ab3302SCarolineConcatto 
44564ab3302SCarolineConcatto // R1157 goto-stmt -> GO TO label
44664ab3302SCarolineConcatto TYPE_CONTEXT_PARSER(
44764ab3302SCarolineConcatto     "GOTO statement"_en_US, construct<GotoStmt>("GO TO" >> label))
44864ab3302SCarolineConcatto 
44964ab3302SCarolineConcatto // R1158 computed-goto-stmt -> GO TO ( label-list ) [,] scalar-int-expr
45064ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("computed GOTO statement"_en_US,
45164ab3302SCarolineConcatto     construct<ComputedGotoStmt>("GO TO" >> parenthesized(nonemptyList(label)),
45264ab3302SCarolineConcatto         maybe(","_tok) >> scalarIntExpr))
45364ab3302SCarolineConcatto 
45464ab3302SCarolineConcatto // R1160 stop-stmt -> STOP [stop-code] [, QUIET = scalar-logical-expr]
45564ab3302SCarolineConcatto // R1161 error-stop-stmt ->
45664ab3302SCarolineConcatto //         ERROR STOP [stop-code] [, QUIET = scalar-logical-expr]
45764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("STOP statement"_en_US,
45864ab3302SCarolineConcatto     construct<StopStmt>("STOP" >> pure(StopStmt::Kind::Stop) ||
45964ab3302SCarolineConcatto             "ERROR STOP"_sptok >> pure(StopStmt::Kind::ErrorStop),
46064ab3302SCarolineConcatto         maybe(Parser<StopCode>{}), maybe(", QUIET =" >> scalarLogicalExpr)))
46164ab3302SCarolineConcatto 
46264ab3302SCarolineConcatto // R1162 stop-code -> scalar-default-char-expr | scalar-int-expr
46364ab3302SCarolineConcatto // The two alternatives for stop-code can't be distinguished at
46464ab3302SCarolineConcatto // parse time.
46564ab3302SCarolineConcatto TYPE_PARSER(construct<StopCode>(scalar(expr)))
46664ab3302SCarolineConcatto 
467a2d7af75SKatherine Rasmussen // F2030: R1166 notify-wait-stmt ->
468a2d7af75SKatherine Rasmussen //         NOTIFY WAIT ( notify-variable [, event-wait-spec-list] )
469a2d7af75SKatherine Rasmussen TYPE_CONTEXT_PARSER("NOTIFY WAIT statement"_en_US,
470a2d7af75SKatherine Rasmussen     construct<NotifyWaitStmt>(
471a2d7af75SKatherine Rasmussen         "NOTIFY WAIT"_sptok >> "("_tok >> scalar(variable),
472a2d7af75SKatherine Rasmussen         defaulted("," >> nonemptyList(Parser<EventWaitSpec>{})) / ")"))
473a2d7af75SKatherine Rasmussen 
47464ab3302SCarolineConcatto // R1164 sync-all-stmt -> SYNC ALL [( [sync-stat-list] )]
47564ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SYNC ALL statement"_en_US,
47664ab3302SCarolineConcatto     construct<SyncAllStmt>("SYNC ALL"_sptok >>
47764ab3302SCarolineConcatto         defaulted(parenthesized(optionalList(statOrErrmsg)))))
47864ab3302SCarolineConcatto 
47964ab3302SCarolineConcatto // R1166 sync-images-stmt -> SYNC IMAGES ( image-set [, sync-stat-list] )
48064ab3302SCarolineConcatto // R1167 image-set -> int-expr | *
48164ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SYNC IMAGES statement"_en_US,
48264ab3302SCarolineConcatto     "SYNC IMAGES"_sptok >> parenthesized(construct<SyncImagesStmt>(
48364ab3302SCarolineConcatto                                construct<SyncImagesStmt::ImageSet>(intExpr) ||
48464ab3302SCarolineConcatto                                    construct<SyncImagesStmt::ImageSet>(star),
48564ab3302SCarolineConcatto                                defaulted("," >> nonemptyList(statOrErrmsg)))))
48664ab3302SCarolineConcatto 
48764ab3302SCarolineConcatto // R1168 sync-memory-stmt -> SYNC MEMORY [( [sync-stat-list] )]
48864ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SYNC MEMORY statement"_en_US,
48964ab3302SCarolineConcatto     construct<SyncMemoryStmt>("SYNC MEMORY"_sptok >>
49064ab3302SCarolineConcatto         defaulted(parenthesized(optionalList(statOrErrmsg)))))
49164ab3302SCarolineConcatto 
49264ab3302SCarolineConcatto // R1169 sync-team-stmt -> SYNC TEAM ( team-value [, sync-stat-list] )
49364ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("SYNC TEAM statement"_en_US,
49464ab3302SCarolineConcatto     construct<SyncTeamStmt>("SYNC TEAM"_sptok >> "("_tok >> teamValue,
49564ab3302SCarolineConcatto         defaulted("," >> nonemptyList(statOrErrmsg)) / ")"))
49664ab3302SCarolineConcatto 
49764ab3302SCarolineConcatto // R1170 event-post-stmt -> EVENT POST ( event-variable [, sync-stat-list] )
49864ab3302SCarolineConcatto // R1171 event-variable -> scalar-variable
49964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("EVENT POST statement"_en_US,
50064ab3302SCarolineConcatto     construct<EventPostStmt>("EVENT POST"_sptok >> "("_tok >> scalar(variable),
50164ab3302SCarolineConcatto         defaulted("," >> nonemptyList(statOrErrmsg)) / ")"))
50264ab3302SCarolineConcatto 
50364ab3302SCarolineConcatto // R1172 event-wait-stmt ->
50464ab3302SCarolineConcatto //         EVENT WAIT ( event-variable [, event-wait-spec-list] )
50564ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("EVENT WAIT statement"_en_US,
50664ab3302SCarolineConcatto     construct<EventWaitStmt>("EVENT WAIT"_sptok >> "("_tok >> scalar(variable),
507a2d7af75SKatherine Rasmussen         defaulted("," >> nonemptyList(Parser<EventWaitSpec>{})) / ")"))
50864ab3302SCarolineConcatto 
50964ab3302SCarolineConcatto // R1174 until-spec -> UNTIL_COUNT = scalar-int-expr
51064ab3302SCarolineConcatto constexpr auto untilSpec{"UNTIL_COUNT =" >> scalarIntExpr};
51164ab3302SCarolineConcatto 
51264ab3302SCarolineConcatto // R1173 event-wait-spec -> until-spec | sync-stat
513a2d7af75SKatherine Rasmussen TYPE_PARSER(construct<EventWaitSpec>(untilSpec) ||
514a2d7af75SKatherine Rasmussen     construct<EventWaitSpec>(statOrErrmsg))
51564ab3302SCarolineConcatto 
51664ab3302SCarolineConcatto // R1177 team-variable -> scalar-variable
51764ab3302SCarolineConcatto constexpr auto teamVariable{scalar(variable)};
51864ab3302SCarolineConcatto 
51964ab3302SCarolineConcatto // R1175 form-team-stmt ->
52064ab3302SCarolineConcatto //         FORM TEAM ( team-number , team-variable [, form-team-spec-list] )
52164ab3302SCarolineConcatto // R1176 team-number -> scalar-int-expr
52264ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("FORM TEAM statement"_en_US,
52364ab3302SCarolineConcatto     construct<FormTeamStmt>("FORM TEAM"_sptok >> "("_tok >> scalarIntExpr,
52464ab3302SCarolineConcatto         "," >> teamVariable,
52564ab3302SCarolineConcatto         defaulted("," >> nonemptyList(Parser<FormTeamStmt::FormTeamSpec>{})) /
52664ab3302SCarolineConcatto             ")"))
52764ab3302SCarolineConcatto 
52864ab3302SCarolineConcatto // R1178 form-team-spec -> NEW_INDEX = scalar-int-expr | sync-stat
52964ab3302SCarolineConcatto TYPE_PARSER(
53064ab3302SCarolineConcatto     construct<FormTeamStmt::FormTeamSpec>("NEW_INDEX =" >> scalarIntExpr) ||
53164ab3302SCarolineConcatto     construct<FormTeamStmt::FormTeamSpec>(statOrErrmsg))
53264ab3302SCarolineConcatto 
53364ab3302SCarolineConcatto // R1182 lock-variable -> scalar-variable
53464ab3302SCarolineConcatto constexpr auto lockVariable{scalar(variable)};
53564ab3302SCarolineConcatto 
53664ab3302SCarolineConcatto // R1179 lock-stmt -> LOCK ( lock-variable [, lock-stat-list] )
53764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("LOCK statement"_en_US,
53864ab3302SCarolineConcatto     construct<LockStmt>("LOCK (" >> lockVariable,
53964ab3302SCarolineConcatto         defaulted("," >> nonemptyList(Parser<LockStmt::LockStat>{})) / ")"))
54064ab3302SCarolineConcatto 
54164ab3302SCarolineConcatto // R1180 lock-stat -> ACQUIRED_LOCK = scalar-logical-variable | sync-stat
54264ab3302SCarolineConcatto TYPE_PARSER(
54364ab3302SCarolineConcatto     construct<LockStmt::LockStat>("ACQUIRED_LOCK =" >> scalarLogicalVariable) ||
54464ab3302SCarolineConcatto     construct<LockStmt::LockStat>(statOrErrmsg))
54564ab3302SCarolineConcatto 
54664ab3302SCarolineConcatto // R1181 unlock-stmt -> UNLOCK ( lock-variable [, sync-stat-list] )
54764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("UNLOCK statement"_en_US,
54864ab3302SCarolineConcatto     construct<UnlockStmt>("UNLOCK (" >> lockVariable,
54964ab3302SCarolineConcatto         defaulted("," >> nonemptyList(statOrErrmsg)) / ")"))
55064ab3302SCarolineConcatto 
5515bbb63bdSPeter Klausler // CUF-kernel-do-construct ->
5525bbb63bdSPeter Klausler //   !$CUF KERNEL DO [ (scalar-int-constant-expr) ]
5535bbb63bdSPeter Klausler //      <<< grid, block [, stream] >>>
5545bbb63bdSPeter Klausler //      [ cuf-reduction... ]
5555bbb63bdSPeter Klausler //      do-construct
55660fa2b06SPeter Klausler // star-or-expr -> * | scalar-int-expr
55760fa2b06SPeter Klausler // grid -> * | scalar-int-expr | ( star-or-expr-list )
55860fa2b06SPeter Klausler // block -> * | scalar-int-expr | ( star-or-expr-list )
5595bbb63bdSPeter Klausler // stream -> 0, scalar-int-expr | STREAM = scalar-int-expr
5605bbb63bdSPeter Klausler // cuf-reduction -> [ REDUCTION | REDUCE ] (
5615bbb63bdSPeter Klausler //                  acc-reduction-op : scalar-variable-list )
5625bbb63bdSPeter Klausler 
56360fa2b06SPeter Klausler constexpr auto starOrExpr{construct<CUFKernelDoConstruct::StarOrExpr>(
56460fa2b06SPeter Klausler     "*" >> pure<std::optional<ScalarIntExpr>>() ||
56560fa2b06SPeter Klausler     applyFunction(presentOptional<ScalarIntExpr>, scalarIntExpr))};
56660fa2b06SPeter Klausler constexpr auto gridOrBlock{parenthesized(nonemptyList(starOrExpr)) ||
56760fa2b06SPeter Klausler     applyFunction(singletonList<CUFKernelDoConstruct::StarOrExpr>, starOrExpr)};
5685bbb63bdSPeter Klausler 
5695bbb63bdSPeter Klausler TYPE_PARSER(("REDUCTION"_tok || "REDUCE"_tok) >>
5705bbb63bdSPeter Klausler     parenthesized(construct<CUFReduction>(Parser<CUFReduction::Operator>{},
5715bbb63bdSPeter Klausler         ":" >> nonemptyList(scalar(variable)))))
5725bbb63bdSPeter Klausler 
57337143fe2SValentin Clement (バレンタイン クレメン) TYPE_PARSER("<<<" >>
57437143fe2SValentin Clement (バレンタイン クレメン)     construct<CUFKernelDoConstruct::LaunchConfiguration>(gridOrBlock,
57537143fe2SValentin Clement (バレンタイン クレメン)         "," >> gridOrBlock,
57637143fe2SValentin Clement (バレンタイン クレメン)         maybe((", 0 ,"_tok || ", STREAM ="_tok) >> scalarIntExpr) / ">>>"))
57737143fe2SValentin Clement (バレンタイン クレメン) 
5784ad72793SPeter Klausler TYPE_PARSER(sourced(beginDirective >> "$CUF KERNEL DO"_tok >>
5794ad72793SPeter Klausler     construct<CUFKernelDoConstruct::Directive>(
58037143fe2SValentin Clement (バレンタイン クレメン)         maybe(parenthesized(scalarIntConstantExpr)),
58137143fe2SValentin Clement (バレンタイン クレメン)         maybe(Parser<CUFKernelDoConstruct::LaunchConfiguration>{}),
5825bbb63bdSPeter Klausler         many(Parser<CUFReduction>{}) / endDirective)))
5834ad72793SPeter Klausler TYPE_CONTEXT_PARSER("!$CUF KERNEL DO construct"_en_US,
5844ad72793SPeter Klausler     extension<LanguageFeature::CUDA>(construct<CUFKernelDoConstruct>(
5854ad72793SPeter Klausler         Parser<CUFKernelDoConstruct::Directive>{},
5864ad72793SPeter Klausler         maybe(Parser<DoConstruct>{}))))
5874ad72793SPeter Klausler 
5881f879005STim Keith } // namespace Fortran::parser
589