From 817163f9f5ff476aca28bb86e633bf7127052d6c Mon Sep 17 00:00:00 2001 From: peter klausler Date: Tue, 24 Apr 2018 12:15:51 -0700 Subject: [PATCH] [flang] Add constructIf<>(); complete pass over grammar. Original-commit: flang-compiler/f18@4d5b4055bd083b1df7ae2e5456cf52be1109d0a4 Reviewed-on: https://github.com/flang-compiler/f18/pull/69 Tree-same-pre-rewrite: false --- flang/documentation/ParserCombinators.md | 2 + flang/lib/parser/basic-parsers.h | 90 +-- flang/lib/parser/grammar.h | 701 ++++++++++++----------- 3 files changed, 412 insertions(+), 381 deletions(-) diff --git a/flang/documentation/ParserCombinators.md b/flang/documentation/ParserCombinators.md index 18ce7995eee5..2e527208a801 100644 --- a/flang/documentation/ParserCombinators.md +++ b/flang/documentation/ParserCombinators.md @@ -99,6 +99,8 @@ collect the values that they return. * `construct(p1, p2, ...)` matches zero or more parsers in succession, collecting their results and then passing them with move semantics to a constructor for the type T if they all succeed. +* `constructIf(p)` matches p and then returns the default-constructed `T{}`. + The value of p must be the vacant `Success{}` value. * `sourced(p)` matches p, and fills in its `source` data member with the locations of the cooked character stream that it consumed * `applyFunction(f, p1, p2, ...)` matches one or more parsers in succession, diff --git a/flang/lib/parser/basic-parsers.h b/flang/lib/parser/basic-parsers.h index af41fac5da9d..80541982c3d2 100644 --- a/flang/lib/parser/basic-parsers.h +++ b/flang/lib/parser/basic-parsers.h @@ -861,11 +861,31 @@ template constexpr Construct0 construct() { return Construct0{}; } +template struct Construct01 { + using resultType = T; + constexpr explicit Construct01(const PA &parser) : parser_{parser} {} + constexpr Construct01(const Construct01 &) = default; + std::optional Parse(ParseState &state) const { + if (std::optional{parser_.Parse(state)}) { + return {T{}}; + } + return {}; + } + +private: + const PA parser_; +}; + +template +constexpr Construct01 constructIf(const PA &parser) { + return Construct01{parser}; +} + template class Construct1 { public: using resultType = T; - constexpr Construct1(const Construct1 &) = default; constexpr explicit Construct1(const PA &parser) : parser_{parser} {} + constexpr Construct1(const Construct1 &) = default; std::optional Parse(ParseState &state) const { if (auto ax = parser_.Parse(state)) { return {T(std::move(*ax))}; @@ -877,11 +897,16 @@ private: const PA parser_; }; +template +constexpr Construct1 construct(const PA &parser) { + return Construct1{parser}; +} + template class Construct2 { public: using resultType = T; - constexpr Construct2(const Construct2 &) = default; constexpr Construct2(const PA &pa, const PB &pb) : pa_{pa}, pb_{pb} {} + constexpr Construct2(const Construct2 &) = default; std::optional Parse(ParseState &state) const { if (auto ax = pa_.Parse(state)) { if (auto bx = pb_.Parse(state)) { @@ -896,12 +921,17 @@ private: const PB pb_; }; +template +constexpr Construct2 construct(const PA &pa, const PB &pb) { + return Construct2{pa, pb}; +} + template class Construct3 { public: using resultType = T; - constexpr Construct3(const Construct3 &) = default; constexpr Construct3(const PA &pa, const PB &pb, const PC &pc) : pa_{pa}, pb_{pb}, pc_{pc} {} + constexpr Construct3(const Construct3 &) = default; std::optional Parse(ParseState &state) const { if (auto ax = pa_.Parse(state)) { if (auto bx = pb_.Parse(state)) { @@ -919,13 +949,19 @@ private: const PC pc_; }; +template +constexpr Construct3 construct( + const PA &pa, const PB &pb, const PC &pc) { + return Construct3{pa, pb, pc}; +} + template class Construct4 { public: using resultType = T; - constexpr Construct4(const Construct4 &) = default; constexpr Construct4(const PA &pa, const PB &pb, const PC &pc, const PD &pd) : pa_{pa}, pb_{pb}, pc_{pc}, pd_{pd} {} + constexpr Construct4(const Construct4 &) = default; std::optional Parse(ParseState &state) const { if (auto ax = pa_.Parse(state)) { if (auto bx = pb_.Parse(state)) { @@ -947,15 +983,21 @@ private: const PD pd_; }; +template +constexpr Construct4 construct( + const PA &pa, const PB &pb, const PC &pc, const PD &pd) { + return Construct4{pa, pb, pc, pd}; +} + template class Construct5 { public: using resultType = T; - constexpr Construct5(const Construct5 &) = default; constexpr Construct5( const PA &pa, const PB &pb, const PC &pc, const PD &pd, const PE &pe) : pa_{pa}, pb_{pb}, pc_{pc}, pd_{pd}, pe_{pe} {} + constexpr Construct5(const Construct5 &) = default; std::optional Parse(ParseState &state) const { if (auto ax = pa_.Parse(state)) { if (auto bx = pb_.Parse(state)) { @@ -980,15 +1022,22 @@ private: const PE pe_; }; +template +constexpr Construct5 construct( + const PA &pa, const PB &pb, const PC &pc, const PD &pd, const PE &pe) { + return Construct5{pa, pb, pc, pd, pe}; +} + template class Construct6 { public: using resultType = T; - constexpr Construct6(const Construct6 &) = default; constexpr Construct6(const PA &pa, const PB &pb, const PC &pc, const PD &pd, const PE &pe, const PF &pf) : pa_{pa}, pb_{pb}, pc_{pc}, pd_{pd}, pe_{pe}, pf_{pf} {} + constexpr Construct6(const Construct6 &) = default; std::optional Parse(ParseState &state) const { if (auto ax = pa_.Parse(state)) { if (auto bx = pb_.Parse(state)) { @@ -1016,35 +1065,6 @@ private: const PF pf_; }; -template -constexpr Construct1 construct(const PA &parser) { - return Construct1{parser}; -} - -template -constexpr Construct2 construct(const PA &pa, const PB &pb) { - return Construct2{pa, pb}; -} - -template -constexpr Construct3 construct( - const PA &pa, const PB &pb, const PC &pc) { - return Construct3{pa, pb, pc}; -} - -template -constexpr Construct4 construct( - const PA &pa, const PB &pb, const PC &pc, const PD &pd) { - return Construct4{pa, pb, pc, pd}; -} - -template -constexpr Construct5 construct( - const PA &pa, const PB &pb, const PC &pc, const PD &pd, const PE &pe) { - return Construct5{pa, pb, pc, pd, pe}; -} - template constexpr Construct6 construct(const PA &pa, diff --git a/flang/lib/parser/grammar.h b/flang/lib/parser/grammar.h index 2394c4cc595c..490fdd4d9837 100644 --- a/flang/lib/parser/grammar.h +++ b/flang/lib/parser/grammar.h @@ -279,14 +279,14 @@ TYPE_PARSER(construct(indirect(Parser{})) || construct(indirect(Parser{})) || construct(indirect(Parser{})) || construct(indirect(Parser{})) || - "CONTINUE" >> construct(construct()) || + construct(constructIf("CONTINUE"_tok)) || construct(indirect(Parser{})) || construct(indirect(Parser{})) || construct(indirect(Parser{})) || construct(indirect(Parser{})) || construct(indirect(Parser{})) || construct(indirect(Parser{})) || - "FAIL IMAGE"_sptok >> construct(construct()) || + construct(constructIf("FAIL IMAGE"_sptok)) || construct(indirect(Parser{})) || construct(indirect(Parser{})) || construct(indirect(Parser{})) || @@ -388,10 +388,10 @@ TYPE_PARSER(construct(Parser{}) || TYPE_PARSER(construct(name)) // R701 type-param-value -> scalar-int-expr | * | : -constexpr auto star = "*" >> construct(); +constexpr auto star = constructIf("*"_tok); TYPE_PARSER(construct(scalarIntExpr) || construct(star) || - construct(":" >> construct())) + construct(constructIf(":"_tok))) // R702 type-spec -> intrinsic-type-spec | derived-type-spec // N.B. This type-spec production is one of two instances in the Fortran @@ -417,17 +417,15 @@ TYPE_CONTEXT_PARSER("declaration type spec"_en_US, (parenthesized(construct(intrinsicTypeSpec)) || parenthesized(construct( construct(derivedTypeSpec))) || - "( * )" >> construct( - construct())) || - "CLASS" >> - parenthesized( construct( - construct(derivedTypeSpec)) || - "*" >> construct( + "( * )" >> construct())) || + "CLASS" >> parenthesized(construct( + construct( + derivedTypeSpec)) || + construct("*" >> construct())) || - extension("RECORD /" >> - construct( - construct(name / "/")))) + extension(construct( + construct("RECORD /" >> name / "/")))) // R704 intrinsic-type-spec -> // integer-type-spec | REAL [kind-selector] | DOUBLE PRECISION | @@ -436,30 +434,23 @@ TYPE_CONTEXT_PARSER("declaration type spec"_en_US, // Extensions: DOUBLE COMPLEX, NCHARACTER, BYTE TYPE_CONTEXT_PARSER("intrinsic type spec"_en_US, construct(integerTypeSpec) || - "REAL" >> - construct( - construct(maybe(kindSelector))) || - "DOUBLE PRECISION" >> - construct( - construct()) || - "COMPLEX" >> - construct( - construct(maybe(kindSelector))) || - "CHARACTER" >> construct( - construct( - maybe(Parser{}))) || - "LOGICAL" >> - construct( - construct(maybe(kindSelector))) || - "DOUBLE COMPLEX" >> - construct( - extension(construct())) || - "NCHARACTER" >> construct( - extension(construct( - maybe(Parser{})))) || - extension( - "BYTE" >> construct(construct( - construct>(pure(1)))))) + construct(construct( + "REAL" >> maybe(kindSelector))) || + construct("DOUBLE PRECISION" >> + construct()) || + construct(construct( + "COMPLEX" >> maybe(kindSelector))) || + construct(construct( + "CHARACTER" >> maybe(Parser{}))) || + construct(construct( + "LOGICAL" >> maybe(kindSelector))) || + construct("DOUBLE COMPLEX" >> + extension(construct())) || + construct( + extension(construct( + "NCHARACTER" >> maybe(Parser{})))) || + extension(construct(construct( + "BYTE" >> construct>(pure(1)))))) // R705 integer-type-spec -> INTEGER [kind-selector] TYPE_PARSER(construct("INTEGER" >> maybe(kindSelector))) @@ -582,8 +573,8 @@ TYPE_CONTEXT_PARSER("CHARACTER literal constant"_en_US, construct(construct>(), space >> charLiteralConstantWithoutKind) || construct( - "NC" >> construct>( - construct(construct())), + construct>( + construct(constructIf("NC"_tok))), charLiteralConstantWithoutKind)) // deprecated: Hollerith literals @@ -625,8 +616,9 @@ TYPE_CONTEXT_PARSER("TYPE statement"_en_US, // R728 type-attr-spec -> // ABSTRACT | access-spec | BIND(C) | EXTENDS ( parent-type-name ) -TYPE_PARSER(construct("ABSTRACT" >> construct()) || - construct("BIND ( C )" >> construct()) || +TYPE_PARSER(construct(constructIf("ABSTRACT"_tok)) || + construct( + constructIf("BIND ( C )"_tok)) || construct( construct("EXTENDS" >> parenthesized(name))) || construct(accessSpec)) @@ -643,7 +635,7 @@ TYPE_PARSER(construct( recovery("END TYPE" >> maybe(name), endStmtErrorRecovery))) // R731 sequence-stmt -> SEQUENCE -TYPE_PARSER("SEQUENCE" >> construct()) +TYPE_PARSER(constructIf("SEQUENCE"_tok)) // R732 type-param-def-stmt -> // integer-type-spec , type-param-attr-spec :: type-param-decl-list @@ -676,9 +668,9 @@ TYPE_PARSER(construct(declarationTypeSpec, // access-spec | ALLOCATABLE | // CODIMENSION lbracket coarray-spec rbracket | // CONTIGUOUS | DIMENSION ( component-array-spec ) | POINTER -constexpr auto allocatable = "ALLOCATABLE" >> construct(); -constexpr auto contiguous = "CONTIGUOUS" >> construct(); -constexpr auto pointer = "POINTER" >> construct(); +constexpr auto allocatable = constructIf("ALLOCATABLE"_tok); +constexpr auto contiguous = constructIf("CONTIGUOUS"_tok); +constexpr auto pointer = constructIf("POINTER"_tok); TYPE_PARSER(construct(accessSpec) || construct(allocatable) || construct("CODIMENSION" >> coarraySpec) || @@ -712,7 +704,7 @@ TYPE_CONTEXT_PARSER("PROCEDURE component definition statement"_en_US, // R742 proc-component-attr-spec -> // access-spec | NOPASS | PASS [(arg-name)] | POINTER -constexpr auto noPass = "NOPASS" >> construct(); +constexpr auto noPass = constructIf("NOPASS"_tok); constexpr auto pass = construct("PASS" >> maybe(parenthesized(name))); TYPE_PARSER(construct(accessSpec) || construct(noPass) || @@ -730,12 +722,12 @@ constexpr auto initialDataTarget = indirect(designator); TYPE_PARSER(construct("=>" >> nullInit) || construct("=>" >> initialDataTarget) || construct("=" >> constantExpr) || - extension(construct("/" >> - nonemptyList(indirect(Parser{})) / "/"))) + extension(construct( + "/" >> nonemptyList(indirect(Parser{})) / "/"))) // R745 private-components-stmt -> PRIVATE // R747 binding-private-stmt -> PRIVATE -TYPE_PARSER("PRIVATE" >> construct()) +TYPE_PARSER(constructIf("PRIVATE"_tok)) // R746 type-bound-procedure-part -> // contains-stmt [binding-private-stmt] [type-bound-proc-binding]... @@ -774,18 +766,20 @@ TYPE_PARSER(construct(name, maybe("=>" >> name))) // GENERIC [, access-spec] :: generic-spec => binding-name-list TYPE_CONTEXT_PARSER("type bound GENERIC statement"_en_US, construct("GENERIC" >> maybe("," >> accessSpec), - "::" >> indirect(genericSpec), "=>" >> nonemptyList(name))) + "::" >> indirect(genericSpec), "=>" >> nonemptyList(name))) // R752 bind-attr -> // access-spec | DEFERRED | NON_OVERRIDABLE | NOPASS | PASS [(arg-name)] TYPE_PARSER(construct(accessSpec) || - construct("DEFERRED" >> construct()) || - construct("NON_OVERRIDABLE" >> construct()) || + construct(constructIf("DEFERRED"_tok)) || + construct( + constructIf("NON_OVERRIDABLE"_tok)) || construct(noPass) || construct(pass)) // R753 final-procedure-stmt -> FINAL [::] final-subroutine-name-list TYPE_CONTEXT_PARSER("FINAL statement"_en_US, - construct("FINAL" >> maybe("::"_tok) >> nonemptyList(name))) + construct( + "FINAL" >> maybe("::"_tok) >> nonemptyList(name))) // R754 derived-type-spec -> type-name [(type-param-spec-list)] TYPE_PARSER(construct( @@ -822,7 +816,7 @@ TYPE_CONTEXT_PARSER("enum definition"_en_US, statement(Parser{}))) // R760 enum-def-stmt -> ENUM, BIND(C) -TYPE_PARSER("ENUM , BIND ( C )" >> construct()) +TYPE_PARSER(constructIf("ENUM , BIND ( C )"_tok)) // R761 enumerator-def-stmt -> ENUMERATOR [::] enumerator-list TYPE_CONTEXT_PARSER("ENUMERATOR statement"_en_US, @@ -902,25 +896,25 @@ TYPE_PARSER(construct(declarationTypeSpec, // DIMENSION ( array-spec ) | EXTERNAL | INTENT ( intent-spec ) | // INTRINSIC | language-binding-spec | OPTIONAL | PARAMETER | POINTER | // PROTECTED | SAVE | TARGET | VALUE | VOLATILE -constexpr auto optional = "OPTIONAL" >> construct(); -constexpr auto protectedAttr = "PROTECTED" >> construct(); -constexpr auto save = "SAVE" >> construct(); +constexpr auto optional = constructIf("OPTIONAL"_tok); +constexpr auto protectedAttr = constructIf("PROTECTED"_tok); +constexpr auto save = constructIf("SAVE"_tok); TYPE_PARSER(construct(accessSpec) || construct(allocatable) || - construct("ASYNCHRONOUS" >> construct()) || + construct(constructIf("ASYNCHRONOUS"_tok)) || construct("CODIMENSION" >> coarraySpec) || construct(contiguous) || construct("DIMENSION" >> arraySpec) || - construct("EXTERNAL" >> construct()) || + construct(constructIf("EXTERNAL"_tok)) || construct("INTENT" >> parenthesized(intentSpec)) || - construct("INTRINSIC" >> construct()) || + construct(constructIf("INTRINSIC"_tok)) || construct(languageBindingSpec) || construct(optional) || - construct("PARAMETER" >> construct()) || + construct(constructIf("PARAMETER"_tok)) || construct(pointer) || construct(protectedAttr) || construct(save) || - construct("TARGET" >> construct()) || - construct("VALUE" >> construct()) || - construct("VOLATILE" >> construct())) + construct(constructIf("TARGET"_tok)) || + construct(constructIf("VALUE"_tok)) || + construct(constructIf("VOLATILE"_tok))) // R804 object-name -> name constexpr auto objectName = name; @@ -934,7 +928,7 @@ TYPE_PARSER(construct(objectName, maybe(arraySpec), // R806 null-init -> function-reference // TODO: confirm in semantics that NULL still intrinsic in this scope -TYPE_PARSER("NULL ( )" >> construct() / !"("_tok) +TYPE_PARSER(constructIf("NULL ( )"_tok) / !"("_tok) // R807 access-spec -> PUBLIC | PRIVATE TYPE_PARSER(construct("PUBLIC" >> pure(AccessSpec::Kind::Public)) || @@ -1010,7 +1004,7 @@ TYPE_PARSER(construct( TYPE_PARSER(construct(nonemptyList(assumedImpliedSpec))) // R825 assumed-rank-spec -> .. -TYPE_PARSER(".." >> construct()) +TYPE_PARSER(constructIf(".."_tok)) // R826 intent-spec -> IN | OUT | INOUT TYPE_PARSER(construct("IN OUT" >> pure(IntentSpec::Intent::InOut) || @@ -1026,8 +1020,8 @@ TYPE_PARSER(construct(indirect(genericSpec)) || construct(name)) // initially ambiguous with genericSpec // R829 allocatable-stmt -> ALLOCATABLE [::] allocatable-decl-list -TYPE_PARSER("ALLOCATABLE" >> maybe("::"_tok) >> - construct(nonemptyList(Parser{}))) +TYPE_PARSER(construct( + "ALLOCATABLE" >> maybe("::"_tok) >> nonemptyList(Parser{}))) // R830 allocatable-decl -> // object-name [( array-spec )] [lbracket coarray-spec rbracket] @@ -1037,8 +1031,8 @@ TYPE_PARSER( construct(objectName, maybe(arraySpec), maybe(coarraySpec))) // R831 asynchronous-stmt -> ASYNCHRONOUS [::] object-name-list -TYPE_PARSER("ASYNCHRONOUS" >> maybe("::"_tok) >> - construct(nonemptyList(objectName))) +TYPE_PARSER(construct( + "ASYNCHRONOUS" >> maybe("::"_tok) >> nonemptyList(objectName))) // R832 bind-stmt -> language-binding-spec [::] bind-entity-list TYPE_PARSER(construct( @@ -1049,19 +1043,20 @@ TYPE_PARSER(construct(pure(BindEntity::Kind::Object), name) || construct("/" >> pure(BindEntity::Kind::Common), name / "/")) // R834 codimension-stmt -> CODIMENSION [::] codimension-decl-list -TYPE_PARSER("CODIMENSION" >> maybe("::"_tok) >> - construct(nonemptyList(Parser{}))) +TYPE_PARSER(construct("CODIMENSION" >> maybe("::"_tok) >> + nonemptyList(Parser{}))) // R835 codimension-decl -> coarray-name lbracket coarray-spec rbracket TYPE_PARSER(construct(name, coarraySpec)) // R836 contiguous-stmt -> CONTIGUOUS [::] object-name-list -TYPE_PARSER("CONTIGUOUS" >> maybe("::"_tok) >> - construct(nonemptyList(objectName))) +TYPE_PARSER(construct( + "CONTIGUOUS" >> maybe("::"_tok) >> nonemptyList(objectName))) // R837 data-stmt -> DATA data-stmt-set [[,] data-stmt-set]... TYPE_CONTEXT_PARSER("DATA statement"_en_US, - construct("DATA" >> nonemptySeparated(Parser{}, maybe(","_tok)))) + construct( + "DATA" >> nonemptySeparated(Parser{}, maybe(","_tok)))) // R838 data-stmt-set -> data-stmt-object-list / data-stmt-value-list / TYPE_PARSER(construct(nonemptyList(Parser{}), @@ -1122,16 +1117,18 @@ TYPE_PARSER(construct(scalar(Parser{})) || // DIMENSION [::] array-name ( array-spec ) // [, array-name ( array-spec )]... TYPE_CONTEXT_PARSER("DIMENSION statement"_en_US, - "DIMENSION" >> maybe("::"_tok) >> - construct(nonemptyList( - construct(name, arraySpec)))) + construct("DIMENSION" >> maybe("::"_tok) >> + nonemptyList(construct(name, arraySpec)))) // R849 intent-stmt -> INTENT ( intent-spec ) [::] dummy-arg-name-list TYPE_CONTEXT_PARSER("INTENT statement"_en_US, - construct("INTENT" >> parenthesized(intentSpec) / maybe("::"_tok), nonemptyList(name))) + construct( + "INTENT" >> parenthesized(intentSpec) / maybe("::"_tok), + nonemptyList(name))) // R850 optional-stmt -> OPTIONAL [::] dummy-arg-name-list -TYPE_PARSER(construct("OPTIONAL" >> maybe("::"_tok) >> nonemptyList(name))) +TYPE_PARSER(construct( + "OPTIONAL" >> maybe("::"_tok) >> nonemptyList(name))) // R851 parameter-stmt -> PARAMETER ( named-constant-def-list ) // Legacy extension: omitted parentheses, no implicit typing from names @@ -1146,8 +1143,8 @@ TYPE_CONTEXT_PARSER("old style PARAMETER statement"_en_US, TYPE_PARSER(construct(namedConstant, "=" >> constantExpr)) // R853 pointer-stmt -> POINTER [::] pointer-decl-list -TYPE_PARSER( - construct("POINTER" >> maybe("::"_tok) >> nonemptyList(Parser{}))) +TYPE_PARSER(construct( + "POINTER" >> maybe("::"_tok) >> nonemptyList(Parser{}))) // R854 pointer-decl -> // object-name [( deferred-shape-spec-list )] | proc-entity-name @@ -1155,11 +1152,12 @@ TYPE_PARSER( construct(name, maybe(parenthesized(deferredShapeSpecList)))) // R855 protected-stmt -> PROTECTED [::] entity-name-list -TYPE_PARSER(construct("PROTECTED" >> maybe("::"_tok) >> nonemptyList(name))) +TYPE_PARSER(construct( + "PROTECTED" >> maybe("::"_tok) >> nonemptyList(name))) // R856 save-stmt -> SAVE [[::] saved-entity-list] -TYPE_PARSER(construct("SAVE" >> defaulted(maybe("::"_tok) >> - nonemptyList(Parser{})))) +TYPE_PARSER(construct("SAVE" >> + defaulted(maybe("::"_tok) >> nonemptyList(Parser{})))) // R857 saved-entity -> object-name | proc-pointer-name | / common-block-name / // R858 proc-pointer-name -> name @@ -1168,13 +1166,16 @@ TYPE_PARSER(construct(pure(SavedEntity::Kind::Object), name) || construct("/" >> pure(SavedEntity::Kind::Common), name / "/")) // R859 target-stmt -> TARGET [::] target-decl-list -TYPE_PARSER(construct("TARGET" >> maybe("::"_tok) >> nonemptyList(Parser{}))) +TYPE_PARSER(construct( + "TARGET" >> maybe("::"_tok) >> nonemptyList(Parser{}))) // R861 value-stmt -> VALUE [::] dummy-arg-name-list -TYPE_PARSER(construct("VALUE" >> maybe("::"_tok) >> nonemptyList(name))) +TYPE_PARSER( + construct("VALUE" >> maybe("::"_tok) >> nonemptyList(name))) // R862 volatile-stmt -> VOLATILE [::] object-name-list -TYPE_PARSER(construct("VOLATILE" >> maybe("::"_tok) >> nonemptyList(objectName))) +TYPE_PARSER(construct( + "VOLATILE" >> maybe("::"_tok) >> nonemptyList(objectName))) // R866 implicit-name-spec -> EXTERNAL | TYPE constexpr auto implicitNameSpec = "EXTERNAL" >> @@ -1201,16 +1202,15 @@ constexpr auto noKindSelector = construct>(); constexpr auto implicitSpecDeclarationTypeSpecRetry = construct( construct( - "INTEGER" >> construct(noKindSelector)) || + construct("INTEGER" >> noKindSelector)) || construct( - "REAL" >> construct(noKindSelector)) || - construct("COMPLEX" >> - construct(noKindSelector)) || - construct( - "CHARACTER" >> construct( - construct>())) || - construct("LOGICAL" >> - construct(noKindSelector))); + construct("REAL" >> noKindSelector)) || + construct(construct( + "COMPLEX" >> noKindSelector)) || + construct(construct( + "CHARACTER" >> construct>())) || + construct(construct( + "LOGICAL" >> noKindSelector))); TYPE_PARSER(construct(declarationTypeSpec, parenthesized(nonemptyList(Parser{}))) || @@ -1230,8 +1230,7 @@ TYPE_CONTEXT_PARSER("IMPORT statement"_en_US, nonemptyList(name)) || construct( "IMPORT , NONE" >> pure(ImportStmt::Kind::None)) || - construct( - "IMPORT , ALL" >> pure(ImportStmt::Kind::All)) || + construct("IMPORT , ALL" >> pure(ImportStmt::Kind::All)) || construct( "IMPORT" >> maybe("::"_tok) >> optionalList(name))) @@ -1257,9 +1256,9 @@ TYPE_PARSER(construct(indirect(designator))) // [[,] / [common-block-name] / common-block-object-list]... TYPE_PARSER(construct("COMMON" >> maybe("/" >> maybe(name) / "/"), nonemptyList(Parser{}), - many(maybe(","_tok) >> - construct("/" >> maybe(name) / "/", - nonemptyList(Parser{}))))) + many( + maybe(","_tok) >> construct("/" >> maybe(name) / "/", + nonemptyList(Parser{}))))) // R874 common-block-object -> variable-name [( array-spec )] TYPE_PARSER(construct(name, maybe(arraySpec))) @@ -1503,8 +1502,7 @@ constexpr auto primary = instrumented("primary"_en_US, constexpr auto level1Expr = construct(construct(definedOpName, primary)) || primary || - extension( - construct(construct("+" >> primary))) || + extension(construct(construct("+" >> primary))) || extension(construct(construct("-" >> primary))); // R1004 mult-operand -> level-1-expr [power-op mult-operand] @@ -2012,7 +2010,7 @@ TYPE_PARSER(construct(construct( construct(construct( "SHARED" >> parenthesized(nonemptyList(name)))) || construct( - "DEFAULT ( NONE )" >> construct())) + constructIf("DEFAULT ( NONE )"_tok))) // R1123 loop-control -> // [,] do-variable = scalar-int-expr , scalar-int-expr @@ -2039,7 +2037,8 @@ TYPE_CONTEXT_PARSER("nonlabel DO statement"_en_US, construct(maybe(name / ":"), "DO" >> maybe(loopControl))) // R1132 end-do-stmt -> END DO [do-construct-name] -TYPE_CONTEXT_PARSER("END DO statement"_en_US, construct("END DO" >> maybe(name))) +TYPE_CONTEXT_PARSER( + "END DO statement"_en_US, construct("END DO" >> maybe(name))) // R1133 cycle-stmt -> CYCLE [do-construct-name] TYPE_CONTEXT_PARSER( @@ -2092,10 +2091,10 @@ TYPE_CONTEXT_PARSER("CASE statement"_en_US, // R1143 end-select-stmt -> END SELECT [case-construct-name] // R1151 end-select-rank-stmt -> END SELECT [select-construct-name] // R1155 end-select-type-stmt -> END SELECT [select-construct-name] -TYPE_PARSER("END SELECT" >> construct(maybe(name))) +TYPE_PARSER(construct("END SELECT" >> maybe(name))) // R1145 case-selector -> ( case-value-range-list ) | DEFAULT -constexpr auto defaultKeyword = "DEFAULT" >> construct(); +constexpr auto defaultKeyword = constructIf("DEFAULT"_tok); TYPE_PARSER(parenthesized(construct( nonemptyList(Parser{}))) || construct(defaultKeyword)) @@ -2165,7 +2164,7 @@ TYPE_CONTEXT_PARSER("type guard statement"_en_US, parenthesized(construct(typeSpec)) || "CLASS IS"_sptok >> parenthesized(construct( derivedTypeSpec)) || - "CLASS" >> construct(defaultKeyword), + construct("CLASS" >> defaultKeyword), maybe(name))) // R1156 exit-stmt -> EXIT [construct-name] @@ -2219,15 +2218,13 @@ TYPE_CONTEXT_PARSER("SYNC TEAM statement"_en_US, // R1170 event-post-stmt -> EVENT POST ( event-variable [, sync-stat-list] ) // R1171 event-variable -> scalar-variable TYPE_CONTEXT_PARSER("EVENT POST statement"_en_US, - construct( - "EVENT POST"_sptok >> "("_tok >> scalar(variable), + construct("EVENT POST"_sptok >> "("_tok >> scalar(variable), defaulted("," >> nonemptyList(statOrErrmsg)) / ")")) // R1172 event-wait-stmt -> // EVENT WAIT ( event-variable [, event-wait-spec-list] ) TYPE_CONTEXT_PARSER("EVENT WAIT statement"_en_US, - construct( - "EVENT WAIT"_sptok >> "("_tok >> scalar(variable), + construct("EVENT WAIT"_sptok >> "("_tok >> scalar(variable), defaulted("," >> nonemptyList(Parser{})) / ")")) @@ -2261,8 +2258,8 @@ TYPE_CONTEXT_PARSER("LOCK statement"_en_US, defaulted("," >> nonemptyList(Parser{})) / ")")) // R1179 lock-stat -> ACQUIRED_LOCK = scalar-logical-variable | sync-stat -TYPE_PARSER(construct( - "ACQUIRED_LOCK =" >> scalarLogicalVariable) || +TYPE_PARSER( + construct("ACQUIRED_LOCK =" >> scalarLogicalVariable) || construct(statOrErrmsg)) // R1180 unlock-stmt -> UNLOCK ( lock-variable [, sync-stat-list] ) @@ -2280,8 +2277,7 @@ TYPE_PARSER(construct(scalarIntExpr / !"="_tok)) // R1204 open-stmt -> OPEN ( connect-spec-list ) TYPE_CONTEXT_PARSER("OPEN statement"_en_US, - construct( - "OPEN (" >> nonemptyList(Parser{}) / ")")) + construct("OPEN (" >> nonemptyList(Parser{}) / ")")) // R1206 file-name-expr -> scalar-default-char-expr constexpr auto fileNameExpr = scalarDefaultCharExpr; @@ -2386,22 +2382,21 @@ constexpr auto inputItemList = optionalList(inputItem); TYPE_CONTEXT_PARSER("READ statement"_en_US, - "READ" >> - ("(" >> construct(construct>( - maybe("UNIT ="_tok) >> ioUnit), - "," >> construct>(format), - defaulted("," >> nonemptyList(ioControlSpec)) / ")", - inputItemList) || - "(" >> construct(construct>(ioUnit), - construct>(), - defaulted("," >> nonemptyList(ioControlSpec)) / ")", - inputItemList) || - construct(construct>(), - construct>(), - parenthesized(nonemptyList(ioControlSpec)), inputItemList) || - construct(construct>(), - construct>(format), - construct>(), many("," >> inputItem)))) + construct("READ (" >> + construct>(maybe("UNIT ="_tok) >> ioUnit), + "," >> construct>(format), + defaulted("," >> nonemptyList(ioControlSpec)) / ")", inputItemList) || + construct( + "READ (" >> construct>(ioUnit), + construct>(), + defaulted("," >> nonemptyList(ioControlSpec)) / ")", + inputItemList) || + construct("READ" >> construct>(), + construct>(), + parenthesized(nonemptyList(ioControlSpec)), inputItemList) || + construct("READ" >> construct>(), + construct>(format), + construct>(), many("," >> inputItem))) // R1214 id-variable -> scalar-int-variable constexpr auto idVariable = construct(scalarIntVariable); @@ -2420,45 +2415,50 @@ constexpr auto idVariable = construct(scalarIntVariable); // SIZE = scalar-int-variable constexpr auto endLabel = construct(label); constexpr auto eorLabel = construct(label); -TYPE_PARSER("UNIT =" >> construct(ioUnit) || - "FMT =" >> construct(format) || - "NML =" >> construct(name) || - "ADVANCE =" >> construct(construct( - pure(IoControlSpec::CharExpr::Kind::Advance), - scalarDefaultCharExpr)) || - "ASYNCHRONOUS =" >> - construct(construct( - scalarDefaultCharConstantExpr)) || - "BLANK =" >> construct(construct( - pure(IoControlSpec::CharExpr::Kind::Blank), - scalarDefaultCharExpr)) || - "DECIMAL =" >> construct(construct( - pure(IoControlSpec::CharExpr::Kind::Decimal), - scalarDefaultCharExpr)) || - "DELIM =" >> construct(construct( - pure(IoControlSpec::CharExpr::Kind::Delim), - scalarDefaultCharExpr)) || - "END =" >> construct(endLabel) || - "EOR =" >> construct(eorLabel) || - "ERR =" >> construct(errLabel) || - "ID =" >> construct(idVariable) || - "IOMSG = " >> construct(msgVariable) || - "IOSTAT = " >> construct(statVariable) || - "PAD =" >> - construct(construct( +TYPE_PARSER(construct("UNIT =" >> ioUnit) || + construct("FMT =" >> format) || + construct("NML =" >> name) || + construct( + "ADVANCE =" >> construct( + pure(IoControlSpec::CharExpr::Kind::Advance), + scalarDefaultCharExpr)) || + construct(construct( + "ASYNCHRONOUS =" >> scalarDefaultCharConstantExpr)) || + construct( + "BLANK =" >> construct( + pure(IoControlSpec::CharExpr::Kind::Blank), + scalarDefaultCharExpr)) || + construct( + "DECIMAL =" >> construct( + pure(IoControlSpec::CharExpr::Kind::Decimal), + scalarDefaultCharExpr)) || + construct( + "DELIM =" >> construct( + pure(IoControlSpec::CharExpr::Kind::Delim), + scalarDefaultCharExpr)) || + construct("END =" >> endLabel) || + construct("EOR =" >> eorLabel) || + construct("ERR =" >> errLabel) || + construct("ID =" >> idVariable) || + construct("IOMSG = " >> msgVariable) || + construct("IOSTAT = " >> statVariable) || + construct("PAD =" >> + construct( pure(IoControlSpec::CharExpr::Kind::Pad), scalarDefaultCharExpr)) || - "POS =" >> construct( - construct(scalarIntExpr)) || - "REC =" >> construct( - construct(scalarIntExpr)) || - "ROUND =" >> construct(construct( - pure(IoControlSpec::CharExpr::Kind::Round), - scalarDefaultCharExpr)) || - "SIGN =" >> construct(construct( - pure(IoControlSpec::CharExpr::Kind::Sign), - scalarDefaultCharExpr)) || - "SIZE =" >> construct( - construct(scalarIntVariable))) + construct( + "POS =" >> construct(scalarIntExpr)) || + construct( + "REC =" >> construct(scalarIntExpr)) || + construct( + "ROUND =" >> construct( + pure(IoControlSpec::CharExpr::Kind::Round), + scalarDefaultCharExpr)) || + construct( + "SIGN =" >> construct( + pure(IoControlSpec::CharExpr::Kind::Sign), + scalarDefaultCharExpr)) || + construct( + "SIZE =" >> construct(scalarIntVariable))) // R1211 write-stmt -> WRITE ( io-control-spec-list ) [output-item-list] constexpr auto outputItemList = @@ -2466,25 +2466,23 @@ constexpr auto outputItemList = optionalList(outputItem); TYPE_CONTEXT_PARSER("WRITE statement"_en_US, - "WRITE" >> - (construct("(" >> construct>( - maybe("UNIT ="_tok) >> ioUnit), - "," >> construct>(format), - defaulted("," >> nonemptyList(ioControlSpec)) / ")", - outputItemList) || - construct( - "(" >> construct>(ioUnit), - construct>(), - defaulted("," >> nonemptyList(ioControlSpec)) / ")", - outputItemList) || - construct(construct>(), - construct>(), - parenthesized(nonemptyList(ioControlSpec)), outputItemList))) + construct("WRITE (" >> + construct>(maybe("UNIT ="_tok) >> ioUnit), + "," >> construct>(format), + defaulted("," >> nonemptyList(ioControlSpec)) / ")", outputItemList) || + construct( + "WRITE (" >> construct>(ioUnit), + construct>(), + defaulted("," >> nonemptyList(ioControlSpec)) / ")", + outputItemList) || + construct("WRITE" >> construct>(), + construct>(), + parenthesized(nonemptyList(ioControlSpec)), outputItemList)) // R1212 print-stmt PRINT format [, output-item-list] TYPE_CONTEXT_PARSER("PRINT statement"_en_US, - "PRINT" >> construct( - format, defaulted("," >> nonemptyList(outputItem)))) + construct( + "PRINT" >> format, defaulted("," >> nonemptyList(outputItem)))) // R1215 format -> default-char-expr | label | * TYPE_PARSER(construct(defaultCharExpr / !"="_tok) || @@ -2524,13 +2522,13 @@ TYPE_CONTEXT_PARSER("WAIT statement"_en_US, // IOSTAT = scalar-int-variable constexpr auto idExpr = construct(scalarIntExpr); -TYPE_PARSER(maybe("UNIT ="_tok) >> construct(fileUnitNumber) || - "END =" >> construct(endLabel) || - "EOR =" >> construct(eorLabel) || - "ERR =" >> construct(errLabel) || - "ID =" >> construct(idExpr) || - "IOMSG =" >> construct(msgVariable) || - "IOSTAT =" >> construct(statVariable)) +TYPE_PARSER(construct(maybe("UNIT ="_tok) >> fileUnitNumber) || + construct("END =" >> endLabel) || + construct("EOR =" >> eorLabel) || + construct("ERR =" >> errLabel) || + construct("ID =" >> idExpr) || + construct("IOMSG =" >> msgVariable) || + construct("IOSTAT =" >> statVariable)) template std::list singletonList(A &&x) { std::list result; @@ -2564,10 +2562,10 @@ TYPE_CONTEXT_PARSER("REWIND statement"_en_US, // [UNIT =] file-unit-number | IOSTAT = scalar-int-variable | // IOMSG = iomsg-variable | ERR = label TYPE_PARSER( - maybe("UNIT ="_tok) >> construct(fileUnitNumber) || - "IOMSG =" >> construct(msgVariable) || - "IOSTAT =" >> construct(statVariable) || - "ERR =" >> construct(errLabel)) + construct(maybe("UNIT ="_tok) >> fileUnitNumber) || + construct("IOMSG =" >> msgVariable) || + construct("IOSTAT =" >> statVariable) || + construct("ERR =" >> errLabel)) // R1228 flush-stmt -> FLUSH file-unit-number | FLUSH ( flush-spec-list ) TYPE_CONTEXT_PARSER("FLUSH statement"_en_US, @@ -2603,109 +2601,122 @@ TYPE_CONTEXT_PARSER("FLUSH statement"_en_US, // STREAM = scalar-default-char-variable | // STATUS = scalar-default-char-variable | // WRITE = scalar-default-char-variable -TYPE_PARSER(maybe("UNIT ="_tok) >> construct(fileUnitNumber) || - "FILE =" >> construct(fileNameExpr) || - "ACCESS =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Access), - scalarDefaultCharVariable)) || - "ACTION =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Action), - scalarDefaultCharVariable)) || - "ASYNCHRONOUS =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Asynchronous), - scalarDefaultCharVariable)) || - "BLANK =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Blank), - scalarDefaultCharVariable)) || - "DECIMAL =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Decimal), - scalarDefaultCharVariable)) || - "DELIM =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Delim), - scalarDefaultCharVariable)) || - "DIRECT =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Direct), - scalarDefaultCharVariable)) || - "ENCODING =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Encoding), - scalarDefaultCharVariable)) || - "ERR =" >> construct(errLabel) || - "EXIST =" >> - construct(construct( - pure(InquireSpec::LogVar::Kind::Exist), scalarLogicalVariable)) || - "FORM =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Form), - scalarDefaultCharVariable)) || - "FORMATTED =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Formatted), - scalarDefaultCharVariable)) || - "ID =" >> construct(idExpr) || - "IOMSG =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Iomsg), - scalarDefaultCharVariable)) || - "IOSTAT =" >> construct(construct( - pure(InquireSpec::IntVar::Kind::Iostat), - scalar(integer(variable)))) || - "NAME =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Name), - scalarDefaultCharVariable)) || - "NAMED =" >> - construct(construct( - pure(InquireSpec::LogVar::Kind::Named), scalarLogicalVariable)) || - "NEXTREC =" >> construct(construct( - pure(InquireSpec::IntVar::Kind::Nextrec), - scalar(integer(variable)))) || - "NUMBER =" >> construct(construct( - pure(InquireSpec::IntVar::Kind::Number), - scalar(integer(variable)))) || - "OPENED =" >> - construct(construct( - pure(InquireSpec::LogVar::Kind::Opened), scalarLogicalVariable)) || - "PAD =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Pad), - scalarDefaultCharVariable)) || - "PENDING =" >> - construct(construct( - pure(InquireSpec::LogVar::Kind::Pending), scalarLogicalVariable)) || - "POS =" >> - construct(construct( - pure(InquireSpec::IntVar::Kind::Pos), scalar(integer(variable)))) || - "POSITION =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Position), - scalarDefaultCharVariable)) || - "READ =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Read), - scalarDefaultCharVariable)) || - "READWRITE =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Readwrite), - scalarDefaultCharVariable)) || - "RECL =" >> construct(construct( - pure(InquireSpec::IntVar::Kind::Recl), - scalar(integer(variable)))) || - "ROUND =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Round), - scalarDefaultCharVariable)) || - "SEQUENTIAL =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Sequential), +TYPE_PARSER(construct(maybe("UNIT ="_tok) >> fileUnitNumber) || + construct("FILE =" >> fileNameExpr) || + construct( + "ACCESS =" >> construct( + pure(InquireSpec::CharVar::Kind::Access), scalarDefaultCharVariable)) || - "SIGN =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Sign), - scalarDefaultCharVariable)) || - "SIZE =" >> construct(construct( - pure(InquireSpec::IntVar::Kind::Size), - scalar(integer(variable)))) || - "STREAM =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Stream), - scalarDefaultCharVariable)) || - "STATUS =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Status), - scalarDefaultCharVariable)) || - "UNFORMATTED =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Unformatted), + construct( + "ACTION =" >> construct( + pure(InquireSpec::CharVar::Kind::Action), + scalarDefaultCharVariable)) || + construct( + "ASYNCHRONOUS =" >> construct( + pure(InquireSpec::CharVar::Kind::Asynchronous), + scalarDefaultCharVariable)) || + construct("BLANK =" >> + construct(pure(InquireSpec::CharVar::Kind::Blank), + scalarDefaultCharVariable)) || + construct( + "DECIMAL =" >> construct( + pure(InquireSpec::CharVar::Kind::Decimal), scalarDefaultCharVariable)) || - "WRITE =" >> construct(construct( - pure(InquireSpec::CharVar::Kind::Write), - scalarDefaultCharVariable))) + construct("DELIM =" >> + construct(pure(InquireSpec::CharVar::Kind::Delim), + scalarDefaultCharVariable)) || + construct( + "DIRECT =" >> construct( + pure(InquireSpec::CharVar::Kind::Direct), + scalarDefaultCharVariable)) || + construct( + "ENCODING =" >> construct( + pure(InquireSpec::CharVar::Kind::Encoding), + scalarDefaultCharVariable)) || + construct("ERR =" >> errLabel) || + construct("EXIST =" >> + construct( + pure(InquireSpec::LogVar::Kind::Exist), scalarLogicalVariable)) || + construct("FORM =" >> + construct(pure(InquireSpec::CharVar::Kind::Form), + scalarDefaultCharVariable)) || + construct( + "FORMATTED =" >> construct( + pure(InquireSpec::CharVar::Kind::Formatted), + scalarDefaultCharVariable)) || + construct("ID =" >> idExpr) || + construct("IOMSG =" >> + construct(pure(InquireSpec::CharVar::Kind::Iomsg), + scalarDefaultCharVariable)) || + construct("IOSTAT =" >> + construct(pure(InquireSpec::IntVar::Kind::Iostat), + scalar(integer(variable)))) || + construct("NAME =" >> + construct(pure(InquireSpec::CharVar::Kind::Name), + scalarDefaultCharVariable)) || + construct("NAMED =" >> + construct( + pure(InquireSpec::LogVar::Kind::Named), scalarLogicalVariable)) || + construct("NEXTREC =" >> + construct(pure(InquireSpec::IntVar::Kind::Nextrec), + scalar(integer(variable)))) || + construct("NUMBER =" >> + construct(pure(InquireSpec::IntVar::Kind::Number), + scalar(integer(variable)))) || + construct("OPENED =" >> + construct( + pure(InquireSpec::LogVar::Kind::Opened), scalarLogicalVariable)) || + construct("PAD =" >> + construct(pure(InquireSpec::CharVar::Kind::Pad), + scalarDefaultCharVariable)) || + construct("PENDING =" >> + construct( + pure(InquireSpec::LogVar::Kind::Pending), scalarLogicalVariable)) || + construct("POS =" >> + construct( + pure(InquireSpec::IntVar::Kind::Pos), scalar(integer(variable)))) || + construct( + "POSITION =" >> construct( + pure(InquireSpec::CharVar::Kind::Position), + scalarDefaultCharVariable)) || + construct("READ =" >> + construct(pure(InquireSpec::CharVar::Kind::Read), + scalarDefaultCharVariable)) || + construct( + "READWRITE =" >> construct( + pure(InquireSpec::CharVar::Kind::Readwrite), + scalarDefaultCharVariable)) || + construct("RECL =" >> + construct(pure(InquireSpec::IntVar::Kind::Recl), + scalar(integer(variable)))) || + construct("ROUND =" >> + construct(pure(InquireSpec::CharVar::Kind::Round), + scalarDefaultCharVariable)) || + construct( + "SEQUENTIAL =" >> construct( + pure(InquireSpec::CharVar::Kind::Sequential), + scalarDefaultCharVariable)) || + construct("SIGN =" >> + construct(pure(InquireSpec::CharVar::Kind::Sign), + scalarDefaultCharVariable)) || + construct("SIZE =" >> + construct(pure(InquireSpec::IntVar::Kind::Size), + scalar(integer(variable)))) || + construct( + "STREAM =" >> construct( + pure(InquireSpec::CharVar::Kind::Stream), + scalarDefaultCharVariable)) || + construct( + "STATUS =" >> construct( + pure(InquireSpec::CharVar::Kind::Status), + scalarDefaultCharVariable)) || + construct( + "UNFORMATTED =" >> construct( + pure(InquireSpec::CharVar::Kind::Unformatted), + scalarDefaultCharVariable)) || + construct("WRITE =" >> + construct(pure(InquireSpec::CharVar::Kind::Write), + scalarDefaultCharVariable))) // R1230 inquire-stmt -> // INQUIRE ( inquire-spec-list ) | @@ -2720,7 +2731,7 @@ TYPE_CONTEXT_PARSER("INQUIRE statement"_en_US, // R1301 format-stmt -> FORMAT format-specification TYPE_CONTEXT_PARSER("FORMAT statement"_en_US, - "FORMAT" >> construct(Parser{})) + construct("FORMAT" >> Parser{})) // R1321 char-string-edit-desc // N.B. C1313 disallows any kind parameter on the character literal. @@ -2760,7 +2771,7 @@ constexpr auto width = repeat; constexpr auto mandatoryWidth = construct>(width); constexpr auto digits = repeat; constexpr auto noInt = construct>(); -constexpr auto mandatoryDigits = "." >> construct>(width); +constexpr auto mandatoryDigits = construct>("." >> width); // R1307 data-edit-desc -> // I w [. m] | B w [. m] | O w [. m] | Z w [. m] | F w . d | @@ -2849,8 +2860,8 @@ TYPE_PARSER(construct("T"_ch >> "/"_ch >> pure(format::ControlEditDesc::Kind::Slash)) || construct( scaleFactor, "P"_ch >> pure(format::ControlEditDesc::Kind::P)) || - ":"_ch >> construct( - pure(format::ControlEditDesc::Kind::Colon)) || + construct( + ":"_ch >> pure(format::ControlEditDesc::Kind::Colon)) || "S"_ch >> ("S"_ch >> construct( pure(format::ControlEditDesc::Kind::SS)) || "P"_ch >> construct( @@ -2907,7 +2918,7 @@ TYPE_CONTEXT_PARSER("module"_en_US, // R1405 module-stmt -> MODULE module-name TYPE_CONTEXT_PARSER( - "MODULE statement"_en_US, "MODULE" >> construct(name)) + "MODULE statement"_en_US, construct("MODULE" >> name)) // R1406 end-module-stmt -> END [MODULE [module-name]] TYPE_CONTEXT_PARSER("END MODULE statement"_en_US, @@ -2982,7 +2993,7 @@ TYPE_CONTEXT_PARSER("BLOCK DATA subprogram"_en_US, // R1421 block-data-stmt -> BLOCK DATA [block-data-name] TYPE_CONTEXT_PARSER("BLOCK DATA statement"_en_US, - "BLOCK DATA" >> construct(maybe(name))) + construct("BLOCK DATA" >> maybe(name))) // R1422 end-block-data-stmt -> END [BLOCK DATA [block-data-name]] TYPE_CONTEXT_PARSER("END BLOCK DATA statement"_en_US, @@ -3000,12 +3011,11 @@ TYPE_PARSER(construct(Parser{}) || construct(statement(Parser{}))) // R1503 interface-stmt -> INTERFACE [generic-spec] | ABSTRACT INTERFACE -TYPE_PARSER("INTERFACE" >> construct(maybe(genericSpec)) || - "ABSTRACT INTERFACE"_sptok >> - construct(construct())) +TYPE_PARSER(construct("INTERFACE" >> maybe(genericSpec)) || + construct(constructIf("ABSTRACT INTERFACE"_sptok))) // R1504 end-interface-stmt -> END INTERFACE [generic-spec] -TYPE_PARSER("END INTERFACE" >> construct(maybe(genericSpec))) +TYPE_PARSER(construct("END INTERFACE" >> maybe(genericSpec))) // R1505 interface-body -> // function-stmt [specification-part] end-function-stmt | @@ -3038,22 +3048,21 @@ TYPE_PARSER(construct("MODULE PROCEDURE"_sptok >> TYPE_PARSER(construct( "OPERATOR" >> parenthesized(Parser{})) || construct( - "ASSIGNMENT ( = )" >> construct()) || + constructIf("ASSIGNMENT ( = )"_tok)) || construct( - "READ ( FORMATTED )" >> construct()) || + constructIf("READ ( FORMATTED )"_tok)) || + construct(constructIf( + "READ ( UNFORMATTED )"_tok)) || construct( - "READ ( UNFORMATTED )" >> construct()) || - construct( - "WRITE ( FORMATTED )" >> construct()) || - construct("WRITE ( UNFORMATTED )" >> - construct()) || + constructIf("WRITE ( FORMATTED )"_tok)) || + construct(constructIf( + "WRITE ( UNFORMATTED )"_tok)) || construct(name)) // R1510 generic-stmt -> // GENERIC [, access-spec] :: generic-spec => specific-procedure-list -TYPE_PARSER("GENERIC" >> construct(maybe("," >> accessSpec), - "::" >> genericSpec, - "=>" >> nonemptyList(specificProcedure))) +TYPE_PARSER(construct("GENERIC" >> maybe("," >> accessSpec), + "::" >> genericSpec, "=>" >> nonemptyList(specificProcedure))) // R1511 external-stmt -> EXTERNAL [::] external-name-list TYPE_PARSER("EXTERNAL" >> maybe("::"_tok) >> @@ -3120,25 +3129,26 @@ TYPE_PARSER(construct( TYPE_PARSER(construct(variable) / lookAhead(","_tok || ")"_tok) || construct(expr) || construct(Parser{}) || - extension("%REF" >> construct(construct( - parenthesized(variable)))) || - extension("%VAL" >> construct(construct( - parenthesized(expr))))) + extension(construct( + construct("%REF" >> parenthesized(variable)))) || + extension(construct( + construct("%VAL" >> parenthesized(expr))))) // R1525 alt-return-spec -> * label -TYPE_PARSER(star >> construct(label)) +TYPE_PARSER(construct(star >> label)) // R1527 prefix-spec -> // declaration-type-spec | ELEMENTAL | IMPURE | MODULE | // NON_RECURSIVE | PURE | RECURSIVE TYPE_PARSER(construct(declarationTypeSpec) || - "ELEMENTAL" >> construct(construct()) || - "IMPURE" >> construct(construct()) || - "MODULE" >> construct(construct()) || - "NON_RECURSIVE" >> - construct(construct()) || - "PURE" >> construct(construct()) || - "RECURSIVE" >> construct(construct())) + construct( + constructIf("ELEMENTAL"_tok)) || + construct(constructIf("IMPURE"_tok)) || + construct(constructIf("MODULE"_tok)) || + construct( + constructIf("NON_RECURSIVE"_tok)) || + construct(constructIf("PURE"_tok)) || + construct(constructIf("RECURSIVE"_tok))) // R1529 function-subprogram -> // function-stmt [specification-part] [execution-part] @@ -3222,10 +3232,10 @@ TYPE_PARSER( // R1542 return-stmt -> RETURN [scalar-int-expr] TYPE_CONTEXT_PARSER("RETURN statement"_en_US, - "RETURN" >> construct(maybe(scalarIntExpr))) + construct("RETURN" >> maybe(scalarIntExpr))) // R1543 contains-stmt -> CONTAINS -TYPE_PARSER("CONTAINS" >> construct()) +TYPE_PARSER(constructIf("CONTAINS"_tok)) // R1544 stmt-function-stmt -> // function-name ( [dummy-arg-name-list] ) = scalar-expr @@ -3238,7 +3248,7 @@ TYPE_CONTEXT_PARSER("statement function definition"_en_US, // !DIR$ IGNORE_TKR [ [(tkr...)] name ]... constexpr auto beginDirective = skipEmptyLines >> space >> "!"_ch; constexpr auto endDirective = space >> endOfLine; -constexpr auto ivdep = "DIR$ IVDEP" >> construct(); +constexpr auto ivdep = constructIf("DIR$ IVDEP"_tok); constexpr auto ignore_tkr = "DIR$ IGNORE_TKR" >> optionalList(construct( defaulted(parenthesized(some("tkr"_ch))), name)); @@ -3263,32 +3273,31 @@ TYPE_CONTEXT_PARSER("STRUCTURE definition"_en_US, extension(construct(statement(Parser{}), many(Parser{}), statement( - "END STRUCTURE" >> construct())))) + constructIf("END STRUCTURE"_tok))))) TYPE_CONTEXT_PARSER("UNION definition"_en_US, - construct(statement("UNION" >> construct()), + construct(statement(constructIf("UNION"_tok)), many(Parser{}), - statement("END UNION" >> construct()))) + statement(constructIf("END UNION"_tok)))) TYPE_CONTEXT_PARSER("MAP definition"_en_US, - construct(statement("MAP" >> construct()), + construct(statement(constructIf("MAP"_tok)), many(Parser{}), - statement("END MAP" >> construct()))) + statement(constructIf("END MAP"_tok)))) TYPE_CONTEXT_PARSER("arithmetic IF statement"_en_US, - deprecated("IF" >> construct(parenthesized(expr), - label / ",", label / ",", label))) + deprecated(construct( + "IF" >> parenthesized(expr), label / ",", label / ",", label))) TYPE_CONTEXT_PARSER("ASSIGN statement"_en_US, - deprecated("ASSIGN" >> construct(label, "TO" >> name))) + deprecated(construct("ASSIGN" >> label, "TO" >> name))) TYPE_CONTEXT_PARSER("assigned GOTO statement"_en_US, - deprecated("GO TO" >> - construct(name, - defaulted(maybe(","_tok) >> parenthesized(nonemptyList(label)))))) + deprecated(construct("GO TO" >> name, + defaulted(maybe(","_tok) >> parenthesized(nonemptyList(label)))))) TYPE_CONTEXT_PARSER("PAUSE statement"_en_US, - deprecated("PAUSE" >> construct(maybe(Parser{})))) + deprecated(construct("PAUSE" >> maybe(Parser{})))) // These requirement productions are defined by the Fortran standard but never // used directly by the grammar: