// OpenMP Directives and Clauses
namespace Fortran::parser {
+constexpr auto startOmpLine = skipStuffBeforeStatement >> "!$OMP "_sptok;
constexpr auto endOmpLine = space >> endOfLine;
// OpenMP Clauses
// DEFAULT (PRIVATE | FIRSTPRIVATE | SHARED | NONE )
TYPE_PARSER(construct<OmpDefaultClause>(
- "PRIVATE"_id >> pure(OmpDefaultClause::Type::Private) ||
- "FIRSTPRIVATE"_id >> pure(OmpDefaultClause::Type::Firstprivate) ||
- "SHARED"_id >> pure(OmpDefaultClause::Type::Shared) ||
- "NONE"_id >> pure(OmpDefaultClause::Type::None)))
+ "PRIVATE" >> pure(OmpDefaultClause::Type::Private) ||
+ "FIRSTPRIVATE" >> pure(OmpDefaultClause::Type::Firstprivate) ||
+ "SHARED" >> pure(OmpDefaultClause::Type::Shared) ||
+ "NONE" >> pure(OmpDefaultClause::Type::None)))
// PROC_BIND(CLOSE | MASTER | SPREAD)
TYPE_PARSER(construct<OmpProcBindClause>(
- "CLOSE"_id >> pure(OmpProcBindClause::Type::Close) ||
- "MASTER"_id >> pure(OmpProcBindClause::Type::Master) ||
- "SPREAD"_id >> pure(OmpProcBindClause::Type::Spread)))
+ "CLOSE" >> pure(OmpProcBindClause::Type::Close) ||
+ "MASTER" >> pure(OmpProcBindClause::Type::Master) ||
+ "SPREAD" >> pure(OmpProcBindClause::Type::Spread)))
// MAP ([ [map-type-modifier[,]] map-type : ] list)
// map-type-modifier -> ALWAYS
// map-type -> TO | FROM | TOFROM | ALLOC | RELEASE | DELETE
TYPE_PARSER(construct<OmpMapType>(
- maybe("ALWAYS"_id >> construct<OmpMapType::Always>() / maybe(","_tok)),
+ maybe("ALWAYS" >> construct<OmpMapType::Always>() / maybe(","_tok)),
"TO"_id >> pure(OmpMapType::Type::To) / ":"_tok ||
- "FROM"_id >> pure(OmpMapType::Type::From) / ":"_tok ||
- "TOFROM"_id >> pure(OmpMapType::Type::Tofrom) / ":"_tok ||
- "ALLOC"_id >> pure(OmpMapType::Type::Alloc) / ":"_tok ||
- "RELEASE"_id >> pure(OmpMapType::Type::Release) / ":"_tok ||
- "DELETE"_id >> pure(OmpMapType::Type::Delete) / ":"_tok))
+ "FROM" >> pure(OmpMapType::Type::From) / ":"_tok ||
+ "TOFROM" >> pure(OmpMapType::Type::Tofrom) / ":"_tok ||
+ "ALLOC" >> pure(OmpMapType::Type::Alloc) / ":"_tok ||
+ "RELEASE" >> pure(OmpMapType::Type::Release) / ":"_tok ||
+ "DELETE" >> pure(OmpMapType::Type::Delete) / ":"_tok))
TYPE_PARSER(construct<OmpMapClause>(
maybe(Parser<OmpMapType>{}), Parser<OmpObjectList>{}))
// kind -> STATIC | DYNAMIC | GUIDED | AUTO | RUNTIME
// chunk_size -> ScalarIntExpr
TYPE_PARSER(construct<OmpScheduleModifierType>(
- "MONOTONIC"_id >> pure(OmpScheduleModifierType::ModType::Monotonic) ||
- "NONMONOTONIC"_id >> pure(OmpScheduleModifierType::ModType::Nonmonotonic) ||
- "SIMD"_id >> pure(OmpScheduleModifierType::ModType::Simd)))
+ "MONOTONIC" >> pure(OmpScheduleModifierType::ModType::Monotonic) ||
+ "NONMONOTONIC" >> pure(OmpScheduleModifierType::ModType::Nonmonotonic) ||
+ "SIMD" >> pure(OmpScheduleModifierType::ModType::Simd)))
TYPE_PARSER(construct<OmpScheduleModifier>(Parser<OmpScheduleModifierType>{},
- maybe(","_tok >> Parser<OmpScheduleModifierType>{}) / ":"_tok))
+ maybe("," >> Parser<OmpScheduleModifierType>{}) / ":"))
TYPE_PARSER(construct<OmpScheduleClause>(maybe(Parser<OmpScheduleModifier>{}),
- "STATIC"_id >> pure(OmpScheduleClause::ScheduleType::Static) ||
- "DYNAMIC"_id >> pure(OmpScheduleClause::ScheduleType::Dynamic) ||
- "GUIDED"_id >> pure(OmpScheduleClause::ScheduleType::Guided) ||
- "AUTO"_id >> pure(OmpScheduleClause::ScheduleType::Auto) ||
- "RUNTIME"_id >> pure(OmpScheduleClause::ScheduleType::Runtime),
- maybe(","_tok >> scalarIntExpr)))
+ "STATIC" >> pure(OmpScheduleClause::ScheduleType::Static) ||
+ "DYNAMIC" >> pure(OmpScheduleClause::ScheduleType::Dynamic) ||
+ "GUIDED" >> pure(OmpScheduleClause::ScheduleType::Guided) ||
+ "AUTO" >> pure(OmpScheduleClause::ScheduleType::Auto) ||
+ "RUNTIME" >> pure(OmpScheduleClause::ScheduleType::Runtime),
+ maybe("," >> scalarIntExpr)))
// IF(directive-name-modifier: scalar-logical-expr)
TYPE_PARSER(construct<OmpIfClause>(
- maybe(
- ("PARALLEL"_id >> pure(OmpIfClause::DirectiveNameModifier::Parallel) ||
- "TARGET ENTER DATA"_id >>
- pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) ||
- "TARGET EXIT DATA"_id >>
- pure(OmpIfClause::DirectiveNameModifier::TargetExitData) ||
- "TARGET DATA"_id >>
- pure(OmpIfClause::DirectiveNameModifier::TargetData) ||
- "TARGET UPDATE"_id >>
- pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) ||
- "TARGET"_id >> pure(OmpIfClause::DirectiveNameModifier::Target) ||
- "TASKLOOP"_id >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) ||
- "TASK"_id >> pure(OmpIfClause::DirectiveNameModifier::Task)) /
- ":"_tok),
+ maybe(("PARALLEL" >> pure(OmpIfClause::DirectiveNameModifier::Parallel) ||
+ "TARGET ENTER DATA" >>
+ pure(OmpIfClause::DirectiveNameModifier::TargetEnterData) ||
+ "TARGET EXIT DATA" >>
+ pure(OmpIfClause::DirectiveNameModifier::TargetExitData) ||
+ "TARGET DATA" >>
+ pure(OmpIfClause::DirectiveNameModifier::TargetData) ||
+ "TARGET UPDATE" >>
+ pure(OmpIfClause::DirectiveNameModifier::TargetUpdate) ||
+ "TARGET" >> pure(OmpIfClause::DirectiveNameModifier::Target) ||
+ "TASK"_id >> pure(OmpIfClause::DirectiveNameModifier::Taskloop) ||
+ "TASKLOOP" >> pure(OmpIfClause::DirectiveNameModifier::Task)) /
+ ":"),
scalarLogicalExpr))
TYPE_PARSER(
construct<OmpReductionOperator>(Parser<ProcedureDesignator>{}))
TYPE_PARSER(construct<OmpReductionClause>(
- Parser<OmpReductionOperator>{} / ":"_tok, nonemptyList(designator)))
+ Parser<OmpReductionOperator>{} / ":", nonemptyList(designator)))
// DEPEND(SOURCE | SINK : vec | (IN | OUT | INOUT) : list
TYPE_PARSER(construct<OmpDependSinkVecLength>(
TYPE_PARSER(
construct<OmpDependSinkVec>(name, maybe(Parser<OmpDependSinkVecLength>{})))
-TYPE_PARSER(construct<OmpDependenceType>(
- "INOUT"_id >> pure(OmpDependenceType::Type::Inout) ||
- "IN"_id >> pure(OmpDependenceType::Type::In) ||
- "OUT"_id >> pure(OmpDependenceType::Type::Out)))
+TYPE_PARSER(
+ construct<OmpDependenceType>("IN"_id >> pure(OmpDependenceType::Type::In) ||
+ "INOUT" >> pure(OmpDependenceType::Type::Inout) ||
+ "OUT" >> pure(OmpDependenceType::Type::Out)))
TYPE_CONTEXT_PARSER("Omp Depend clause"_en_US,
construct<OmpDependClause>(construct<OmpDependClause::Sink>(
- "SINK"_id_tok >> ":"_tok >> nonemptyList(Parser<OmpDependSinkVec>{}))) ||
+ "SINK :" >> nonemptyList(Parser<OmpDependSinkVec>{}))) ||
construct<OmpDependClause>(
- construct<OmpDependClause::Source>("SOURCE"_id)) ||
+ construct<OmpDependClause::Source>("SOURCE"_tok)) ||
construct<OmpDependClause>(construct<OmpDependClause::InOut>(
- Parser<OmpDependenceType>{}, ":"_tok >> nonemptyList(designator))))
+ Parser<OmpDependenceType>{}, ":" >> nonemptyList(designator))))
// linear-modifier
TYPE_PARSER(
- construct<OmpLinearModifier>("REF"_id >> pure(OmpLinearModifier::Type::Ref) ||
- "VAL"_id >> pure(OmpLinearModifier::Type::Val) ||
- "UVAL"_id >> pure(OmpLinearModifier::Type::Uval)))
+ construct<OmpLinearModifier>("REF" >> pure(OmpLinearModifier::Type::Ref) ||
+ "VAL" >> pure(OmpLinearModifier::Type::Val) ||
+ "UVAL" >> pure(OmpLinearModifier::Type::Uval)))
// LINEAR(list: linear-step)
TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US,
construct<OmpLinearClause>(
construct<OmpLinearClause>(construct<OmpLinearClause::WithModifier>(
Parser<OmpLinearModifier>{}, parenthesized(nonemptyList(name)),
- maybe(":"_tok >> scalarIntConstantExpr))) ||
+ maybe(":" >> scalarIntConstantExpr))) ||
construct<OmpLinearClause>(construct<OmpLinearClause::WithoutModifier>(
- nonemptyList(name), maybe(":"_tok >> scalarIntConstantExpr)))))
+ nonemptyList(name), maybe(":" >> scalarIntConstantExpr)))))
// ALIGNED(list: alignment)
TYPE_PARSER(construct<OmpAlignedClause>(
parenthesized(Parser<OmpObjectList>{}))) ||
"COPYPRIVATE" >> construct<OmpClause>(construct<OmpClause::Copyprivate>(
(parenthesized(Parser<OmpObjectList>{})))) ||
- "DEFAULTMAP" >>
- construct<OmpClause>(construct<OmpClause::Defaultmap>(
- parenthesized("TOFROM"_tok >> ":"_tok >> "SCALAR"_tok))) ||
- "DEFAULT" >>
+ "DEFAULT"_id >>
construct<OmpClause>(parenthesized(Parser<OmpDefaultClause>{})) ||
+ "DEFAULTMAP" >> construct<OmpClause>(construct<OmpClause::Defaultmap>(
+ "( TOFROM : SCALAR )"_tok)) ||
"DEPEND" >>
construct<OmpClause>(parenthesized(Parser<OmpDependClause>{})) ||
"DEVICE" >> construct<OmpClause>(construct<OmpClause::Device>(
parenthesized(scalarIntExpr))) ||
- "DIST_SCHEDULE" >>
- construct<OmpClause>(construct<OmpClause::DistSchedule>(
- parenthesized("STATIC"_tok >> ","_tok >> scalarIntExpr))) ||
+ "DIST_SCHEDULE" >> construct<OmpClause>(construct<OmpClause::DistSchedule>(
+ parenthesized("STATIC ," >> scalarIntExpr))) ||
"FINAL" >> construct<OmpClause>(
construct<OmpClause::Final>(parenthesized(scalarIntExpr))) ||
"FIRSTPRIVATE" >> construct<OmpClause>(construct<OmpClause::Firstprivate>(
construct<OmpClause>(parenthesized(Parser<OmpScheduleClause>{})) ||
"SHARED" >> construct<OmpClause>(construct<OmpClause::Shared>(
parenthesized(Parser<OmpObjectList>{}))) ||
+ "SIMD"_id >> construct<OmpClause>(construct<OmpClause::Simd>()) ||
"SIMDLEN" >> construct<OmpClause>(construct<OmpClause::Simdlen>(
parenthesized(scalarIntConstantExpr))) ||
- "SIMD" >> construct<OmpClause>(construct<OmpClause::Simd>()) ||
"THREADS" >> construct<OmpClause>(construct<OmpClause::Threads>()) ||
"THREAD_LIMIT" >> construct<OmpClause>(construct<OmpClause::ThreadLimit>(
parenthesized(scalarIntExpr))) ||
construct<OmpLoopDirective::DistributeSimd>()) ||
"DISTRIBUTE" >> construct<OmpLoopDirective>(
construct<OmpLoopDirective::Distribute>()) ||
+ "DO SIMD" >>
+ construct<OmpLoopDirective>(construct<OmpLoopDirective::DoSimd>()) ||
+ "DO" >> construct<OmpLoopDirective>(construct<OmpLoopDirective::Do>()) ||
"PARALLEL DO SIMD" >> construct<OmpLoopDirective>(
construct<OmpLoopDirective::ParallelDoSimd>()) ||
"PARALLEL DO" >> construct<OmpLoopDirective>(
construct<OmpLoopDirective::ParallelDo>()) ||
"SIMD" >>
construct<OmpLoopDirective>(construct<OmpLoopDirective::Simd>()) ||
- "DO SIMD" >>
- construct<OmpLoopDirective>(construct<OmpLoopDirective::DoSimd>()) ||
- "DO" >> construct<OmpLoopDirective>(construct<OmpLoopDirective::Do>()) ||
"TARGET PARALLEL DO SIMD" >>
construct<OmpLoopDirective>(
construct<OmpLoopDirective::TargetParallelDoSimd>()) ||
construct<OmpBlockDirective::TargetTeams>()) ||
"TARGET" >>
construct<OmpBlockDirective>(construct<OmpBlockDirective::Target>()) ||
+ "TASK"_id >>
+ construct<OmpBlockDirective>(construct<OmpBlockDirective::Task>()) ||
"TASKGROUP" >> construct<OmpBlockDirective>(
construct<OmpBlockDirective::Taskgroup>()) ||
- "TASK" >>
- construct<OmpBlockDirective>(construct<OmpBlockDirective::Task>()) ||
"TEAMS" >>
construct<OmpBlockDirective>(construct<OmpBlockDirective::Teams>()))
-TYPE_PARSER(construct<OmpReductionInitializerClause>("INITIALIZER"_tok >>
- parenthesized("OMP_PRIV"_tok >> "="_tok >> indirect(expr))))
+TYPE_PARSER(construct<OmpReductionInitializerClause>(
+ "INITIALIZER" >> parenthesized("OMP_PRIV =" >> indirect(expr))))
// Declare Reduction Construct
TYPE_PARSER(construct<OpenMPDeclareReductionConstruct>(
- "("_tok >> Parser<OmpReductionOperator>{} / ":"_tok,
- nonemptyList(Parser<DeclarationTypeSpec>{}) / ":"_tok,
- Parser<OmpReductionCombiner>{} / ")"_tok,
+ "(" >> Parser<OmpReductionOperator>{} / ":",
+ nonemptyList(Parser<DeclarationTypeSpec>{}) / ":",
+ Parser<OmpReductionCombiner>{} / ")",
maybe(Parser<OmpReductionInitializerClause>{})))
// declare-target-map-type
parenthesized(optionalList(actualArgSpec))))))
// OMP END ATOMIC
-TYPE_PARSER(construct<OmpEndAtomic>("!$OMP "_sptok >> "END ATOMIC"_tok))
+TYPE_PARSER(construct<OmpEndAtomic>(startOmpLine >> "END ATOMIC"_tok))
// OMP [SEQ_CST] ATOMIC READ [SEQ_CST]
TYPE_PARSER(construct<OmpAtomicRead>(
- maybe(
- "SEQ_CST"_tok >> construct<OmpAtomicRead::SeqCst1>() / maybe(","_tok)),
+ maybe("SEQ_CST" >> construct<OmpAtomicRead::SeqCst1>() / maybe(","_tok)),
"READ" >> maybe(","_tok) >>
- maybe("SEQ_CST"_tok >> construct<OmpAtomicRead::SeqCst2>()) /
- endOmpLine,
+ maybe("SEQ_CST" >> construct<OmpAtomicRead::SeqCst2>()) / endOmpLine,
statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
// OMP ATOMIC [SEQ_CST] CAPTURE [SEQ_CST]
TYPE_PARSER(construct<OmpAtomicCapture>(
- maybe("SEQ_CST"_tok >>
- construct<OmpAtomicCapture::SeqCst1>() / maybe(","_tok)),
+ maybe("SEQ_CST" >> construct<OmpAtomicCapture::SeqCst1>() / maybe(","_tok)),
"CAPTURE" >> maybe(","_tok) >>
- maybe("SEQ_CST"_tok >> construct<OmpAtomicCapture::SeqCst2>()) /
- endOmpLine,
+ maybe("SEQ_CST" >> construct<OmpAtomicCapture::SeqCst2>()) / endOmpLine,
statement(assignmentStmt), statement(assignmentStmt),
Parser<OmpEndAtomic>{} / endOmpLine))
// OMP ATOMIC [SEQ_CST] UPDATE [SEQ_CST]
TYPE_PARSER(construct<OmpAtomicUpdate>(
- maybe("SEQ_CST"_tok >>
- construct<OmpAtomicUpdate::SeqCst1>() / maybe(","_tok)),
+ maybe("SEQ_CST" >> construct<OmpAtomicUpdate::SeqCst1>() / maybe(","_tok)),
"UPDATE" >> maybe(","_tok) >>
- maybe("SEQ_CST"_tok >> construct<OmpAtomicUpdate::SeqCst2>()) /
- endOmpLine,
+ maybe("SEQ_CST" >> construct<OmpAtomicUpdate::SeqCst2>()) / endOmpLine,
statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
// OMP ATOMIC [SEQ_CST]
TYPE_PARSER(construct<OmpAtomic>(
- maybe("SEQ_CST"_tok >> construct<OmpAtomic::SeqCst>()) / endOmpLine,
+ maybe("SEQ_CST" >> construct<OmpAtomic::SeqCst>()) / endOmpLine,
statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
// ATOMIC [SEQ_CST] WRITE [SEQ_CST]
TYPE_PARSER(construct<OmpAtomicWrite>(
- maybe(
- "SEQ_CST"_tok >> construct<OmpAtomicWrite::SeqCst1>() / maybe(","_tok)),
+ maybe("SEQ_CST" >> construct<OmpAtomicWrite::SeqCst1>() / maybe(","_tok)),
"WRITE" >> maybe(","_tok) >>
- maybe("SEQ_CST"_tok >> construct<OmpAtomicWrite::SeqCst2>()) /
- endOmpLine,
+ maybe("SEQ_CST" >> construct<OmpAtomicWrite::SeqCst2>()) / endOmpLine,
statement(assignmentStmt), maybe(Parser<OmpEndAtomic>{} / endOmpLine)))
// Atomic Construct
construct<OpenMPAtomicConstruct>(Parser<OmpAtomic>{})))
// OMP CRITICAL
-TYPE_PARSER("!$OMP "_sptok >> "END"_tok >> "CRITICAL"_tok >>
+TYPE_PARSER(startOmpLine >> "END CRITICAL"_tok >>
construct<OmpEndCritical>(maybe(parenthesized(name))))
-TYPE_PARSER("CRITICAL" >>
- construct<OpenMPCriticalConstruct>(maybe(parenthesized(name)),
- maybe("HINT"_tok >> construct<OpenMPCriticalConstruct::Hint>(
- parenthesized(constantExpr))) /
- endOmpLine,
- block, Parser<OmpEndCritical>{} / endOmpLine))
+TYPE_PARSER(
+ "CRITICAL" >> construct<OpenMPCriticalConstruct>(maybe(parenthesized(name)),
+ maybe("HINT" >> construct<OpenMPCriticalConstruct::Hint>(
+ parenthesized(constantExpr))) /
+ endOmpLine,
+ block, Parser<OmpEndCritical>{} / endOmpLine))
// Declare Simd construct
TYPE_PARSER(construct<OpenMPDeclareSimdConstruct>(
maybe(parenthesized(name)), Parser<OmpClauseList>{}))
// Declarative construct & Threadprivate directive
-TYPE_PARSER(!"!$OMP END"_tok >> "!$OMP "_tok >>
+TYPE_PARSER(startOmpLine >>
("DECLARE REDUCTION" >>
construct<OpenMPDeclarativeConstruct>(
construct<OpenMPDeclarativeConstruct>(
TYPE_PARSER("TASKYIELD" >> construct<OpenMPTaskyieldConstruct>() / endOmpLine)
// OMP SINGLE
-TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
- construct<OmpEndSingle>("SINGLE"_tok >> Parser<OmpClauseList>{}))
+TYPE_PARSER(startOmpLine >> "END"_tok >>
+ construct<OmpEndSingle>("SINGLE" >> Parser<OmpClauseList>{}))
TYPE_PARSER("SINGLE" >>
construct<OpenMPSingleConstruct>(Parser<OmpClauseList>{} / endOmpLine,
block, Parser<OmpEndSingle>{} / endOmpLine))
-TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
- construct<OmpEndWorkshare>("WORKSHARE"_tok))
+TYPE_PARSER(
+ startOmpLine >> "END"_tok >> construct<OmpEndWorkshare>("WORKSHARE"_tok))
// OMP WORKSHARE
TYPE_PARSER("WORKSHARE" >>
TYPE_PARSER(construct<OmpEndDo>(maybe(construct<OmpNowait>("NOWAIT"_tok))))
// OMP END SECTIONS [NOWAIT]
-TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
- "SECTIONS"_tok >>
+TYPE_PARSER(startOmpLine >> "END SECTIONS"_tok >>
construct<OmpEndSections>(
- maybe("NOWAIT"_tok >> construct<OmpNowait>()) / endOmpLine))
+ maybe("NOWAIT" >> construct<OmpNowait>()) / endOmpLine))
// OMP SECTIONS
TYPE_PARSER("SECTIONS" >>
Parser<OmpClauseList>{} / endOmpLine, block, Parser<OmpEndSections>{}))
// OMP END PARALLEL SECTIONS [NOWAIT]
-TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
- "PARALLEL SECTIONS"_tok >>
+TYPE_PARSER(startOmpLine >> "END PARALLEL SECTIONS"_tok >>
construct<OmpEndParallelSections>(
- maybe("NOWAIT"_tok >> construct<OmpNowait>()) / endOmpLine))
+ maybe("NOWAIT" >> construct<OmpNowait>()) / endOmpLine))
// OMP PARALLEL SECTIONS
TYPE_PARSER("PARALLEL SECTIONS" >> construct<OpenMPParallelSectionsConstruct>(
block, Parser<OmpEndParallelSections>{}))
TYPE_CONTEXT_PARSER("OpenMP construct"_en_US,
- skipStuffBeforeStatement >> "!$OMP "_sptok >> !"END"_tok >>
+ startOmpLine >>
(construct<OpenMPConstruct>(
indirect(Parser<OpenMPStandaloneConstruct>{})) ||
construct<OpenMPConstruct>(
indirect(Parser<OpenMPCancellationPointConstruct>{})) ||
construct<OpenMPConstruct>(
indirect(Parser<OpenMPFlushConstruct>{})) ||
- "SECTION"_tok >> endOmpLine >>
+ "SECTION" >> endOmpLine >>
construct<OpenMPConstruct>(construct<OmpSection>())))
// END OMP Block directives
-TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
+TYPE_PARSER(startOmpLine >> "END"_tok >>
construct<OmpEndBlockDirective>(indirect(Parser<OmpBlockDirective>{})))
// END OMP Loop directives
-TYPE_PARSER(skipStuffBeforeStatement >> "!$OMP "_sptok >> "END"_tok >>
+TYPE_PARSER(startOmpLine >> "END"_tok >>
(construct<OpenMPEndLoopDirective>(
"DO SIMD" >> indirect(Parser<OmpEndDoSimd>{}) / endOmpLine) ||
construct<OpenMPEndLoopDirective>(