#include "basic-parsers.h"
#include "debug-parser.h"
#include "expr-parsers.h"
#include "misc-parsers.h"
#include "stmt-parser.h"
#include "token-parsers.h"
#include "type-parser-implementation.h"
#include "flang/Parser/characters.h"
#include "flang/Parser/parse-tree.h"
namespace Fortran::parser {
constexpr auto executableConstruct{first(
construct<ExecutableConstruct>(CapturedLabelDoStmt{}),
construct<ExecutableConstruct>(EndDoStmtForCapturedLabelDoStmt{}),
construct<ExecutableConstruct>(indirect(Parser<DoConstruct>{})),
construct<ExecutableConstruct>(statement(actionStmt)),
construct<ExecutableConstruct>(indirect(Parser<AssociateConstruct>{})),
construct<ExecutableConstruct>(indirect(Parser<BlockConstruct>{})),
construct<ExecutableConstruct>(indirect(Parser<CaseConstruct>{})),
construct<ExecutableConstruct>(indirect(Parser<ChangeTeamConstruct>{})),
construct<ExecutableConstruct>(indirect(Parser<CriticalConstruct>{})),
construct<ExecutableConstruct>(indirect(Parser<IfConstruct>{})),
construct<ExecutableConstruct>(indirect(Parser<SelectRankConstruct>{})),
construct<ExecutableConstruct>(indirect(Parser<SelectTypeConstruct>{})),
construct<ExecutableConstruct>(indirect(whereConstruct)),
construct<ExecutableConstruct>(indirect(forallConstruct)),
construct<ExecutableConstruct>(indirect(ompEndLoopDirective)),
construct<ExecutableConstruct>(indirect(openmpConstruct)),
construct<ExecutableConstruct>(indirect(Parser<OpenACCConstruct>{})),
construct<ExecutableConstruct>(indirect(compilerDirective)),
construct<ExecutableConstruct>(indirect(Parser<CUFKernelDoConstruct>{})))};
constexpr auto obsoleteExecutionPartConstruct{recovery(ignoredStatementPrefix >>
fail<ExecutionPartConstruct>(
"obsolete legacy extension is not supported"_err_en_US),
construct<ExecutionPartConstruct>(construct<ErrorRecovery>(ok /
statement("REDIMENSION" >> name /
parenthesized(nonemptyList(Parser<AllocateShapeSpec>{}))))))};
TYPE_PARSER(recovery(
withMessage("expected execution part construct"_err_en_US,
CONTEXT_PARSER("execution part construct"_en_US,
first(construct<ExecutionPartConstruct>(executableConstruct),
construct<ExecutionPartConstruct>(
statement(indirect(formatStmt))),
construct<ExecutionPartConstruct>(
statement(indirect(entryStmt))),
construct<ExecutionPartConstruct>(
statement(indirect(dataStmt))),
extension<LanguageFeature::ExecutionPartNamelist>(
"nonstandard usage: NAMELIST in execution part"_port_en_US,
construct<ExecutionPartConstruct>(
statement(indirect(Parser<NamelistStmt>{})))),
obsoleteExecutionPartConstruct))),
construct<ExecutionPartConstruct>(executionPartErrorRecovery)))
TYPE_CONTEXT_PARSER("execution part"_en_US,
construct<ExecutionPart>(many(executionPartConstruct)))
TYPE_PARSER(first(construct<ActionStmt>(indirect(Parser<AllocateStmt>{})),
construct<ActionStmt>(indirect(assignmentStmt)),
construct<ActionStmt>(indirect(pointerAssignmentStmt)),
construct<ActionStmt>(indirect(Parser<BackspaceStmt>{})),
construct<ActionStmt>(indirect(Parser<CallStmt>{})),
construct<ActionStmt>(indirect(Parser<CloseStmt>{})),
construct<ActionStmt>(construct<ContinueStmt>("CONTINUE"_tok)),
construct<ActionStmt>(indirect(Parser<CycleStmt>{})),
construct<ActionStmt>(indirect(Parser<DeallocateStmt>{})),
construct<ActionStmt>(indirect(Parser<EndfileStmt>{})),
construct<ActionStmt>(indirect(Parser<EventPostStmt>{})),
construct<ActionStmt>(indirect(Parser<EventWaitStmt>{})),
construct<ActionStmt>(indirect(Parser<ExitStmt>{})),
construct<ActionStmt>(construct<FailImageStmt>("FAIL IMAGE"_sptok)),
construct<ActionStmt>(indirect(Parser<FlushStmt>{})),
construct<ActionStmt>(indirect(Parser<FormTeamStmt>{})),
construct<ActionStmt>(indirect(Parser<GotoStmt>{})),
construct<ActionStmt>(indirect(Parser<IfStmt>{})),
construct<ActionStmt>(indirect(Parser<InquireStmt>{})),
construct<ActionStmt>(indirect(Parser<LockStmt>{})),
construct<ActionStmt>(indirect(Parser<NotifyWaitStmt>{})),
construct<ActionStmt>(indirect(Parser<NullifyStmt>{})),
construct<ActionStmt>(indirect(Parser<OpenStmt>{})),
construct<ActionStmt>(indirect(Parser<PrintStmt>{})),
construct<ActionStmt>(indirect(Parser<ReadStmt>{})),
construct<ActionStmt>(indirect(Parser<ReturnStmt>{})),
construct<ActionStmt>(indirect(Parser<RewindStmt>{})),
construct<ActionStmt>(indirect(Parser<StopStmt>{})),
construct<ActionStmt>(indirect(Parser<SyncAllStmt>{})),
construct<ActionStmt>(indirect(Parser<SyncImagesStmt>{})),
construct<ActionStmt>(indirect(Parser<SyncMemoryStmt>{})),
construct<ActionStmt>(indirect(Parser<SyncTeamStmt>{})),
construct<ActionStmt>(indirect(Parser<UnlockStmt>{})),
construct<ActionStmt>(indirect(Parser<WaitStmt>{})),
construct<ActionStmt>(indirect(whereStmt)),
construct<ActionStmt>(indirect(Parser<WriteStmt>{})),
construct<ActionStmt>(indirect(Parser<ComputedGotoStmt>{})),
construct<ActionStmt>(indirect(forallStmt)),
construct<ActionStmt>(indirect(Parser<ArithmeticIfStmt>{})),
construct<ActionStmt>(indirect(Parser<AssignStmt>{})),
construct<ActionStmt>(indirect(Parser<AssignedGotoStmt>{})),
construct<ActionStmt>(indirect(Parser<PauseStmt>{}))))
TYPE_CONTEXT_PARSER("ASSOCIATE construct"_en_US,
construct<AssociateConstruct>(statement(Parser<AssociateStmt>{}), block,
statement(Parser<EndAssociateStmt>{})))
TYPE_CONTEXT_PARSER("ASSOCIATE statement"_en_US,
construct<AssociateStmt>(maybe(name / ":"),
"ASSOCIATE" >> parenthesized(nonemptyList(Parser<Association>{}))))
TYPE_PARSER(construct<Association>(name, "=>" >> selector))
TYPE_PARSER(construct<Selector>(variable) / lookAhead(","_tok || ")"_tok) ||
construct<Selector>(expr))
TYPE_PARSER(construct<EndAssociateStmt>(recovery(
"END ASSOCIATE" >> maybe(name), namedConstructEndStmtErrorRecovery)))
TYPE_CONTEXT_PARSER("BLOCK construct"_en_US,
construct<BlockConstruct>(statement(Parser<BlockStmt>{}),
Parser<BlockSpecificationPart>{},
block, statement(Parser<EndBlockStmt>{})))
TYPE_PARSER(construct<BlockStmt>(maybe(name / ":") / "BLOCK"))
TYPE_PARSER(construct<BlockSpecificationPart>(specificationPart))
TYPE_PARSER(construct<EndBlockStmt>(
recovery("END BLOCK" >> maybe(name), namedConstructEndStmtErrorRecovery)))
TYPE_CONTEXT_PARSER("CHANGE TEAM construct"_en_US,
construct<ChangeTeamConstruct>(statement(Parser<ChangeTeamStmt>{}), block,
statement(Parser<EndChangeTeamStmt>{})))
TYPE_CONTEXT_PARSER("CHANGE TEAM statement"_en_US,
construct<ChangeTeamStmt>(maybe(name / ":"),
"CHANGE TEAM"_sptok >> "("_tok >> teamValue,
defaulted("," >> nonemptyList(Parser<CoarrayAssociation>{})),
defaulted("," >> nonemptyList(statOrErrmsg))) /
")")
TYPE_PARSER(
construct<CoarrayAssociation>(Parser<CodimensionDecl>{}, "=>" >> selector))
TYPE_CONTEXT_PARSER("END TEAM statement"_en_US,
construct<EndChangeTeamStmt>(
"END TEAM" >> defaulted(parenthesized(optionalList(statOrErrmsg))),
maybe(name)))
TYPE_CONTEXT_PARSER("CRITICAL statement"_en_US,
construct<CriticalStmt>(maybe(name / ":"),
"CRITICAL" >> defaulted(parenthesized(optionalList(statOrErrmsg)))))
TYPE_CONTEXT_PARSER("CRITICAL construct"_en_US,
construct<CriticalConstruct>(statement(Parser<CriticalStmt>{}), block,
statement(Parser<EndCriticalStmt>{})))
TYPE_PARSER(construct<EndCriticalStmt>(recovery(
"END CRITICAL" >> maybe(name), namedConstructEndStmtErrorRecovery)))
TYPE_CONTEXT_PARSER("DO construct"_en_US,
construct<DoConstruct>(
statement(Parser<NonLabelDoStmt>{}) / EnterNonlabelDoConstruct{}, block,
statement(Parser<EndDoStmt>{}) / LeaveDoConstruct{}))
TYPE_PARSER(parenthesized(construct<ConcurrentHeader>(
maybe(integerTypeSpec / "::"), nonemptyList(Parser<ConcurrentControl>{}),
maybe("," >> scalarLogicalExpr))))
TYPE_PARSER(construct<ConcurrentControl>(name / "=", scalarIntExpr / ":",
scalarIntExpr, maybe(":" >> scalarIntExpr)))
TYPE_PARSER(construct<LocalitySpec>(construct<LocalitySpec::Local>(
"LOCAL" >> parenthesized(listOfNames))) ||
construct<LocalitySpec>(construct<LocalitySpec::LocalInit>(
"LOCAL_INIT"_sptok >> parenthesized(listOfNames))) ||
construct<LocalitySpec>(construct<LocalitySpec::Reduce>(
"REDUCE (" >> Parser<LocalitySpec::Reduce::Operator>{} / ":",
listOfNames / ")")) ||
construct<LocalitySpec>(construct<LocalitySpec::Shared>(
"SHARED" >> parenthesized(listOfNames))) ||
construct<LocalitySpec>(
construct<LocalitySpec::DefaultNone>("DEFAULT ( NONE )"_tok)))
TYPE_CONTEXT_PARSER("loop control"_en_US,
maybe(","_tok) >>
(construct<LoopControl>(loopBounds(scalarExpr)) ||
construct<LoopControl>(
"WHILE" >> parenthesized(scalarLogicalExpr)) ||
construct<LoopControl>(construct<LoopControl::Concurrent>(
"CONCURRENT" >> concurrentHeader,
many(Parser<LocalitySpec>{})))))
TYPE_CONTEXT_PARSER("label DO statement"_en_US,
construct<LabelDoStmt>("DO" >> label, maybe(loopControl)))
TYPE_CONTEXT_PARSER("nonlabel DO statement"_en_US,
construct<NonLabelDoStmt>(
name / ":", "DO" >> maybe(label), maybe(loopControl)) ||
construct<NonLabelDoStmt>(construct<std::optional<Name>>(),
construct<std::optional<Label>>(), "DO" >> maybe(loopControl)))
TYPE_CONTEXT_PARSER("END DO statement"_en_US,
construct<EndDoStmt>(
recovery("END DO" >> maybe(name), namedConstructEndStmtErrorRecovery)))
TYPE_CONTEXT_PARSER(
"CYCLE statement"_en_US, construct<CycleStmt>("CYCLE" >> maybe(name)))
TYPE_CONTEXT_PARSER("IF construct"_en_US,
construct<IfConstruct>(
statement(construct<IfThenStmt>(maybe(name / ":"),
"IF" >> parenthesized(scalarLogicalExpr) /
recovery("THEN"_tok, lookAhead(endOfStmt)))),
block,
many(construct<IfConstruct::ElseIfBlock>(
unambiguousStatement(construct<ElseIfStmt>(
"ELSE IF" >> parenthesized(scalarLogicalExpr),
recovery("THEN"_tok, ok) >> maybe(name))),
block)),
maybe(construct<IfConstruct::ElseBlock>(
statement(construct<ElseStmt>("ELSE" >> maybe(name))), block)),
statement(construct<EndIfStmt>(recovery(
"END IF" >> maybe(name), namedConstructEndStmtErrorRecovery)))))
TYPE_CONTEXT_PARSER("IF statement"_en_US,
construct<IfStmt>("IF" >> parenthesized(scalarLogicalExpr),
unlabeledStatement(actionStmt)))
TYPE_CONTEXT_PARSER("SELECT CASE construct"_en_US,
construct<CaseConstruct>(statement(Parser<SelectCaseStmt>{}),
many(construct<CaseConstruct::Case>(
unambiguousStatement(Parser<CaseStmt>{}), block)),
statement(endSelectStmt)))
TYPE_CONTEXT_PARSER("SELECT CASE statement"_en_US,
construct<SelectCaseStmt>(
maybe(name / ":"), "SELECT CASE" >> parenthesized(scalar(expr))))
TYPE_CONTEXT_PARSER("CASE statement"_en_US,
construct<CaseStmt>("CASE" >> Parser<CaseSelector>{}, maybe(name)))
TYPE_PARSER(construct<EndSelectStmt>(
recovery("END SELECT" >> maybe(name), namedConstructEndStmtErrorRecovery)))
constexpr auto defaultKeyword{construct<Default>("DEFAULT"_tok)};
TYPE_PARSER(parenthesized(construct<CaseSelector>(
nonemptyList(Parser<CaseValueRange>{}))) ||
construct<CaseSelector>(defaultKeyword))
constexpr auto caseValue{scalar(constantExpr)};
TYPE_PARSER(construct<CaseValueRange>(construct<CaseValueRange::Range>(
construct<std::optional<CaseValue>>(caseValue),
":" >> maybe(caseValue))) ||
construct<CaseValueRange>(
construct<CaseValueRange::Range>(construct<std::optional<CaseValue>>(),
":" >> construct<std::optional<CaseValue>>(caseValue))) ||
construct<CaseValueRange>(caseValue))
TYPE_CONTEXT_PARSER("SELECT RANK construct"_en_US,
construct<SelectRankConstruct>(statement(Parser<SelectRankStmt>{}),
many(construct<SelectRankConstruct::RankCase>(
unambiguousStatement(Parser<SelectRankCaseStmt>{}), block)),
statement(endSelectStmt)))
TYPE_CONTEXT_PARSER("SELECT RANK statement"_en_US,
construct<SelectRankStmt>(maybe(name / ":"),
"SELECT RANK"_sptok >> "("_tok >> maybe(name / "=>"), selector / ")"))
TYPE_CONTEXT_PARSER("RANK case statement"_en_US,
"RANK" >> (construct<SelectRankCaseStmt>(
parenthesized(construct<SelectRankCaseStmt::Rank>(
scalarIntConstantExpr) ||
construct<SelectRankCaseStmt::Rank>(star)) ||
construct<SelectRankCaseStmt::Rank>(defaultKeyword),
maybe(name))))
TYPE_CONTEXT_PARSER("SELECT TYPE construct"_en_US,
construct<SelectTypeConstruct>(statement(Parser<SelectTypeStmt>{}),
many(construct<SelectTypeConstruct::TypeCase>(
unambiguousStatement(Parser<TypeGuardStmt>{}), block)),
statement(endSelectStmt)))
TYPE_CONTEXT_PARSER("SELECT TYPE statement"_en_US,
construct<SelectTypeStmt>(maybe(name / ":"),
"SELECT TYPE (" >> maybe(name / "=>"), selector / ")"))
TYPE_CONTEXT_PARSER("type guard statement"_en_US,
construct<TypeGuardStmt>("TYPE IS"_sptok >>
parenthesized(construct<TypeGuardStmt::Guard>(typeSpec)) ||
"CLASS IS"_sptok >> parenthesized(construct<TypeGuardStmt::Guard>(
derivedTypeSpec)) ||
construct<TypeGuardStmt::Guard>("CLASS" >> defaultKeyword),
maybe(name)))
TYPE_CONTEXT_PARSER(
"EXIT statement"_en_US, construct<ExitStmt>("EXIT" >> maybe(name)))
TYPE_CONTEXT_PARSER(
"GOTO statement"_en_US, construct<GotoStmt>("GO TO" >> label))
TYPE_CONTEXT_PARSER("computed GOTO statement"_en_US,
construct<ComputedGotoStmt>("GO TO" >> parenthesized(nonemptyList(label)),
maybe(","_tok) >> scalarIntExpr))
TYPE_CONTEXT_PARSER("STOP statement"_en_US,
construct<StopStmt>("STOP" >> pure(StopStmt::Kind::Stop) ||
"ERROR STOP"_sptok >> pure(StopStmt::Kind::ErrorStop),
maybe(Parser<StopCode>{}), maybe(", QUIET =" >> scalarLogicalExpr)))
TYPE_PARSER(construct<StopCode>(scalar(expr)))
TYPE_CONTEXT_PARSER("NOTIFY WAIT statement"_en_US,
construct<NotifyWaitStmt>(
"NOTIFY WAIT"_sptok >> "("_tok >> scalar(variable),
defaulted("," >> nonemptyList(Parser<EventWaitSpec>{})) / ")"))
TYPE_CONTEXT_PARSER("SYNC ALL statement"_en_US,
construct<SyncAllStmt>("SYNC ALL"_sptok >>
defaulted(parenthesized(optionalList(statOrErrmsg)))))
TYPE_CONTEXT_PARSER("SYNC IMAGES statement"_en_US,
"SYNC IMAGES"_sptok >> parenthesized(construct<SyncImagesStmt>(
construct<SyncImagesStmt::ImageSet>(intExpr) ||
construct<SyncImagesStmt::ImageSet>(star),
defaulted("," >> nonemptyList(statOrErrmsg)))))
TYPE_CONTEXT_PARSER("SYNC MEMORY statement"_en_US,
construct<SyncMemoryStmt>("SYNC MEMORY"_sptok >>
defaulted(parenthesized(optionalList(statOrErrmsg)))))
TYPE_CONTEXT_PARSER("SYNC TEAM statement"_en_US,
construct<SyncTeamStmt>("SYNC TEAM"_sptok >> "("_tok >> teamValue,
defaulted("," >> nonemptyList(statOrErrmsg)) / ")"))
TYPE_CONTEXT_PARSER("EVENT POST statement"_en_US,
construct<EventPostStmt>("EVENT POST"_sptok >> "("_tok >> scalar(variable),
defaulted("," >> nonemptyList(statOrErrmsg)) / ")"))
TYPE_CONTEXT_PARSER("EVENT WAIT statement"_en_US,
construct<EventWaitStmt>("EVENT WAIT"_sptok >> "("_tok >> scalar(variable),
defaulted("," >> nonemptyList(Parser<EventWaitSpec>{})) / ")"))
constexpr auto untilSpec{"UNTIL_COUNT =" >> scalarIntExpr};
TYPE_PARSER(construct<EventWaitSpec>(untilSpec) ||
construct<EventWaitSpec>(statOrErrmsg))
constexpr auto teamVariable{scalar(variable)};
TYPE_CONTEXT_PARSER("FORM TEAM statement"_en_US,
construct<FormTeamStmt>("FORM TEAM"_sptok >> "("_tok >> scalarIntExpr,
"," >> teamVariable,
defaulted("," >> nonemptyList(Parser<FormTeamStmt::FormTeamSpec>{})) /
")"))
TYPE_PARSER(
construct<FormTeamStmt::FormTeamSpec>("NEW_INDEX =" >> scalarIntExpr) ||
construct<FormTeamStmt::FormTeamSpec>(statOrErrmsg))
constexpr auto lockVariable{scalar(variable)};
TYPE_CONTEXT_PARSER("LOCK statement"_en_US,
construct<LockStmt>("LOCK (" >> lockVariable,
defaulted("," >> nonemptyList(Parser<LockStmt::LockStat>{})) / ")"))
TYPE_PARSER(
construct<LockStmt::LockStat>("ACQUIRED_LOCK =" >> scalarLogicalVariable) ||
construct<LockStmt::LockStat>(statOrErrmsg))
TYPE_CONTEXT_PARSER("UNLOCK statement"_en_US,
construct<UnlockStmt>("UNLOCK (" >> lockVariable,
defaulted("," >> nonemptyList(statOrErrmsg)) / ")"))
constexpr auto starOrExpr{construct<CUFKernelDoConstruct::StarOrExpr>(
"*" >> pure<std::optional<ScalarIntExpr>>() ||
applyFunction(presentOptional<ScalarIntExpr>, scalarIntExpr))};
constexpr auto gridOrBlock{parenthesized(nonemptyList(starOrExpr)) ||
applyFunction(singletonList<CUFKernelDoConstruct::StarOrExpr>, starOrExpr)};
TYPE_PARSER(("REDUCTION"_tok || "REDUCE"_tok) >>
parenthesized(construct<CUFReduction>(Parser<CUFReduction::Operator>{},
":" >> nonemptyList(scalar(variable)))))
TYPE_PARSER(sourced(beginDirective >> "$CUF KERNEL DO"_tok >>
construct<CUFKernelDoConstruct::Directive>(
maybe(parenthesized(scalarIntConstantExpr)), "<<<" >> gridOrBlock,
"," >> gridOrBlock,
maybe((", 0 ,"_tok || ", STREAM ="_tok) >> scalarIntExpr) / ">>>",
many(Parser<CUFReduction>{}) / endDirective)))
TYPE_CONTEXT_PARSER("!$CUF KERNEL DO construct"_en_US,
extension<LanguageFeature::CUDA>(construct<CUFKernelDoConstruct>(
Parser<CUFKernelDoConstruct::Directive>{},
maybe(Parser<DoConstruct>{}))))
}