[flang] Remove needless empty braces from construct<>() calls.
authorpeter klausler <pklausler@nvidia.com>
Mon, 23 Apr 2018 23:53:16 +0000 (16:53 -0700)
committerpeter klausler <pklausler@nvidia.com>
Mon, 23 Apr 2018 23:53:16 +0000 (16:53 -0700)
Original-commit: flang-compiler/f18@f9c4a27034f52468eaee2397580685effa26e759
Reviewed-on: https://github.com/flang-compiler/f18/pull/68

flang/documentation/ParserCombinators.md
flang/lib/parser/basic-parsers.h
flang/lib/parser/grammar.h
flang/lib/parser/stmt-parser.h
flang/lib/parser/token-parsers.h

index d27a9cc..18ce799 100644 (file)
@@ -96,7 +96,7 @@ obtained by matching `c`.
 The following *applicative* combinators combine parsers and modify or
 collect the values that they return.
 
-* `construct<T>{}(p1, p2, ...)` matches zero or more parsers in succession,
+* `construct<T>(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.
 * `sourced(p)` matches p, and fills in its `source` data member with the
index 6501dfa..af41fac 100644 (file)
@@ -847,212 +847,215 @@ inline constexpr auto applyMem(typename Apply4Mem<PA, PB, PC, PD>::funcType f,
 // As is done with function application via applyFunction() above, class
 // instance construction can also be based upon the results of successful
 // parses.  For some type T and zero or more parsers a, b, &c., the call
-// construct<T>{}(a, b, ...) returns a parser that succeeds if all of
+// construct<T>(a, b, ...) returns a parser that succeeds if all of
 // its argument parsers do so in succession, and whose result is an
 // instance of T constructed upon the values they returned.
-template<class T> struct construct {
-
+template<class T> struct Construct0 {
   using resultType = T;
-  constexpr construct(const construct &) = default;
+  constexpr Construct0() {}
+  constexpr Construct0(const Construct0 &) = default;
   std::optional<T> Parse(ParseState &state) const { return {T{}}; }
+};
 
-  constexpr construct operator()() const { return *this; }
+template<class T> constexpr Construct0<T> construct() {
+  return Construct0<T>{};
+}
 
-  template<typename PA> class Construct1 {
-  public:
-    using resultType = T;
-    constexpr Construct1(const Construct1 &) = default;
-    constexpr explicit Construct1(const PA &parser) : parser_{parser} {}
-    std::optional<T> Parse(ParseState &state) const {
-      if (auto ax = parser_.Parse(state)) {
-        return {T(std::move(*ax))};
-      }
-      return {};
+template<typename T, typename PA> class Construct1 {
+public:
+  using resultType = T;
+  constexpr Construct1(const Construct1 &) = default;
+  constexpr explicit Construct1(const PA &parser) : parser_{parser} {}
+  std::optional<T> Parse(ParseState &state) const {
+    if (auto ax = parser_.Parse(state)) {
+      return {T(std::move(*ax))};
     }
+    return {};
+  }
 
-  private:
-    const PA parser_;
-  };
+private:
+  const PA parser_;
+};
 
-  template<typename PA>
-  constexpr Construct1<PA> operator()(const PA &pa) const {
-    return Construct1<PA>{pa};
+template<typename T, typename PA, typename PB> class Construct2 {
+public:
+  using resultType = T;
+  constexpr Construct2(const Construct2 &) = default;
+  constexpr Construct2(const PA &pa, const PB &pb) : pa_{pa}, pb_{pb} {}
+  std::optional<T> Parse(ParseState &state) const {
+    if (auto ax = pa_.Parse(state)) {
+      if (auto bx = pb_.Parse(state)) {
+        return {T{std::move(*ax), std::move(*bx)}};
+      }
+    }
+    return {};
   }
 
-  template<typename PA, typename PB> class Construct2 {
-  public:
-    using resultType = T;
-    constexpr Construct2(const Construct2 &) = default;
-    constexpr Construct2(const PA &pa, const PB &pb) : pa_{pa}, pb_{pb} {}
-    std::optional<T> Parse(ParseState &state) const {
-      if (auto ax = pa_.Parse(state)) {
-        if (auto bx = pb_.Parse(state)) {
-          return {T{std::move(*ax), std::move(*bx)}};
+private:
+  const PA pa_;
+  const PB pb_;
+};
+
+template<typename T, typename PA, typename PB, typename PC> 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} {}
+  std::optional<resultType> Parse(ParseState &state) const {
+    if (auto ax = pa_.Parse(state)) {
+      if (auto bx = pb_.Parse(state)) {
+        if (auto cx = pc_.Parse(state)) {
+          return {T{std::move(*ax), std::move(*bx), std::move(*cx)}};
         }
       }
-      return {};
     }
-
-  private:
-    const PA pa_;
-    const PB pb_;
-  };
-
-  template<typename PA, typename PB>
-  constexpr Construct2<PA, PB> operator()(const PA &pa, const PB &pb) const {
-    return Construct2<PA, PB>{pa, pb};
+    return {};
   }
 
-  template<typename PA, typename PB, typename PC> 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} {}
-    std::optional<resultType> Parse(ParseState &state) const {
-      if (auto ax = pa_.Parse(state)) {
-        if (auto bx = pb_.Parse(state)) {
-          if (auto cx = pc_.Parse(state)) {
-            return {T{std::move(*ax), std::move(*bx), std::move(*cx)}};
+private:
+  const PA pa_;
+  const PB pb_;
+  const PC pc_;
+};
+
+template<typename T, typename PA, typename PB, typename PC, typename PD>
+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} {}
+  std::optional<resultType> Parse(ParseState &state) const {
+    if (auto ax = pa_.Parse(state)) {
+      if (auto bx = pb_.Parse(state)) {
+        if (auto cx = pc_.Parse(state)) {
+          if (auto dx = pd_.Parse(state)) {
+            return {T{std::move(*ax), std::move(*bx), std::move(*cx),
+                std::move(*dx)}};
           }
         }
       }
-      return {};
     }
-
-  private:
-    const PA pa_;
-    const PB pb_;
-    const PC pc_;
-  };
-
-  template<typename PA, typename PB, typename PC>
-  constexpr Construct3<PA, PB, PC> operator()(
-      const PA &pa, const PB &pb, const PC &pc) const {
-    return Construct3<PA, PB, PC>{pa, pb, pc};
+    return {};
   }
 
-  template<typename PA, typename PB, typename PC, typename PD>
-  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} {}
-    std::optional<resultType> Parse(ParseState &state) const {
-      if (auto ax = pa_.Parse(state)) {
-        if (auto bx = pb_.Parse(state)) {
-          if (auto cx = pc_.Parse(state)) {
-            if (auto dx = pd_.Parse(state)) {
+private:
+  const PA pa_;
+  const PB pb_;
+  const PC pc_;
+  const PD pd_;
+};
+
+template<typename T, typename PA, typename PB, typename PC, typename PD,
+    typename PE>
+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} {}
+  std::optional<resultType> Parse(ParseState &state) const {
+    if (auto ax = pa_.Parse(state)) {
+      if (auto bx = pb_.Parse(state)) {
+        if (auto cx = pc_.Parse(state)) {
+          if (auto dx = pd_.Parse(state)) {
+            if (auto ex = pe_.Parse(state)) {
               return {T{std::move(*ax), std::move(*bx), std::move(*cx),
-                  std::move(*dx)}};
+                  std::move(*dx), std::move(*ex)}};
             }
           }
         }
       }
-      return {};
     }
-
-  private:
-    const PA pa_;
-    const PB pb_;
-    const PC pc_;
-    const PD pd_;
-  };
-
-  template<typename PA, typename PB, typename PC, typename PD>
-  constexpr Construct4<PA, PB, PC, PD> operator()(
-      const PA &pa, const PB &pb, const PC &pc, const PD &pd) const {
-    return Construct4<PA, PB, PC, PD>{pa, pb, pc, pd};
+    return {};
   }
 
-  template<typename PA, typename PB, typename PC, typename PD, typename PE>
-  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} {}
-    std::optional<resultType> Parse(ParseState &state) const {
-      if (auto ax = pa_.Parse(state)) {
-        if (auto bx = pb_.Parse(state)) {
-          if (auto cx = pc_.Parse(state)) {
-            if (auto dx = pd_.Parse(state)) {
-              if (auto ex = pe_.Parse(state)) {
+private:
+  const PA pa_;
+  const PB pb_;
+  const PC pc_;
+  const PD pd_;
+  const PE pe_;
+};
+
+template<typename T, typename PA, typename PB, typename PC, typename PD,
+    typename PE, typename PF>
+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} {}
+  std::optional<resultType> Parse(ParseState &state) const {
+    if (auto ax = pa_.Parse(state)) {
+      if (auto bx = pb_.Parse(state)) {
+        if (auto cx = pc_.Parse(state)) {
+          if (auto dx = pd_.Parse(state)) {
+            if (auto ex = pe_.Parse(state)) {
+              if (auto fx = pf_.Parse(state)) {
                 return {T{std::move(*ax), std::move(*bx), std::move(*cx),
-                    std::move(*dx), std::move(*ex)}};
+                    std::move(*dx), std::move(*ex), std::move(*fx)}};
               }
             }
           }
         }
       }
-      return {};
     }
-
-  private:
-    const PA pa_;
-    const PB pb_;
-    const PC pc_;
-    const PD pd_;
-    const PE pe_;
-  };
-
-  template<typename PA, typename PB, typename PC, typename PD, typename PE>
-  constexpr Construct5<PA, PB, PC, PD, PE> operator()(const PA &pa,
-      const PB &pb, const PC &pc, const PD &pd, const PE &pe) const {
-    return Construct5<PA, PB, PC, PD, PE>{pa, pb, pc, pd, pe};
+    return {};
   }
 
-  template<typename PA, typename PB, typename PC, typename PD, typename PE,
-      typename PF>
-  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} {}
-    std::optional<resultType> Parse(ParseState &state) const {
-      if (auto ax = pa_.Parse(state)) {
-        if (auto bx = pb_.Parse(state)) {
-          if (auto cx = pc_.Parse(state)) {
-            if (auto dx = pd_.Parse(state)) {
-              if (auto ex = pe_.Parse(state)) {
-                if (auto fx = pf_.Parse(state)) {
-                  return {T{std::move(*ax), std::move(*bx), std::move(*cx),
-                      std::move(*dx), std::move(*ex), std::move(*fx)}};
-                }
-              }
-            }
-          }
-        }
-      }
-      return {};
-    }
-
-  private:
-    const PA pa_;
-    const PB pb_;
-    const PC pc_;
-    const PD pd_;
-    const PE pe_;
-    const PF pf_;
-  };
-
-  template<typename PA, typename PB, typename PC, typename PD, typename PE,
-      typename PF>
-  constexpr Construct6<PA, PB, PC, PD, PE, PF> operator()(const PA &pa,
-      const PB &pb, const PC &pc, const PD &pd, const PE &pe,
-      const PF &pf) const {
-    return Construct6<PA, PB, PC, PD, PE, PF>{pa, pb, pc, pd, pe, pf};
-  }
+private:
+  const PA pa_;
+  const PB pb_;
+  const PC pc_;
+  const PD pd_;
+  const PE pe_;
+  const PF pf_;
 };
 
+template<typename T, typename PA>
+constexpr Construct1<T, PA> construct(const PA &parser) {
+  return Construct1<T, PA>{parser};
+}
+
+template<typename T, typename PA, typename PB>
+constexpr Construct2<T, PA, PB> construct(const PA &pa, const PB &pb) {
+  return Construct2<T, PA, PB>{pa, pb};
+}
+
+template<typename T, typename PA, typename PB, typename PC>
+constexpr Construct3<T, PA, PB, PC> construct(
+    const PA &pa, const PB &pb, const PC &pc) {
+  return Construct3<T, PA, PB, PC>{pa, pb, pc};
+}
+
+template<typename T, typename PA, typename PB, typename PC, typename PD>
+constexpr Construct4<T, PA, PB, PC, PD> construct(
+    const PA &pa, const PB &pb, const PC &pc, const PD &pd) {
+  return Construct4<T, PA, PB, PC, PD>{pa, pb, pc, pd};
+}
+
+template<typename T, typename PA, typename PB, typename PC, typename PD,
+    typename PE>
+constexpr Construct5<T, PA, PB, PC, PD, PE> construct(
+    const PA &pa, const PB &pb, const PC &pc, const PD &pd, const PE &pe) {
+  return Construct5<T, PA, PB, PC, PD, PE>{pa, pb, pc, pd, pe};
+}
+
+template<typename T, typename PA, typename PB, typename PC, typename PD,
+    typename PE, typename PF>
+constexpr Construct6<T, PA, PB, PC, PD, PE, PF> construct(const PA &pa,
+    const PB &pb, const PC &pc, const PD &pd, const PE &pe, const PF &pf) {
+  return Construct6<T, PA, PB, PC, PD, PE, PF>{pa, pb, pc, pd, pe, pf};
+}
+
 // For a parser p, indirect(p) returns a parser that builds an indirect
 // reference to p's return type.
 template<typename PA> inline constexpr auto indirect(const PA &p) {
-  return construct<Indirection<typename PA::resultType>>{}(p);
+  return construct<Indirection<typename PA::resultType>>(p);
 }
 
 // If a and b are parsers, then nonemptySeparated(a, b) returns a parser
index 2829f67..83e3033 100644 (file)
@@ -42,37 +42,35 @@ constexpr auto execPartLookAhead = actionStmt >> ok || "ASSOCIATE ("_tok ||
 constexpr auto declErrorRecovery =
     errorRecoveryStart >> !execPartLookAhead >> stmtErrorRecovery;
 TYPE_CONTEXT_PARSER("declaration construct"_en_US,
-    recovery(construct<DeclarationConstruct>{}(specificationConstruct) ||
-            construct<DeclarationConstruct>{}(statement(indirect(dataStmt))) ||
-            construct<DeclarationConstruct>{}(
-                statement(indirect(formatStmt))) ||
-            construct<DeclarationConstruct>{}(statement(indirect(entryStmt))) ||
-            construct<DeclarationConstruct>{}(
+    recovery(construct<DeclarationConstruct>(specificationConstruct) ||
+            construct<DeclarationConstruct>(statement(indirect(dataStmt))) ||
+            construct<DeclarationConstruct>(statement(indirect(formatStmt))) ||
+            construct<DeclarationConstruct>(statement(indirect(entryStmt))) ||
+            construct<DeclarationConstruct>(
                 statement(indirect(Parser<StmtFunctionStmt>{}))),
-        construct<DeclarationConstruct>{}(declErrorRecovery)))
+        construct<DeclarationConstruct>(declErrorRecovery)))
 
 // R508 specification-construct ->
 //        derived-type-def | enum-def | generic-stmt | interface-block |
 //        parameter-stmt | procedure-declaration-stmt |
 //        other-specification-stmt | type-declaration-stmt
 TYPE_CONTEXT_PARSER("specification construct"_en_US,
-    construct<SpecificationConstruct>{}(indirect(Parser<DerivedTypeDef>{})) ||
-        construct<SpecificationConstruct>{}(indirect(Parser<EnumDef>{})) ||
-        construct<SpecificationConstruct>{}(
+    construct<SpecificationConstruct>(indirect(Parser<DerivedTypeDef>{})) ||
+        construct<SpecificationConstruct>(indirect(Parser<EnumDef>{})) ||
+        construct<SpecificationConstruct>(
             statement(indirect(Parser<GenericStmt>{}))) ||
-        construct<SpecificationConstruct>{}(indirect(interfaceBlock)) ||
-        construct<SpecificationConstruct>{}(
-            statement(indirect(parameterStmt))) ||
-        construct<SpecificationConstruct>{}(
+        construct<SpecificationConstruct>(indirect(interfaceBlock)) ||
+        construct<SpecificationConstruct>(statement(indirect(parameterStmt))) ||
+        construct<SpecificationConstruct>(
             statement(indirect(oldParameterStmt))) ||
-        construct<SpecificationConstruct>{}(
+        construct<SpecificationConstruct>(
             statement(indirect(Parser<ProcedureDeclarationStmt>{}))) ||
-        construct<SpecificationConstruct>{}(
+        construct<SpecificationConstruct>(
             statement(Parser<OtherSpecificationStmt>{})) ||
-        construct<SpecificationConstruct>{}(
+        construct<SpecificationConstruct>(
             statement(indirect(typeDeclarationStmt))) ||
-        construct<SpecificationConstruct>{}(indirect(Parser<StructureDef>{})) ||
-        construct<SpecificationConstruct>{}(indirect(compilerDirective)))
+        construct<SpecificationConstruct>(indirect(Parser<StructureDef>{})) ||
+        construct<SpecificationConstruct>(indirect(compilerDirective)))
 
 // R513 other-specification-stmt ->
 //        access-stmt | allocatable-stmt | asynchronous-stmt | bind-stmt |
@@ -80,35 +78,34 @@ TYPE_CONTEXT_PARSER("specification construct"_en_US,
 //        intent-stmt | intrinsic-stmt | namelist-stmt | optional-stmt |
 //        pointer-stmt | protected-stmt | save-stmt | target-stmt |
 //        volatile-stmt | value-stmt | common-stmt | equivalence-stmt
-TYPE_PARSER(
-    construct<OtherSpecificationStmt>{}(indirect(Parser<AccessStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<AllocatableStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<AsynchronousStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<BindStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<CodimensionStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<ContiguousStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<DimensionStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<ExternalStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<IntentStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<IntrinsicStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<NamelistStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<OptionalStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<PointerStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<ProtectedStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<SaveStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<TargetStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<ValueStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<VolatileStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<CommonStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<EquivalenceStmt>{})) ||
-    construct<OtherSpecificationStmt>{}(indirect(Parser<BasedPointerStmt>{})))
+TYPE_PARSER(construct<OtherSpecificationStmt>(indirect(Parser<AccessStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<AllocatableStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<AsynchronousStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<BindStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<CodimensionStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<ContiguousStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<DimensionStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<ExternalStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<IntentStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<IntrinsicStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<NamelistStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<OptionalStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<PointerStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<ProtectedStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<SaveStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<TargetStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<ValueStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<VolatileStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<CommonStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<EquivalenceStmt>{})) ||
+    construct<OtherSpecificationStmt>(indirect(Parser<BasedPointerStmt>{})))
 
 // R604 constant ->  literal-constant | named-constant
 // Used only via R607 int-constant and R845 data-stmt-constant.
 // The look-ahead check prevents occlusion of constant-subobject in
 // data-stmt-constant.
-TYPE_PARSER(construct<ConstantValue>{}(literalConstant) ||
-    construct<ConstantValue>{}(namedConstant / !"%"_tok / !"("_tok))
+TYPE_PARSER(construct<ConstantValue>(literalConstant) ||
+    construct<ConstantValue>(namedConstant / !"%"_tok / !"("_tok))
 
 // R608 intrinsic-operator ->
 //        power-op | mult-op | add-op | concat-op | rel-op |
@@ -151,8 +148,8 @@ constexpr auto intrinsicOperator = "**" >>
 
 // R609 defined-operator ->
 //        defined-unary-op | defined-binary-op | extended-intrinsic-op
-TYPE_PARSER(construct<DefinedOperator>{}(intrinsicOperator) ||
-    construct<DefinedOperator>{}(definedOpName))
+TYPE_PARSER(construct<DefinedOperator>(intrinsicOperator) ||
+    construct<DefinedOperator>(definedOpName))
 
 // R401 xzy-list -> xzy [, xzy]...
 template<typename PA> inline constexpr auto nonemptyList(const PA &p) {
@@ -168,24 +165,23 @@ template<typename PA> inline constexpr auto optionalList(const PA &p) {
 // R403 scalar-xyz -> xyz
 // Also define constant-xyz, int-xyz, default-char-xyz.
 template<typename PA> inline constexpr auto scalar(const PA &p) {
-  return construct<Scalar<typename PA::resultType>>{}(p);  // scalar-p
+  return construct<Scalar<typename PA::resultType>>(p);  // scalar-p
 }
 
 template<typename PA> inline constexpr auto constant(const PA &p) {
-  return construct<Constant<typename PA::resultType>>{}(p);  // constant-p
+  return construct<Constant<typename PA::resultType>>(p);  // constant-p
 }
 
 template<typename PA> inline constexpr auto integer(const PA &p) {
-  return construct<Integer<typename PA::resultType>>{}(p);  // int-p
+  return construct<Integer<typename PA::resultType>>(p);  // int-p
 }
 
 template<typename PA> inline constexpr auto logical(const PA &p) {
-  return construct<Logical<typename PA::resultType>>{}(p);  // logical-p
+  return construct<Logical<typename PA::resultType>>(p);  // logical-p
 }
 
 template<typename PA> inline constexpr auto defaultChar(const PA &p) {
-  return construct<DefaultChar<typename PA::resultType>>{}(
-      p);  // default-char-p
+  return construct<DefaultChar<typename PA::resultType>>(p);  // default-char-p
 }
 
 // R1024 logical-expr -> expr
@@ -215,7 +211,7 @@ constexpr auto scalarIntConstantExpr = scalar(intConstantExpr);
 // This is the top-level production for the Fortran language.
 constexpr StartNewSubprogram startNewSubprogram;
 TYPE_PARSER(
-    construct<Program>{}(
+    construct<Program>(
         // statements consume only trailing noise; consume leading noise here.
         skipEmptyLines >>
         some(startNewSubprogram >> Parser<ProgramUnit>{} / endOfLine)) /
@@ -224,18 +220,18 @@ TYPE_PARSER(
 // R502 program-unit ->
 //        main-program | external-subprogram | module | submodule | block-data
 // R503 external-subprogram -> function-subprogram | subroutine-subprogram
-TYPE_PARSER(construct<ProgramUnit>{}(indirect(functionSubprogram)) ||
-    construct<ProgramUnit>{}(indirect(subroutineSubprogram)) ||
-    construct<ProgramUnit>{}(indirect(Parser<Module>{})) ||
-    construct<ProgramUnit>{}(indirect(Parser<Submodule>{})) ||
-    construct<ProgramUnit>{}(indirect(Parser<BlockData>{})) ||
-    construct<ProgramUnit>{}(indirect(Parser<MainProgram>{})))
+TYPE_PARSER(construct<ProgramUnit>(indirect(functionSubprogram)) ||
+    construct<ProgramUnit>(indirect(subroutineSubprogram)) ||
+    construct<ProgramUnit>(indirect(Parser<Module>{})) ||
+    construct<ProgramUnit>(indirect(Parser<Submodule>{})) ||
+    construct<ProgramUnit>(indirect(Parser<BlockData>{})) ||
+    construct<ProgramUnit>(indirect(Parser<MainProgram>{})))
 
 // R504 specification-part ->
 //         [use-stmt]... [import-stmt]... [implicit-part]
 //         [declaration-construct]...
 TYPE_CONTEXT_PARSER("specification part"_en_US,
-    construct<SpecificationPart>{}(many(statement(indirect(Parser<UseStmt>{}))),
+    construct<SpecificationPart>(many(statement(indirect(Parser<UseStmt>{}))),
         many(statement(indirect(Parser<ImportStmt>{}))), implicitPart,
         many(declarationConstruct)))
 
@@ -244,26 +240,26 @@ TYPE_CONTEXT_PARSER("specification part"_en_US,
 // statements after the last IMPLICIT should be transferred to the
 // list of declaration-constructs.
 TYPE_CONTEXT_PARSER("implicit part"_en_US,
-    construct<ImplicitPart>{}(many(Parser<ImplicitPartStmt>{})))
+    construct<ImplicitPart>(many(Parser<ImplicitPartStmt>{})))
 
 // R506 implicit-part-stmt ->
 //         implicit-stmt | parameter-stmt | format-stmt | entry-stmt
-TYPE_PARSER(construct<ImplicitPartStmt>{}(
-                statement(indirect(Parser<ImplicitStmt>{}))) ||
-    construct<ImplicitPartStmt>{}(statement(indirect(parameterStmt))) ||
-    construct<ImplicitPartStmt>{}(statement(indirect(oldParameterStmt))) ||
-    construct<ImplicitPartStmt>{}(statement(indirect(formatStmt))) ||
-    construct<ImplicitPartStmt>{}(statement(indirect(entryStmt))))
+TYPE_PARSER(
+    construct<ImplicitPartStmt>(statement(indirect(Parser<ImplicitStmt>{}))) ||
+    construct<ImplicitPartStmt>(statement(indirect(parameterStmt))) ||
+    construct<ImplicitPartStmt>(statement(indirect(oldParameterStmt))) ||
+    construct<ImplicitPartStmt>(statement(indirect(formatStmt))) ||
+    construct<ImplicitPartStmt>(statement(indirect(entryStmt))))
 
 // R512 internal-subprogram -> function-subprogram | subroutine-subprogram
 constexpr auto internalSubprogram =
-    (construct<InternalSubprogram>{}(indirect(functionSubprogram)) ||
-        construct<InternalSubprogram>{}(indirect(subroutineSubprogram))) /
+    (construct<InternalSubprogram>(indirect(functionSubprogram)) ||
+        construct<InternalSubprogram>(indirect(subroutineSubprogram))) /
     endOfStmt;
 
 // R511 internal-subprogram-part -> contains-stmt [internal-subprogram]...
 TYPE_CONTEXT_PARSER("internal subprogram part"_en_US,
-    construct<InternalSubprogramPart>{}(statement(containsStmt),
+    construct<InternalSubprogramPart>(statement(containsStmt),
         many(startNewSubprogram >> internalSubprogram)))
 
 // R515 action-stmt ->
@@ -278,48 +274,47 @@ TYPE_CONTEXT_PARSER("internal subprogram part"_en_US,
 //        wait-stmt | where-stmt | write-stmt | computed-goto-stmt | forall-stmt
 // R1159 continue-stmt -> CONTINUE
 // R1163 fail-image-stmt -> FAIL IMAGE
-TYPE_PARSER(construct<ActionStmt>{}(indirect(Parser<AllocateStmt>{})) ||
-    construct<ActionStmt>{}(indirect(assignmentStmt)) ||
-    construct<ActionStmt>{}(indirect(Parser<BackspaceStmt>{})) ||
-    construct<ActionStmt>{}(indirect(Parser<CallStmt>{})) ||
-    construct<ActionStmt>{}(indirect(Parser<CloseStmt>{})) ||
-    "CONTINUE" >> construct<ActionStmt>{}(construct<ContinueStmt>{}) ||
-    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>{})) ||
-    "FAIL IMAGE"_sptok >> construct<ActionStmt>{}(construct<FailImageStmt>{}) ||
-    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<NullifyStmt>{})) ||
-    construct<ActionStmt>{}(indirect(Parser<OpenStmt>{})) ||
-    construct<ActionStmt>{}(indirect(pointerAssignmentStmt)) ||
-    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>{})) ||  // & error-stop-stmt
-    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_PARSER(construct<ActionStmt>(indirect(Parser<AllocateStmt>{})) ||
+    construct<ActionStmt>(indirect(assignmentStmt)) ||
+    construct<ActionStmt>(indirect(Parser<BackspaceStmt>{})) ||
+    construct<ActionStmt>(indirect(Parser<CallStmt>{})) ||
+    construct<ActionStmt>(indirect(Parser<CloseStmt>{})) ||
+    "CONTINUE" >> construct<ActionStmt>(construct<ContinueStmt>()) ||
+    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>{})) ||
+    "FAIL IMAGE"_sptok >> construct<ActionStmt>(construct<FailImageStmt>()) ||
+    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<NullifyStmt>{})) ||
+    construct<ActionStmt>(indirect(Parser<OpenStmt>{})) ||
+    construct<ActionStmt>(indirect(pointerAssignmentStmt)) ||
+    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>{})) ||  // & error-stop-stmt
+    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>{})))
 
 // Fortran allows the statement with the corresponding label at the end of
 // a do-construct that begins with an old-style label-do-stmt to be a
@@ -334,21 +329,21 @@ TYPE_PARSER(construct<ActionStmt>{}(indirect(Parser<AllocateStmt>{})) ||
 //        do-construct | if-construct | select-rank-construct |
 //        select-type-construct | where-construct | forall-construct
 constexpr auto executableConstruct =
-    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>{}(CapturedLabelDoStmt{}) ||
-    construct<ExecutableConstruct>{}(EndDoStmtForCapturedLabelDoStmt{}) ||
-    construct<ExecutableConstruct>{}(indirect(Parser<DoConstruct>{})) ||
-    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(compilerDirective));
+    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>(CapturedLabelDoStmt{}) ||
+    construct<ExecutableConstruct>(EndDoStmtForCapturedLabelDoStmt{}) ||
+    construct<ExecutableConstruct>(indirect(Parser<DoConstruct>{})) ||
+    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(compilerDirective));
 
 // R510 execution-part-construct ->
 //        executable-construct | format-stmt | entry-stmt | data-stmt
@@ -357,48 +352,46 @@ constexpr auto obsoleteExecutionPartConstruct = recovery(
     ignoredStatementPrefix >>
         fail<ExecutionPartConstruct>(
             "obsolete legacy extension is not supported"_err_en_US),
-    construct<ExecutionPartConstruct>{}(
+    construct<ExecutionPartConstruct>(
         statement("REDIMENSION" >> name >>
             parenthesized(nonemptyList(Parser<AllocateShapeSpec>{})) >> ok) >>
         errorRecovery));
 
 TYPE_CONTEXT_PARSER("execution part construct"_en_US,
-    recovery(construct<ExecutionPartConstruct>{}(executableConstruct) ||
-            construct<ExecutionPartConstruct>{}(
+    recovery(construct<ExecutionPartConstruct>(executableConstruct) ||
+            construct<ExecutionPartConstruct>(
                 statement(indirect(formatStmt))) ||
-            construct<ExecutionPartConstruct>{}(
-                statement(indirect(entryStmt))) ||
-            construct<ExecutionPartConstruct>{}(
-                statement(indirect(dataStmt))) ||
-            extension(construct<ExecutionPartConstruct>{}(
+            construct<ExecutionPartConstruct>(statement(indirect(entryStmt))) ||
+            construct<ExecutionPartConstruct>(statement(indirect(dataStmt))) ||
+            extension(construct<ExecutionPartConstruct>(
                           statement(indirect(Parser<NamelistStmt>{}))) ||
                 obsoleteExecutionPartConstruct),
-        construct<ExecutionPartConstruct>{}(executionPartErrorRecovery)))
+        construct<ExecutionPartConstruct>(executionPartErrorRecovery)))
 
 // R509 execution-part -> executable-construct [execution-part-construct]...
 TYPE_CONTEXT_PARSER("execution part"_en_US,
-    construct<ExecutionPart>{}(many(executionPartConstruct)))
+    construct<ExecutionPart>(many(executionPartConstruct)))
 
 // R605 literal-constant ->
 //        int-literal-constant | real-literal-constant |
 //        complex-literal-constant | logical-literal-constant |
 //        char-literal-constant | boz-literal-constant
-TYPE_PARSER(construct<LiteralConstant>{}(Parser<HollerithLiteralConstant>{}) ||
-    construct<LiteralConstant>{}(space >> realLiteralConstant) ||
-    construct<LiteralConstant>{}(intLiteralConstant) ||
-    construct<LiteralConstant>{}(Parser<ComplexLiteralConstant>{}) ||
-    construct<LiteralConstant>{}(Parser<BOZLiteralConstant>{}) ||
-    construct<LiteralConstant>{}(charLiteralConstant) ||
-    construct<LiteralConstant>{}(Parser<LogicalLiteralConstant>{}))
+TYPE_PARSER(construct<LiteralConstant>(Parser<HollerithLiteralConstant>{}) ||
+    construct<LiteralConstant>(space >> realLiteralConstant) ||
+    construct<LiteralConstant>(intLiteralConstant) ||
+    construct<LiteralConstant>(Parser<ComplexLiteralConstant>{}) ||
+    construct<LiteralConstant>(Parser<BOZLiteralConstant>{}) ||
+    construct<LiteralConstant>(charLiteralConstant) ||
+    construct<LiteralConstant>(Parser<LogicalLiteralConstant>{}))
 
 // R606 named-constant -> name
-TYPE_PARSER(construct<NamedConstant>{}(name))
+TYPE_PARSER(construct<NamedConstant>(name))
 
 // R701 type-param-value -> scalar-int-expr | * | :
-constexpr auto star = "*" >> construct<Star>{};
-TYPE_PARSER(construct<TypeParamValue>{}(scalarIntExpr) ||
-    construct<TypeParamValue>{}(star) ||
-    construct<TypeParamValue>{}(":" >> construct<TypeParamValue::Deferred>{}))
+constexpr auto star = "*" >> construct<Star>();
+TYPE_PARSER(construct<TypeParamValue>(scalarIntExpr) ||
+    construct<TypeParamValue>(star) ||
+    construct<TypeParamValue>(":" >> construct<TypeParamValue::Deferred>()))
 
 // R702 type-spec -> intrinsic-type-spec | derived-type-spec
 // N.B. This type-spec production is one of two instances in the Fortran
@@ -407,8 +400,8 @@ TYPE_PARSER(construct<TypeParamValue>{}(scalarIntExpr) ||
 // to disambiguate the cases where a derived type name begins with the name
 // of an intrinsic type, e.g., REALITY.
 TYPE_CONTEXT_PARSER("type spec"_en_US,
-    construct<TypeSpec>{}(intrinsicTypeSpec / lookAhead("::"_tok || ")"_tok)) ||
-        construct<TypeSpec>{}(derivedTypeSpec))
+    construct<TypeSpec>(intrinsicTypeSpec / lookAhead("::"_tok || ")"_tok)) ||
+        construct<TypeSpec>(derivedTypeSpec))
 
 // R703 declaration-type-spec ->
 //        intrinsic-type-spec | TYPE ( intrinsic-type-spec ) |
@@ -419,23 +412,22 @@ TYPE_CONTEXT_PARSER("type spec"_en_US,
 // would fail on "TYPE(real_derived)" with a misrecognition of "real" as an
 // intrinsic-type-spec.
 TYPE_CONTEXT_PARSER("declaration type spec"_en_US,
-    construct<DeclarationTypeSpec>{}(intrinsicTypeSpec) ||
+    construct<DeclarationTypeSpec>(intrinsicTypeSpec) ||
         "TYPE" >>
-            (parenthesized(
-                 construct<DeclarationTypeSpec>{}(intrinsicTypeSpec)) ||
-                parenthesized(construct<DeclarationTypeSpec>{}(
-                    construct<DeclarationTypeSpec::Type>{}(derivedTypeSpec))) ||
-                "( * )" >> construct<DeclarationTypeSpec>{}(
-                               construct<DeclarationTypeSpec::TypeStar>{})) ||
+            (parenthesized(construct<DeclarationTypeSpec>(intrinsicTypeSpec)) ||
+                parenthesized(construct<DeclarationTypeSpec>(
+                    construct<DeclarationTypeSpec::Type>(derivedTypeSpec))) ||
+                "( * )" >> construct<DeclarationTypeSpec>(
+                               construct<DeclarationTypeSpec::TypeStar>())) ||
         "CLASS" >>
             parenthesized(
-                construct<DeclarationTypeSpec>{}(
-                    construct<DeclarationTypeSpec::Class>{}(derivedTypeSpec)) ||
-                "*" >> construct<DeclarationTypeSpec>{}(
-                           construct<DeclarationTypeSpec::ClassStar>{})) ||
+                construct<DeclarationTypeSpec>(
+                    construct<DeclarationTypeSpec::Class>(derivedTypeSpec)) ||
+                "*" >> construct<DeclarationTypeSpec>(
+                           construct<DeclarationTypeSpec::ClassStar>())) ||
         extension("RECORD /" >>
-            construct<DeclarationTypeSpec>{}(
-                construct<DeclarationTypeSpec::Record>{}(name / "/"))))
+            construct<DeclarationTypeSpec>(
+                construct<DeclarationTypeSpec::Record>(name / "/"))))
 
 // R704 intrinsic-type-spec ->
 //        integer-type-spec | REAL [kind-selector] | DOUBLE PRECISION |
@@ -443,59 +435,59 @@ TYPE_CONTEXT_PARSER("declaration type spec"_en_US,
 //        LOGICAL [kind-selector]
 // Extensions: DOUBLE COMPLEX, NCHARACTER, BYTE
 TYPE_CONTEXT_PARSER("intrinsic type spec"_en_US,
-    construct<IntrinsicTypeSpec>{}(integerTypeSpec) ||
+    construct<IntrinsicTypeSpec>(integerTypeSpec) ||
         "REAL" >>
-            construct<IntrinsicTypeSpec>{}(
-                construct<IntrinsicTypeSpec::Real>{}(maybe(kindSelector))) ||
+            construct<IntrinsicTypeSpec>(
+                construct<IntrinsicTypeSpec::Real>(maybe(kindSelector))) ||
         "DOUBLE PRECISION" >>
-            construct<IntrinsicTypeSpec>{}(
-                construct<IntrinsicTypeSpec::DoublePrecision>{}) ||
+            construct<IntrinsicTypeSpec>(
+                construct<IntrinsicTypeSpec::DoublePrecision>()) ||
         "COMPLEX" >>
-            construct<IntrinsicTypeSpec>{}(
-                construct<IntrinsicTypeSpec::Complex>{}(maybe(kindSelector))) ||
-        "CHARACTER" >> construct<IntrinsicTypeSpec>{}(
-                           construct<IntrinsicTypeSpec::Character>{}(
+            construct<IntrinsicTypeSpec>(
+                construct<IntrinsicTypeSpec::Complex>(maybe(kindSelector))) ||
+        "CHARACTER" >> construct<IntrinsicTypeSpec>(
+                           construct<IntrinsicTypeSpec::Character>(
                                maybe(Parser<CharSelector>{}))) ||
         "LOGICAL" >>
-            construct<IntrinsicTypeSpec>{}(
-                construct<IntrinsicTypeSpec::Logical>{}(maybe(kindSelector))) ||
+            construct<IntrinsicTypeSpec>(
+                construct<IntrinsicTypeSpec::Logical>(maybe(kindSelector))) ||
         "DOUBLE COMPLEX" >>
-            construct<IntrinsicTypeSpec>{}(
-                extension(construct<IntrinsicTypeSpec::DoubleComplex>{})) ||
-        "NCHARACTER" >> construct<IntrinsicTypeSpec>{}(extension(
-                            construct<IntrinsicTypeSpec::NCharacter>{}(
+            construct<IntrinsicTypeSpec>(
+                extension(construct<IntrinsicTypeSpec::DoubleComplex>())) ||
+        "NCHARACTER" >> construct<IntrinsicTypeSpec>(
+                            extension(construct<IntrinsicTypeSpec::NCharacter>(
                                 maybe(Parser<LengthSelector>{})))) ||
-        extension("BYTE" >>
-            construct<IntrinsicTypeSpec>{}(construct<IntegerTypeSpec>{}(
-                construct<std::optional<KindSelector>>{}(pure(1))))))
+        extension(
+            "BYTE" >> construct<IntrinsicTypeSpec>(construct<IntegerTypeSpec>(
+                          construct<std::optional<KindSelector>>(pure(1))))))
 
 // R705 integer-type-spec -> INTEGER [kind-selector]
-TYPE_PARSER(construct<IntegerTypeSpec>{}("INTEGER" >> maybe(kindSelector)))
+TYPE_PARSER(construct<IntegerTypeSpec>("INTEGER" >> maybe(kindSelector)))
 
 // R706 kind-selector -> ( [KIND =] scalar-int-constant-expr )
 // Legacy extension: kind-selector -> * digit-string
-TYPE_PARSER(construct<KindSelector>{}(
+TYPE_PARSER(construct<KindSelector>(
                 parenthesized(maybe("KIND ="_tok) >> scalarIntConstantExpr)) ||
-    extension(construct<KindSelector>{}(
-        construct<KindSelector::StarSize>{}("*" >> digitString / spaceCheck))))
+    extension(construct<KindSelector>(
+        construct<KindSelector::StarSize>("*" >> digitString / spaceCheck))))
 
 // R710 signed-digit-string -> [sign] digit-string
 // N.B. Not a complete token -- no space is skipped.
 constexpr SignedDigitString signedDigitString;
 
 // R707 signed-int-literal-constant -> [sign] int-literal-constant
-TYPE_PARSER(space >> sourced(construct<SignedIntLiteralConstant>{}(
+TYPE_PARSER(space >> sourced(construct<SignedIntLiteralConstant>(
                          signedDigitString, maybe(underscore >> kindParam))))
 
 // R708 int-literal-constant -> digit-string [_ kind-param]
 // The negated look-ahead for a trailing underscore prevents misrecognition
 // when the digit string is a numeric kind parameter of a character literal.
-TYPE_PARSER(construct<IntLiteralConstant>{}(
+TYPE_PARSER(construct<IntLiteralConstant>(
     space >> digitString, maybe(underscore >> kindParam) / !underscore))
 
 // R709 kind-param -> digit-string | scalar-int-constant-name
-TYPE_PARSER(construct<KindParam>{}(digitString) ||
-    construct<KindParam>{}(scalar(integer(constant(name)))))
+TYPE_PARSER(construct<KindParam>(digitString) ||
+    construct<KindParam>(scalar(integer(constant(name)))))
 
 // R712 sign -> + | -
 // Not a complete token.
@@ -504,7 +496,7 @@ constexpr auto sign = "+"_ch >> pure(Sign::Positive) ||
 
 // R713 signed-real-literal-constant -> [sign] real-literal-constant
 constexpr auto signedRealLiteralConstant = space >>
-    construct<SignedRealLiteralConstant>{}(maybe(sign), realLiteralConstant);
+    construct<SignedRealLiteralConstant>(maybe(sign), realLiteralConstant);
 
 // R714 real-literal-constant ->
 //        significand [exponent-letter exponent] [_ kind-param] |
@@ -518,23 +510,23 @@ constexpr auto exponentPart =
     ("ed"_ch || extension("q"_ch)) >> signedDigitString;
 
 TYPE_CONTEXT_PARSER("REAL literal constant"_en_US,
-    construct<RealLiteralConstant>{}(
+    construct<RealLiteralConstant>(
         sourced(
             (skipDigitString >> "."_ch >>
                     !(some(letter) >> "."_ch /* don't misinterpret 1.AND. */) >>
                     maybe(skipDigitString) >> maybe(exponentPart) >> ok ||
                 "."_ch >> skipDigitString >> maybe(exponentPart) >> ok ||
                 skipDigitString >> exponentPart >> ok) >>
-            construct<RealLiteralConstant::Real>{}),
+            construct<RealLiteralConstant::Real>()),
         maybe(underscore >> kindParam)))
 
 // R718 complex-literal-constant -> ( real-part , imag-part )
 TYPE_CONTEXT_PARSER("COMPLEX literal constant"_en_US,
-    parenthesized(construct<ComplexLiteralConstant>{}(
+    parenthesized(construct<ComplexLiteralConstant>(
         Parser<ComplexPart>{} / ",", Parser<ComplexPart>{})))
 
 // PGI/Intel extension: signed complex literal constant
-TYPE_PARSER(construct<SignedComplexLiteralConstant>{}(
+TYPE_PARSER(construct<SignedComplexLiteralConstant>(
     space >> sign, Parser<ComplexLiteralConstant>{}))
 
 // R719 real-part ->
@@ -543,21 +535,21 @@ TYPE_PARSER(construct<SignedComplexLiteralConstant>{}(
 // R720 imag-part ->
 //        signed-int-literal-constant | signed-real-literal-constant |
 //        named-constant
-TYPE_PARSER(construct<ComplexPart>{}(signedRealLiteralConstant) ||
-    construct<ComplexPart>{}(signedIntLiteralConstant) ||
-    construct<ComplexPart>{}(namedConstant))
+TYPE_PARSER(construct<ComplexPart>(signedRealLiteralConstant) ||
+    construct<ComplexPart>(signedIntLiteralConstant) ||
+    construct<ComplexPart>(namedConstant))
 
 // R721 char-selector ->
 //        length-selector |
 //        ( LEN = type-param-value , KIND = scalar-int-constant-expr ) |
 //        ( type-param-value , [KIND =] scalar-int-constant-expr ) |
 //        ( KIND = scalar-int-constant-expr [, LEN = type-param-value] )
-TYPE_PARSER(construct<CharSelector>{}(Parser<LengthSelector>{}) ||
-    parenthesized(construct<CharSelector>{}(
+TYPE_PARSER(construct<CharSelector>(Parser<LengthSelector>{}) ||
+    parenthesized(construct<CharSelector>(
         "LEN =" >> typeParamValue, ", KIND =" >> scalarIntConstantExpr)) ||
-    parenthesized(construct<CharSelector>{}(
+    parenthesized(construct<CharSelector>(
         typeParamValue / ",", maybe("KIND ="_tok) >> scalarIntConstantExpr)) ||
-    parenthesized(construct<CharSelector>{}(
+    parenthesized(construct<CharSelector>(
         "KIND =" >> scalarIntConstantExpr, maybe(", LEN =" >> typeParamValue))))
 
 // R722 length-selector -> ( [LEN =] type-param-value ) | * char-length [,]
@@ -565,13 +557,13 @@ TYPE_PARSER(construct<CharSelector>{}(Parser<LengthSelector>{}) ||
 // only in the context of a type-declaration-stmt, but even with that
 // limitation, it would seem to be unnecessary and buggy to consume the comma
 // here.
-TYPE_PARSER(construct<LengthSelector>{}(
+TYPE_PARSER(construct<LengthSelector>(
                 parenthesized(maybe("LEN ="_tok) >> typeParamValue)) ||
-    construct<LengthSelector>{}("*" >> charLength /* / maybe(","_tok) */))
+    construct<LengthSelector>("*" >> charLength /* / maybe(","_tok) */))
 
 // R723 char-length -> ( type-param-value ) | digit-string
-TYPE_PARSER(construct<CharLength>{}(parenthesized(typeParamValue)) ||
-    construct<CharLength>{}(space >> digitString / spaceCheck))
+TYPE_PARSER(construct<CharLength>(parenthesized(typeParamValue)) ||
+    construct<CharLength>(space >> digitString / spaceCheck))
 
 // R724 char-literal-constant ->
 //        [kind-param _] ' [rep-char]... ' |
@@ -585,28 +577,28 @@ constexpr auto charLiteralConstantWithoutKind =
     "'"_ch >> CharLiteral<'\''>{} || "\""_ch >> CharLiteral<'"'>{};
 
 TYPE_CONTEXT_PARSER("CHARACTER literal constant"_en_US,
-    construct<CharLiteralConstant>{}(
+    construct<CharLiteralConstant>(
         kindParam / underscore, charLiteralConstantWithoutKind) ||
-        construct<CharLiteralConstant>{}(construct<std::optional<KindParam>>{},
+        construct<CharLiteralConstant>(construct<std::optional<KindParam>>(),
             space >> charLiteralConstantWithoutKind) ||
-        construct<CharLiteralConstant>{}(
-            "NC" >> construct<std::optional<KindParam>>{}(
-                        construct<KindParam>{}(construct<KindParam::Kanji>{})),
+        construct<CharLiteralConstant>(
+            "NC" >> construct<std::optional<KindParam>>(
+                        construct<KindParam>(construct<KindParam::Kanji>())),
             charLiteralConstantWithoutKind))
 
 // deprecated: Hollerith literals
 constexpr auto rawHollerithLiteral = deprecated(HollerithLiteral{});
 
-TYPE_CONTEXT_PARSER("Hollerith"_en_US,
-    construct<HollerithLiteralConstant>{}(rawHollerithLiteral))
+TYPE_CONTEXT_PARSER(
+    "Hollerith"_en_US, construct<HollerithLiteralConstant>(rawHollerithLiteral))
 
 // R725 logical-literal-constant ->
 //        .TRUE. [_ kind-param] | .FALSE. [_ kind-param]
 // Also accept .T. and .F. as extensions.
-TYPE_PARSER(construct<LogicalLiteralConstant>{}(
+TYPE_PARSER(construct<LogicalLiteralConstant>(
                 (".TRUE."_tok || extension(".T."_tok)) >> pure(true),
                 maybe(underscore >> kindParam)) ||
-    construct<LogicalLiteralConstant>{}(
+    construct<LogicalLiteralConstant>(
         (".FALSE."_tok || extension(".F."_tok)) >> pure(false),
         maybe(underscore >> kindParam)))
 
@@ -616,7 +608,7 @@ TYPE_PARSER(construct<LogicalLiteralConstant>{}(
 //        [type-bound-procedure-part] end-type-stmt
 // R735 component-part -> [component-def-stmt]...
 TYPE_CONTEXT_PARSER("derived type definition"_en_US,
-    construct<DerivedTypeDef>{}(statement(Parser<DerivedTypeStmt>{}),
+    construct<DerivedTypeDef>(statement(Parser<DerivedTypeStmt>{}),
         many(statement(Parser<TypeParamDefStmt>{})),
         many(statement(Parser<PrivateOrSequence>{})),
         many(statement(Parser<ComponentDefStmt>{})),
@@ -627,58 +619,56 @@ TYPE_CONTEXT_PARSER("derived type definition"_en_US,
 //        TYPE [[, type-attr-spec-list] ::] type-name [(
 //        type-param-name-list )]
 TYPE_CONTEXT_PARSER("TYPE statement"_en_US,
-    construct<DerivedTypeStmt>{}(
+    construct<DerivedTypeStmt>(
         "TYPE" >> optionalListBeforeColons(Parser<TypeAttrSpec>{}), name,
         defaulted(parenthesized(nonemptyList(name)))))
 
 // R728 type-attr-spec ->
 //        ABSTRACT | access-spec | BIND(C) | EXTENDS ( parent-type-name )
-TYPE_PARSER(construct<TypeAttrSpec>{}("ABSTRACT" >> construct<Abstract>{}) ||
-    construct<TypeAttrSpec>{}(
-        "BIND ( C )" >> construct<TypeAttrSpec::BindC>{}) ||
-    construct<TypeAttrSpec>{}(
-        "EXTENDS" >> construct<TypeAttrSpec::Extends>{}(parenthesized(name))) ||
-    construct<TypeAttrSpec>{}(accessSpec))
+TYPE_PARSER(construct<TypeAttrSpec>("ABSTRACT" >> construct<Abstract>()) ||
+    construct<TypeAttrSpec>("BIND ( C )" >> construct<TypeAttrSpec::BindC>()) ||
+    construct<TypeAttrSpec>(
+        "EXTENDS" >> construct<TypeAttrSpec::Extends>(parenthesized(name))) ||
+    construct<TypeAttrSpec>(accessSpec))
 
 // R729 private-or-sequence -> private-components-stmt | sequence-stmt
-TYPE_PARSER(construct<PrivateOrSequence>{}(Parser<PrivateStmt>{}) ||
-    construct<PrivateOrSequence>{}(Parser<SequenceStmt>{}))
+TYPE_PARSER(construct<PrivateOrSequence>(Parser<PrivateStmt>{}) ||
+    construct<PrivateOrSequence>(Parser<SequenceStmt>{}))
 
 // R730 end-type-stmt -> END TYPE [type-name]
 constexpr auto noNameEnd = "END" >> defaulted(cut >> maybe(name));
 constexpr auto bareEnd = noNameEnd / lookAhead(endOfStmt);
 constexpr auto endStmtErrorRecovery = noNameEnd / SkipTo<'\n'>{};
-TYPE_PARSER(construct<EndTypeStmt>{}(
+TYPE_PARSER(construct<EndTypeStmt>(
     recovery("END TYPE" >> maybe(name), endStmtErrorRecovery)))
 
 // R731 sequence-stmt -> SEQUENCE
-TYPE_PARSER("SEQUENCE" >> construct<SequenceStmt>{})
+TYPE_PARSER("SEQUENCE" >> construct<SequenceStmt>())
 
 // R732 type-param-def-stmt ->
 //        integer-type-spec , type-param-attr-spec :: type-param-decl-list
 // R734 type-param-attr-spec -> KIND | LEN
-TYPE_PARSER(construct<TypeParamDefStmt>{}(integerTypeSpec / ",",
+TYPE_PARSER(construct<TypeParamDefStmt>(integerTypeSpec / ",",
     "KIND" >> pure(TypeParamDefStmt::KindOrLen::Kind) ||
         "LEN" >> pure(TypeParamDefStmt::KindOrLen::Len),
     "::" >> nonemptyList(Parser<TypeParamDecl>{})))
 
 // R733 type-param-decl -> type-param-name [= scalar-int-constant-expr]
-TYPE_PARSER(
-    construct<TypeParamDecl>{}(name, maybe("=" >> scalarIntConstantExpr)))
+TYPE_PARSER(construct<TypeParamDecl>(name, maybe("=" >> scalarIntConstantExpr)))
 
 // R736 component-def-stmt -> data-component-def-stmt |
 //        proc-component-def-stmt
 // Accidental extension not enabled here: PGI accepts type-param-def-stmt in
 // component-part of derived-type-def.
 TYPE_PARSER(
-    recovery(construct<ComponentDefStmt>{}(Parser<DataComponentDefStmt>{}) ||
-            construct<ComponentDefStmt>{}(Parser<ProcComponentDefStmt>{}),
-        construct<ComponentDefStmt>{}(stmtErrorRecovery)))
+    recovery(construct<ComponentDefStmt>(Parser<DataComponentDefStmt>{}) ||
+            construct<ComponentDefStmt>(Parser<ProcComponentDefStmt>{}),
+        construct<ComponentDefStmt>(stmtErrorRecovery)))
 
 // R737 data-component-def-stmt ->
 //        declaration-type-spec [[, component-attr-spec-list] ::]
 //        component-decl-list
-TYPE_PARSER(construct<DataComponentDefStmt>{}(declarationTypeSpec,
+TYPE_PARSER(construct<DataComponentDefStmt>(declarationTypeSpec,
     optionalListBeforeColons(Parser<ComponentAttrSpec>{}),
     nonemptyList(Parser<ComponentDecl>{})))
 
@@ -686,49 +676,48 @@ TYPE_PARSER(construct<DataComponentDefStmt>{}(declarationTypeSpec,
 //        access-spec | ALLOCATABLE |
 //        CODIMENSION lbracket coarray-spec rbracket |
 //        CONTIGUOUS | DIMENSION ( component-array-spec ) | POINTER
-constexpr auto allocatable = "ALLOCATABLE" >> construct<Allocatable>{};
-constexpr auto contiguous = "CONTIGUOUS" >> construct<Contiguous>{};
-constexpr auto pointer = "POINTER" >> construct<Pointer>{};
-TYPE_PARSER(construct<ComponentAttrSpec>{}(accessSpec) ||
-    construct<ComponentAttrSpec>{}(allocatable) ||
-    "CODIMENSION" >> construct<ComponentAttrSpec>{}(coarraySpec) ||
-    construct<ComponentAttrSpec>{}(contiguous) ||
-    "DIMENSION" >>
-        construct<ComponentAttrSpec>{}(Parser<ComponentArraySpec>{}) ||
-    construct<ComponentAttrSpec>{}(pointer))
+constexpr auto allocatable = "ALLOCATABLE" >> construct<Allocatable>();
+constexpr auto contiguous = "CONTIGUOUS" >> construct<Contiguous>();
+constexpr auto pointer = "POINTER" >> construct<Pointer>();
+TYPE_PARSER(construct<ComponentAttrSpec>(accessSpec) ||
+    construct<ComponentAttrSpec>(allocatable) ||
+    "CODIMENSION" >> construct<ComponentAttrSpec>(coarraySpec) ||
+    construct<ComponentAttrSpec>(contiguous) ||
+    "DIMENSION" >> construct<ComponentAttrSpec>(Parser<ComponentArraySpec>{}) ||
+    construct<ComponentAttrSpec>(pointer))
 
 // R739 component-decl ->
 //        component-name [( component-array-spec )]
 //        [lbracket coarray-spec rbracket] [* char-length]
 //        [component-initialization]
 TYPE_CONTEXT_PARSER("component declaration"_en_US,
-    construct<ComponentDecl>{}(name, maybe(Parser<ComponentArraySpec>{}),
+    construct<ComponentDecl>(name, maybe(Parser<ComponentArraySpec>{}),
         maybe(coarraySpec), maybe("*" >> charLength), maybe(initialization)))
 
 // R740 component-array-spec ->
 //        explicit-shape-spec-list | deferred-shape-spec-list
 // N.B. Parenthesized here rather than around references to this production.
-TYPE_PARSER(construct<ComponentArraySpec>{}(
+TYPE_PARSER(construct<ComponentArraySpec>(
                 parenthesized(nonemptyList(explicitShapeSpec))) ||
-    construct<ComponentArraySpec>{}(parenthesized(deferredShapeSpecList)))
+    construct<ComponentArraySpec>(parenthesized(deferredShapeSpecList)))
 
 // R741 proc-component-def-stmt ->
 //        PROCEDURE ( [proc-interface] ) , proc-component-attr-spec-list
 //          :: proc-decl-list
 TYPE_CONTEXT_PARSER("PROCEDURE component definition statement"_en_US,
     "PROCEDURE" >>
-        construct<ProcComponentDefStmt>{}(parenthesized(maybe(procInterface)),
+        construct<ProcComponentDefStmt>(parenthesized(maybe(procInterface)),
             "," >> nonemptyList(Parser<ProcComponentAttrSpec>{}) / "::",
             nonemptyList(procDecl)))
 
 // R742 proc-component-attr-spec ->
 //        access-spec | NOPASS | PASS [(arg-name)] | POINTER
-constexpr auto noPass = "NOPASS" >> construct<NoPass>{};
-constexpr auto pass = "PASS" >> construct<Pass>{}(maybe(parenthesized(name)));
-TYPE_PARSER(construct<ProcComponentAttrSpec>{}(accessSpec) ||
-    construct<ProcComponentAttrSpec>{}(noPass) ||
-    construct<ProcComponentAttrSpec>{}(pass) ||
-    construct<ProcComponentAttrSpec>{}(pointer))
+constexpr auto noPass = "NOPASS" >> construct<NoPass>();
+constexpr auto pass = "PASS" >> construct<Pass>(maybe(parenthesized(name)));
+TYPE_PARSER(construct<ProcComponentAttrSpec>(accessSpec) ||
+    construct<ProcComponentAttrSpec>(noPass) ||
+    construct<ProcComponentAttrSpec>(pass) ||
+    construct<ProcComponentAttrSpec>(pointer))
 
 // R744 initial-data-target -> designator
 constexpr auto initialDataTarget = indirect(designator);
@@ -738,21 +727,21 @@ constexpr auto initialDataTarget = indirect(designator);
 // R805 initialization ->
 //        = constant-expr | => null-init | => initial-data-target
 // Universal extension: initialization -> / data-stmt-value-list /
-TYPE_PARSER("=>" >> construct<Initialization>{}(nullInit) ||
-    "=>" >> construct<Initialization>{}(initialDataTarget) ||
-    "=" >> construct<Initialization>{}(constantExpr) ||
-    extension("/" >> construct<Initialization>{}(
+TYPE_PARSER("=>" >> construct<Initialization>(nullInit) ||
+    "=>" >> construct<Initialization>(initialDataTarget) ||
+    "=" >> construct<Initialization>(constantExpr) ||
+    extension("/" >> construct<Initialization>(
                          nonemptyList(indirect(Parser<DataStmtValue>{}))) /
             "/"))
 
 // R745 private-components-stmt -> PRIVATE
 // R747 binding-private-stmt -> PRIVATE
-TYPE_PARSER("PRIVATE" >> construct<PrivateStmt>{})
+TYPE_PARSER("PRIVATE" >> construct<PrivateStmt>())
 
 // R746 type-bound-procedure-part ->
 //        contains-stmt [binding-private-stmt] [type-bound-proc-binding]...
 TYPE_CONTEXT_PARSER("type bound procedure part"_en_US,
-    construct<TypeBoundProcedurePart>{}(statement(containsStmt),
+    construct<TypeBoundProcedurePart>(statement(containsStmt),
         maybe(statement(Parser<PrivateStmt>{})),
         many(statement(Parser<TypeBoundProcBinding>{}))))
 
@@ -760,97 +749,96 @@ TYPE_CONTEXT_PARSER("type bound procedure part"_en_US,
 //        type-bound-procedure-stmt | type-bound-generic-stmt |
 //        final-procedure-stmt
 TYPE_PARSER(recovery(
-    construct<TypeBoundProcBinding>{}(Parser<TypeBoundProcedureStmt>{}) ||
-        construct<TypeBoundProcBinding>{}(Parser<TypeBoundGenericStmt>{}) ||
-        construct<TypeBoundProcBinding>{}(Parser<FinalProcedureStmt>{}),
-    construct<TypeBoundProcBinding>{}(stmtErrorRecovery)))
+    construct<TypeBoundProcBinding>(Parser<TypeBoundProcedureStmt>{}) ||
+        construct<TypeBoundProcBinding>(Parser<TypeBoundGenericStmt>{}) ||
+        construct<TypeBoundProcBinding>(Parser<FinalProcedureStmt>{}),
+    construct<TypeBoundProcBinding>(stmtErrorRecovery)))
 
 // R749 type-bound-procedure-stmt ->
 //        PROCEDURE [[, bind-attr-list] ::] type-bound-proc-decl-list |
 //        PROCEDURE ( interface-name ) , bind-attr-list :: binding-name-list
 TYPE_CONTEXT_PARSER("type bound PROCEDURE statement"_en_US,
-    "PROCEDURE" >>
-        (construct<TypeBoundProcedureStmt>{}(
-             construct<TypeBoundProcedureStmt::WithInterface>{}(
-                 parenthesized(name) / ",",
-                 nonemptyList(Parser<BindAttr>{}) / "::",
-                 nonemptyList(name))) ||
-            construct<TypeBoundProcedureStmt>{}(
-                construct<TypeBoundProcedureStmt::WithoutInterface>{}(
-                    optionalListBeforeColons(Parser<BindAttr>{}),
-                    nonemptyList(Parser<TypeBoundProcDecl>{})))))
+    "PROCEDURE" >> (construct<TypeBoundProcedureStmt>(
+                        construct<TypeBoundProcedureStmt::WithInterface>(
+                            parenthesized(name) / ",",
+                            nonemptyList(Parser<BindAttr>{}) / "::",
+                            nonemptyList(name))) ||
+                       construct<TypeBoundProcedureStmt>(
+                           construct<TypeBoundProcedureStmt::WithoutInterface>(
+                               optionalListBeforeColons(Parser<BindAttr>{}),
+                               nonemptyList(Parser<TypeBoundProcDecl>{})))))
 
 // R750 type-bound-proc-decl -> binding-name [=> procedure-name]
-TYPE_PARSER(construct<TypeBoundProcDecl>{}(name, maybe("=>" >> name)))
+TYPE_PARSER(construct<TypeBoundProcDecl>(name, maybe("=>" >> name)))
 
 // R751 type-bound-generic-stmt ->
 //        GENERIC [, access-spec] :: generic-spec => binding-name-list
 TYPE_CONTEXT_PARSER("type bound GENERIC statement"_en_US,
-    "GENERIC" >> construct<TypeBoundGenericStmt>{}(maybe("," >> accessSpec),
+    "GENERIC" >> construct<TypeBoundGenericStmt>(maybe("," >> accessSpec),
                      "::" >> indirect(genericSpec), "=>" >> nonemptyList(name)))
 
 // R752 bind-attr ->
 //        access-spec | DEFERRED | NON_OVERRIDABLE | NOPASS | PASS [(arg-name)]
-TYPE_PARSER(construct<BindAttr>{}(accessSpec) ||
-    "DEFERRED" >> construct<BindAttr>{}(construct<BindAttr::Deferred>{}) ||
+TYPE_PARSER(construct<BindAttr>(accessSpec) ||
+    "DEFERRED" >> construct<BindAttr>(construct<BindAttr::Deferred>()) ||
     "NON_OVERRIDABLE" >>
-        construct<BindAttr>{}(construct<BindAttr::Non_Overridable>{}) ||
-    construct<BindAttr>{}(noPass) || construct<BindAttr>{}(pass))
+        construct<BindAttr>(construct<BindAttr::Non_Overridable>()) ||
+    construct<BindAttr>(noPass) || construct<BindAttr>(pass))
 
 // R753 final-procedure-stmt -> FINAL [::] final-subroutine-name-list
 TYPE_CONTEXT_PARSER("FINAL statement"_en_US,
     "FINAL" >> maybe("::"_tok) >>
-        construct<FinalProcedureStmt>{}(nonemptyList(name)))
+        construct<FinalProcedureStmt>(nonemptyList(name)))
 
 // R754 derived-type-spec -> type-name [(type-param-spec-list)]
-TYPE_PARSER(construct<DerivedTypeSpec>{}(
+TYPE_PARSER(construct<DerivedTypeSpec>(
     name, defaulted(parenthesized(nonemptyList(Parser<TypeParamSpec>{})))))
 
 // R755 type-param-spec -> [keyword =] type-param-value
-TYPE_PARSER(construct<TypeParamSpec>{}(maybe(keyword / "="), typeParamValue))
+TYPE_PARSER(construct<TypeParamSpec>(maybe(keyword / "="), typeParamValue))
 
 // R756 structure-constructor -> derived-type-spec ( [component-spec-list] )
-TYPE_PARSER((construct<StructureConstructor>{}(derivedTypeSpec,
+TYPE_PARSER((construct<StructureConstructor>(derivedTypeSpec,
                  parenthesized(optionalList(Parser<ComponentSpec>{}))) ||
                 // This alternative corrects misrecognition of the
                 // component-spec-list as the type-param-spec-list in
                 // derived-type-spec.
-                construct<StructureConstructor>{}(
-                    construct<DerivedTypeSpec>{}(
-                        name, construct<std::list<TypeParamSpec>>{}),
+                construct<StructureConstructor>(
+                    construct<DerivedTypeSpec>(
+                        name, construct<std::list<TypeParamSpec>>()),
                     parenthesized(optionalList(Parser<ComponentSpec>{})))) /
     !"("_tok)
 
 // R757 component-spec -> [keyword =] component-data-source
-TYPE_PARSER(construct<ComponentSpec>{}(
+TYPE_PARSER(construct<ComponentSpec>(
     maybe(keyword / "="), Parser<ComponentDataSource>{}))
 
 // R758 component-data-source -> expr | data-target | proc-target
-TYPE_PARSER(construct<ComponentDataSource>{}(indirect(expr)))
+TYPE_PARSER(construct<ComponentDataSource>(indirect(expr)))
 
 // R759 enum-def ->
 //        enum-def-stmt enumerator-def-stmt [enumerator-def-stmt]...
 //        end-enum-stmt
 TYPE_CONTEXT_PARSER("enum definition"_en_US,
-    construct<EnumDef>{}(statement(Parser<EnumDefStmt>{}),
+    construct<EnumDef>(statement(Parser<EnumDefStmt>{}),
         some(statement(Parser<EnumeratorDefStmt>{})),
         statement(Parser<EndEnumStmt>{})))
 
 // R760 enum-def-stmt -> ENUM, BIND(C)
-TYPE_PARSER("ENUM , BIND ( C )" >> construct<EnumDefStmt>{})
+TYPE_PARSER("ENUM , BIND ( C )" >> construct<EnumDefStmt>())
 
 // R761 enumerator-def-stmt -> ENUMERATOR [::] enumerator-list
 TYPE_CONTEXT_PARSER("ENUMERATOR statement"_en_US,
-    construct<EnumeratorDefStmt>{}(
+    construct<EnumeratorDefStmt>(
         "ENUMERATOR" >> maybe("::"_tok) >> nonemptyList(Parser<Enumerator>{})))
 
 // R762 enumerator -> named-constant [= scalar-int-constant-expr]
 TYPE_PARSER(
-    construct<Enumerator>{}(namedConstant, maybe("=" >> scalarIntConstantExpr)))
+    construct<Enumerator>(namedConstant, maybe("=" >> scalarIntConstantExpr)))
 
 // R763 end-enum-stmt -> END ENUM
 TYPE_PARSER(recovery("END ENUM"_tok, "END" >> SkipTo<'\n'>{}) >>
-    construct<EndEnumStmt>{})
+    construct<EndEnumStmt>())
 
 // R764 boz-literal-constant -> binary-constant | octal-constant | hex-constant
 // R765 binary-constant -> B ' digit [digit]... ' | B " digit [digit]... "
@@ -859,55 +847,55 @@ TYPE_PARSER(recovery("END ENUM"_tok, "END" >> SkipTo<'\n'>{}) >>
 //        Z ' hex-digit [hex-digit]... ' | Z " hex-digit [hex-digit]... "
 // extension: X accepted for Z
 // extension: BOZX suffix accepted
-TYPE_PARSER(construct<BOZLiteralConstant>{}(BOZLiteral{}))
+TYPE_PARSER(construct<BOZLiteralConstant>(BOZLiteral{}))
 
 // R1124 do-variable -> scalar-int-variable-name
 constexpr auto doVariable = scalar(integer(name));
 
 template<typename PA> inline constexpr auto loopBounds(const PA &p) {
-  return construct<LoopBounds<typename PA::resultType>>{}(
+  return construct<LoopBounds<typename PA::resultType>>(
       doVariable / "=", p / ",", p, maybe("," >> p));
 }
 
 // R769 array-constructor -> (/ ac-spec /) | lbracket ac-spec rbracket
 TYPE_CONTEXT_PARSER("array constructor"_en_US,
-    construct<ArrayConstructor>{}(
+    construct<ArrayConstructor>(
         "(/" >> Parser<AcSpec>{} / "/)" || bracketed(Parser<AcSpec>{})))
 
 // R770 ac-spec -> type-spec :: | [type-spec ::] ac-value-list
-TYPE_PARSER(construct<AcSpec>{}(maybe(indirect(typeSpec) / "::"),
+TYPE_PARSER(construct<AcSpec>(maybe(indirect(typeSpec) / "::"),
                 nonemptyList(Parser<AcValue>{})) ||
-    construct<AcSpec>{}(indirect(typeSpec) / "::"))
+    construct<AcSpec>(indirect(typeSpec) / "::"))
 
 // R773 ac-value -> expr | ac-implied-do
 TYPE_PARSER(
     // PGI/Intel extension: accept triplets in array constructors
-    extension(construct<AcValue>{}(construct<AcValue::Triplet>{}(
+    extension(construct<AcValue>(construct<AcValue::Triplet>(
         scalarIntExpr, ":" >> scalarIntExpr, maybe(":" >> scalarIntExpr)))) ||
-    construct<AcValue>{}(indirect(expr)) ||
-    construct<AcValue>{}(indirect(Parser<AcImpliedDo>{})))
+    construct<AcValue>(indirect(expr)) ||
+    construct<AcValue>(indirect(Parser<AcImpliedDo>{})))
 
 // R774 ac-implied-do -> ( ac-value-list , ac-implied-do-control )
-TYPE_PARSER(parenthesized(construct<AcImpliedDo>{}(
-    nonemptyList(Parser<AcValue>{} / lookAhead(","_tok)),
-    "," >> Parser<AcImpliedDoControl>{})))
+TYPE_PARSER(parenthesized(
+    construct<AcImpliedDo>(nonemptyList(Parser<AcValue>{} / lookAhead(","_tok)),
+        "," >> Parser<AcImpliedDoControl>{})))
 
 // R775 ac-implied-do-control ->
 //        [integer-type-spec ::] ac-do-variable = scalar-int-expr ,
 //        scalar-int-expr [, scalar-int-expr]
 // R776 ac-do-variable -> do-variable
-TYPE_PARSER(construct<AcImpliedDoControl>{}(
+TYPE_PARSER(construct<AcImpliedDoControl>(
     maybe(integerTypeSpec / "::"), loopBounds(scalarIntExpr)))
 
 // R801 type-declaration-stmt ->
 //        declaration-type-spec [[, attr-spec]... ::] entity-decl-list
-TYPE_PARSER(construct<TypeDeclarationStmt>{}(declarationTypeSpec,
+TYPE_PARSER(construct<TypeDeclarationStmt>(declarationTypeSpec,
                 optionalListBeforeColons(Parser<AttrSpec>{}),
                 nonemptyList(entityDecl)) ||
     // PGI-only extension: don't require the colons
     // N.B.: The standard requires the colons if the entity
     // declarations contain initializers.
-    extension(construct<TypeDeclarationStmt>{}(declarationTypeSpec,
+    extension(construct<TypeDeclarationStmt>(declarationTypeSpec,
         defaulted("," >> nonemptyList(Parser<AttrSpec>{})),
         "," >> nonemptyList(entityDecl))))
 
@@ -917,26 +905,25 @@ TYPE_PARSER(construct<TypeDeclarationStmt>{}(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<Optional>{};
-constexpr auto protectedAttr = "PROTECTED" >> construct<Protected>{};
-constexpr auto save = "SAVE" >> construct<Save>{};
-TYPE_PARSER(construct<AttrSpec>{}(accessSpec) ||
-    construct<AttrSpec>{}(allocatable) ||
-    construct<AttrSpec>{}("ASYNCHRONOUS" >> construct<Asynchronous>{}) ||
-    construct<AttrSpec>{}("CODIMENSION" >> coarraySpec) ||
-    construct<AttrSpec>{}(contiguous) ||
-    construct<AttrSpec>{}("DIMENSION" >> arraySpec) ||
-    construct<AttrSpec>{}("EXTERNAL" >> construct<External>{}) ||
-    construct<AttrSpec>{}("INTENT" >> parenthesized(intentSpec)) ||
-    construct<AttrSpec>{}("INTRINSIC" >> construct<Intrinsic>{}) ||
-    construct<AttrSpec>{}(languageBindingSpec) ||
-    construct<AttrSpec>{}(optional) ||
-    construct<AttrSpec>{}("PARAMETER" >> construct<Parameter>{}) ||
-    construct<AttrSpec>{}(pointer) || construct<AttrSpec>{}(protectedAttr) ||
-    construct<AttrSpec>{}(save) ||
-    construct<AttrSpec>{}("TARGET" >> construct<Target>{}) ||
-    construct<AttrSpec>{}("VALUE" >> construct<Value>{}) ||
-    construct<AttrSpec>{}("VOLATILE" >> construct<Volatile>{}))
+constexpr auto optional = "OPTIONAL" >> construct<Optional>();
+constexpr auto protectedAttr = "PROTECTED" >> construct<Protected>();
+constexpr auto save = "SAVE" >> construct<Save>();
+TYPE_PARSER(construct<AttrSpec>(accessSpec) ||
+    construct<AttrSpec>(allocatable) ||
+    construct<AttrSpec>("ASYNCHRONOUS" >> construct<Asynchronous>()) ||
+    construct<AttrSpec>("CODIMENSION" >> coarraySpec) ||
+    construct<AttrSpec>(contiguous) ||
+    construct<AttrSpec>("DIMENSION" >> arraySpec) ||
+    construct<AttrSpec>("EXTERNAL" >> construct<External>()) ||
+    construct<AttrSpec>("INTENT" >> parenthesized(intentSpec)) ||
+    construct<AttrSpec>("INTRINSIC" >> construct<Intrinsic>()) ||
+    construct<AttrSpec>(languageBindingSpec) || construct<AttrSpec>(optional) ||
+    construct<AttrSpec>("PARAMETER" >> construct<Parameter>()) ||
+    construct<AttrSpec>(pointer) || construct<AttrSpec>(protectedAttr) ||
+    construct<AttrSpec>(save) ||
+    construct<AttrSpec>("TARGET" >> construct<Target>()) ||
+    construct<AttrSpec>("VALUE" >> construct<Value>()) ||
+    construct<AttrSpec>("VOLATILE" >> construct<Volatile>()))
 
 // R804 object-name -> name
 constexpr auto objectName = name;
@@ -945,43 +932,42 @@ constexpr auto objectName = name;
 //        object-name [( array-spec )] [lbracket coarray-spec rbracket]
 //          [* char-length] [initialization] |
 //        function-name [* char-length]
-TYPE_PARSER(construct<EntityDecl>{}(objectName, maybe(arraySpec),
+TYPE_PARSER(construct<EntityDecl>(objectName, maybe(arraySpec),
     maybe(coarraySpec), maybe("*" >> charLength), maybe(initialization)))
 
 // R806 null-init -> function-reference
 // TODO: confirm in semantics that NULL still intrinsic in this scope
-TYPE_PARSER("NULL ( )" >> construct<NullInit>{} / !"("_tok)
+TYPE_PARSER("NULL ( )" >> construct<NullInit>() / !"("_tok)
 
 // R807 access-spec -> PUBLIC | PRIVATE
-TYPE_PARSER(
-    "PUBLIC" >> construct<AccessSpec>{}(pure(AccessSpec::Kind::Public)) ||
-    "PRIVATE" >> construct<AccessSpec>{}(pure(AccessSpec::Kind::Private)))
+TYPE_PARSER("PUBLIC" >> construct<AccessSpec>(pure(AccessSpec::Kind::Public)) ||
+    "PRIVATE" >> construct<AccessSpec>(pure(AccessSpec::Kind::Private)))
 
 // R808 language-binding-spec ->
 //        BIND ( C [, NAME = scalar-default-char-constant-expr] )
 // R1528 proc-language-binding-spec -> language-binding-spec
-TYPE_PARSER(construct<LanguageBindingSpec>{}(
+TYPE_PARSER(construct<LanguageBindingSpec>(
     "BIND ( C" >> maybe(", NAME =" >> scalarDefaultCharConstantExpr) / ")"))
 
 // R809 coarray-spec -> deferred-coshape-spec-list | explicit-coshape-spec
 // N.B. Bracketed here rather than around references, for consistency with
 // array-spec.
 TYPE_PARSER(
-    construct<CoarraySpec>{}(bracketed(Parser<DeferredCoshapeSpecList>{})) ||
-    construct<CoarraySpec>{}(bracketed(Parser<ExplicitCoshapeSpec>{})))
+    construct<CoarraySpec>(bracketed(Parser<DeferredCoshapeSpecList>{})) ||
+    construct<CoarraySpec>(bracketed(Parser<ExplicitCoshapeSpec>{})))
 
 // R810 deferred-coshape-spec -> :
 // deferred-coshape-spec-list - just a list of colons
 inline int listLength(std::list<Success> &&xs) { return xs.size(); }
 
-TYPE_PARSER(construct<DeferredCoshapeSpecList>{}(
+TYPE_PARSER(construct<DeferredCoshapeSpecList>(
     applyFunction(listLength, nonemptyList(":"_tok))))
 
 // R811 explicit-coshape-spec ->
 //        [[lower-cobound :] upper-cobound ,]... [lower-cobound :] *
 // R812 lower-cobound -> specification-expr
 // R813 upper-cobound -> specification-expr
-TYPE_PARSER(construct<ExplicitCoshapeSpec>{}(
+TYPE_PARSER(construct<ExplicitCoshapeSpec>(
     many(explicitShapeSpec / ","), maybe(specificationExpr / ":") / "*"))
 
 // R815 array-spec ->
@@ -991,122 +977,120 @@ TYPE_PARSER(construct<ExplicitCoshapeSpec>{}(
 // N.B. Parenthesized here rather than around references to avoid
 // a need for forced look-ahead.
 TYPE_PARSER(
-    construct<ArraySpec>{}(parenthesized(nonemptyList(explicitShapeSpec))) ||
-    construct<ArraySpec>{}(
+    construct<ArraySpec>(parenthesized(nonemptyList(explicitShapeSpec))) ||
+    construct<ArraySpec>(
         parenthesized(nonemptyList(Parser<AssumedShapeSpec>{}))) ||
-    construct<ArraySpec>{}(parenthesized(deferredShapeSpecList)) ||
-    construct<ArraySpec>{}(parenthesized(Parser<AssumedSizeSpec>{})) ||
-    construct<ArraySpec>{}(parenthesized(Parser<ImpliedShapeSpec>{})) ||
-    construct<ArraySpec>{}(parenthesized(Parser<AssumedRankSpec>{})))
+    construct<ArraySpec>(parenthesized(deferredShapeSpecList)) ||
+    construct<ArraySpec>(parenthesized(Parser<AssumedSizeSpec>{})) ||
+    construct<ArraySpec>(parenthesized(Parser<ImpliedShapeSpec>{})) ||
+    construct<ArraySpec>(parenthesized(Parser<AssumedRankSpec>{})))
 
 // R816 explicit-shape-spec -> [lower-bound :] upper-bound
 // R817 lower-bound -> specification-expr
 // R818 upper-bound -> specification-expr
-TYPE_PARSER(construct<ExplicitShapeSpec>{}(
+TYPE_PARSER(construct<ExplicitShapeSpec>(
     maybe(specificationExpr / ":"), specificationExpr))
 
 // R819 assumed-shape-spec -> [lower-bound] :
-TYPE_PARSER(construct<AssumedShapeSpec>{}(maybe(specificationExpr) / ":"))
+TYPE_PARSER(construct<AssumedShapeSpec>(maybe(specificationExpr) / ":"))
 
 // R820 deferred-shape-spec -> :
 // deferred-shape-spec-list - just a list of colons
-TYPE_PARSER(construct<DeferredShapeSpecList>{}(
+TYPE_PARSER(construct<DeferredShapeSpecList>(
     applyFunction(listLength, nonemptyList(":"_tok))))
 
 // R821 assumed-implied-spec -> [lower-bound :] *
-TYPE_PARSER(
-    construct<AssumedImpliedSpec>{}(maybe(specificationExpr / ":") / "*"))
+TYPE_PARSER(construct<AssumedImpliedSpec>(maybe(specificationExpr / ":") / "*"))
 
 // R822 assumed-size-spec -> explicit-shape-spec-list , assumed-implied-spec
-TYPE_PARSER(construct<AssumedSizeSpec>{}(
+TYPE_PARSER(construct<AssumedSizeSpec>(
     nonemptyList(explicitShapeSpec) / ",", assumedImpliedSpec))
 
 // R823 implied-shape-or-assumed-size-spec -> assumed-implied-spec
 // R824 implied-shape-spec -> assumed-implied-spec , assumed-implied-spec-list
 // I.e., when the assumed-implied-spec-list has a single item, it constitutes an
 // implied-shape-or-assumed-size-spec; otherwise, an implied-shape-spec.
-TYPE_PARSER(construct<ImpliedShapeSpec>{}(nonemptyList(assumedImpliedSpec)))
+TYPE_PARSER(construct<ImpliedShapeSpec>(nonemptyList(assumedImpliedSpec)))
 
 // R825 assumed-rank-spec -> ..
-TYPE_PARSER(".." >> construct<AssumedRankSpec>{})
+TYPE_PARSER(".." >> construct<AssumedRankSpec>())
 
 // R826 intent-spec -> IN | OUT | INOUT
-TYPE_PARSER(
-    construct<IntentSpec>{}("IN OUT" >> pure(IntentSpec::Intent::InOut) ||
-        "IN" >> pure(IntentSpec::Intent::In) ||
-        "OUT" >> pure(IntentSpec::Intent::Out)))
+TYPE_PARSER(construct<IntentSpec>("IN OUT" >> pure(IntentSpec::Intent::InOut) ||
+    "IN" >> pure(IntentSpec::Intent::In) ||
+    "OUT" >> pure(IntentSpec::Intent::Out)))
 
 // R827 access-stmt -> access-spec [[::] access-id-list]
-TYPE_PARSER(construct<AccessStmt>{}(
+TYPE_PARSER(construct<AccessStmt>(
     accessSpec, defaulted(maybe("::"_tok) >> nonemptyList(Parser<AccessId>{}))))
 
 // R828 access-id -> access-name | generic-spec
-TYPE_PARSER(construct<AccessId>{}(indirect(genericSpec)) ||
-    construct<AccessId>{}(name))  // initially ambiguous with genericSpec
+TYPE_PARSER(construct<AccessId>(indirect(genericSpec)) ||
+    construct<AccessId>(name))  // initially ambiguous with genericSpec
 
 // R829 allocatable-stmt -> ALLOCATABLE [::] allocatable-decl-list
 TYPE_PARSER("ALLOCATABLE" >> maybe("::"_tok) >>
-    construct<AllocatableStmt>{}(nonemptyList(Parser<ObjectDecl>{})))
+    construct<AllocatableStmt>(nonemptyList(Parser<ObjectDecl>{})))
 
 // R830 allocatable-decl ->
 //        object-name [( array-spec )] [lbracket coarray-spec rbracket]
 // R860 target-decl ->
 //        object-name [( array-spec )] [lbracket coarray-spec rbracket]
 TYPE_PARSER(
-    construct<ObjectDecl>{}(objectName, maybe(arraySpec), maybe(coarraySpec)))
+    construct<ObjectDecl>(objectName, maybe(arraySpec), maybe(coarraySpec)))
 
 // R831 asynchronous-stmt -> ASYNCHRONOUS [::] object-name-list
 TYPE_PARSER("ASYNCHRONOUS" >> maybe("::"_tok) >>
-    construct<AsynchronousStmt>{}(nonemptyList(objectName)))
+    construct<AsynchronousStmt>(nonemptyList(objectName)))
 
 // R832 bind-stmt -> language-binding-spec [::] bind-entity-list
-TYPE_PARSER(construct<BindStmt>{}(
+TYPE_PARSER(construct<BindStmt>(
     languageBindingSpec / maybe("::"_tok), nonemptyList(Parser<BindEntity>{})))
 
 // R833 bind-entity -> entity-name | / common-block-name /
-TYPE_PARSER(construct<BindEntity>{}(pure(BindEntity::Kind::Object), name) ||
-    "/" >> construct<BindEntity>{}(pure(BindEntity::Kind::Common), name) / "/")
+TYPE_PARSER(construct<BindEntity>(pure(BindEntity::Kind::Object), name) ||
+    "/" >> construct<BindEntity>(pure(BindEntity::Kind::Common), name) / "/")
 
 // R834 codimension-stmt -> CODIMENSION [::] codimension-decl-list
 TYPE_PARSER("CODIMENSION" >> maybe("::"_tok) >>
-    construct<CodimensionStmt>{}(nonemptyList(Parser<CodimensionDecl>{})))
+    construct<CodimensionStmt>(nonemptyList(Parser<CodimensionDecl>{})))
 
 // R835 codimension-decl -> coarray-name lbracket coarray-spec rbracket
-TYPE_PARSER(construct<CodimensionDecl>{}(name, coarraySpec))
+TYPE_PARSER(construct<CodimensionDecl>(name, coarraySpec))
 
 // R836 contiguous-stmt -> CONTIGUOUS [::] object-name-list
 TYPE_PARSER("CONTIGUOUS" >> maybe("::"_tok) >>
-    construct<ContiguousStmt>{}(nonemptyList(objectName)))
+    construct<ContiguousStmt>(nonemptyList(objectName)))
 
 // R837 data-stmt -> DATA data-stmt-set [[,] data-stmt-set]...
 TYPE_CONTEXT_PARSER("DATA statement"_en_US,
-    "DATA" >> construct<DataStmt>{}(
+    "DATA" >> construct<DataStmt>(
                   nonemptySeparated(Parser<DataStmtSet>{}, maybe(","_tok))))
 
 // R838 data-stmt-set -> data-stmt-object-list / data-stmt-value-list /
-TYPE_PARSER(construct<DataStmtSet>{}(nonemptyList(Parser<DataStmtObject>{}),
+TYPE_PARSER(construct<DataStmtSet>(nonemptyList(Parser<DataStmtObject>{}),
     "/"_tok >> nonemptyList(Parser<DataStmtValue>{}) / "/"))
 
 // R839 data-stmt-object -> variable | data-implied-do
-TYPE_PARSER(construct<DataStmtObject>{}(indirect(variable)) ||
-    construct<DataStmtObject>{}(dataImpliedDo))
+TYPE_PARSER(construct<DataStmtObject>(indirect(variable)) ||
+    construct<DataStmtObject>(dataImpliedDo))
 
 // R840 data-implied-do ->
 //        ( data-i-do-object-list , [integer-type-spec ::] data-i-do-variable
 //        = scalar-int-constant-expr , scalar-int-constant-expr
 //        [, scalar-int-constant-expr] )
 // R842 data-i-do-variable -> do-variable
-TYPE_PARSER(parenthesized(construct<DataImpliedDo>{}(
+TYPE_PARSER(parenthesized(construct<DataImpliedDo>(
     nonemptyList(Parser<DataIDoObject>{} / lookAhead(","_tok)) / ",",
     maybe(integerTypeSpec / "::"), loopBounds(scalarIntConstantExpr))))
 
 // R841 data-i-do-object ->
 //        array-element | scalar-structure-component | data-implied-do
-TYPE_PARSER(construct<DataIDoObject>{}(scalar(indirect(designator))) ||
-    construct<DataIDoObject>{}(indirect(dataImpliedDo)))
+TYPE_PARSER(construct<DataIDoObject>(scalar(indirect(designator))) ||
+    construct<DataIDoObject>(indirect(dataImpliedDo)))
 
 // R843 data-stmt-value -> [data-stmt-repeat *] data-stmt-constant
-TYPE_PARSER(construct<DataStmtValue>{}(
+TYPE_PARSER(construct<DataStmtValue>(
     maybe(Parser<DataStmtRepeat>{} / "*"), Parser<DataStmtConstant>{}))
 
 // R847 constant-subobject -> designator
@@ -1118,9 +1102,9 @@ constexpr auto constantSubobject = constant(indirect(designator));
 // Factored into:
 //   constant -> literal-constant -> int-literal-constant   and
 //   constant -> named-constant
-TYPE_PARSER(construct<DataStmtRepeat>{}(intLiteralConstant) ||
-    construct<DataStmtRepeat>{}(scalar(integer(constantSubobject))) ||
-    construct<DataStmtRepeat>{}(scalar(integer(namedConstant))))
+TYPE_PARSER(construct<DataStmtRepeat>(intLiteralConstant) ||
+    construct<DataStmtRepeat>(scalar(integer(constantSubobject))) ||
+    construct<DataStmtRepeat>(scalar(integer(namedConstant))))
 
 // R845 data-stmt-constant ->
 //        scalar-constant | scalar-constant-subobject |
@@ -1128,81 +1112,80 @@ TYPE_PARSER(construct<DataStmtRepeat>{}(intLiteralConstant) ||
 //        null-init | initial-data-target | structure-constructor
 // TODO: Some structure constructors can be misrecognized as array
 // references into constant subobjects.
-TYPE_PARSER(construct<DataStmtConstant>{}(scalar(Parser<ConstantValue>{})) ||
-    construct<DataStmtConstant>{}(nullInit) ||
-    construct<DataStmtConstant>{}(Parser<StructureConstructor>{}) ||
-    construct<DataStmtConstant>{}(scalar(constantSubobject)) ||
-    construct<DataStmtConstant>{}(signedRealLiteralConstant) ||
-    construct<DataStmtConstant>{}(signedIntLiteralConstant) ||
-    extension(construct<DataStmtConstant>{}(
-        Parser<SignedComplexLiteralConstant>{})) ||
-    construct<DataStmtConstant>{}(initialDataTarget))
+TYPE_PARSER(construct<DataStmtConstant>(scalar(Parser<ConstantValue>{})) ||
+    construct<DataStmtConstant>(nullInit) ||
+    construct<DataStmtConstant>(Parser<StructureConstructor>{}) ||
+    construct<DataStmtConstant>(scalar(constantSubobject)) ||
+    construct<DataStmtConstant>(signedRealLiteralConstant) ||
+    construct<DataStmtConstant>(signedIntLiteralConstant) ||
+    extension(
+        construct<DataStmtConstant>(Parser<SignedComplexLiteralConstant>{})) ||
+    construct<DataStmtConstant>(initialDataTarget))
 
 // R848 dimension-stmt ->
 //        DIMENSION [::] array-name ( array-spec )
 //        [, array-name ( array-spec )]...
 TYPE_CONTEXT_PARSER("DIMENSION statement"_en_US,
     "DIMENSION" >> maybe("::"_tok) >>
-        construct<DimensionStmt>{}(nonemptyList(
-            construct<DimensionStmt::Declaration>{}(name, arraySpec))))
+        construct<DimensionStmt>(nonemptyList(
+            construct<DimensionStmt::Declaration>(name, arraySpec))))
 
 // R849 intent-stmt -> INTENT ( intent-spec ) [::] dummy-arg-name-list
 TYPE_CONTEXT_PARSER("INTENT statement"_en_US,
     "INTENT" >>
-        construct<IntentStmt>{}(
+        construct<IntentStmt>(
             parenthesized(intentSpec) / maybe("::"_tok), nonemptyList(name)))
 
 // R850 optional-stmt -> OPTIONAL [::] dummy-arg-name-list
 TYPE_PARSER("OPTIONAL" >> maybe("::"_tok) >>
-    construct<OptionalStmt>{}(nonemptyList(name)))
+    construct<OptionalStmt>(nonemptyList(name)))
 
 // R851 parameter-stmt -> PARAMETER ( named-constant-def-list )
 // Legacy extension: omitted parentheses, no implicit typing from names
 TYPE_CONTEXT_PARSER("PARAMETER statement"_en_US,
-    construct<ParameterStmt>{}(
+    construct<ParameterStmt>(
         "PARAMETER" >> parenthesized(nonemptyList(Parser<NamedConstantDef>{}))))
 TYPE_CONTEXT_PARSER("old style PARAMETER statement"_en_US,
-    extension(construct<OldParameterStmt>{}(
+    extension(construct<OldParameterStmt>(
         "PARAMETER" >> nonemptyList(Parser<NamedConstantDef>{}))))
 
 // R852 named-constant-def -> named-constant = constant-expr
-TYPE_PARSER(construct<NamedConstantDef>{}(namedConstant, "=" >> constantExpr))
+TYPE_PARSER(construct<NamedConstantDef>(namedConstant, "=" >> constantExpr))
 
 // R853 pointer-stmt -> POINTER [::] pointer-decl-list
 TYPE_PARSER("POINTER" >> maybe("::"_tok) >>
-    construct<PointerStmt>{}(nonemptyList(Parser<PointerDecl>{})))
+    construct<PointerStmt>(nonemptyList(Parser<PointerDecl>{})))
 
 // R854 pointer-decl ->
 //        object-name [( deferred-shape-spec-list )] | proc-entity-name
 TYPE_PARSER(
-    construct<PointerDecl>{}(name, maybe(parenthesized(deferredShapeSpecList))))
+    construct<PointerDecl>(name, maybe(parenthesized(deferredShapeSpecList))))
 
 // R855 protected-stmt -> PROTECTED [::] entity-name-list
 TYPE_PARSER("PROTECTED" >> maybe("::"_tok) >>
-    construct<ProtectedStmt>{}(nonemptyList(name)))
+    construct<ProtectedStmt>(nonemptyList(name)))
 
 // R856 save-stmt -> SAVE [[::] saved-entity-list]
-TYPE_PARSER("SAVE" >> construct<SaveStmt>{}(defaulted(maybe("::"_tok) >>
+TYPE_PARSER("SAVE" >> construct<SaveStmt>(defaulted(maybe("::"_tok) >>
                           nonemptyList(Parser<SavedEntity>{}))))
 
 // R857 saved-entity -> object-name | proc-pointer-name | / common-block-name /
 // R858 proc-pointer-name -> name
 // TODO: Distinguish Kind::ProcPointer and Kind::Object
-TYPE_PARSER(construct<SavedEntity>{}(pure(SavedEntity::Kind::Object), name) ||
-    "/" >>
-        construct<SavedEntity>{}(pure(SavedEntity::Kind::Common), name) / "/")
+TYPE_PARSER(construct<SavedEntity>(pure(SavedEntity::Kind::Object), name) ||
+    "/" >> construct<SavedEntity>(pure(SavedEntity::Kind::Common), name) / "/")
 
 // R859 target-stmt -> TARGET [::] target-decl-list
 TYPE_PARSER("TARGET" >> maybe("::"_tok) >>
-    construct<TargetStmt>{}(nonemptyList(Parser<ObjectDecl>{})))
+    construct<TargetStmt>(nonemptyList(Parser<ObjectDecl>{})))
 
 // R861 value-stmt -> VALUE [::] dummy-arg-name-list
 TYPE_PARSER(
-    "VALUE" >> maybe("::"_tok) >> construct<ValueStmt>{}(nonemptyList(name)))
+    "VALUE" >> maybe("::"_tok) >> construct<ValueStmt>(nonemptyList(name)))
 
 // R862 volatile-stmt -> VOLATILE [::] object-name-list
 TYPE_PARSER("VOLATILE" >> maybe("::"_tok) >>
-    construct<VolatileStmt>{}(nonemptyList(objectName)))
+    construct<VolatileStmt>(nonemptyList(objectName)))
 
 // R866 implicit-name-spec -> EXTERNAL | TYPE
 constexpr auto implicitNameSpec = "EXTERNAL" >>
@@ -1214,8 +1197,8 @@ constexpr auto implicitNameSpec = "EXTERNAL" >>
 //        IMPLICIT NONE [( [implicit-name-spec-list] )]
 TYPE_CONTEXT_PARSER("IMPLICIT statement"_en_US,
     "IMPLICIT" >>
-        (construct<ImplicitStmt>{}(nonemptyList(Parser<ImplicitSpec>{})) ||
-            construct<ImplicitStmt>{}("NONE" >>
+        (construct<ImplicitStmt>(nonemptyList(Parser<ImplicitSpec>{})) ||
+            construct<ImplicitStmt>("NONE" >>
                 defaulted(parenthesized(optionalList(implicitNameSpec))))))
 
 // R864 implicit-spec -> declaration-type-spec ( letter-spec-list )
@@ -1225,74 +1208,74 @@ TYPE_CONTEXT_PARSER("IMPLICIT statement"_en_US,
 // IMPLICIT REAL(I-N).  The variant form needs to attempt to reparse only
 // types with optional parenthesized kind/length expressions, so derived
 // type specs, DOUBLE PRECISION, and DOUBLE COMPLEX need not be considered.
-constexpr auto noKindSelector = construct<std::optional<KindSelector>>{};
+constexpr auto noKindSelector = construct<std::optional<KindSelector>>();
 constexpr auto implicitSpecDeclarationTypeSpecRetry =
-    construct<DeclarationTypeSpec>{}(
-        "INTEGER" >> construct<IntrinsicTypeSpec>{}(
-                         construct<IntegerTypeSpec>{}(noKindSelector)) ||
-        "REAL" >> construct<IntrinsicTypeSpec>{}(
-                      construct<IntrinsicTypeSpec::Real>{}(noKindSelector)) ||
+    construct<DeclarationTypeSpec>(
+        "INTEGER" >> construct<IntrinsicTypeSpec>(
+                         construct<IntegerTypeSpec>(noKindSelector)) ||
+        "REAL" >> construct<IntrinsicTypeSpec>(
+                      construct<IntrinsicTypeSpec::Real>(noKindSelector)) ||
         "COMPLEX" >>
-            construct<IntrinsicTypeSpec>{}(
-                construct<IntrinsicTypeSpec::Complex>{}(noKindSelector)) ||
-        "CHARACTER" >> construct<IntrinsicTypeSpec>{}(
-                           construct<IntrinsicTypeSpec::Character>{}(
-                               construct<std::optional<CharSelector>>{})) ||
+            construct<IntrinsicTypeSpec>(
+                construct<IntrinsicTypeSpec::Complex>(noKindSelector)) ||
+        "CHARACTER" >> construct<IntrinsicTypeSpec>(
+                           construct<IntrinsicTypeSpec::Character>(
+                               construct<std::optional<CharSelector>>())) ||
         "LOGICAL" >>
-            construct<IntrinsicTypeSpec>{}(
-                construct<IntrinsicTypeSpec::Logical>{}(noKindSelector)));
+            construct<IntrinsicTypeSpec>(
+                construct<IntrinsicTypeSpec::Logical>(noKindSelector)));
 
-TYPE_PARSER(construct<ImplicitSpec>{}(declarationTypeSpec,
+TYPE_PARSER(construct<ImplicitSpec>(declarationTypeSpec,
                 parenthesized(nonemptyList(Parser<LetterSpec>{}))) ||
-    construct<ImplicitSpec>{}(implicitSpecDeclarationTypeSpecRetry,
+    construct<ImplicitSpec>(implicitSpecDeclarationTypeSpecRetry,
         parenthesized(nonemptyList(Parser<LetterSpec>{}))))
 
 // R865 letter-spec -> letter [- letter]
-TYPE_PARSER(space >> (construct<LetterSpec>{}(letter, maybe("-" >> letter)) ||
-                         construct<LetterSpec>{}(otherIdChar,
-                             construct<std::optional<const char *>>{})))
+TYPE_PARSER(space >> (construct<LetterSpec>(letter, maybe("-" >> letter)) ||
+                         construct<LetterSpec>(otherIdChar,
+                             construct<std::optional<const char *>>())))
 
 // R867 import-stmt ->
 //        IMPORT [[::] import-name-list] |
 //        IMPORT , ONLY : import-name-list | IMPORT , NONE | IMPORT , ALL
 TYPE_CONTEXT_PARSER("IMPORT statement"_en_US,
     "IMPORT" >>
-        (construct<ImportStmt>{}(
+        (construct<ImportStmt>(
              ", ONLY :" >> pure(ImportStmt::Kind::Only), nonemptyList(name)) ||
-            construct<ImportStmt>{}(", NONE" >> pure(ImportStmt::Kind::None)) ||
-            construct<ImportStmt>{}(", ALL" >> pure(ImportStmt::Kind::All)) ||
-            construct<ImportStmt>{}(maybe("::"_tok) >> optionalList(name))))
+            construct<ImportStmt>(", NONE" >> pure(ImportStmt::Kind::None)) ||
+            construct<ImportStmt>(", ALL" >> pure(ImportStmt::Kind::All)) ||
+            construct<ImportStmt>(maybe("::"_tok) >> optionalList(name))))
 
 // R868 namelist-stmt ->
 //        NAMELIST / namelist-group-name / namelist-group-object-list
 //        [[,] / namelist-group-name / namelist-group-object-list]...
 // R869 namelist-group-object -> variable-name
 TYPE_PARSER("NAMELIST" >>
-    construct<NamelistStmt>{}(nonemptySeparated(
-        construct<NamelistStmt::Group>{}("/" >> name / "/", nonemptyList(name)),
+    construct<NamelistStmt>(nonemptySeparated(
+        construct<NamelistStmt::Group>("/" >> name / "/", nonemptyList(name)),
         maybe(","_tok))))
 
 // R870 equivalence-stmt -> EQUIVALENCE equivalence-set-list
 // R871 equivalence-set -> ( equivalence-object , equivalence-object-list )
 TYPE_PARSER("EQUIVALENCE" >>
-    construct<EquivalenceStmt>{}(
+    construct<EquivalenceStmt>(
         nonemptyList(parenthesized(nonemptyList(Parser<EquivalenceObject>{})))))
 
 // R872 equivalence-object -> variable-name | array-element | substring
-TYPE_PARSER(construct<EquivalenceObject>{}(indirect(designator)))
+TYPE_PARSER(construct<EquivalenceObject>(indirect(designator)))
 
 // R873 common-stmt ->
 //        COMMON [/ [common-block-name] /] common-block-object-list
 //        [[,] / [common-block-name] / common-block-object-list]...
 TYPE_PARSER(
-    "COMMON" >> construct<CommonStmt>{}(maybe("/" >> maybe(name) / "/"),
+    "COMMON" >> construct<CommonStmt>(maybe("/" >> maybe(name) / "/"),
                     nonemptyList(Parser<CommonBlockObject>{}),
                     many(maybe(","_tok) >>
-                        construct<CommonStmt::Block>{}("/" >> maybe(name) / "/",
+                        construct<CommonStmt::Block>("/" >> maybe(name) / "/",
                             nonemptyList(Parser<CommonBlockObject>{})))))
 
 // R874 common-block-object -> variable-name [( array-spec )]
-TYPE_PARSER(construct<CommonBlockObject>{}(name, maybe(arraySpec)))
+TYPE_PARSER(construct<CommonBlockObject>(name, maybe(arraySpec)))
 
 // R901 designator -> object-name | array-element | array-section |
 //                    coindexed-named-object | complex-part-designator |
@@ -1309,7 +1292,7 @@ TYPE_PARSER(construct<CommonBlockObject>{}(name, maybe(arraySpec)))
 //  maybe an [image-selector].
 //  If it's a substring, it ends with (substring-range).
 TYPE_CONTEXT_PARSER("designator"_en_US,
-    construct<Designator>{}(substring) || construct<Designator>{}(dataRef))
+    construct<Designator>(substring) || construct<Designator>(dataRef))
 
 constexpr auto percentOrDot = "%"_tok ||
     // legacy VAX extension for RECORD field access
@@ -1326,16 +1309,16 @@ constexpr auto percentOrDot = "%"_tok ||
 // proc-component-ref to be a data-ref without coindices (C1027).
 // Some array element references will be misrecognized as function references.
 TYPE_CONTEXT_PARSER("variable"_en_US,
-    construct<Variable>{}(
+    construct<Variable>(
         indirect(functionReference / !"("_ch) / !percentOrDot) ||
-        construct<Variable>{}(indirect(designator)))
+        construct<Variable>(indirect(designator)))
 
 // R904 logical-variable -> variable
 // Appears only as part of scalar-logical-variable.
 constexpr auto scalarLogicalVariable = scalar(logical(variable));
 
 // R905 char-variable -> variable
-constexpr auto charVariable = construct<CharVariable>{}(variable);
+constexpr auto charVariable = construct<CharVariable>(variable);
 
 // R906 default-char-variable -> variable
 // Appears only as part of scalar-default-char-variable.
@@ -1351,13 +1334,13 @@ constexpr auto scalarIntVariable = scalar(integer(variable));
 //        scalar-structure-component | scalar-char-literal-constant |
 //        scalar-named-constant
 TYPE_PARSER(
-    construct<Substring>{}(dataRef, parenthesized(Parser<SubstringRange>{})))
+    construct<Substring>(dataRef, parenthesized(Parser<SubstringRange>{})))
 
-TYPE_PARSER(construct<CharLiteralConstantSubstring>{}(
+TYPE_PARSER(construct<CharLiteralConstantSubstring>(
     charLiteralConstant, parenthesized(Parser<SubstringRange>{})))
 
 // R910 substring-range -> [scalar-int-expr] : [scalar-int-expr]
-TYPE_PARSER(construct<SubstringRange>{}(
+TYPE_PARSER(construct<SubstringRange>(
     maybe(scalarIntExpr), ":" >> maybe(scalarIntExpr)))
 
 // R1003 defined-unary-op -> . letter [letter]... .
@@ -1366,37 +1349,37 @@ TYPE_PARSER(construct<SubstringRange>{}(
 // R1415 use-defined-operator -> defined-unary-op | defined-binary-op
 // N.B. The name of the operator is captured without the periods around it.
 TYPE_PARSER(space >> "."_ch >>
-    construct<DefinedOpName>{}(sourced(some(letter) >> construct<Name>{})) /
+    construct<DefinedOpName>(sourced(some(letter) >> construct<Name>())) /
         "."_ch)
 
 // R911 data-ref -> part-ref [% part-ref]...
 // R914 coindexed-named-object -> data-ref
 // R917 array-element -> data-ref
 TYPE_PARSER(
-    construct<DataRef>{}(nonemptySeparated(Parser<PartRef>{}, percentOrDot)))
+    construct<DataRef>(nonemptySeparated(Parser<PartRef>{}, percentOrDot)))
 
 // R912 part-ref -> part-name [( section-subscript-list )] [image-selector]
-TYPE_PARSER(construct<PartRef>{}(name,
+TYPE_PARSER(construct<PartRef>(name,
     defaulted(
         parenthesized(nonemptyList(Parser<SectionSubscript>{})) / !"=>"_tok),
     maybe(Parser<ImageSelector>{})))
 
 // R913 structure-component -> data-ref
-TYPE_PARSER(construct<StructureComponent>{}(
-    construct<DataRef>{}(some(Parser<PartRef>{} / percentOrDot)), name))
+TYPE_PARSER(construct<StructureComponent>(
+    construct<DataRef>(some(Parser<PartRef>{} / percentOrDot)), name))
 
 // R915 complex-part-designator -> designator % RE | designator % IM
 // %RE and %IM are initially recognized as structure components.
 constexpr auto complexPartDesignator =
-    construct<ComplexPartDesignator>{}(dataRef);
+    construct<ComplexPartDesignator>(dataRef);
 
 // R916 type-param-inquiry -> designator % type-param-name
 // Type parameter inquiries are initially recognized as structure components.
-TYPE_PARSER(construct<TypeParamInquiry>{}(structureComponent))
+TYPE_PARSER(construct<TypeParamInquiry>(structureComponent))
 
 // R918 array-section ->
 //        data-ref [( substring-range )] | complex-part-designator
-constexpr auto arraySection = construct<ArraySection>{}(designator);
+constexpr auto arraySection = construct<ArraySection>(designator);
 
 // R919 subscript -> scalar-int-expr
 constexpr auto subscript = scalarIntExpr;
@@ -1407,12 +1390,12 @@ constexpr auto vectorSubscript = intExpr;
 // R920 section-subscript -> subscript | subscript-triplet | vector-subscript
 // N.B. The distinction that needs to be made between "subscript" and
 // "vector-subscript" is deferred to semantic analysis.
-TYPE_PARSER(construct<SectionSubscript>{}(Parser<SubscriptTriplet>{}) ||
-    construct<SectionSubscript>{}(vectorSubscript) ||
-    construct<SectionSubscript>{}(subscript))
+TYPE_PARSER(construct<SectionSubscript>(Parser<SubscriptTriplet>{}) ||
+    construct<SectionSubscript>(vectorSubscript) ||
+    construct<SectionSubscript>(subscript))
 
 // R921 subscript-triplet -> [subscript] : [subscript] [: stride]
-TYPE_PARSER(construct<SubscriptTriplet>{}(
+TYPE_PARSER(construct<SubscriptTriplet>(
     maybe(subscript), ":" >> maybe(subscript), maybe(":" >> subscript)))
 
 // R925 cosubscript -> scalar-int-expr
@@ -1420,7 +1403,7 @@ constexpr auto cosubscript = scalarIntExpr;
 
 // R924 image-selector ->
 //        lbracket cosubscript-list [, image-selector-spec-list] rbracket
-TYPE_PARSER(bracketed(construct<ImageSelector>{}(nonemptyList(cosubscript),
+TYPE_PARSER(bracketed(construct<ImageSelector>(nonemptyList(cosubscript),
     defaulted("," >> nonemptyList(Parser<ImageSelectorSpec>{})))))
 
 // R1115 team-variable -> scalar-variable
@@ -1429,53 +1412,51 @@ constexpr auto teamVariable = scalar(indirect(variable));
 // R926 image-selector-spec ->
 //        STAT = stat-variable | TEAM = team-variable |
 //        TEAM_NUMBER = scalar-int-expr
-TYPE_PARSER("STAT =" >>
-        construct<ImageSelectorSpec>{}(construct<ImageSelectorSpec::Stat>{}(
-            scalar(integer(indirect(variable))))) ||
-    "TEAM =" >> construct<ImageSelectorSpec>{}(
-                    construct<ImageSelectorSpec::Team>{}(teamVariable)) ||
+TYPE_PARSER(
+    "STAT =" >> construct<ImageSelectorSpec>(construct<ImageSelectorSpec::Stat>(
+                    scalar(integer(indirect(variable))))) ||
+    "TEAM =" >> construct<ImageSelectorSpec>(
+                    construct<ImageSelectorSpec::Team>(teamVariable)) ||
     "TEAM_NUMBER =" >>
-        construct<ImageSelectorSpec>{}(
-            construct<ImageSelectorSpec::Team_Number>{}(scalarIntExpr)))
+        construct<ImageSelectorSpec>(
+            construct<ImageSelectorSpec::Team_Number>(scalarIntExpr)))
 
 // R927 allocate-stmt ->
 //        ALLOCATE ( [type-spec ::] allocation-list [, alloc-opt-list] )
 TYPE_CONTEXT_PARSER("ALLOCATE statement"_en_US,
-    "ALLOCATE" >>
-        parenthesized(construct<AllocateStmt>{}(maybe(typeSpec / "::"),
-            nonemptyList(Parser<Allocation>{}),
-            defaulted("," >> nonemptyList(Parser<AllocOpt>{})))))
+    "ALLOCATE" >> parenthesized(construct<AllocateStmt>(maybe(typeSpec / "::"),
+                      nonemptyList(Parser<Allocation>{}),
+                      defaulted("," >> nonemptyList(Parser<AllocOpt>{})))))
 
 // R928 alloc-opt ->
 //        ERRMSG = errmsg-variable | MOLD = source-expr |
 //        SOURCE = source-expr | STAT = stat-variable
 // R931 source-expr -> expr
 TYPE_PARSER("MOLD =" >>
-        construct<AllocOpt>{}(construct<AllocOpt::Mold>{}(indirect(expr))) ||
+        construct<AllocOpt>(construct<AllocOpt::Mold>(indirect(expr))) ||
     "SOURCE =" >>
-        construct<AllocOpt>{}(construct<AllocOpt::Source>{}(indirect(expr))) ||
-    construct<AllocOpt>{}(statOrErrmsg))
+        construct<AllocOpt>(construct<AllocOpt::Source>(indirect(expr))) ||
+    construct<AllocOpt>(statOrErrmsg))
 
 // R929 stat-variable -> scalar-int-variable
-TYPE_PARSER(construct<StatVariable>{}(scalar(integer(variable))))
+TYPE_PARSER(construct<StatVariable>(scalar(integer(variable))))
 
 // R930 errmsg-variable -> scalar-default-char-variable
 // R1207 iomsg-variable -> scalar-default-char-variable
-constexpr auto msgVariable =
-    construct<MsgVariable>{}(scalarDefaultCharVariable);
+constexpr auto msgVariable = construct<MsgVariable>(scalarDefaultCharVariable);
 
 // R932 allocation ->
 //        allocate-object [( allocate-shape-spec-list )]
 //        [lbracket allocate-coarray-spec rbracket]
 // TODO: allocate-shape-spec-list might be misrecognized as
 // the final list of subscripts in allocate-object.
-TYPE_PARSER(construct<Allocation>{}(Parser<AllocateObject>{},
+TYPE_PARSER(construct<Allocation>(Parser<AllocateObject>{},
     defaulted(parenthesized(nonemptyList(Parser<AllocateShapeSpec>{}))),
     maybe(bracketed(Parser<AllocateCoarraySpec>{}))))
 
 // R933 allocate-object -> variable-name | structure-component
-TYPE_PARSER(construct<AllocateObject>{}(structureComponent) ||
-    construct<AllocateObject>{}(name / !"="_tok))
+TYPE_PARSER(construct<AllocateObject>(structureComponent) ||
+    construct<AllocateObject>(name / !"="_tok))
 
 // R935 lower-bound-expr -> scalar-int-expr
 // R936 upper-bound-expr -> scalar-int-expr
@@ -1483,64 +1464,62 @@ constexpr auto boundExpr = scalarIntExpr;
 
 // R934 allocate-shape-spec -> [lower-bound-expr :] upper-bound-expr
 // R938 allocate-coshape-spec -> [lower-bound-expr :] upper-bound-expr
-TYPE_PARSER(construct<AllocateShapeSpec>{}(maybe(boundExpr / ":"), boundExpr))
+TYPE_PARSER(construct<AllocateShapeSpec>(maybe(boundExpr / ":"), boundExpr))
 
 // R937 allocate-coarray-spec ->
 //      [allocate-coshape-spec-list ,] [lower-bound-expr :] *
-TYPE_PARSER(construct<AllocateCoarraySpec>{}(
+TYPE_PARSER(construct<AllocateCoarraySpec>(
     defaulted(nonemptyList(Parser<AllocateShapeSpec>{}) / ","),
     maybe(boundExpr / ":") / "*"))
 
 // R939 nullify-stmt -> NULLIFY ( pointer-object-list )
 TYPE_CONTEXT_PARSER("NULLIFY statement"_en_US,
-    "NULLIFY" >> parenthesized(construct<NullifyStmt>{}(
+    "NULLIFY" >> parenthesized(construct<NullifyStmt>(
                      nonemptyList(Parser<PointerObject>{}))))
 
 // R940 pointer-object ->
 //        variable-name | structure-component | proc-pointer-name
-TYPE_PARSER(construct<PointerObject>{}(structureComponent) ||
-    construct<PointerObject>{}(name))
+TYPE_PARSER(construct<PointerObject>(structureComponent) ||
+    construct<PointerObject>(name))
 
 // R941 deallocate-stmt ->
 //        DEALLOCATE ( allocate-object-list [, dealloc-opt-list] )
 TYPE_CONTEXT_PARSER("DEALLOCATE statement"_en_US,
-    "DEALLOCATE" >> parenthesized(construct<DeallocateStmt>{}(
+    "DEALLOCATE" >> parenthesized(construct<DeallocateStmt>(
                         nonemptyList(Parser<AllocateObject>{}),
                         defaulted("," >> nonemptyList(statOrErrmsg)))))
 
 // R942 dealloc-opt -> STAT = stat-variable | ERRMSG = errmsg-variable
 // R1165 sync-stat -> STAT = stat-variable | ERRMSG = errmsg-variable
-TYPE_PARSER("STAT =" >> construct<StatOrErrmsg>{}(statVariable) ||
-    "ERRMSG =" >> construct<StatOrErrmsg>{}(msgVariable))
+TYPE_PARSER("STAT =" >> construct<StatOrErrmsg>(statVariable) ||
+    "ERRMSG =" >> construct<StatOrErrmsg>(msgVariable))
 
 // R1001 primary ->
 //         literal-constant | designator | array-constructor |
 //         structure-constructor | function-reference | type-param-inquiry |
 //         type-param-name | ( expr )
 constexpr auto primary = instrumented("primary"_en_US,
-    construct<Expr>{}(indirect(Parser<CharLiteralConstantSubstring>{})) ||
-        construct<Expr>{}(literalConstant) ||
-        construct<Expr>{}(
-            construct<Expr::Parentheses>{}(parenthesized(expr))) ||
-        construct<Expr>{}(indirect(functionReference) / !"("_tok) ||
-        construct<Expr>{}(designator / !"("_tok) ||
-        construct<Expr>{}(Parser<StructureConstructor>{}) ||
-        construct<Expr>{}(Parser<ArrayConstructor>{}) ||
-        construct<Expr>{}(indirect(Parser<TypeParamInquiry>{})) ||  // occulted
+    construct<Expr>(indirect(Parser<CharLiteralConstantSubstring>{})) ||
+        construct<Expr>(literalConstant) ||
+        construct<Expr>(construct<Expr::Parentheses>(parenthesized(expr))) ||
+        construct<Expr>(indirect(functionReference) / !"("_tok) ||
+        construct<Expr>(designator / !"("_tok) ||
+        construct<Expr>(Parser<StructureConstructor>{}) ||
+        construct<Expr>(Parser<ArrayConstructor>{}) ||
+        construct<Expr>(indirect(Parser<TypeParamInquiry>{})) ||  // occulted
         // PGI/XLF extension: COMPLEX constructor (x,y)
-        extension(construct<Expr>{}(parenthesized(
-            construct<Expr::ComplexConstructor>{}(expr, "," >> expr)))) ||
-        extension(construct<Expr>{}("%LOC" >>
-            parenthesized(construct<Expr::PercentLoc>{}(indirect(variable))))));
+        extension(construct<Expr>(parenthesized(
+            construct<Expr::ComplexConstructor>(expr, "," >> expr)))) ||
+        extension(construct<Expr>("%LOC" >>
+            parenthesized(construct<Expr::PercentLoc>(indirect(variable))))));
 
 // R1002 level-1-expr -> [defined-unary-op] primary
 // TODO: Reasonable extension: permit multiple defined-unary-ops
-constexpr auto level1Expr = construct<Expr>{}(construct<Expr::DefinedUnary>{}(
-                                definedOpName, primary)) ||
+constexpr auto level1Expr =
+    construct<Expr>(construct<Expr::DefinedUnary>(definedOpName, primary)) ||
     primary ||
-    extension(
-        "+" >> construct<Expr>{}(construct<Expr::UnaryPlus>{}(primary))) ||
-    extension("-" >> construct<Expr>{}(construct<Expr::Negate>{}(primary)));
+    extension("+" >> construct<Expr>(construct<Expr::UnaryPlus>(primary))) ||
+    extension("-" >> construct<Expr>(construct<Expr::Negate>(primary)));
 
 // R1004 mult-operand -> level-1-expr [power-op mult-operand]
 // R1007 power-op -> **
@@ -1604,8 +1583,8 @@ constexpr struct Level2Expr {
   constexpr Level2Expr() {}
   static inline std::optional<Expr> Parse(ParseState &state) {
     static constexpr auto unary =
-        "+" >> construct<Expr>{}(construct<Expr::UnaryPlus>{}(addOperand)) ||
-        "-" >> construct<Expr>{}(construct<Expr::Negate>{}(addOperand)) ||
+        "+" >> construct<Expr>(construct<Expr::UnaryPlus>(addOperand)) ||
+        "-" >> construct<Expr>(construct<Expr::Negate>(addOperand)) ||
         addOperand;
     std::optional<Expr> result{unary.Parse(state)};
     if (result) {
@@ -1811,11 +1790,11 @@ template<> inline std::optional<Expr> Parser<Expr>::Parse(ParseState &state) {
 }
 
 // R1028 specification-expr -> scalar-int-expr
-TYPE_PARSER(construct<SpecificationExpr>{}(scalarIntExpr))
+TYPE_PARSER(construct<SpecificationExpr>(scalarIntExpr))
 
 // R1032 assignment-stmt -> variable = expr
 TYPE_CONTEXT_PARSER("assignment statement"_en_US,
-    construct<AssignmentStmt>{}(variable / "=", expr))
+    construct<AssignmentStmt>(variable / "=", expr))
 
 // R1033 pointer-assignment-stmt ->
 //         data-pointer-object [( bounds-spec-list )] => data-target |
@@ -1831,136 +1810,135 @@ TYPE_CONTEXT_PARSER("assignment statement"_en_US,
 // data-pointer-object and proc-pointer-object, or between data-target
 // and proc-target.
 TYPE_CONTEXT_PARSER("pointer assignment statement"_en_US,
-    construct<PointerAssignmentStmt>{}(dataRef,
+    construct<PointerAssignmentStmt>(dataRef,
         parenthesized(nonemptyList(Parser<BoundsRemapping>{})), "=>" >> expr) ||
-        construct<PointerAssignmentStmt>{}(dataRef,
+        construct<PointerAssignmentStmt>(dataRef,
             defaulted(parenthesized(nonemptyList(Parser<BoundsSpec>{}))),
             "=>" >> expr))
 
 // R1035 bounds-spec -> lower-bound-expr :
-TYPE_PARSER(construct<BoundsSpec>{}(boundExpr / ":"))
+TYPE_PARSER(construct<BoundsSpec>(boundExpr / ":"))
 
 // R1036 bounds-remapping -> lower-bound-expr : upper-bound-expr
-TYPE_PARSER(construct<BoundsRemapping>{}(boundExpr / ":", boundExpr))
+TYPE_PARSER(construct<BoundsRemapping>(boundExpr / ":", boundExpr))
 
 // R1039 proc-component-ref -> scalar-variable % procedure-component-name
 //   C1027 the scalar-variable must be a data-ref without coindices.
-TYPE_PARSER(construct<ProcComponentRef>{}(structureComponent))
+TYPE_PARSER(construct<ProcComponentRef>(structureComponent))
 
 // R1041 where-stmt -> WHERE ( mask-expr ) where-assignment-stmt
 // R1045 where-assignment-stmt -> assignment-stmt
 // R1046 mask-expr -> logical-expr
 TYPE_CONTEXT_PARSER("WHERE statement"_en_US,
-    "WHERE" >>
-        construct<WhereStmt>{}(parenthesized(logicalExpr), assignmentStmt))
+    "WHERE" >> construct<WhereStmt>(parenthesized(logicalExpr), assignmentStmt))
 
 // R1042 where-construct ->
 //         where-construct-stmt [where-body-construct]...
 //         [masked-elsewhere-stmt [where-body-construct]...]...
 //         [elsewhere-stmt [where-body-construct]...] end-where-stmt
 TYPE_CONTEXT_PARSER("WHERE construct"_en_US,
-    construct<WhereConstruct>{}(statement(Parser<WhereConstructStmt>{}),
+    construct<WhereConstruct>(statement(Parser<WhereConstructStmt>{}),
         many(whereBodyConstruct),
-        many(construct<WhereConstruct::MaskedElsewhere>{}(
+        many(construct<WhereConstruct::MaskedElsewhere>(
             statement(Parser<MaskedElsewhereStmt>{}),
             many(whereBodyConstruct))),
-        maybe(construct<WhereConstruct::Elsewhere>{}(
+        maybe(construct<WhereConstruct::Elsewhere>(
             statement(Parser<ElsewhereStmt>{}), many(whereBodyConstruct))),
         statement(Parser<EndWhereStmt>{})))
 
 // R1043 where-construct-stmt -> [where-construct-name :] WHERE ( mask-expr )
 TYPE_CONTEXT_PARSER("WHERE construct statement"_en_US,
-    construct<WhereConstructStmt>{}(
+    construct<WhereConstructStmt>(
         maybe(name / ":"), "WHERE" >> parenthesized(logicalExpr)))
 
 // R1044 where-body-construct ->
 //         where-assignment-stmt | where-stmt | where-construct
-TYPE_PARSER(construct<WhereBodyConstruct>{}(statement(assignmentStmt)) ||
-    construct<WhereBodyConstruct>{}(statement(whereStmt)) ||
-    construct<WhereBodyConstruct>{}(indirect(whereConstruct)))
+TYPE_PARSER(construct<WhereBodyConstruct>(statement(assignmentStmt)) ||
+    construct<WhereBodyConstruct>(statement(whereStmt)) ||
+    construct<WhereBodyConstruct>(indirect(whereConstruct)))
 
 // R1047 masked-elsewhere-stmt ->
 //         ELSEWHERE ( mask-expr ) [where-construct-name]
 TYPE_CONTEXT_PARSER("masked ELSEWHERE statement"_en_US,
-    "ELSE WHERE" >> construct<MaskedElsewhereStmt>{}(
-                        parenthesized(logicalExpr), maybe(name)))
+    "ELSE WHERE" >>
+        construct<MaskedElsewhereStmt>(parenthesized(logicalExpr), maybe(name)))
 
 // R1048 elsewhere-stmt -> ELSEWHERE [where-construct-name]
 TYPE_CONTEXT_PARSER("ELSEWHERE statement"_en_US,
-    "ELSE WHERE" >> construct<ElsewhereStmt>{}(maybe(name)))
+    "ELSE WHERE" >> construct<ElsewhereStmt>(maybe(name)))
 
 // R1049 end-where-stmt -> ENDWHERE [where-construct-name]
 TYPE_CONTEXT_PARSER("END WHERE statement"_en_US,
-    "END WHERE" >> construct<EndWhereStmt>{}(maybe(name)))
+    "END WHERE" >> construct<EndWhereStmt>(maybe(name)))
 
 // R1050 forall-construct ->
 //         forall-construct-stmt [forall-body-construct]... end-forall-stmt
 TYPE_CONTEXT_PARSER("FORALL construct"_en_US,
-    construct<ForallConstruct>{}(statement(Parser<ForallConstructStmt>{}),
+    construct<ForallConstruct>(statement(Parser<ForallConstructStmt>{}),
         many(Parser<ForallBodyConstruct>{}),
         statement(Parser<EndForallStmt>{})))
 
 // R1051 forall-construct-stmt ->
 //         [forall-construct-name :] FORALL concurrent-header
 TYPE_CONTEXT_PARSER("FORALL construct statement"_en_US,
-    construct<ForallConstructStmt>{}(
+    construct<ForallConstructStmt>(
         maybe(name / ":"), "FORALL" >> indirect(concurrentHeader)))
 
 // R1052 forall-body-construct ->
 //         forall-assignment-stmt | where-stmt | where-construct |
 //         forall-construct | forall-stmt
-TYPE_PARSER(construct<ForallBodyConstruct>{}(statement(forallAssignmentStmt)) ||
-    construct<ForallBodyConstruct>{}(statement(whereStmt)) ||
-    construct<ForallBodyConstruct>{}(whereConstruct) ||
-    construct<ForallBodyConstruct>{}(indirect(forallConstruct)) ||
-    construct<ForallBodyConstruct>{}(statement(forallStmt)))
+TYPE_PARSER(construct<ForallBodyConstruct>(statement(forallAssignmentStmt)) ||
+    construct<ForallBodyConstruct>(statement(whereStmt)) ||
+    construct<ForallBodyConstruct>(whereConstruct) ||
+    construct<ForallBodyConstruct>(indirect(forallConstruct)) ||
+    construct<ForallBodyConstruct>(statement(forallStmt)))
 
 // R1053 forall-assignment-stmt -> assignment-stmt | pointer-assignment-stmt
-TYPE_PARSER(construct<ForallAssignmentStmt>{}(assignmentStmt) ||
-    construct<ForallAssignmentStmt>{}(pointerAssignmentStmt))
+TYPE_PARSER(construct<ForallAssignmentStmt>(assignmentStmt) ||
+    construct<ForallAssignmentStmt>(pointerAssignmentStmt))
 
 // R1054 end-forall-stmt -> END FORALL [forall-construct-name]
 TYPE_CONTEXT_PARSER("END FORALL statement"_en_US,
-    "END FORALL" >> construct<EndForallStmt>{}(maybe(name)))
+    "END FORALL" >> construct<EndForallStmt>(maybe(name)))
 
 // R1055 forall-stmt -> FORALL concurrent-header forall-assignment-stmt
 TYPE_CONTEXT_PARSER("FORALL statement"_en_US,
-    "FORALL" >> construct<ForallStmt>{}(
-                    indirect(concurrentHeader), forallAssignmentStmt))
+    "FORALL" >>
+        construct<ForallStmt>(indirect(concurrentHeader), forallAssignmentStmt))
 
 // R1101 block -> [execution-part-construct]...
 constexpr auto block = many(executionPartConstruct);
 
 // R1102 associate-construct -> associate-stmt block end-associate-stmt
 TYPE_CONTEXT_PARSER("ASSOCIATE construct"_en_US,
-    construct<AssociateConstruct>{}(statement(Parser<AssociateStmt>{}), block,
+    construct<AssociateConstruct>(statement(Parser<AssociateStmt>{}), block,
         statement(Parser<EndAssociateStmt>{})))
 
 // R1103 associate-stmt ->
 //        [associate-construct-name :] ASSOCIATE ( association-list )
 TYPE_CONTEXT_PARSER("ASSOCIATE statement"_en_US,
-    construct<AssociateStmt>{}(maybe(name / ":"),
+    construct<AssociateStmt>(maybe(name / ":"),
         "ASSOCIATE" >> parenthesized(nonemptyList(Parser<Association>{}))))
 
 // R1104 association -> associate-name => selector
-TYPE_PARSER(construct<Association>{}(name, "=>" >> selector))
+TYPE_PARSER(construct<Association>(name, "=>" >> selector))
 
 // R1105 selector -> expr | variable
-TYPE_PARSER(construct<Selector>{}(variable) / lookAhead(","_tok || ")"_tok) ||
-    construct<Selector>{}(expr))
+TYPE_PARSER(construct<Selector>(variable) / lookAhead(","_tok || ")"_tok) ||
+    construct<Selector>(expr))
 
 // R1106 end-associate-stmt -> END ASSOCIATE [associate-construct-name]
-TYPE_PARSER("END ASSOCIATE" >> construct<EndAssociateStmt>{}(maybe(name)))
+TYPE_PARSER("END ASSOCIATE" >> construct<EndAssociateStmt>(maybe(name)))
 
 // R1107 block-construct ->
 //         block-stmt [block-specification-part] block end-block-stmt
 TYPE_CONTEXT_PARSER("BLOCK construct"_en_US,
-    construct<BlockConstruct>{}(statement(Parser<BlockStmt>{}),
+    construct<BlockConstruct>(statement(Parser<BlockStmt>{}),
         Parser<BlockSpecificationPart>{},  // can be empty
         block, statement(Parser<EndBlockStmt>{})))
 
 // R1108 block-stmt -> [block-construct-name :] BLOCK
-TYPE_PARSER(construct<BlockStmt>{}(maybe(name / ":") / "BLOCK"))
+TYPE_PARSER(construct<BlockStmt>(maybe(name / ":") / "BLOCK"))
 
 // R1109 block-specification-part ->
 //         [use-stmt]... [import-stmt]... [implicit-part]
@@ -1972,62 +1950,62 @@ TYPE_PARSER(construct<BlockStmt>{}(maybe(name / ":") / "BLOCK"))
 // trailing FORMAT and DATA statements after the last specification-construct
 // to be recognized as part of the block-construct's block part rather than
 // its block-specification-part, a distinction without any apparent difference.
-TYPE_PARSER(construct<BlockSpecificationPart>{}(specificationPart))
+TYPE_PARSER(construct<BlockSpecificationPart>(specificationPart))
 
 // R1110 end-block-stmt -> END BLOCK [block-construct-name]
-TYPE_PARSER(construct<EndBlockStmt>{}("END BLOCK" >> maybe(name)))
+TYPE_PARSER(construct<EndBlockStmt>("END BLOCK" >> maybe(name)))
 
 // R1111 change-team-construct -> change-team-stmt block end-change-team-stmt
 TYPE_CONTEXT_PARSER("CHANGE TEAM construct"_en_US,
-    construct<ChangeTeamConstruct>{}(statement(Parser<ChangeTeamStmt>{}), block,
+    construct<ChangeTeamConstruct>(statement(Parser<ChangeTeamStmt>{}), block,
         statement(Parser<EndChangeTeamStmt>{})))
 
 // R1112 change-team-stmt ->
 //         [team-construct-name :] CHANGE TEAM
 //         ( team-variable [, coarray-association-list] [, sync-stat-list] )
 TYPE_CONTEXT_PARSER("CHANGE TEAM statement"_en_US,
-    construct<ChangeTeamStmt>{}(maybe(name / ":"),
+    construct<ChangeTeamStmt>(maybe(name / ":"),
         "CHANGE TEAM"_sptok >> "("_tok >> teamVariable,
         defaulted("," >> nonemptyList(Parser<CoarrayAssociation>{})),
         defaulted("," >> nonemptyList(statOrErrmsg))) /
         ")")
 
 // R1113 coarray-association -> codimension-decl => selector
-TYPE_PARSER(construct<CoarrayAssociation>{}(
-    Parser<CodimensionDecl>{}, "=>" >> selector))
+TYPE_PARSER(
+    construct<CoarrayAssociation>(Parser<CodimensionDecl>{}, "=>" >> selector))
 
 // R1114 end-change-team-stmt ->
 //         END TEAM [( [sync-stat-list] )] [team-construct-name]
 TYPE_CONTEXT_PARSER("END TEAM statement"_en_US,
     "END TEAM" >>
-        construct<EndChangeTeamStmt>{}(
+        construct<EndChangeTeamStmt>(
             defaulted(parenthesized(optionalList(statOrErrmsg))), maybe(name)))
 
 // R1117 critical-stmt ->
 //         [critical-construct-name :] CRITICAL [( [sync-stat-list] )]
 TYPE_CONTEXT_PARSER("CRITICAL statement"_en_US,
-    construct<CriticalStmt>{}(maybe(name / ":"),
+    construct<CriticalStmt>(maybe(name / ":"),
         "CRITICAL" >> defaulted(parenthesized(optionalList(statOrErrmsg)))))
 
 // R1116 critical-construct -> critical-stmt block end-critical-stmt
 TYPE_CONTEXT_PARSER("CRITICAL construct"_en_US,
-    construct<CriticalConstruct>{}(statement(Parser<CriticalStmt>{}), block,
+    construct<CriticalConstruct>(statement(Parser<CriticalStmt>{}), block,
         statement(Parser<EndCriticalStmt>{})))
 
 // R1118 end-critical-stmt -> END CRITICAL [critical-construct-name]
-TYPE_PARSER("END CRITICAL" >> construct<EndCriticalStmt>{}(maybe(name)))
+TYPE_PARSER("END CRITICAL" >> construct<EndCriticalStmt>(maybe(name)))
 
 // R1119 do-construct -> do-stmt block end-do
 // R1120 do-stmt -> nonlabel-do-stmt | label-do-stmt
 TYPE_CONTEXT_PARSER("DO construct"_en_US,
-    construct<DoConstruct>{}(
+    construct<DoConstruct>(
         statement(Parser<NonLabelDoStmt>{}) / EnterNonlabelDoConstruct{}, block,
         statement(endDoStmt) / LeaveDoConstruct{}))
 
 // R1125 concurrent-header ->
 //         ( [integer-type-spec ::] concurrent-control-list
 //         [, scalar-mask-expr] )
-TYPE_PARSER(parenthesized(construct<ConcurrentHeader>{}(
+TYPE_PARSER(parenthesized(construct<ConcurrentHeader>(
     maybe(integerTypeSpec / "::"), nonemptyList(Parser<ConcurrentControl>{}),
     maybe("," >> scalarLogicalExpr))))
 
@@ -2035,22 +2013,21 @@ TYPE_PARSER(parenthesized(construct<ConcurrentHeader>{}(
 //         index-name = concurrent-limit : concurrent-limit [: concurrent-step]
 // R1127 concurrent-limit -> scalar-int-expr
 // R1128 concurrent-step -> scalar-int-expr
-TYPE_PARSER(construct<ConcurrentControl>{}(name / "=", scalarIntExpr / ":",
+TYPE_PARSER(construct<ConcurrentControl>(name / "=", scalarIntExpr / ":",
     scalarIntExpr, maybe(":" >> scalarIntExpr)))
 
 // R1130 locality-spec ->
 //         LOCAL ( variable-name-list ) | LOCAL INIT ( variable-name-list ) |
 //         SHARED ( variable-name-list ) | DEFAULT ( NONE )
-TYPE_PARSER(
-    "LOCAL" >> construct<LocalitySpec>{}(construct<LocalitySpec::Local>{}(
-                   parenthesized(nonemptyList(name)))) ||
+TYPE_PARSER("LOCAL" >> construct<LocalitySpec>(construct<LocalitySpec::Local>(
+                           parenthesized(nonemptyList(name)))) ||
     "LOCAL INIT"_sptok >>
-        construct<LocalitySpec>{}(construct<LocalitySpec::LocalInit>{}(
+        construct<LocalitySpec>(construct<LocalitySpec::LocalInit>(
             parenthesized(nonemptyList(name)))) ||
-    "SHARED" >> construct<LocalitySpec>{}(construct<LocalitySpec::Shared>{}(
+    "SHARED" >> construct<LocalitySpec>(construct<LocalitySpec::Shared>(
                     parenthesized(nonemptyList(name)))) ||
     "DEFAULT ( NONE )" >>
-        construct<LocalitySpec>{}(construct<LocalitySpec::DefaultNone>{}))
+        construct<LocalitySpec>(construct<LocalitySpec::DefaultNone>()))
 
 // R1123 loop-control ->
 //         [,] do-variable = scalar-int-expr , scalar-int-expr
@@ -2060,29 +2037,29 @@ TYPE_PARSER(
 // R1129 concurrent-locality -> [locality-spec]...
 TYPE_CONTEXT_PARSER("loop control"_en_US,
     maybe(","_tok) >>
-        (construct<LoopControl>{}(loopBounds(scalarIntExpr)) ||
+        (construct<LoopControl>(loopBounds(scalarIntExpr)) ||
             "WHILE" >>
-                construct<LoopControl>{}(parenthesized(scalarLogicalExpr)) ||
+                construct<LoopControl>(parenthesized(scalarLogicalExpr)) ||
             "CONCURRENT" >>
-                construct<LoopControl>{}(construct<LoopControl::Concurrent>{}(
+                construct<LoopControl>(construct<LoopControl::Concurrent>(
                     concurrentHeader, many(Parser<LocalitySpec>{})))))
 
 // R1121 label-do-stmt -> [do-construct-name :] DO label [loop-control]
 TYPE_CONTEXT_PARSER("label DO statement"_en_US,
-    construct<LabelDoStmt>{}(
+    construct<LabelDoStmt>(
         maybe(name / ":"), "DO" >> label, maybe(loopControl)))
 
 // R1122 nonlabel-do-stmt -> [do-construct-name :] DO [loop-control]
 TYPE_CONTEXT_PARSER("nonlabel DO statement"_en_US,
-    construct<NonLabelDoStmt>{}(maybe(name / ":"), "DO" >> maybe(loopControl)))
+    construct<NonLabelDoStmt>(maybe(name / ":"), "DO" >> maybe(loopControl)))
 
 // R1132 end-do-stmt -> END DO [do-construct-name]
 TYPE_CONTEXT_PARSER(
-    "END DO statement"_en_US, "END DO" >> construct<EndDoStmt>{}(maybe(name)))
+    "END DO statement"_en_US, "END DO" >> construct<EndDoStmt>(maybe(name)))
 
 // R1133 cycle-stmt -> CYCLE [do-construct-name]
 TYPE_CONTEXT_PARSER(
-    "CYCLE statement"_en_US, "CYCLE" >> construct<CycleStmt>{}(maybe(name)))
+    "CYCLE statement"_en_US, "CYCLE" >> construct<CycleStmt>(maybe(name)))
 
 // R1134 if-construct ->
 //         if-then-stmt block [else-if-stmt block]...
@@ -2093,71 +2070,71 @@ TYPE_CONTEXT_PARSER(
 // R1137 else-stmt -> ELSE [if-construct-name]
 // R1138 end-if-stmt -> END IF [if-construct-name]
 TYPE_CONTEXT_PARSER("IF construct"_en_US,
-    construct<IfConstruct>{}(
-        statement(construct<IfThenStmt>{}(maybe(name / ":"),
+    construct<IfConstruct>(
+        statement(construct<IfThenStmt>(maybe(name / ":"),
             "IF" >> parenthesized(scalarLogicalExpr) / "THEN")),
         block,
-        many(construct<IfConstruct::ElseIfBlock>{}(
-            statement(construct<ElseIfStmt>{}(
+        many(construct<IfConstruct::ElseIfBlock>(
+            statement(construct<ElseIfStmt>(
                 "ELSE IF" >> parenthesized(scalarLogicalExpr),
                 "THEN" >> maybe(name))),
             block)),
-        maybe(construct<IfConstruct::ElseBlock>{}(
-            statement(construct<ElseStmt>{}("ELSE" >> maybe(name))), block)),
-        statement(construct<EndIfStmt>{}("END IF" >> maybe(name)))))
+        maybe(construct<IfConstruct::ElseBlock>(
+            statement(construct<ElseStmt>("ELSE" >> maybe(name))), block)),
+        statement(construct<EndIfStmt>("END IF" >> maybe(name)))))
 
 // R1139 if-stmt -> IF ( scalar-logical-expr ) action-stmt
 TYPE_CONTEXT_PARSER("IF statement"_en_US,
-    "IF" >> construct<IfStmt>{}(parenthesized(scalarLogicalExpr), actionStmt))
+    "IF" >> construct<IfStmt>(parenthesized(scalarLogicalExpr), actionStmt))
 
 // R1140 case-construct ->
 //         select-case-stmt [case-stmt block]... end-select-stmt
 TYPE_CONTEXT_PARSER("SELECT CASE construct"_en_US,
-    construct<CaseConstruct>{}(statement(Parser<SelectCaseStmt>{}),
-        many(construct<CaseConstruct::Case>{}(
+    construct<CaseConstruct>(statement(Parser<SelectCaseStmt>{}),
+        many(construct<CaseConstruct::Case>(
             statement(Parser<CaseStmt>{}), block)),
         statement(endSelectStmt)))
 
 // R1141 select-case-stmt -> [case-construct-name :] SELECT CASE ( case-expr
 // ) R1144 case-expr -> scalar-expr
 TYPE_CONTEXT_PARSER("SELECT CASE statement"_en_US,
-    construct<SelectCaseStmt>{}(
+    construct<SelectCaseStmt>(
         maybe(name / ":"), "SELECT CASE" >> parenthesized(scalar(expr))))
 
 // R1142 case-stmt -> CASE case-selector [case-construct-name]
 TYPE_CONTEXT_PARSER("CASE statement"_en_US,
-    "CASE" >> construct<CaseStmt>{}(Parser<CaseSelector>{}, maybe(name)))
+    "CASE" >> construct<CaseStmt>(Parser<CaseSelector>{}, maybe(name)))
 
 // 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<EndSelectStmt>{}(maybe(name)))
+TYPE_PARSER("END SELECT" >> construct<EndSelectStmt>(maybe(name)))
 
 // R1145 case-selector -> ( case-value-range-list ) | DEFAULT
-constexpr auto defaultKeyword = "DEFAULT" >> construct<Default>{};
-TYPE_PARSER(parenthesized(construct<CaseSelector>{}(
+constexpr auto defaultKeyword = "DEFAULT" >> construct<Default>();
+TYPE_PARSER(parenthesized(construct<CaseSelector>(
                 nonemptyList(Parser<CaseValueRange>{}))) ||
-    construct<CaseSelector>{}(defaultKeyword))
+    construct<CaseSelector>(defaultKeyword))
 
 // R1147 case-value -> scalar-constant-expr
 constexpr auto caseValue = scalar(constantExpr);
 
 // R1146 case-value-range ->
 //         case-value | case-value : | : case-value | case-value : case-value
-TYPE_PARSER(construct<CaseValueRange>{}(construct<CaseValueRange::Range>{}(
-                construct<std::optional<CaseValue>>{}(caseValue),
+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))
+    construct<CaseValueRange>(
+        construct<CaseValueRange::Range>(construct<std::optional<CaseValue>>(),
+            ":" >> construct<std::optional<CaseValue>>(caseValue))) ||
+    construct<CaseValueRange>(caseValue))
 
 // R1148 select-rank-construct ->
 //         select-rank-stmt [select-rank-case-stmt block]...
 //         end-select-rank-stmt
 TYPE_CONTEXT_PARSER("SELECT RANK construct"_en_US,
-    construct<SelectRankConstruct>{}(statement(Parser<SelectRankStmt>{}),
-        many(construct<SelectRankConstruct::RankCase>{}(
+    construct<SelectRankConstruct>(statement(Parser<SelectRankStmt>{}),
+        many(construct<SelectRankConstruct::RankCase>(
             statement(Parser<SelectRankCaseStmt>{}), block)),
         statement(endSelectStmt)))
 
@@ -2165,7 +2142,7 @@ TYPE_CONTEXT_PARSER("SELECT RANK construct"_en_US,
 //         [select-construct-name :] SELECT RANK
 //         ( [associate-name =>] selector )
 TYPE_CONTEXT_PARSER("SELECT RANK statement"_en_US,
-    construct<SelectRankStmt>{}(maybe(name / ":"),
+    construct<SelectRankStmt>(maybe(name / ":"),
         "SELECT RANK"_sptok >> "("_tok >> maybe(name / "=>"), selector / ")"))
 
 // R1150 select-rank-case-stmt ->
@@ -2173,18 +2150,18 @@ TYPE_CONTEXT_PARSER("SELECT RANK statement"_en_US,
 //         RANK ( * ) [select-construct-name] |
 //         RANK DEFAULT [select-construct-name]
 TYPE_CONTEXT_PARSER("RANK case statement"_en_US,
-    "RANK" >> (construct<SelectRankCaseStmt>{}(
-                  parenthesized(construct<SelectRankCaseStmt::Rank>{}(
+    "RANK" >> (construct<SelectRankCaseStmt>(
+                  parenthesized(construct<SelectRankCaseStmt::Rank>(
                                     scalarIntConstantExpr) ||
-                      construct<SelectRankCaseStmt::Rank>{}(star)) ||
-                      construct<SelectRankCaseStmt::Rank>{}(defaultKeyword),
+                      construct<SelectRankCaseStmt::Rank>(star)) ||
+                      construct<SelectRankCaseStmt::Rank>(defaultKeyword),
                   maybe(name))))
 
 // R1152 select-type-construct ->
 //         select-type-stmt [type-guard-stmt block]... end-select-type-stmt
 TYPE_CONTEXT_PARSER("SELECT TYPE construct"_en_US,
-    construct<SelectTypeConstruct>{}(statement(Parser<SelectTypeStmt>{}),
-        many(construct<SelectTypeConstruct::TypeCase>{}(
+    construct<SelectTypeConstruct>(statement(Parser<SelectTypeStmt>{}),
+        many(construct<SelectTypeConstruct::TypeCase>(
             statement(Parser<TypeGuardStmt>{}), block)),
         statement(endSelectStmt)))
 
@@ -2192,7 +2169,7 @@ TYPE_CONTEXT_PARSER("SELECT TYPE construct"_en_US,
 //         [select-construct-name :] SELECT TYPE
 //         ( [associate-name =>] selector )
 TYPE_CONTEXT_PARSER("SELECT TYPE statement"_en_US,
-    construct<SelectTypeStmt>{}(maybe(name / ":"),
+    construct<SelectTypeStmt>(maybe(name / ":"),
         "SELECT TYPE (" >> maybe(name / "=>"), selector / ")"))
 
 // R1154 type-guard-stmt ->
@@ -2200,73 +2177,73 @@ TYPE_CONTEXT_PARSER("SELECT TYPE statement"_en_US,
 //         CLASS IS ( derived-type-spec ) [select-construct-name] |
 //         CLASS DEFAULT [select-construct-name]
 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>{}(
+    construct<TypeGuardStmt>("TYPE IS"_sptok >>
+                parenthesized(construct<TypeGuardStmt::Guard>(typeSpec)) ||
+            "CLASS IS"_sptok >> parenthesized(construct<TypeGuardStmt::Guard>(
                                     derivedTypeSpec)) ||
-            "CLASS" >> construct<TypeGuardStmt::Guard>{}(defaultKeyword),
+            "CLASS" >> construct<TypeGuardStmt::Guard>(defaultKeyword),
         maybe(name)))
 
 // R1156 exit-stmt -> EXIT [construct-name]
 TYPE_CONTEXT_PARSER(
-    "EXIT statement"_en_US, "EXIT" >> construct<ExitStmt>{}(maybe(name)))
+    "EXIT statement"_en_US, "EXIT" >> construct<ExitStmt>(maybe(name)))
 
 // R1157 goto-stmt -> GO TO label
 TYPE_CONTEXT_PARSER(
-    "GOTO statement"_en_US, "GO TO" >> construct<GotoStmt>{}(label))
+    "GOTO statement"_en_US, "GO TO" >> construct<GotoStmt>(label))
 
 // R1158 computed-goto-stmt -> GO TO ( label-list ) [,] scalar-int-expr
 TYPE_CONTEXT_PARSER("computed GOTO statement"_en_US,
-    "GO TO" >> construct<ComputedGotoStmt>{}(parenthesized(nonemptyList(label)),
+    "GO TO" >> construct<ComputedGotoStmt>(parenthesized(nonemptyList(label)),
                    maybe(","_tok) >> scalarIntExpr))
 
 // R1160 stop-stmt -> STOP [stop-code] [, QUIET = scalar-logical-expr]
 // R1161 error-stop-stmt ->
 //         ERROR STOP [stop-code] [, QUIET = scalar-logical-expr]
 TYPE_CONTEXT_PARSER("STOP statement"_en_US,
-    construct<StopStmt>{}("STOP" >> pure(StopStmt::Kind::Stop) ||
+    construct<StopStmt>("STOP" >> pure(StopStmt::Kind::Stop) ||
             "ERROR STOP"_sptok >> pure(StopStmt::Kind::ErrorStop),
         maybe(Parser<StopCode>{}), maybe(", QUIET =" >> scalarLogicalExpr)))
 
 // R1162 stop-code -> scalar-default-char-expr | scalar-int-expr
-TYPE_PARSER(construct<StopCode>{}(scalarDefaultCharExpr) ||
-    construct<StopCode>{}(scalarIntExpr))
+TYPE_PARSER(construct<StopCode>(scalarDefaultCharExpr) ||
+    construct<StopCode>(scalarIntExpr))
 
 // R1164 sync-all-stmt -> SYNC ALL [( [sync-stat-list] )]
 TYPE_CONTEXT_PARSER("SYNC ALL statement"_en_US,
-    "SYNC ALL"_sptok >> construct<SyncAllStmt>{}(defaulted(
+    "SYNC ALL"_sptok >> construct<SyncAllStmt>(defaulted(
                             parenthesized(optionalList(statOrErrmsg)))))
 
 // R1166 sync-images-stmt -> SYNC IMAGES ( image-set [, sync-stat-list] )
 // R1167 image-set -> int-expr | *
 TYPE_CONTEXT_PARSER("SYNC IMAGES statement"_en_US,
-    "SYNC IMAGES"_sptok >> parenthesized(construct<SyncImagesStmt>{}(
-                               construct<SyncImagesStmt::ImageSet>{}(intExpr) ||
-                                   construct<SyncImagesStmt::ImageSet>{}(star),
+    "SYNC IMAGES"_sptok >> parenthesized(construct<SyncImagesStmt>(
+                               construct<SyncImagesStmt::ImageSet>(intExpr) ||
+                                   construct<SyncImagesStmt::ImageSet>(star),
                                defaulted("," >> nonemptyList(statOrErrmsg)))))
 
 // R1168 sync-memory-stmt -> SYNC MEMORY [( [sync-stat-list] )]
 TYPE_CONTEXT_PARSER("SYNC MEMORY statement"_en_US,
-    "SYNC MEMORY"_sptok >> construct<SyncMemoryStmt>{}(defaulted(
+    "SYNC MEMORY"_sptok >> construct<SyncMemoryStmt>(defaulted(
                                parenthesized(optionalList(statOrErrmsg)))))
 
 // R1169 sync-team-stmt -> SYNC TEAM ( team-variable [, sync-stat-list] )
 TYPE_CONTEXT_PARSER("SYNC TEAM statement"_en_US,
-    "SYNC TEAM"_sptok >> parenthesized(construct<SyncTeamStmt>{}(teamVariable,
+    "SYNC TEAM"_sptok >> parenthesized(construct<SyncTeamStmt>(teamVariable,
                              defaulted("," >> nonemptyList(statOrErrmsg)))))
 
 // R1170 event-post-stmt -> EVENT POST ( event-variable [, sync-stat-list] )
 // R1171 event-variable -> scalar-variable
 TYPE_CONTEXT_PARSER("EVENT POST statement"_en_US,
     "EVENT POST"_sptok >>
-        parenthesized(construct<EventPostStmt>{}(
+        parenthesized(construct<EventPostStmt>(
             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,
     "EVENT WAIT"_sptok >>
-        parenthesized(construct<EventWaitStmt>{}(scalar(variable),
+        parenthesized(construct<EventWaitStmt>(scalar(variable),
             defaulted(
                 "," >> nonemptyList(Parser<EventWaitStmt::EventWaitSpec>{})))))
 
@@ -2274,23 +2251,23 @@ TYPE_CONTEXT_PARSER("EVENT WAIT statement"_en_US,
 constexpr auto untilSpec = "UNTIL_COUNT =" >> scalarIntExpr;
 
 // R1173 event-wait-spec -> until-spec | sync-stat
-TYPE_PARSER(construct<EventWaitStmt::EventWaitSpec>{}(untilSpec) ||
-    construct<EventWaitStmt::EventWaitSpec>{}(statOrErrmsg))
+TYPE_PARSER(construct<EventWaitStmt::EventWaitSpec>(untilSpec) ||
+    construct<EventWaitStmt::EventWaitSpec>(statOrErrmsg))
 
 // R1175 form-team-stmt ->
 //         FORM TEAM ( team-number , team-variable [, form-team-spec-list] )
 // R1176 team-number -> scalar-int-expr
 TYPE_CONTEXT_PARSER("FORM TEAM statement"_en_US,
     "FORM TEAM"_sptok >>
-        parenthesized(construct<FormTeamStmt>{}(scalarIntExpr,
+        parenthesized(construct<FormTeamStmt>(scalarIntExpr,
             "," >> teamVariable,
             defaulted(
                 "," >> nonemptyList(Parser<FormTeamStmt::FormTeamSpec>{})))))
 
 // R1177 form-team-spec -> NEW_INDEX = scalar-int-expr | sync-stat
 TYPE_PARSER(
-    "NEW_INDEX =" >> construct<FormTeamStmt::FormTeamSpec>{}(scalarIntExpr) ||
-    construct<FormTeamStmt::FormTeamSpec>{}(statOrErrmsg))
+    "NEW_INDEX =" >> construct<FormTeamStmt::FormTeamSpec>(scalarIntExpr) ||
+    construct<FormTeamStmt::FormTeamSpec>(statOrErrmsg))
 
 // R1181 lock-variable -> scalar-variable
 constexpr auto lockVariable = scalar(variable);
@@ -2298,31 +2275,31 @@ constexpr auto lockVariable = scalar(variable);
 // R1178 lock-stmt -> LOCK ( lock-variable [, lock-stat-list] )
 TYPE_CONTEXT_PARSER("LOCK statement"_en_US,
     "LOCK" >>
-        parenthesized(construct<LockStmt>{}(lockVariable,
+        parenthesized(construct<LockStmt>(lockVariable,
             defaulted("," >> nonemptyList(Parser<LockStmt::LockStat>{})))))
 
 // R1179 lock-stat -> ACQUIRED_LOCK = scalar-logical-variable | sync-stat
-TYPE_PARSER("ACQUIRED_LOCK =" >>
-        construct<LockStmt::LockStat>{}(scalarLogicalVariable) ||
-    construct<LockStmt::LockStat>{}(statOrErrmsg))
+TYPE_PARSER(
+    "ACQUIRED_LOCK =" >> construct<LockStmt::LockStat>(scalarLogicalVariable) ||
+    construct<LockStmt::LockStat>(statOrErrmsg))
 
 // R1180 unlock-stmt -> UNLOCK ( lock-variable [, sync-stat-list] )
 TYPE_CONTEXT_PARSER("UNLOCK statement"_en_US,
-    "UNLOCK" >> parenthesized(construct<UnlockStmt>{}(lockVariable,
+    "UNLOCK" >> parenthesized(construct<UnlockStmt>(lockVariable,
                     defaulted("," >> nonemptyList(statOrErrmsg)))))
 
 // R1201 io-unit -> file-unit-number | * | internal-file-variable
 // R1203 internal-file-variable -> char-variable
-TYPE_PARSER(construct<IoUnit>{}(fileUnitNumber) || construct<IoUnit>{}(star) ||
-    construct<IoUnit>{}(charVariable / !"="_tok))
+TYPE_PARSER(construct<IoUnit>(fileUnitNumber) || construct<IoUnit>(star) ||
+    construct<IoUnit>(charVariable / !"="_tok))
 
 // R1202 file-unit-number -> scalar-int-expr
-TYPE_PARSER(construct<FileUnitNumber>{}(scalarIntExpr / !"="_tok))
+TYPE_PARSER(construct<FileUnitNumber>(scalarIntExpr / !"="_tok))
 
 // R1204 open-stmt -> OPEN ( connect-spec-list )
 TYPE_CONTEXT_PARSER("OPEN statement"_en_US,
-    "OPEN" >> parenthesized(
-                  construct<OpenStmt>{}(nonemptyList(Parser<ConnectSpec>{}))))
+    "OPEN" >>
+        parenthesized(construct<OpenStmt>(nonemptyList(Parser<ConnectSpec>{}))))
 
 // R1206 file-name-expr -> scalar-default-char-expr
 constexpr auto fileNameExpr = scalarDefaultCharExpr;
@@ -2341,61 +2318,60 @@ constexpr auto fileNameExpr = scalarDefaultCharExpr;
 //         POSITION = scalar-default-char-expr | RECL = scalar-int-expr |
 //         ROUND = scalar-default-char-expr | SIGN = scalar-default-char-expr |
 //         STATUS = scalar-default-char-expr
-constexpr auto statusExpr = construct<StatusExpr>{}(scalarDefaultCharExpr);
-constexpr auto errLabel = construct<ErrLabel>{}(label);
+constexpr auto statusExpr = construct<StatusExpr>(scalarDefaultCharExpr);
+constexpr auto errLabel = construct<ErrLabel>(label);
 
-TYPE_PARSER(maybe("UNIT ="_tok) >> construct<ConnectSpec>{}(fileUnitNumber) ||
-    "ACCESS =" >> construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+TYPE_PARSER(maybe("UNIT ="_tok) >> construct<ConnectSpec>(fileUnitNumber) ||
+    "ACCESS =" >> construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
                       pure(ConnectSpec::CharExpr::Kind::Access),
                       scalarDefaultCharExpr)) ||
-    "ACTION =" >> construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+    "ACTION =" >> construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
                       pure(ConnectSpec::CharExpr::Kind::Action),
                       scalarDefaultCharExpr)) ||
-    "ASYNCHRONOUS =" >>
-        construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
-            pure(ConnectSpec::CharExpr::Kind::Asynchronous),
-            scalarDefaultCharExpr)) ||
+    "ASYNCHRONOUS =" >> construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
+                            pure(ConnectSpec::CharExpr::Kind::Asynchronous),
+                            scalarDefaultCharExpr)) ||
     "BLANK =" >>
-        construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+        construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
             pure(ConnectSpec::CharExpr::Kind::Blank), scalarDefaultCharExpr)) ||
-    "DECIMAL =" >> construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+    "DECIMAL =" >> construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
                        pure(ConnectSpec::CharExpr::Kind::Decimal),
                        scalarDefaultCharExpr)) ||
     "DELIM =" >>
-        construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+        construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
             pure(ConnectSpec::CharExpr::Kind::Delim), scalarDefaultCharExpr)) ||
-    "ENCODING =" >> construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+    "ENCODING =" >> construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
                         pure(ConnectSpec::CharExpr::Kind::Encoding),
                         scalarDefaultCharExpr)) ||
-    "ERR =" >> construct<ConnectSpec>{}(errLabel) ||
-    "FILE =" >> construct<ConnectSpec>{}(fileNameExpr) ||
-    extension("NAME =" >> construct<ConnectSpec>{}(fileNameExpr)) ||
+    "ERR =" >> construct<ConnectSpec>(errLabel) ||
+    "FILE =" >> construct<ConnectSpec>(fileNameExpr) ||
+    extension("NAME =" >> construct<ConnectSpec>(fileNameExpr)) ||
     "FORM =" >>
-        construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+        construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
             pure(ConnectSpec::CharExpr::Kind::Form), scalarDefaultCharExpr)) ||
-    "IOMSG =" >> construct<ConnectSpec>{}(msgVariable) ||
-    "IOSTAT =" >> construct<ConnectSpec>{}(statVariable) ||
-    "NEWUNIT =" >> construct<ConnectSpec>{}(construct<ConnectSpec::Newunit>{}(
+    "IOMSG =" >> construct<ConnectSpec>(msgVariable) ||
+    "IOSTAT =" >> construct<ConnectSpec>(statVariable) ||
+    "NEWUNIT =" >> construct<ConnectSpec>(construct<ConnectSpec::Newunit>(
                        scalar(integer(variable)))) ||
     "PAD =" >>
-        construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+        construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
             pure(ConnectSpec::CharExpr::Kind::Pad), scalarDefaultCharExpr)) ||
-    "POSITION =" >> construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+    "POSITION =" >> construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
                         pure(ConnectSpec::CharExpr::Kind::Position),
                         scalarDefaultCharExpr)) ||
-    "RECL =" >> construct<ConnectSpec>{}(
-                    construct<ConnectSpec::Recl>{}(scalarIntExpr)) ||
+    "RECL =" >>
+        construct<ConnectSpec>(construct<ConnectSpec::Recl>(scalarIntExpr)) ||
     "ROUND =" >>
-        construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+        construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
             pure(ConnectSpec::CharExpr::Kind::Round), scalarDefaultCharExpr)) ||
     "SIGN =" >>
-        construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+        construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
             pure(ConnectSpec::CharExpr::Kind::Sign), scalarDefaultCharExpr)) ||
-    "STATUS =" >> construct<ConnectSpec>{}(statusExpr) ||
-    extension(construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+    "STATUS =" >> construct<ConnectSpec>(statusExpr) ||
+    extension(construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
                   "CONVERT =" >> pure(ConnectSpec::CharExpr::Kind::Convert),
                   scalarDefaultCharExpr)) ||
-        construct<ConnectSpec>{}(construct<ConnectSpec::CharExpr>{}(
+        construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
             "DISPOSE =" >> pure(ConnectSpec::CharExpr::Kind::Dispose),
             scalarDefaultCharExpr))))
 
@@ -2404,15 +2380,15 @@ TYPE_PARSER(maybe("UNIT ="_tok) >> construct<ConnectSpec>{}(fileUnitNumber) ||
 //         IOMSG = iomsg-variable | ERR = label |
 //         STATUS = scalar-default-char-expr
 constexpr auto closeSpec = maybe("UNIT ="_tok) >>
-        construct<CloseStmt::CloseSpec>{}(fileUnitNumber) ||
-    "IOSTAT =" >> construct<CloseStmt::CloseSpec>{}(statVariable) ||
-    "IOMSG =" >> construct<CloseStmt::CloseSpec>{}(msgVariable) ||
-    "ERR =" >> construct<CloseStmt::CloseSpec>{}(errLabel) ||
-    "STATUS =" >> construct<CloseStmt::CloseSpec>{}(statusExpr);
+        construct<CloseStmt::CloseSpec>(fileUnitNumber) ||
+    "IOSTAT =" >> construct<CloseStmt::CloseSpec>(statVariable) ||
+    "IOMSG =" >> construct<CloseStmt::CloseSpec>(msgVariable) ||
+    "ERR =" >> construct<CloseStmt::CloseSpec>(errLabel) ||
+    "STATUS =" >> construct<CloseStmt::CloseSpec>(statusExpr);
 
 // R1208 close-stmt -> CLOSE ( close-spec-list )
 TYPE_CONTEXT_PARSER("CLOSE statement"_en_US,
-    "CLOSE" >> construct<CloseStmt>{}(parenthesized(nonemptyList(closeSpec))))
+    "CLOSE" >> construct<CloseStmt>(parenthesized(nonemptyList(closeSpec))))
 
 // R1210 read-stmt ->
 //         READ ( io-control-spec-list ) [input-item-list] |
@@ -2423,25 +2399,24 @@ constexpr auto inputItemList =
 
 TYPE_CONTEXT_PARSER("READ statement"_en_US,
     "READ" >>
-        ("(" >> construct<ReadStmt>{}(construct<std::optional<IoUnit>>{}(
-                                          maybe("UNIT ="_tok) >> ioUnit),
-                    "," >> construct<std::optional<Format>>{}(format),
+        ("(" >> construct<ReadStmt>(construct<std::optional<IoUnit>>(
+                                        maybe("UNIT ="_tok) >> ioUnit),
+                    "," >> construct<std::optional<Format>>(format),
                     defaulted("," >> nonemptyList(ioControlSpec)) / ")",
                     inputItemList) ||
-            "(" >> construct<ReadStmt>{}(
-                       construct<std::optional<IoUnit>>{}(ioUnit),
-                       construct<std::optional<Format>>{},
+            "(" >> construct<ReadStmt>(construct<std::optional<IoUnit>>(ioUnit),
+                       construct<std::optional<Format>>(),
                        defaulted("," >> nonemptyList(ioControlSpec)) / ")",
                        inputItemList) ||
-            construct<ReadStmt>{}(construct<std::optional<IoUnit>>{},
-                construct<std::optional<Format>>{},
+            construct<ReadStmt>(construct<std::optional<IoUnit>>(),
+                construct<std::optional<Format>>(),
                 parenthesized(nonemptyList(ioControlSpec)), inputItemList) ||
-            construct<ReadStmt>{}(construct<std::optional<IoUnit>>{},
-                construct<std::optional<Format>>{}(format),
-                construct<std::list<IoControlSpec>>{}, many("," >> inputItem))))
+            construct<ReadStmt>(construct<std::optional<IoUnit>>(),
+                construct<std::optional<Format>>(format),
+                construct<std::list<IoControlSpec>>(), many("," >> inputItem))))
 
 // R1214 id-variable -> scalar-int-variable
-constexpr auto idVariable = construct<IdVariable>{}(scalarIntVariable);
+constexpr auto idVariable = construct<IdVariable>(scalarIntVariable);
 
 // R1213 io-control-spec ->
 //         [UNIT =] io-unit | [FMT =] format | [NML =] namelist-group-name |
@@ -2455,52 +2430,47 @@ constexpr auto idVariable = construct<IdVariable>{}(scalarIntVariable);
 //         POS = scalar-int-expr | REC = scalar-int-expr |
 //         ROUND = scalar-default-char-expr | SIGN = scalar-default-char-expr |
 //         SIZE = scalar-int-variable
-constexpr auto endLabel = construct<EndLabel>{}(label);
-constexpr auto eorLabel = construct<EorLabel>{}(label);
-TYPE_PARSER("UNIT =" >> construct<IoControlSpec>{}(ioUnit) ||
-    "FMT =" >> construct<IoControlSpec>{}(format) ||
-    "NML =" >> construct<IoControlSpec>{}(name) ||
-    "ADVANCE =" >>
-        construct<IoControlSpec>{}(construct<IoControlSpec::CharExpr>{}(
-            pure(IoControlSpec::CharExpr::Kind::Advance),
-            scalarDefaultCharExpr)) ||
+constexpr auto endLabel = construct<EndLabel>(label);
+constexpr auto eorLabel = construct<EorLabel>(label);
+TYPE_PARSER("UNIT =" >> construct<IoControlSpec>(ioUnit) ||
+    "FMT =" >> construct<IoControlSpec>(format) ||
+    "NML =" >> construct<IoControlSpec>(name) ||
+    "ADVANCE =" >> construct<IoControlSpec>(construct<IoControlSpec::CharExpr>(
+                       pure(IoControlSpec::CharExpr::Kind::Advance),
+                       scalarDefaultCharExpr)) ||
     "ASYNCHRONOUS =" >>
-        construct<IoControlSpec>{}(construct<IoControlSpec::Asynchronous>{}(
+        construct<IoControlSpec>(construct<IoControlSpec::Asynchronous>(
             scalarDefaultCharConstantExpr)) ||
-    "BLANK =" >>
-        construct<IoControlSpec>{}(construct<IoControlSpec::CharExpr>{}(
-            pure(IoControlSpec::CharExpr::Kind::Blank),
-            scalarDefaultCharExpr)) ||
-    "DECIMAL =" >>
-        construct<IoControlSpec>{}(construct<IoControlSpec::CharExpr>{}(
-            pure(IoControlSpec::CharExpr::Kind::Decimal),
-            scalarDefaultCharExpr)) ||
-    "DELIM =" >>
-        construct<IoControlSpec>{}(construct<IoControlSpec::CharExpr>{}(
-            pure(IoControlSpec::CharExpr::Kind::Delim),
-            scalarDefaultCharExpr)) ||
-    "END =" >> construct<IoControlSpec>{}(endLabel) ||
-    "EOR =" >> construct<IoControlSpec>{}(eorLabel) ||
-    "ERR =" >> construct<IoControlSpec>{}(errLabel) ||
-    "ID =" >> construct<IoControlSpec>{}(idVariable) ||
-    "IOMSG = " >> construct<IoControlSpec>{}(msgVariable) ||
-    "IOSTAT = " >> construct<IoControlSpec>{}(statVariable) ||
+    "BLANK =" >> construct<IoControlSpec>(construct<IoControlSpec::CharExpr>(
+                     pure(IoControlSpec::CharExpr::Kind::Blank),
+                     scalarDefaultCharExpr)) ||
+    "DECIMAL =" >> construct<IoControlSpec>(construct<IoControlSpec::CharExpr>(
+                       pure(IoControlSpec::CharExpr::Kind::Decimal),
+                       scalarDefaultCharExpr)) ||
+    "DELIM =" >> construct<IoControlSpec>(construct<IoControlSpec::CharExpr>(
+                     pure(IoControlSpec::CharExpr::Kind::Delim),
+                     scalarDefaultCharExpr)) ||
+    "END =" >> construct<IoControlSpec>(endLabel) ||
+    "EOR =" >> construct<IoControlSpec>(eorLabel) ||
+    "ERR =" >> construct<IoControlSpec>(errLabel) ||
+    "ID =" >> construct<IoControlSpec>(idVariable) ||
+    "IOMSG = " >> construct<IoControlSpec>(msgVariable) ||
+    "IOSTAT = " >> construct<IoControlSpec>(statVariable) ||
     "PAD =" >>
-        construct<IoControlSpec>{}(construct<IoControlSpec::CharExpr>{}(
+        construct<IoControlSpec>(construct<IoControlSpec::CharExpr>(
             pure(IoControlSpec::CharExpr::Kind::Pad), scalarDefaultCharExpr)) ||
-    "POS =" >> construct<IoControlSpec>{}(
-                   construct<IoControlSpec::Pos>{}(scalarIntExpr)) ||
-    "REC =" >> construct<IoControlSpec>{}(
-                   construct<IoControlSpec::Rec>{}(scalarIntExpr)) ||
-    "ROUND =" >>
-        construct<IoControlSpec>{}(construct<IoControlSpec::CharExpr>{}(
-            pure(IoControlSpec::CharExpr::Kind::Round),
-            scalarDefaultCharExpr)) ||
-    "SIGN =" >> construct<IoControlSpec>{}(construct<IoControlSpec::CharExpr>{}(
+    "POS =" >> construct<IoControlSpec>(
+                   construct<IoControlSpec::Pos>(scalarIntExpr)) ||
+    "REC =" >> construct<IoControlSpec>(
+                   construct<IoControlSpec::Rec>(scalarIntExpr)) ||
+    "ROUND =" >> construct<IoControlSpec>(construct<IoControlSpec::CharExpr>(
+                     pure(IoControlSpec::CharExpr::Kind::Round),
+                     scalarDefaultCharExpr)) ||
+    "SIGN =" >> construct<IoControlSpec>(construct<IoControlSpec::CharExpr>(
                     pure(IoControlSpec::CharExpr::Kind::Sign),
                     scalarDefaultCharExpr)) ||
-    "SIZE =" >> construct<IoControlSpec>{}(
-                    construct<IoControlSpec::Size>{}(scalarIntVariable)))
+    "SIZE =" >> construct<IoControlSpec>(
+                    construct<IoControlSpec::Size>(scalarIntVariable)))
 
 // R1211 write-stmt -> WRITE ( io-control-spec-list ) [output-item-list]
 constexpr auto outputItemList =
@@ -2509,36 +2479,36 @@ constexpr auto outputItemList =
 
 TYPE_CONTEXT_PARSER("WRITE statement"_en_US,
     "WRITE" >>
-        (construct<WriteStmt>{}("(" >> construct<std::optional<IoUnit>>{}(
-                                           maybe("UNIT ="_tok) >> ioUnit),
-             "," >> construct<std::optional<Format>>{}(format),
+        (construct<WriteStmt>("(" >> construct<std::optional<IoUnit>>(
+                                         maybe("UNIT ="_tok) >> ioUnit),
+             "," >> construct<std::optional<Format>>(format),
              defaulted("," >> nonemptyList(ioControlSpec)) / ")",
              outputItemList) ||
-            construct<WriteStmt>{}(
-                "(" >> construct<std::optional<IoUnit>>{}(ioUnit),
-                construct<std::optional<Format>>{},
+            construct<WriteStmt>(
+                "(" >> construct<std::optional<IoUnit>>(ioUnit),
+                construct<std::optional<Format>>(),
                 defaulted("," >> nonemptyList(ioControlSpec)) / ")",
                 outputItemList) ||
-            construct<WriteStmt>{}(construct<std::optional<IoUnit>>{},
-                construct<std::optional<Format>>{},
+            construct<WriteStmt>(construct<std::optional<IoUnit>>(),
+                construct<std::optional<Format>>(),
                 parenthesized(nonemptyList(ioControlSpec)), outputItemList)))
 
 // R1212 print-stmt PRINT format [, output-item-list]
 TYPE_CONTEXT_PARSER("PRINT statement"_en_US,
-    "PRINT" >> construct<PrintStmt>{}(
+    "PRINT" >> construct<PrintStmt>(
                    format, defaulted("," >> nonemptyList(outputItem))))
 
 // R1215 format -> default-char-expr | label | *
-TYPE_PARSER(construct<Format>{}(defaultCharExpr / !"="_tok) ||
-    construct<Format>{}(label) || construct<Format>{}(star))
+TYPE_PARSER(construct<Format>(defaultCharExpr / !"="_tok) ||
+    construct<Format>(label) || construct<Format>(star))
 
 // R1216 input-item -> variable | io-implied-do
-TYPE_PARSER(construct<InputItem>{}(variable) ||
-    construct<InputItem>{}(indirect(inputImpliedDo)))
+TYPE_PARSER(construct<InputItem>(variable) ||
+    construct<InputItem>(indirect(inputImpliedDo)))
 
 // R1217 output-item -> expr | io-implied-do
-TYPE_PARSER(construct<OutputItem>{}(expr) ||
-    construct<OutputItem>{}(indirect(outputImpliedDo)))
+TYPE_PARSER(construct<OutputItem>(expr) ||
+    construct<OutputItem>(indirect(outputImpliedDo)))
 
 // R1220 io-implied-do-control ->
 //         do-variable = scalar-int-expr , scalar-int-expr [, scalar-int-expr]
@@ -2547,32 +2517,32 @@ constexpr auto ioImpliedDoControl = loopBounds(scalarIntExpr);
 // R1218 io-implied-do -> ( io-implied-do-object-list , io-implied-do-control )
 // R1219 io-implied-do-object -> input-item | output-item
 TYPE_CONTEXT_PARSER("input implied DO"_en_US,
-    parenthesized(construct<InputImpliedDo>{}(
-        nonemptyList(inputItem / lookAhead(","_tok)),
-        "," >> ioImpliedDoControl)))
+    parenthesized(
+        construct<InputImpliedDo>(nonemptyList(inputItem / lookAhead(","_tok)),
+            "," >> ioImpliedDoControl)))
 TYPE_CONTEXT_PARSER("output implied DO"_en_US,
-    parenthesized(construct<OutputImpliedDo>{}(
+    parenthesized(construct<OutputImpliedDo>(
         nonemptyList(outputItem / lookAhead(","_tok)),
         "," >> ioImpliedDoControl)))
 
 // R1222 wait-stmt -> WAIT ( wait-spec-list )
 TYPE_CONTEXT_PARSER("WAIT statement"_en_US,
     "WAIT" >>
-        parenthesized(construct<WaitStmt>{}(nonemptyList(Parser<WaitSpec>{}))))
+        parenthesized(construct<WaitStmt>(nonemptyList(Parser<WaitSpec>{}))))
 
 // R1223 wait-spec ->
 //         [UNIT =] file-unit-number | END = label | EOR = label | ERR = label |
 //         ID = scalar-int-expr | IOMSG = iomsg-variable |
 //         IOSTAT = scalar-int-variable
-constexpr auto idExpr = construct<IdExpr>{}(scalarIntExpr);
+constexpr auto idExpr = construct<IdExpr>(scalarIntExpr);
 
-TYPE_PARSER(maybe("UNIT ="_tok) >> construct<WaitSpec>{}(fileUnitNumber) ||
-    "END =" >> construct<WaitSpec>{}(endLabel) ||
-    "EOR =" >> construct<WaitSpec>{}(eorLabel) ||
-    "ERR =" >> construct<WaitSpec>{}(errLabel) ||
-    "ID =" >> construct<WaitSpec>{}(idExpr) ||
-    "IOMSG =" >> construct<WaitSpec>{}(msgVariable) ||
-    "IOSTAT =" >> construct<WaitSpec>{}(statVariable))
+TYPE_PARSER(maybe("UNIT ="_tok) >> construct<WaitSpec>(fileUnitNumber) ||
+    "END =" >> construct<WaitSpec>(endLabel) ||
+    "EOR =" >> construct<WaitSpec>(eorLabel) ||
+    "ERR =" >> construct<WaitSpec>(errLabel) ||
+    "ID =" >> construct<WaitSpec>(idExpr) ||
+    "IOMSG =" >> construct<WaitSpec>(msgVariable) ||
+    "IOSTAT =" >> construct<WaitSpec>(statVariable))
 
 template<typename A> std::list<A> singletonList(A &&x) {
   std::list<A> result;
@@ -2581,23 +2551,23 @@ template<typename A> std::list<A> singletonList(A &&x) {
 }
 constexpr auto bareUnitNumberAsList =
     applyFunction(singletonList<PositionOrFlushSpec>,
-        construct<PositionOrFlushSpec>{}(fileUnitNumber));
+        construct<PositionOrFlushSpec>(fileUnitNumber));
 constexpr auto positionOrFlushSpecList =
     parenthesized(nonemptyList(positionOrFlushSpec)) || bareUnitNumberAsList;
 
 // R1224 backspace-stmt ->
 //         BACKSPACE file-unit-number | BACKSPACE ( position-spec-list )
 TYPE_CONTEXT_PARSER("BACKSPACE statement"_en_US,
-    construct<BackspaceStmt>{}("BACKSPACE" >> positionOrFlushSpecList))
+    construct<BackspaceStmt>("BACKSPACE" >> positionOrFlushSpecList))
 
 // R1225 endfile-stmt ->
 //         ENDFILE file-unit-number | ENDFILE ( position-spec-list )
 TYPE_CONTEXT_PARSER("ENDFILE statement"_en_US,
-    construct<EndfileStmt>{}("ENDFILE" >> positionOrFlushSpecList))
+    construct<EndfileStmt>("ENDFILE" >> positionOrFlushSpecList))
 
 // R1226 rewind-stmt -> REWIND file-unit-number | REWIND ( position-spec-list )
 TYPE_CONTEXT_PARSER("REWIND statement"_en_US,
-    construct<RewindStmt>{}("REWIND" >> positionOrFlushSpecList))
+    construct<RewindStmt>("REWIND" >> positionOrFlushSpecList))
 
 // R1227 position-spec ->
 //         [UNIT =] file-unit-number | IOMSG = iomsg-variable |
@@ -2606,14 +2576,14 @@ 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<PositionOrFlushSpec>{}(fileUnitNumber) ||
-    "IOMSG =" >> construct<PositionOrFlushSpec>{}(msgVariable) ||
-    "IOSTAT =" >> construct<PositionOrFlushSpec>{}(statVariable) ||
-    "ERR =" >> construct<PositionOrFlushSpec>{}(errLabel))
+    maybe("UNIT ="_tok) >> construct<PositionOrFlushSpec>(fileUnitNumber) ||
+    "IOMSG =" >> construct<PositionOrFlushSpec>(msgVariable) ||
+    "IOSTAT =" >> construct<PositionOrFlushSpec>(statVariable) ||
+    "ERR =" >> construct<PositionOrFlushSpec>(errLabel))
 
 // R1228 flush-stmt -> FLUSH file-unit-number | FLUSH ( flush-spec-list )
 TYPE_CONTEXT_PARSER("FLUSH statement"_en_US,
-    construct<FlushStmt>{}("FLUSH" >> positionOrFlushSpecList))
+    construct<FlushStmt>("FLUSH" >> positionOrFlushSpecList))
 
 // R1231 inquire-spec ->
 //         [UNIT =] file-unit-number | FILE = file-name-expr |
@@ -2645,110 +2615,107 @@ 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<InquireSpec>{}(fileUnitNumber) ||
-    "FILE =" >> construct<InquireSpec>{}(fileNameExpr) ||
-    "ACCESS =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+TYPE_PARSER(maybe("UNIT ="_tok) >> construct<InquireSpec>(fileUnitNumber) ||
+    "FILE =" >> construct<InquireSpec>(fileNameExpr) ||
+    "ACCESS =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                       pure(InquireSpec::CharVar::Kind::Access),
                       scalarDefaultCharVariable)) ||
-    "ACTION =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "ACTION =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                       pure(InquireSpec::CharVar::Kind::Action),
                       scalarDefaultCharVariable)) ||
-    "ASYNCHRONOUS =" >>
-        construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
-            pure(InquireSpec::CharVar::Kind::Asynchronous),
-            scalarDefaultCharVariable)) ||
-    "BLANK =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "ASYNCHRONOUS =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
+                            pure(InquireSpec::CharVar::Kind::Asynchronous),
+                            scalarDefaultCharVariable)) ||
+    "BLANK =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                      pure(InquireSpec::CharVar::Kind::Blank),
                      scalarDefaultCharVariable)) ||
-    "DECIMAL =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "DECIMAL =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                        pure(InquireSpec::CharVar::Kind::Decimal),
                        scalarDefaultCharVariable)) ||
-    "DELIM =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "DELIM =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                      pure(InquireSpec::CharVar::Kind::Delim),
                      scalarDefaultCharVariable)) ||
-    "DIRECT =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "DIRECT =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                       pure(InquireSpec::CharVar::Kind::Direct),
                       scalarDefaultCharVariable)) ||
-    "ENCODING =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "ENCODING =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                         pure(InquireSpec::CharVar::Kind::Encoding),
                         scalarDefaultCharVariable)) ||
-    "ERR =" >> construct<InquireSpec>{}(errLabel) ||
+    "ERR =" >> construct<InquireSpec>(errLabel) ||
     "EXIST =" >>
-        construct<InquireSpec>{}(construct<InquireSpec::LogVar>{}(
+        construct<InquireSpec>(construct<InquireSpec::LogVar>(
             pure(InquireSpec::LogVar::Kind::Exist), scalarLogicalVariable)) ||
-    "FORM =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "FORM =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                     pure(InquireSpec::CharVar::Kind::Form),
                     scalarDefaultCharVariable)) ||
-    "FORMATTED =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "FORMATTED =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                          pure(InquireSpec::CharVar::Kind::Formatted),
                          scalarDefaultCharVariable)) ||
-    "ID =" >> construct<InquireSpec>{}(idExpr) ||
-    "IOMSG =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "ID =" >> construct<InquireSpec>(idExpr) ||
+    "IOMSG =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                      pure(InquireSpec::CharVar::Kind::Iomsg),
                      scalarDefaultCharVariable)) ||
-    "IOSTAT =" >> construct<InquireSpec>{}(construct<InquireSpec::IntVar>{}(
+    "IOSTAT =" >> construct<InquireSpec>(construct<InquireSpec::IntVar>(
                       pure(InquireSpec::IntVar::Kind::Iostat),
                       scalar(integer(variable)))) ||
-    "NAME =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "NAME =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                     pure(InquireSpec::CharVar::Kind::Name),
                     scalarDefaultCharVariable)) ||
     "NAMED =" >>
-        construct<InquireSpec>{}(construct<InquireSpec::LogVar>{}(
+        construct<InquireSpec>(construct<InquireSpec::LogVar>(
             pure(InquireSpec::LogVar::Kind::Named), scalarLogicalVariable)) ||
-    "NEXTREC =" >> construct<InquireSpec>{}(construct<InquireSpec::IntVar>{}(
+    "NEXTREC =" >> construct<InquireSpec>(construct<InquireSpec::IntVar>(
                        pure(InquireSpec::IntVar::Kind::Nextrec),
                        scalar(integer(variable)))) ||
-    "NUMBER =" >> construct<InquireSpec>{}(construct<InquireSpec::IntVar>{}(
+    "NUMBER =" >> construct<InquireSpec>(construct<InquireSpec::IntVar>(
                       pure(InquireSpec::IntVar::Kind::Number),
                       scalar(integer(variable)))) ||
     "OPENED =" >>
-        construct<InquireSpec>{}(construct<InquireSpec::LogVar>{}(
+        construct<InquireSpec>(construct<InquireSpec::LogVar>(
             pure(InquireSpec::LogVar::Kind::Opened), scalarLogicalVariable)) ||
-    "PAD =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "PAD =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                    pure(InquireSpec::CharVar::Kind::Pad),
                    scalarDefaultCharVariable)) ||
     "PENDING =" >>
-        construct<InquireSpec>{}(construct<InquireSpec::LogVar>{}(
+        construct<InquireSpec>(construct<InquireSpec::LogVar>(
             pure(InquireSpec::LogVar::Kind::Pending), scalarLogicalVariable)) ||
     "POS =" >>
-        construct<InquireSpec>{}(construct<InquireSpec::IntVar>{}(
+        construct<InquireSpec>(construct<InquireSpec::IntVar>(
             pure(InquireSpec::IntVar::Kind::Pos), scalar(integer(variable)))) ||
-    "POSITION =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "POSITION =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                         pure(InquireSpec::CharVar::Kind::Position),
                         scalarDefaultCharVariable)) ||
-    "READ =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "READ =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                     pure(InquireSpec::CharVar::Kind::Read),
                     scalarDefaultCharVariable)) ||
-    "READWRITE =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "READWRITE =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                          pure(InquireSpec::CharVar::Kind::Readwrite),
                          scalarDefaultCharVariable)) ||
-    "RECL =" >> construct<InquireSpec>{}(construct<InquireSpec::IntVar>{}(
+    "RECL =" >> construct<InquireSpec>(construct<InquireSpec::IntVar>(
                     pure(InquireSpec::IntVar::Kind::Recl),
                     scalar(integer(variable)))) ||
-    "ROUND =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "ROUND =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                      pure(InquireSpec::CharVar::Kind::Round),
                      scalarDefaultCharVariable)) ||
-    "SEQUENTIAL =" >>
-        construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
-            pure(InquireSpec::CharVar::Kind::Sequential),
-            scalarDefaultCharVariable)) ||
-    "SIGN =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "SEQUENTIAL =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
+                          pure(InquireSpec::CharVar::Kind::Sequential),
+                          scalarDefaultCharVariable)) ||
+    "SIGN =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                     pure(InquireSpec::CharVar::Kind::Sign),
                     scalarDefaultCharVariable)) ||
-    "SIZE =" >> construct<InquireSpec>{}(construct<InquireSpec::IntVar>{}(
+    "SIZE =" >> construct<InquireSpec>(construct<InquireSpec::IntVar>(
                     pure(InquireSpec::IntVar::Kind::Size),
                     scalar(integer(variable)))) ||
-    "STREAM =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "STREAM =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                       pure(InquireSpec::CharVar::Kind::Stream),
                       scalarDefaultCharVariable)) ||
-    "STATUS =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "STATUS =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                       pure(InquireSpec::CharVar::Kind::Status),
                       scalarDefaultCharVariable)) ||
-    "UNFORMATTED =" >>
-        construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
-            pure(InquireSpec::CharVar::Kind::Unformatted),
-            scalarDefaultCharVariable)) ||
-    "WRITE =" >> construct<InquireSpec>{}(construct<InquireSpec::CharVar>{}(
+    "UNFORMATTED =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
+                           pure(InquireSpec::CharVar::Kind::Unformatted),
+                           scalarDefaultCharVariable)) ||
+    "WRITE =" >> construct<InquireSpec>(construct<InquireSpec::CharVar>(
                      pure(InquireSpec::CharVar::Kind::Write),
                      scalarDefaultCharVariable)))
 
@@ -2757,15 +2724,15 @@ TYPE_PARSER(maybe("UNIT ="_tok) >> construct<InquireSpec>{}(fileUnitNumber) ||
 //         INQUIRE ( IOLENGTH = scalar-int-variable ) output-item-list
 TYPE_CONTEXT_PARSER("INQUIRE statement"_en_US,
     "INQUIRE" >>
-        (construct<InquireStmt>{}(
+        (construct<InquireStmt>(
              parenthesized(nonemptyList(Parser<InquireSpec>{}))) ||
-            construct<InquireStmt>{}(construct<InquireStmt::Iolength>{}(
+            construct<InquireStmt>(construct<InquireStmt::Iolength>(
                 parenthesized("IOLENGTH =" >> scalar(integer(variable))),
                 nonemptyList(outputItem)))))
 
 // R1301 format-stmt -> FORMAT format-specification
 TYPE_CONTEXT_PARSER("FORMAT statement"_en_US,
-    "FORMAT" >> construct<FormatStmt>{}(Parser<format::FormatSpecification>{}))
+    "FORMAT" >> construct<FormatStmt>(Parser<format::FormatSpecification>{}))
 
 // R1321 char-string-edit-desc
 // N.B. C1313 disallows any kind parameter on the character literal.
@@ -2782,30 +2749,30 @@ constexpr auto repeat = space >> digitString;
 // R1304 format-item ->
 //         [r] data-edit-desc | control-edit-desc | char-string-edit-desc |
 //         [r] ( format-items )
-TYPE_PARSER(construct<format::FormatItem>{}(
+TYPE_PARSER(construct<format::FormatItem>(
                 maybe(repeat), Parser<format::IntrinsicTypeDataEditDesc>{}) ||
-    construct<format::FormatItem>{}(
+    construct<format::FormatItem>(
         maybe(repeat), Parser<format::DerivedTypeDataEditDesc>{}) ||
-    construct<format::FormatItem>{}(Parser<format::ControlEditDesc>{}) ||
-    construct<format::FormatItem>{}(charStringEditDesc) ||
-    construct<format::FormatItem>{}(maybe(repeat), parenthesized(formatItems)))
+    construct<format::FormatItem>(Parser<format::ControlEditDesc>{}) ||
+    construct<format::FormatItem>(charStringEditDesc) ||
+    construct<format::FormatItem>(maybe(repeat), parenthesized(formatItems)))
 
 // R1302 format-specification ->
 //         ( [format-items] ) | ( [format-items ,] unlimited-format-item )
 // R1305 unlimited-format-item -> * ( format-items )
 TYPE_PARSER(parenthesized(
-    construct<format::FormatSpecification>{}(
+    construct<format::FormatSpecification>(
         defaulted(formatItems / ","), "*" >> parenthesized(formatItems)) ||
-    construct<format::FormatSpecification>{}(defaulted(formatItems))))
+    construct<format::FormatSpecification>(defaulted(formatItems))))
 // R1308 w -> digit-string
 // R1309 m -> digit-string
 // R1310 d -> digit-string
 // R1311 e -> digit-string
 constexpr auto width = repeat;
-constexpr auto mandatoryWidth = construct<std::optional<int>>{}(width);
+constexpr auto mandatoryWidth = construct<std::optional<int>>(width);
 constexpr auto digits = repeat;
-constexpr auto noInt = construct<std::optional<int>>{};
-constexpr auto mandatoryDigits = "." >> construct<std::optional<int>>{}(width);
+constexpr auto noInt = construct<std::optional<int>>();
+constexpr auto mandatoryDigits = "." >> construct<std::optional<int>>(width);
 
 // R1307 data-edit-desc ->
 //         I w [. m] | B w [. m] | O w [. m] | Z w [. m] | F w . d |
@@ -2814,34 +2781,34 @@ constexpr auto mandatoryDigits = "." >> construct<std::optional<int>>{}(width);
 //         DT [char-literal-constant] [( v-list )]
 // (part 1 of 2)
 TYPE_PARSER(
-    construct<format::IntrinsicTypeDataEditDesc>{}(
+    construct<format::IntrinsicTypeDataEditDesc>(
         "I"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) ||
             "B"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::B) ||
             "O"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::O) ||
             "Z"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::Z),
         mandatoryWidth, maybe("." >> digits), noInt) ||
-    construct<format::IntrinsicTypeDataEditDesc>{}(
+    construct<format::IntrinsicTypeDataEditDesc>(
         "F"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::F) ||
             "D"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::D),
         mandatoryWidth, mandatoryDigits, noInt) ||
-    construct<format::IntrinsicTypeDataEditDesc>{}("E"_ch >>
+    construct<format::IntrinsicTypeDataEditDesc>("E"_ch >>
             ("N"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::EN) ||
                 "S"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::ES) ||
                 "X"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::EX) ||
                 pure(format::IntrinsicTypeDataEditDesc::Kind::E)),
         mandatoryWidth, mandatoryDigits, maybe("E"_ch >> digits)) ||
-    construct<format::IntrinsicTypeDataEditDesc>{}(
+    construct<format::IntrinsicTypeDataEditDesc>(
         "G"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::G),
         mandatoryWidth, mandatoryDigits, maybe("E"_ch >> digits)) ||
-    construct<format::IntrinsicTypeDataEditDesc>{}(
+    construct<format::IntrinsicTypeDataEditDesc>(
         "G"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::G) ||
             "L"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::L),
         mandatoryWidth, noInt, noInt) ||
-    construct<format::IntrinsicTypeDataEditDesc>{}(
+    construct<format::IntrinsicTypeDataEditDesc>(
         "A"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::A),
         maybe(width), noInt, noInt) ||
     // PGI/Intel extension: omitting width (and all else that follows)
-    extension(construct<format::IntrinsicTypeDataEditDesc>{}(
+    extension(construct<format::IntrinsicTypeDataEditDesc>(
         "I"_ch >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) ||
             ("B"_ch / !letter /* don't occlude BN & BZ */) >>
                 pure(format::IntrinsicTypeDataEditDesc::Kind::B) ||
@@ -2864,7 +2831,7 @@ TYPE_PARSER(
 // R1307 data-edit-desc (part 2 of 2)
 // R1312 v -> [sign] digit-string
 TYPE_PARSER("D"_ch >> "T"_ch >>
-    construct<format::DerivedTypeDataEditDesc>{}(
+    construct<format::DerivedTypeDataEditDesc>(
         space >> defaulted(charLiteralConstantWithoutKind),
         defaulted(parenthesized(nonemptyList(space >> signedDigitString)))))
 
@@ -2881,95 +2848,95 @@ constexpr auto scaleFactor = space >> signedDigitString;
 // R1318 blank-interp-edit-desc -> BN | BZ
 // R1319 round-edit-desc -> RU | RD | RZ | RN | RC | RP
 // R1320 decimal-edit-desc -> DC | DP
-TYPE_PARSER(construct<format::ControlEditDesc>{}("T"_ch >>
+TYPE_PARSER(construct<format::ControlEditDesc>("T"_ch >>
                     ("L"_ch >> pure(format::ControlEditDesc::Kind::TL) ||
                         "R"_ch >> pure(format::ControlEditDesc::Kind::TR) ||
                         pure(format::ControlEditDesc::Kind::T)),
                 count) ||
-    construct<format::ControlEditDesc>{}(count,
+    construct<format::ControlEditDesc>(count,
         "X"_ch >> pure(format::ControlEditDesc::Kind::X) ||
             "/"_ch >> pure(format::ControlEditDesc::Kind::Slash)) ||
-    construct<format::ControlEditDesc>{}(
+    construct<format::ControlEditDesc>(
         "X"_ch >> pure(format::ControlEditDesc::Kind::X) ||
         "/"_ch >> pure(format::ControlEditDesc::Kind::Slash)) ||
-    construct<format::ControlEditDesc>{}(
+    construct<format::ControlEditDesc>(
         scaleFactor, "P"_ch >> pure(format::ControlEditDesc::Kind::P)) ||
-    ":"_ch >> construct<format::ControlEditDesc>{}(
+    ":"_ch >> construct<format::ControlEditDesc>(
                   pure(format::ControlEditDesc::Kind::Colon)) ||
-    "S"_ch >> ("S"_ch >> construct<format::ControlEditDesc>{}(
+    "S"_ch >> ("S"_ch >> construct<format::ControlEditDesc>(
                              pure(format::ControlEditDesc::Kind::SS)) ||
-                  "P"_ch >> construct<format::ControlEditDesc>{}(
+                  "P"_ch >> construct<format::ControlEditDesc>(
                                 pure(format::ControlEditDesc::Kind::SP)) ||
-                  construct<format::ControlEditDesc>{}(
+                  construct<format::ControlEditDesc>(
                       pure(format::ControlEditDesc::Kind::S))) ||
-    "B"_ch >> ("N"_ch >> construct<format::ControlEditDesc>{}(
+    "B"_ch >> ("N"_ch >> construct<format::ControlEditDesc>(
                              pure(format::ControlEditDesc::Kind::BN)) ||
-                  "Z"_ch >> construct<format::ControlEditDesc>{}(
+                  "Z"_ch >> construct<format::ControlEditDesc>(
                                 pure(format::ControlEditDesc::Kind::BZ))) ||
-    "R"_ch >> ("U"_ch >> construct<format::ControlEditDesc>{}(
+    "R"_ch >> ("U"_ch >> construct<format::ControlEditDesc>(
                              pure(format::ControlEditDesc::Kind::RU)) ||
-                  "D"_ch >> construct<format::ControlEditDesc>{}(
+                  "D"_ch >> construct<format::ControlEditDesc>(
                                 pure(format::ControlEditDesc::Kind::RD)) ||
-                  "Z"_ch >> construct<format::ControlEditDesc>{}(
+                  "Z"_ch >> construct<format::ControlEditDesc>(
                                 pure(format::ControlEditDesc::Kind::RZ)) ||
-                  "N"_ch >> construct<format::ControlEditDesc>{}(
+                  "N"_ch >> construct<format::ControlEditDesc>(
                                 pure(format::ControlEditDesc::Kind::RN)) ||
-                  "C"_ch >> construct<format::ControlEditDesc>{}(
+                  "C"_ch >> construct<format::ControlEditDesc>(
                                 pure(format::ControlEditDesc::Kind::RC)) ||
-                  "P"_ch >> construct<format::ControlEditDesc>{}(
+                  "P"_ch >> construct<format::ControlEditDesc>(
                                 pure(format::ControlEditDesc::Kind::RP))) ||
-    "D"_ch >> ("C"_ch >> construct<format::ControlEditDesc>{}(
+    "D"_ch >> ("C"_ch >> construct<format::ControlEditDesc>(
                              pure(format::ControlEditDesc::Kind::DC)) ||
-                  "P"_ch >> construct<format::ControlEditDesc>{}(
+                  "P"_ch >> construct<format::ControlEditDesc>(
                                 pure(format::ControlEditDesc::Kind::DP))))
 
 // R1401 main-program ->
 //         [program-stmt] [specification-part] [execution-part]
 //         [internal-subprogram-part] end-program-stmt
 TYPE_CONTEXT_PARSER("main program"_en_US,
-    construct<MainProgram>{}(maybe(statement(Parser<ProgramStmt>{})),
+    construct<MainProgram>(maybe(statement(Parser<ProgramStmt>{})),
         specificationPart, executionPart, maybe(internalSubprogramPart),
         unterminatedStatement(Parser<EndProgramStmt>{})))
 
 // R1402 program-stmt -> PROGRAM program-name
 // PGI allows empty parentheses after the name.
 TYPE_CONTEXT_PARSER("PROGRAM statement"_en_US,
-    construct<ProgramStmt>{}(
+    construct<ProgramStmt>(
         "PROGRAM" >> name / maybe(extension(parenthesized(ok)))))
 
 // R1403 end-program-stmt -> END [PROGRAM [program-name]]
 TYPE_CONTEXT_PARSER("END PROGRAM statement"_en_US,
-    construct<EndProgramStmt>{}(recovery(
+    construct<EndProgramStmt>(recovery(
         "END PROGRAM" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
 
 // R1404 module ->
 //         module-stmt [specification-part] [module-subprogram-part]
 //         end-module-stmt
 TYPE_CONTEXT_PARSER("module"_en_US,
-    construct<Module>{}(statement(Parser<ModuleStmt>{}), specificationPart,
+    construct<Module>(statement(Parser<ModuleStmt>{}), specificationPart,
         maybe(Parser<ModuleSubprogramPart>{}),
         unterminatedStatement(Parser<EndModuleStmt>{})))
 
 // R1405 module-stmt -> MODULE module-name
 TYPE_CONTEXT_PARSER(
-    "MODULE statement"_en_US, "MODULE" >> construct<ModuleStmt>{}(name))
+    "MODULE statement"_en_US, "MODULE" >> construct<ModuleStmt>(name))
 
 // R1406 end-module-stmt -> END [MODULE [module-name]]
 TYPE_CONTEXT_PARSER("END MODULE statement"_en_US,
-    construct<EndModuleStmt>{}(
+    construct<EndModuleStmt>(
         recovery("END MODULE" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
 
 // R1407 module-subprogram-part -> contains-stmt [module-subprogram]...
 TYPE_CONTEXT_PARSER("module subprogram part"_en_US,
-    construct<ModuleSubprogramPart>{}(statement(containsStmt),
+    construct<ModuleSubprogramPart>(statement(containsStmt),
         many(startNewSubprogram >> Parser<ModuleSubprogram>{})))
 
 // R1408 module-subprogram ->
 //         function-subprogram | subroutine-subprogram |
 //         separate-module-subprogram
-TYPE_PARSER(construct<ModuleSubprogram>{}(indirect(functionSubprogram)) ||
-    construct<ModuleSubprogram>{}(indirect(subroutineSubprogram)) ||
-    construct<ModuleSubprogram>{}(indirect(Parser<SeparateModuleSubprogram>{})))
+TYPE_PARSER(construct<ModuleSubprogram>(indirect(functionSubprogram)) ||
+    construct<ModuleSubprogram>(indirect(subroutineSubprogram)) ||
+    construct<ModuleSubprogram>(indirect(Parser<SeparateModuleSubprogram>{})))
 
 // R1410 module-nature -> INTRINSIC | NON_INTRINSIC
 constexpr auto moduleNature = "INTRINSIC" >>
@@ -2979,99 +2946,98 @@ constexpr auto moduleNature = "INTRINSIC" >>
 // R1409 use-stmt ->
 //         USE [[, module-nature] ::] module-name [, rename-list] |
 //         USE [[, module-nature] ::] module-name , ONLY : [only-list]
-TYPE_PARSER(construct<UseStmt>{}("USE" >> optionalBeforeColons(moduleNature),
+TYPE_PARSER(construct<UseStmt>("USE" >> optionalBeforeColons(moduleNature),
                 name, ", ONLY :" >> optionalList(Parser<Only>{})) ||
-    construct<UseStmt>{}("USE" >> optionalBeforeColons(moduleNature), name,
+    construct<UseStmt>("USE" >> optionalBeforeColons(moduleNature), name,
         defaulted("," >> nonemptyList(Parser<Rename>{}))))
 
 // R1411 rename ->
 //         local-name => use-name |
 //         OPERATOR ( local-defined-operator ) =>
 //           OPERATOR ( use-defined-operator )
-TYPE_PARSER(construct<Rename>{}("OPERATOR (" >>
-                construct<Rename::Operators>{}(
+TYPE_PARSER(construct<Rename>("OPERATOR (" >>
+                construct<Rename::Operators>(
                     definedOpName / ") => OPERATOR (", definedOpName / ")")) ||
-    construct<Rename>{}(construct<Rename::Names>{}(name, "=>" >> name)))
+    construct<Rename>(construct<Rename::Names>(name, "=>" >> name)))
 
 // R1412 only -> generic-spec | only-use-name | rename
 // R1413 only-use-name -> use-name
-TYPE_PARSER(construct<Only>{}(Parser<Rename>{}) ||
-    construct<Only>{}(indirect(genericSpec)) ||
-    construct<Only>{}(name))  // TODO: ambiguous, accepted by genericSpec
+TYPE_PARSER(construct<Only>(Parser<Rename>{}) ||
+    construct<Only>(indirect(genericSpec)) ||
+    construct<Only>(name))  // TODO: ambiguous, accepted by genericSpec
 
 // R1416 submodule ->
 //         submodule-stmt [specification-part] [module-subprogram-part]
 //         end-submodule-stmt
 TYPE_CONTEXT_PARSER("submodule"_en_US,
-    construct<Submodule>{}(statement(Parser<SubmoduleStmt>{}),
-        specificationPart, maybe(Parser<ModuleSubprogramPart>{}),
+    construct<Submodule>(statement(Parser<SubmoduleStmt>{}), specificationPart,
+        maybe(Parser<ModuleSubprogramPart>{}),
         unterminatedStatement(Parser<EndSubmoduleStmt>{})))
 
 // R1417 submodule-stmt -> SUBMODULE ( parent-identifier ) submodule-name
 TYPE_CONTEXT_PARSER("SUBMODULE statement"_en_US,
-    construct<SubmoduleStmt>{}(
+    construct<SubmoduleStmt>(
         "SUBMODULE" >> parenthesized(Parser<ParentIdentifier>{}), name))
 
 // R1418 parent-identifier -> ancestor-module-name [: parent-submodule-name]
-TYPE_PARSER(construct<ParentIdentifier>{}(name, maybe(":" >> name)))
+TYPE_PARSER(construct<ParentIdentifier>(name, maybe(":" >> name)))
 
 // R1419 end-submodule-stmt -> END [SUBMODULE [submodule-name]]
 TYPE_CONTEXT_PARSER("END SUBMODULE statement"_en_US,
-    construct<EndSubmoduleStmt>{}(recovery(
+    construct<EndSubmoduleStmt>(recovery(
         "END SUBMODULE" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
 
 // R1420 block-data -> block-data-stmt [specification-part] end-block-data-stmt
 TYPE_CONTEXT_PARSER("BLOCK DATA subprogram"_en_US,
-    construct<BlockData>{}(statement(Parser<BlockDataStmt>{}),
-        specificationPart, unterminatedStatement(Parser<EndBlockDataStmt>{})))
+    construct<BlockData>(statement(Parser<BlockDataStmt>{}), specificationPart,
+        unterminatedStatement(Parser<EndBlockDataStmt>{})))
 
 // R1421 block-data-stmt -> BLOCK DATA [block-data-name]
 TYPE_CONTEXT_PARSER("BLOCK DATA statement"_en_US,
-    "BLOCK DATA" >> construct<BlockDataStmt>{}(maybe(name)))
+    "BLOCK DATA" >> construct<BlockDataStmt>(maybe(name)))
 
 // R1422 end-block-data-stmt -> END [BLOCK DATA [block-data-name]]
 TYPE_CONTEXT_PARSER("END BLOCK DATA statement"_en_US,
-    construct<EndBlockDataStmt>{}(recovery(
+    construct<EndBlockDataStmt>(recovery(
         "END BLOCK DATA" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
 
 // R1501 interface-block ->
 //         interface-stmt [interface-specification]... end-interface-stmt
-TYPE_PARSER(construct<InterfaceBlock>{}(statement(Parser<InterfaceStmt>{}),
+TYPE_PARSER(construct<InterfaceBlock>(statement(Parser<InterfaceStmt>{}),
     many(Parser<InterfaceSpecification>{}),
     statement(Parser<EndInterfaceStmt>{})))
 
 // R1502 interface-specification -> interface-body | procedure-stmt
-TYPE_PARSER(construct<InterfaceSpecification>{}(Parser<InterfaceBody>{}) ||
-    construct<InterfaceSpecification>{}(statement(Parser<ProcedureStmt>{})))
+TYPE_PARSER(construct<InterfaceSpecification>(Parser<InterfaceBody>{}) ||
+    construct<InterfaceSpecification>(statement(Parser<ProcedureStmt>{})))
 
 // R1503 interface-stmt -> INTERFACE [generic-spec] | ABSTRACT INTERFACE
-TYPE_PARSER("INTERFACE" >> construct<InterfaceStmt>{}(maybe(genericSpec)) ||
+TYPE_PARSER("INTERFACE" >> construct<InterfaceStmt>(maybe(genericSpec)) ||
     "ABSTRACT INTERFACE"_sptok >>
-        construct<InterfaceStmt>{}(construct<Abstract>{}))
+        construct<InterfaceStmt>(construct<Abstract>()))
 
 // R1504 end-interface-stmt -> END INTERFACE [generic-spec]
-TYPE_PARSER(
-    "END INTERFACE" >> construct<EndInterfaceStmt>{}(maybe(genericSpec)))
+TYPE_PARSER("END INTERFACE" >> construct<EndInterfaceStmt>(maybe(genericSpec)))
 
 // R1505 interface-body ->
 //         function-stmt [specification-part] end-function-stmt |
 //         subroutine-stmt [specification-part] end-subroutine-stmt
 TYPE_CONTEXT_PARSER("interface body"_en_US,
-    construct<InterfaceBody>{}(
-        construct<InterfaceBody::Function>{}(statement(functionStmt),
+    construct<InterfaceBody>(
+        construct<InterfaceBody::Function>(statement(functionStmt),
             indirect(specificationPart), statement(endFunctionStmt))) ||
-        construct<InterfaceBody>{}(
-            construct<InterfaceBody::Subroutine>{}(statement(subroutineStmt),
+        construct<InterfaceBody>(
+            construct<InterfaceBody::Subroutine>(statement(subroutineStmt),
                 indirect(specificationPart), statement(endSubroutineStmt))))
 
 // R1507 specific-procedure -> procedure-name
 constexpr auto specificProcedure = name;
 
 // R1506 procedure-stmt -> [MODULE] PROCEDURE [::] specific-procedure-list
-TYPE_PARSER(construct<ProcedureStmt>{}("MODULE PROCEDURE"_sptok >>
+TYPE_PARSER(construct<ProcedureStmt>("MODULE PROCEDURE"_sptok >>
                     pure(ProcedureStmt::Kind::ModuleProcedure),
                 maybe("::"_tok) >> nonemptyList(specificProcedure)) ||
-    construct<ProcedureStmt>{}(
+    construct<ProcedureStmt>(
         "PROCEDURE" >> pure(ProcedureStmt::Kind::Procedure),
         maybe("::"_tok) >> nonemptyList(specificProcedure)))
 
@@ -3081,83 +3047,81 @@ TYPE_PARSER(construct<ProcedureStmt>{}("MODULE PROCEDURE"_sptok >>
 // R1509 defined-io-generic-spec ->
 //         READ ( FORMATTED ) | READ ( UNFORMATTED ) |
 //         WRITE ( FORMATTED ) | WRITE ( UNFORMATTED )
-TYPE_PARSER(construct<GenericSpec>{}(
+TYPE_PARSER(construct<GenericSpec>(
                 "OPERATOR" >> parenthesized(Parser<DefinedOperator>{})) ||
-    construct<GenericSpec>{}(
-        "ASSIGNMENT ( = )" >> construct<GenericSpec::Assignment>{}) ||
-    construct<GenericSpec>{}(
-        "READ ( FORMATTED )" >> construct<GenericSpec::ReadFormatted>{}) ||
-    construct<GenericSpec>{}(
-        "READ ( UNFORMATTED )" >> construct<GenericSpec::ReadUnformatted>{}) ||
-    construct<GenericSpec>{}(
-        "WRITE ( FORMATTED )" >> construct<GenericSpec::WriteFormatted>{}) ||
-    construct<GenericSpec>{}("WRITE ( UNFORMATTED )" >>
-        construct<GenericSpec::WriteUnformatted>{}) ||
-    construct<GenericSpec>{}(name))
+    construct<GenericSpec>(
+        "ASSIGNMENT ( = )" >> construct<GenericSpec::Assignment>()) ||
+    construct<GenericSpec>(
+        "READ ( FORMATTED )" >> construct<GenericSpec::ReadFormatted>()) ||
+    construct<GenericSpec>(
+        "READ ( UNFORMATTED )" >> construct<GenericSpec::ReadUnformatted>()) ||
+    construct<GenericSpec>(
+        "WRITE ( FORMATTED )" >> construct<GenericSpec::WriteFormatted>()) ||
+    construct<GenericSpec>("WRITE ( UNFORMATTED )" >>
+        construct<GenericSpec::WriteUnformatted>()) ||
+    construct<GenericSpec>(name))
 
 // R1510 generic-stmt ->
 //         GENERIC [, access-spec] :: generic-spec => specific-procedure-list
-TYPE_PARSER("GENERIC" >> construct<GenericStmt>{}(maybe("," >> accessSpec),
+TYPE_PARSER("GENERIC" >> construct<GenericStmt>(maybe("," >> accessSpec),
                              "::" >> genericSpec,
                              "=>" >> nonemptyList(specificProcedure)))
 
 // R1511 external-stmt -> EXTERNAL [::] external-name-list
 TYPE_PARSER("EXTERNAL" >> maybe("::"_tok) >>
-    construct<ExternalStmt>{}(nonemptyList(name)))
+    construct<ExternalStmt>(nonemptyList(name)))
 
 // R1512 procedure-declaration-stmt ->
 //         PROCEDURE ( [proc-interface] ) [[, proc-attr-spec]... ::]
 //         proc-decl-list
 TYPE_PARSER("PROCEDURE" >>
-    construct<ProcedureDeclarationStmt>{}(parenthesized(maybe(procInterface)),
+    construct<ProcedureDeclarationStmt>(parenthesized(maybe(procInterface)),
         optionalListBeforeColons(Parser<ProcAttrSpec>{}),
         nonemptyList(procDecl)))
 
 // R1513 proc-interface -> interface-name | declaration-type-spec
 // R1516 interface-name -> name
-TYPE_PARSER(construct<ProcInterface>{}(declarationTypeSpec) ||
-    construct<ProcInterface>{}(name))
+TYPE_PARSER(construct<ProcInterface>(declarationTypeSpec) ||
+    construct<ProcInterface>(name))
 
 // R1514 proc-attr-spec ->
 //         access-spec | proc-language-binding-spec | INTENT ( intent-spec ) |
 //         OPTIONAL | POINTER | PROTECTED | SAVE
-TYPE_PARSER(construct<ProcAttrSpec>{}(accessSpec) ||
-    construct<ProcAttrSpec>{}(languageBindingSpec) ||
-    construct<ProcAttrSpec>{}("INTENT" >> parenthesized(intentSpec)) ||
-    construct<ProcAttrSpec>{}(optional) || construct<ProcAttrSpec>{}(pointer) ||
-    construct<ProcAttrSpec>{}(protectedAttr) || construct<ProcAttrSpec>{}(save))
+TYPE_PARSER(construct<ProcAttrSpec>(accessSpec) ||
+    construct<ProcAttrSpec>(languageBindingSpec) ||
+    construct<ProcAttrSpec>("INTENT" >> parenthesized(intentSpec)) ||
+    construct<ProcAttrSpec>(optional) || construct<ProcAttrSpec>(pointer) ||
+    construct<ProcAttrSpec>(protectedAttr) || construct<ProcAttrSpec>(save))
 
 // R1515 proc-decl -> procedure-entity-name [=> proc-pointer-init]
-TYPE_PARSER(
-    construct<ProcDecl>{}(name, maybe("=>" >> Parser<ProcPointerInit>{})))
+TYPE_PARSER(construct<ProcDecl>(name, maybe("=>" >> Parser<ProcPointerInit>{})))
 
 // R1517 proc-pointer-init -> null-init | initial-proc-target
 // R1518 initial-proc-target -> procedure-name
-TYPE_PARSER(construct<ProcPointerInit>{}(nullInit) ||
-    construct<ProcPointerInit>{}(name))
+TYPE_PARSER(
+    construct<ProcPointerInit>(nullInit) || construct<ProcPointerInit>(name))
 
 // R1519 intrinsic-stmt -> INTRINSIC [::] intrinsic-procedure-name-list
 TYPE_PARSER("INTRINSIC" >> maybe("::"_tok) >>
-    construct<IntrinsicStmt>{}(nonemptyList(name)))
+    construct<IntrinsicStmt>(nonemptyList(name)))
 
 // R1520 function-reference -> procedure-designator ( [actual-arg-spec-list] )
 TYPE_CONTEXT_PARSER("function reference"_en_US,
-    construct<FunctionReference>{}(
-        construct<Call>{}(Parser<ProcedureDesignator>{},
-            parenthesized(optionalList(actualArgSpec)))))
+    construct<FunctionReference>(construct<Call>(Parser<ProcedureDesignator>{},
+        parenthesized(optionalList(actualArgSpec)))))
 
 // R1521 call-stmt -> CALL procedure-designator [( [actual-arg-spec-list] )]
-TYPE_PARSER(construct<CallStmt>{}(
-    construct<Call>{}("CALL" >> Parser<ProcedureDesignator>{},
+TYPE_PARSER(
+    construct<CallStmt>(construct<Call>("CALL" >> Parser<ProcedureDesignator>{},
         defaulted(parenthesized(optionalList(actualArgSpec))))))
 
 // R1522 procedure-designator ->
 //         procedure-name | proc-component-ref | data-ref % binding-name
-TYPE_PARSER(construct<ProcedureDesignator>{}(Parser<ProcComponentRef>{}) ||
-    construct<ProcedureDesignator>{}(name))
+TYPE_PARSER(construct<ProcedureDesignator>(Parser<ProcComponentRef>{}) ||
+    construct<ProcedureDesignator>(name))
 
 // R1523 actual-arg-spec -> [keyword =] actual-arg
-TYPE_PARSER(construct<ActualArgSpec>{}(
+TYPE_PARSER(construct<ActualArgSpec>(
     maybe(keyword / "=" / !"="_ch), Parser<ActualArg>{}))
 
 // R1524 actual-arg ->
@@ -3165,37 +3129,34 @@ TYPE_PARSER(construct<ActualArgSpec>{}(
 //         alt-return-spec
 // N.B. the "procedure-name" and "proc-component-ref" alternatives can't
 // yet be distinguished from "variable".
-TYPE_PARSER(construct<ActualArg>{}(variable) / lookAhead(","_tok || ")"_tok) ||
-    construct<ActualArg>{}(expr) ||
-    construct<ActualArg>{}(Parser<AltReturnSpec>{}) ||
-    extension("%REF" >>
-        construct<ActualArg>{}(
-            construct<ActualArg::PercentRef>{}(parenthesized(variable)))) ||
-    extension(
-        "%VAL" >> construct<ActualArg>{}(
-                      construct<ActualArg::PercentVal>{}(parenthesized(expr)))))
+TYPE_PARSER(construct<ActualArg>(variable) / lookAhead(","_tok || ")"_tok) ||
+    construct<ActualArg>(expr) ||
+    construct<ActualArg>(Parser<AltReturnSpec>{}) ||
+    extension("%REF" >> construct<ActualArg>(construct<ActualArg::PercentRef>(
+                            parenthesized(variable)))) ||
+    extension("%VAL" >> construct<ActualArg>(construct<ActualArg::PercentVal>(
+                            parenthesized(expr)))))
 
 // R1525 alt-return-spec -> * label
-TYPE_PARSER(star >> construct<AltReturnSpec>{}(label))
+TYPE_PARSER(star >> construct<AltReturnSpec>(label))
 
 // R1527 prefix-spec ->
 //         declaration-type-spec | ELEMENTAL | IMPURE | MODULE |
 //         NON_RECURSIVE | PURE | RECURSIVE
-TYPE_PARSER(construct<PrefixSpec>{}(declarationTypeSpec) ||
-    "ELEMENTAL" >>
-        construct<PrefixSpec>{}(construct<PrefixSpec::Elemental>{}) ||
-    "IMPURE" >> construct<PrefixSpec>{}(construct<PrefixSpec::Impure>{}) ||
-    "MODULE" >> construct<PrefixSpec>{}(construct<PrefixSpec::Module>{}) ||
+TYPE_PARSER(construct<PrefixSpec>(declarationTypeSpec) ||
+    "ELEMENTAL" >> construct<PrefixSpec>(construct<PrefixSpec::Elemental>()) ||
+    "IMPURE" >> construct<PrefixSpec>(construct<PrefixSpec::Impure>()) ||
+    "MODULE" >> construct<PrefixSpec>(construct<PrefixSpec::Module>()) ||
     "NON_RECURSIVE" >>
-        construct<PrefixSpec>{}(construct<PrefixSpec::Non_Recursive>{}) ||
-    "PURE" >> construct<PrefixSpec>{}(construct<PrefixSpec::Pure>{}) ||
-    "RECURSIVE" >> construct<PrefixSpec>{}(construct<PrefixSpec::Recursive>{}))
+        construct<PrefixSpec>(construct<PrefixSpec::Non_Recursive>()) ||
+    "PURE" >> construct<PrefixSpec>(construct<PrefixSpec::Pure>()) ||
+    "RECURSIVE" >> construct<PrefixSpec>(construct<PrefixSpec::Recursive>()))
 
 // R1529 function-subprogram ->
 //         function-stmt [specification-part] [execution-part]
 //         [internal-subprogram-part] end-function-stmt
 TYPE_CONTEXT_PARSER("FUNCTION subprogram"_en_US,
-    construct<FunctionSubprogram>{}(statement(functionStmt), specificationPart,
+    construct<FunctionSubprogram>(statement(functionStmt), specificationPart,
         executionPart, maybe(internalSubprogramPart),
         unterminatedStatement(endFunctionStmt)))
 
@@ -3204,29 +3165,29 @@ TYPE_CONTEXT_PARSER("FUNCTION subprogram"_en_US,
 // R1526 prefix -> prefix-spec [prefix-spec]...
 // R1531 dummy-arg-name -> name
 TYPE_CONTEXT_PARSER("FUNCTION statement"_en_US,
-    construct<FunctionStmt>{}(many(prefixSpec), "FUNCTION" >> name,
+    construct<FunctionStmt>(many(prefixSpec), "FUNCTION" >> name,
         parenthesized(optionalList(name)), maybe(suffix)) ||
-        extension(construct<FunctionStmt>{}(  // PGI & Intel accept "FUNCTION F"
-            many(prefixSpec), "FUNCTION" >> name, construct<std::list<Name>>{},
-            construct<std::optional<Suffix>>{})))
+        extension(construct<FunctionStmt>(  // PGI & Intel accept "FUNCTION F"
+            many(prefixSpec), "FUNCTION" >> name, construct<std::list<Name>>(),
+            construct<std::optional<Suffix>>())))
 
 // R1532 suffix ->
 //         proc-language-binding-spec [RESULT ( result-name )] |
 //         RESULT ( result-name ) [proc-language-binding-spec]
-TYPE_PARSER(construct<Suffix>{}(
+TYPE_PARSER(construct<Suffix>(
                 languageBindingSpec, maybe("RESULT" >> parenthesized(name))) ||
-    construct<Suffix>{}(
+    construct<Suffix>(
         "RESULT" >> parenthesized(name), maybe(languageBindingSpec)))
 
 // R1533 end-function-stmt -> END [FUNCTION [function-name]]
-TYPE_PARSER(construct<EndFunctionStmt>{}(
+TYPE_PARSER(construct<EndFunctionStmt>(
     recovery("END FUNCTION" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
 
 // R1534 subroutine-subprogram ->
 //         subroutine-stmt [specification-part] [execution-part]
 //         [internal-subprogram-part] end-subroutine-stmt
 TYPE_CONTEXT_PARSER("SUBROUTINE subprogram"_en_US,
-    construct<SubroutineSubprogram>{}(statement(subroutineStmt),
+    construct<SubroutineSubprogram>(statement(subroutineStmt),
         specificationPart, executionPart, maybe(internalSubprogramPart),
         unterminatedStatement(endSubroutineStmt)))
 
@@ -3234,54 +3195,54 @@ TYPE_CONTEXT_PARSER("SUBROUTINE subprogram"_en_US,
 //         [prefix] SUBROUTINE subroutine-name [( [dummy-arg-list] )
 //         [proc-language-binding-spec]]
 TYPE_PARSER(
-    construct<SubroutineStmt>{}(many(prefixSpec), "SUBROUTINE" >> name,
+    construct<SubroutineStmt>(many(prefixSpec), "SUBROUTINE" >> name,
         parenthesized(optionalList(dummyArg)), maybe(languageBindingSpec)) ||
-    construct<SubroutineStmt>{}(many(prefixSpec), "SUBROUTINE" >> name,
+    construct<SubroutineStmt>(many(prefixSpec), "SUBROUTINE" >> name,
         defaulted(cut >> many(dummyArg)),
         defaulted(cut >> maybe(languageBindingSpec))))
 
 // R1536 dummy-arg -> dummy-arg-name | *
-TYPE_PARSER(construct<DummyArg>{}(name) || construct<DummyArg>{}(star))
+TYPE_PARSER(construct<DummyArg>(name) || construct<DummyArg>(star))
 
 // R1537 end-subroutine-stmt -> END [SUBROUTINE [subroutine-name]]
-TYPE_PARSER(construct<EndSubroutineStmt>{}(
+TYPE_PARSER(construct<EndSubroutineStmt>(
     recovery("END SUBROUTINE" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
 
 // R1538 separate-module-subprogram ->
 //         mp-subprogram-stmt [specification-part] [execution-part]
 //         [internal-subprogram-part] end-mp-subprogram-stmt
 TYPE_CONTEXT_PARSER("separate module subprogram"_en_US,
-    construct<SeparateModuleSubprogram>{}(statement(Parser<MpSubprogramStmt>{}),
+    construct<SeparateModuleSubprogram>(statement(Parser<MpSubprogramStmt>{}),
         specificationPart, executionPart, maybe(internalSubprogramPart),
         statement(Parser<EndMpSubprogramStmt>{})))
 
 // R1539 mp-subprogram-stmt -> MODULE PROCEDURE procedure-name
 TYPE_CONTEXT_PARSER("MODULE PROCEDURE statement"_en_US,
-    construct<MpSubprogramStmt>{}("MODULE PROCEDURE"_sptok >> name))
+    construct<MpSubprogramStmt>("MODULE PROCEDURE"_sptok >> name))
 
 // R1540 end-mp-subprogram-stmt -> END [PROCEDURE [procedure-name]]
 TYPE_CONTEXT_PARSER("END PROCEDURE statement"_en_US,
-    construct<EndMpSubprogramStmt>{}(recovery(
+    construct<EndMpSubprogramStmt>(recovery(
         "END PROCEDURE" >> maybe(name) || bareEnd, endStmtErrorRecovery)))
 
 // R1541 entry-stmt -> ENTRY entry-name [( [dummy-arg-list] ) [suffix]]
-TYPE_PARSER("ENTRY" >>
-    (construct<EntryStmt>{}(
-         name, parenthesized(optionalList(dummyArg)), maybe(suffix)) ||
-        construct<EntryStmt>{}(name, construct<std::list<DummyArg>>{},
-            construct<std::optional<Suffix>>{})))
+TYPE_PARSER(
+    "ENTRY" >> (construct<EntryStmt>(name,
+                    parenthesized(optionalList(dummyArg)), maybe(suffix)) ||
+                   construct<EntryStmt>(name, construct<std::list<DummyArg>>(),
+                       construct<std::optional<Suffix>>())))
 
 // R1542 return-stmt -> RETURN [scalar-int-expr]
 TYPE_CONTEXT_PARSER("RETURN statement"_en_US,
-    "RETURN" >> construct<ReturnStmt>{}(maybe(scalarIntExpr)))
+    "RETURN" >> construct<ReturnStmt>(maybe(scalarIntExpr)))
 
 // R1543 contains-stmt -> CONTAINS
-TYPE_PARSER("CONTAINS" >> construct<ContainsStmt>{})
+TYPE_PARSER("CONTAINS" >> construct<ContainsStmt>())
 
 // R1544 stmt-function-stmt ->
 //         function-name ( [dummy-arg-name-list] ) = scalar-expr
 TYPE_CONTEXT_PARSER("statement function definition"_en_US,
-    construct<StmtFunctionStmt>{}(
+    construct<StmtFunctionStmt>(
         name, parenthesized(optionalList(name)), "=" >> scalar(expr)))
 
 // Directives, extensions, and deprecated statements
@@ -3289,57 +3250,57 @@ 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<CompilerDirective::IVDEP>{};
+constexpr auto ivdep = "DIR$ IVDEP" >> construct<CompilerDirective::IVDEP>();
 constexpr auto ignore_tkr = "DIR$ IGNORE_TKR" >>
-    optionalList(construct<CompilerDirective::IgnoreTKR>{}(
+    optionalList(construct<CompilerDirective::IgnoreTKR>(
         defaulted(parenthesized(some("tkr"_ch))), name));
-TYPE_PARSER(beginDirective >> sourced(construct<CompilerDirective>{}(ivdep) ||
-                                  construct<CompilerDirective>{}(ignore_tkr)) /
+TYPE_PARSER(beginDirective >> sourced(construct<CompilerDirective>(ivdep) ||
+                                  construct<CompilerDirective>(ignore_tkr)) /
         endDirective)
 
 TYPE_PARSER(
-    extension(construct<BasedPointerStmt>{}("POINTER (" >> objectName / ",",
+    extension(construct<BasedPointerStmt>("POINTER (" >> objectName / ",",
         objectName, maybe(Parser<ArraySpec>{}) / ")")))
 
-TYPE_PARSER(construct<StructureStmt>{}("STRUCTURE /" >> name / "/", pure(true),
+TYPE_PARSER(construct<StructureStmt>("STRUCTURE /" >> name / "/", pure(true),
                 optionalList(entityDecl)) ||
-    construct<StructureStmt>{}(
+    construct<StructureStmt>(
         "STRUCTURE" >> name, pure(false), defaulted(cut >> many(entityDecl))))
 
-TYPE_PARSER(construct<StructureField>{}(statement(StructureComponents{})) ||
-    construct<StructureField>{}(indirect(Parser<Union>{})) ||
-    construct<StructureField>{}(indirect(Parser<StructureDef>{})))
+TYPE_PARSER(construct<StructureField>(statement(StructureComponents{})) ||
+    construct<StructureField>(indirect(Parser<Union>{})) ||
+    construct<StructureField>(indirect(Parser<StructureDef>{})))
 
 TYPE_CONTEXT_PARSER("STRUCTURE definition"_en_US,
-    extension(construct<StructureDef>{}(statement(Parser<StructureStmt>{}),
+    extension(construct<StructureDef>(statement(Parser<StructureStmt>{}),
         many(Parser<StructureField>{}),
         statement(
-            "END STRUCTURE" >> construct<StructureDef::EndStructureStmt>{}))))
+            "END STRUCTURE" >> construct<StructureDef::EndStructureStmt>()))))
 
 TYPE_CONTEXT_PARSER("UNION definition"_en_US,
-    construct<Union>{}(statement("UNION" >> construct<Union::UnionStmt>{}),
+    construct<Union>(statement("UNION" >> construct<Union::UnionStmt>()),
         many(Parser<Map>{}),
-        statement("END UNION" >> construct<Union::EndUnionStmt>{})))
+        statement("END UNION" >> construct<Union::EndUnionStmt>())))
 
 TYPE_CONTEXT_PARSER("MAP definition"_en_US,
-    construct<Map>{}(statement("MAP" >> construct<Map::MapStmt>{}),
+    construct<Map>(statement("MAP" >> construct<Map::MapStmt>()),
         many(Parser<StructureField>{}),
-        statement("END MAP" >> construct<Map::EndMapStmt>{})))
+        statement("END MAP" >> construct<Map::EndMapStmt>())))
 
 TYPE_CONTEXT_PARSER("arithmetic IF statement"_en_US,
-    deprecated("IF" >> construct<ArithmeticIfStmt>{}(parenthesized(expr),
+    deprecated("IF" >> construct<ArithmeticIfStmt>(parenthesized(expr),
                            label / ",", label / ",", label)))
 
 TYPE_CONTEXT_PARSER("ASSIGN statement"_en_US,
-    deprecated("ASSIGN" >> construct<AssignStmt>{}(label, "TO" >> name)))
+    deprecated("ASSIGN" >> construct<AssignStmt>(label, "TO" >> name)))
 
 TYPE_CONTEXT_PARSER("assigned GOTO statement"_en_US,
     deprecated("GO TO" >>
-        construct<AssignedGotoStmt>{}(name,
+        construct<AssignedGotoStmt>(name,
             defaulted(maybe(","_tok) >> parenthesized(nonemptyList(label))))))
 
 TYPE_CONTEXT_PARSER("PAUSE statement"_en_US,
-    deprecated("PAUSE" >> construct<PauseStmt>{}(maybe(Parser<StopCode>{}))))
+    deprecated("PAUSE" >> construct<PauseStmt>(maybe(Parser<StopCode>{}))))
 
 // These requirement productions are defined by the Fortran standard but never
 // used directly by the grammar:
index 91faa24..3321436 100644 (file)
@@ -20,12 +20,10 @@ constexpr DigitString digitString;
 // R611 label -> digit [digit]...
 constexpr auto label = space >> digitString / spaceCheck;
 
-template<typename PA>
-using statementConstructor = construct<Statement<typename PA::resultType>>;
-
 template<typename PA> inline constexpr auto unterminatedStatement(const PA &p) {
   return skipEmptyLines >>
-      sourced(statementConstructor<PA>{}(maybe(label), space >> p));
+      sourced(construct<Statement<typename PA::resultType>>(
+          maybe(label), space >> p));
 }
 
 constexpr auto endOfLine = "\n"_ch / skipEmptyLines ||
@@ -43,7 +41,7 @@ constexpr auto ignoredStatementPrefix = skipEmptyLines >> maybe(label) >>
 
 // Error recovery within statements: skip to the end of the line,
 // but not over an END or CONTAINS statement.
-constexpr auto errorRecovery = construct<ErrorRecovery>{};
+constexpr auto errorRecovery = construct<ErrorRecovery>();
 constexpr auto skipToEndOfLine = SkipTo<'\n'>{} >> errorRecovery;
 constexpr auto stmtErrorRecovery =
     !"END"_tok >> !"CONTAINS"_tok >> skipToEndOfLine;
index 6cee1a1..6c23adc 100644 (file)
@@ -574,7 +574,7 @@ template<char goal> struct SkipTo {
 //   [[, xyz] ::]     is  optionalBeforeColons(xyz)
 //   [[, xyz]... ::]  is  optionalBeforeColons(nonemptyList(xyz))
 template<typename PA> inline constexpr auto optionalBeforeColons(const PA &p) {
-  return "," >> construct<std::optional<typename PA::resultType>>{}(p) / "::" ||
+  return "," >> construct<std::optional<typename PA::resultType>>(p) / "::" ||
       ("::"_tok || !","_tok) >> defaulted(cut >> maybe(p));
 }
 template<typename PA>
@@ -634,8 +634,8 @@ constexpr auto underscore = "_"_ch;
 constexpr auto otherIdChar = underscore / !"'\""_ch || extension("$@"_ch);
 constexpr auto nonDigitIdChar = letter || otherIdChar;
 constexpr auto rawName = nonDigitIdChar >> many(nonDigitIdChar || digit);
-TYPE_PARSER(space >> sourced(attempt(rawName) >> construct<Name>{}))
-constexpr auto keyword = construct<Keyword>{}(name);
+TYPE_PARSER(space >> sourced(attempt(rawName) >> construct<Name>()))
+constexpr auto keyword = construct<Keyword>(name);
 
 }  // namespace parser
 }  // namespace Fortran