#include "basic-parsers.h"
#include "expr-parsers.h"
#include "misc-parsers.h"
#include "stmt-parser.h"
#include "token-parsers.h"
#include "type-parser-implementation.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Parser/user-state.h"
namespace Fortran::parser {
constexpr auto nonDigitIdChar{letter || otherIdChar};
constexpr auto rawName{nonDigitIdChar >> many(nonDigitIdChar || digit)};
TYPE_PARSER(space >> sourced(rawName >> construct<Name>()))
constexpr auto namedIntrinsicOperator{
".LT." >> pure(DefinedOperator::IntrinsicOperator::LT) ||
".LE." >> pure(DefinedOperator::IntrinsicOperator::LE) ||
".EQ." >> pure(DefinedOperator::IntrinsicOperator::EQ) ||
".NE." >> pure(DefinedOperator::IntrinsicOperator::NE) ||
".GE." >> pure(DefinedOperator::IntrinsicOperator::GE) ||
".GT." >> pure(DefinedOperator::IntrinsicOperator::GT) ||
".NOT." >> pure(DefinedOperator::IntrinsicOperator::NOT) ||
".AND." >> pure(DefinedOperator::IntrinsicOperator::AND) ||
".OR." >> pure(DefinedOperator::IntrinsicOperator::OR) ||
".EQV." >> pure(DefinedOperator::IntrinsicOperator::EQV) ||
".NEQV." >> pure(DefinedOperator::IntrinsicOperator::NEQV) ||
extension<LanguageFeature::XOROperator>(
"nonstandard usage: .XOR. spelling of .NEQV."_port_en_US,
".XOR." >> pure(DefinedOperator::IntrinsicOperator::NEQV)) ||
extension<LanguageFeature::LogicalAbbreviations>(
"nonstandard usage: abbreviated logical operator"_port_en_US,
".N." >> pure(DefinedOperator::IntrinsicOperator::NOT) ||
".A." >> pure(DefinedOperator::IntrinsicOperator::AND) ||
".O." >> pure(DefinedOperator::IntrinsicOperator::OR) ||
extension<LanguageFeature::XOROperator>(
"nonstandard usage: .X. spelling of .NEQV."_port_en_US,
".X." >> pure(DefinedOperator::IntrinsicOperator::NEQV)))};
constexpr auto intrinsicOperator{
"**" >> pure(DefinedOperator::IntrinsicOperator::Power) ||
"*" >> pure(DefinedOperator::IntrinsicOperator::Multiply) ||
"//" >> pure(DefinedOperator::IntrinsicOperator::Concat) ||
"/=" >> pure(DefinedOperator::IntrinsicOperator::NE) ||
"/" >> pure(DefinedOperator::IntrinsicOperator::Divide) ||
"+" >> pure(DefinedOperator::IntrinsicOperator::Add) ||
"-" >> pure(DefinedOperator::IntrinsicOperator::Subtract) ||
"<=" >> pure(DefinedOperator::IntrinsicOperator::LE) ||
extension<LanguageFeature::AlternativeNE>(
"nonstandard usage: <> spelling of /= or .NE."_port_en_US,
"<>" >> pure(DefinedOperator::IntrinsicOperator::NE)) ||
"<" >> pure(DefinedOperator::IntrinsicOperator::LT) ||
"==" >> pure(DefinedOperator::IntrinsicOperator::EQ) ||
">=" >> pure(DefinedOperator::IntrinsicOperator::GE) ||
">" >> pure(DefinedOperator::IntrinsicOperator::GT) ||
namedIntrinsicOperator};
TYPE_PARSER(construct<DefinedOperator>(intrinsicOperator) ||
construct<DefinedOperator>(definedOpName))
TYPE_CONTEXT_PARSER("implicit part"_en_US,
construct<ImplicitPart>(many(Parser<ImplicitPartStmt>{})))
TYPE_PARSER(first(
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))),
construct<ImplicitPartStmt>(indirect(compilerDirective)),
construct<ImplicitPartStmt>(indirect(openaccDeclarativeConstruct))))
TYPE_CONTEXT_PARSER("internal subprogram"_en_US,
(construct<InternalSubprogram>(indirect(functionSubprogram)) ||
construct<InternalSubprogram>(indirect(subroutineSubprogram))) /
forceEndOfStmt ||
construct<InternalSubprogram>(indirect(compilerDirective)))
TYPE_CONTEXT_PARSER("internal subprogram part"_en_US,
construct<InternalSubprogramPart>(statement(containsStmt),
many(StartNewSubprogram{} >> Parser<InternalSubprogram>{})))
TYPE_PARSER(
first(construct<LiteralConstant>(Parser<HollerithLiteralConstant>{}),
construct<LiteralConstant>(realLiteralConstant),
construct<LiteralConstant>(intLiteralConstant),
construct<LiteralConstant>(Parser<ComplexLiteralConstant>{}),
construct<LiteralConstant>(Parser<BOZLiteralConstant>{}),
construct<LiteralConstant>(charLiteralConstant),
construct<LiteralConstant>(Parser<LogicalLiteralConstant>{})))
TYPE_PARSER(construct<NamedConstant>(name))
TYPE_PARSER(construct<TypeParamValue>(scalarIntExpr) ||
construct<TypeParamValue>(star) ||
construct<TypeParamValue>(construct<TypeParamValue::Deferred>(":"_tok)))
TYPE_CONTEXT_PARSER("type spec"_en_US,
construct<TypeSpec>(intrinsicTypeSpec / lookAhead("::"_tok || ")"_tok)) ||
construct<TypeSpec>(derivedTypeSpec))
TYPE_CONTEXT_PARSER("declaration type spec"_en_US,
construct<DeclarationTypeSpec>(intrinsicTypeSpec) ||
"TYPE" >>
(parenthesized(construct<DeclarationTypeSpec>(
!"DOUBLECOMPLEX"_tok >> !"BYTE"_tok >> 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>())) ||
extension<LanguageFeature::DECStructures>(
"nonstandard usage: STRUCTURE"_port_en_US,
construct<DeclarationTypeSpec>(
construct<DeclarationTypeSpec::Record>(
"RECORD" >> sourced("/" >> name / "/")))) ||
construct<DeclarationTypeSpec>(vectorTypeSpec))
TYPE_CONTEXT_PARSER("intrinsic type spec"_en_US,
first(construct<IntrinsicTypeSpec>(integerTypeSpec),
construct<IntrinsicTypeSpec>(
construct<IntrinsicTypeSpec::Real>("REAL" >> maybe(kindSelector))),
construct<IntrinsicTypeSpec>("DOUBLE PRECISION" >>
construct<IntrinsicTypeSpec::DoublePrecision>()),
construct<IntrinsicTypeSpec>(construct<IntrinsicTypeSpec::Complex>(
"COMPLEX" >> maybe(kindSelector))),
construct<IntrinsicTypeSpec>(construct<IntrinsicTypeSpec::Character>(
"CHARACTER" >> maybe(Parser<CharSelector>{}))),
construct<IntrinsicTypeSpec>(construct<IntrinsicTypeSpec::Logical>(
"LOGICAL" >> maybe(kindSelector))),
extension<LanguageFeature::DoubleComplex>(
"nonstandard usage: DOUBLE COMPLEX"_port_en_US,
construct<IntrinsicTypeSpec>("DOUBLE COMPLEX"_sptok >>
construct<IntrinsicTypeSpec::DoubleComplex>())),
extension<LanguageFeature::Byte>("nonstandard usage: BYTE"_port_en_US,
construct<IntrinsicTypeSpec>(construct<IntegerTypeSpec>(
"BYTE" >> construct<std::optional<KindSelector>>(pure(1)))))))
TYPE_CONTEXT_PARSER("vector type spec"_en_US,
extension<LanguageFeature::PPCVector>(
"nonstandard usage: Vector type"_port_en_US,
first(construct<VectorTypeSpec>(intrinsicVectorTypeSpec),
construct<VectorTypeSpec>("__VECTOR_PAIR" >>
construct<VectorTypeSpec::PairVectorTypeSpec>()),
construct<VectorTypeSpec>("__VECTOR_QUAD" >>
construct<VectorTypeSpec::QuadVectorTypeSpec>()))))
TYPE_PARSER(construct<IntrinsicVectorTypeSpec>("VECTOR" >>
parenthesized(construct<VectorElementType>(integerTypeSpec) ||
construct<VectorElementType>(unsignedTypeSpec) ||
construct<VectorElementType>(construct<IntrinsicTypeSpec::Real>(
"REAL" >> maybe(kindSelector))))))
TYPE_PARSER(construct<UnsignedTypeSpec>("UNSIGNED" >> maybe(kindSelector)))
TYPE_PARSER(construct<IntegerTypeSpec>("INTEGER" >> maybe(kindSelector)))
TYPE_PARSER(construct<KindSelector>(
parenthesized(maybe("KIND ="_tok) >> scalarIntConstantExpr)) ||
extension<LanguageFeature::StarKind>(
"nonstandard usage: TYPE*KIND syntax"_port_en_US,
construct<KindSelector>(construct<KindSelector::StarSize>(
"*" >> digitString64 / spaceCheck))))
constexpr auto noSpace{
recovery(withMessage("invalid space"_err_en_US, !" "_ch), space)};
TYPE_PARSER(sourced(
construct<SignedIntLiteralConstant>(SignedIntLiteralConstantWithoutKind{},
maybe(noSpace >> underscore >> noSpace >> kindParam))))
TYPE_PARSER(construct<IntLiteralConstant>(space >> digitString,
maybe(underscore >> noSpace >> kindParam) / !underscore))
TYPE_PARSER(construct<KindParam>(digitString64) ||
construct<KindParam>(
scalar(integer(constant(sourced(rawName >> construct<Name>()))))))
constexpr auto sign{
"+"_tok >> pure(Sign::Positive) || "-"_tok >> pure(Sign::Negative)};
constexpr auto signedRealLiteralConstant{
construct<SignedRealLiteralConstant>(maybe(sign), realLiteralConstant)};
constexpr auto exponentPart{
("ed"_ch ||
extension<LanguageFeature::QuadPrecision>(
"nonstandard usage: Q exponent"_port_en_US, "q"_ch)) >>
SignedDigitString{}};
TYPE_CONTEXT_PARSER("REAL literal constant"_en_US,
space >>
construct<RealLiteralConstant>(
sourced((digitString >> "."_ch >>
!(some(letter) >>
"."_ch ) >>
maybe(digitString) >> maybe(exponentPart) >> ok ||
"."_ch >> digitString >> maybe(exponentPart) >> ok ||
digitString >> exponentPart >> ok) >>
construct<RealLiteralConstant::Real>()),
maybe(noSpace >> underscore >> noSpace >> kindParam)))
TYPE_CONTEXT_PARSER("COMPLEX literal constant"_en_US,
parenthesized(construct<ComplexLiteralConstant>(
Parser<ComplexPart>{} / ",", Parser<ComplexPart>{})))
TYPE_PARSER(construct<SignedComplexLiteralConstant>(
sign, Parser<ComplexLiteralConstant>{}))
TYPE_PARSER(construct<ComplexPart>(signedRealLiteralConstant) ||
construct<ComplexPart>(signedIntLiteralConstant) ||
construct<ComplexPart>(namedConstant))
TYPE_PARSER(construct<CharSelector>(Parser<LengthSelector>{}) ||
parenthesized(construct<CharSelector>(
"LEN =" >> typeParamValue, ", KIND =" >> scalarIntConstantExpr)) ||
parenthesized(construct<CharSelector>(
typeParamValue / ",", maybe("KIND ="_tok) >> scalarIntConstantExpr)) ||
parenthesized(construct<CharSelector>(
"KIND =" >> scalarIntConstantExpr, maybe(", LEN =" >> typeParamValue))))
TYPE_PARSER(construct<LengthSelector>(
parenthesized(maybe("LEN ="_tok) >> typeParamValue)) ||
construct<LengthSelector>("*" >> charLength ))
TYPE_PARSER(construct<CharLength>(parenthesized(typeParamValue)) ||
construct<CharLength>(space >> digitString64 / spaceCheck))
TYPE_CONTEXT_PARSER("CHARACTER literal constant"_en_US,
construct<CharLiteralConstant>(
kindParam / underscore, charLiteralConstantWithoutKind) ||
construct<CharLiteralConstant>(construct<std::optional<KindParam>>(),
space >> charLiteralConstantWithoutKind))
TYPE_CONTEXT_PARSER(
"Hollerith"_en_US, construct<HollerithLiteralConstant>(rawHollerithLiteral))
TYPE_PARSER(construct<LogicalLiteralConstant>(logicalTRUE,
maybe(noSpace >> underscore >> noSpace >> kindParam)) ||
construct<LogicalLiteralConstant>(
logicalFALSE, maybe(noSpace >> underscore >> noSpace >> kindParam)))
TYPE_CONTEXT_PARSER("derived type definition"_en_US,
construct<DerivedTypeDef>(statement(Parser<DerivedTypeStmt>{}),
many(unambiguousStatement(Parser<TypeParamDefStmt>{})),
many(statement(Parser<PrivateOrSequence>{})),
many(inContext("component"_en_US,
unambiguousStatement(Parser<ComponentDefStmt>{}))),
maybe(Parser<TypeBoundProcedurePart>{}),
statement(Parser<EndTypeStmt>{})))
TYPE_CONTEXT_PARSER("TYPE statement"_en_US,
construct<DerivedTypeStmt>(
"TYPE" >> optionalListBeforeColons(Parser<TypeAttrSpec>{}), name,
defaulted(parenthesized(nonemptyList(name)))))
TYPE_PARSER(construct<TypeAttrSpec>(construct<Abstract>("ABSTRACT"_tok)) ||
construct<TypeAttrSpec>(construct<TypeAttrSpec::BindC>("BIND ( C )"_tok)) ||
construct<TypeAttrSpec>(
construct<TypeAttrSpec::Extends>("EXTENDS" >> parenthesized(name))) ||
construct<TypeAttrSpec>(accessSpec))
TYPE_PARSER(construct<PrivateOrSequence>(Parser<PrivateStmt>{}) ||
construct<PrivateOrSequence>(Parser<SequenceStmt>{}))
TYPE_PARSER(construct<EndTypeStmt>(
recovery("END TYPE" >> maybe(name), namedConstructEndStmtErrorRecovery)))
TYPE_PARSER(construct<SequenceStmt>("SEQUENCE"_tok))
constexpr auto kindOrLen{"KIND" >> pure(common::TypeParamAttr::Kind) ||
"LEN" >> pure(common::TypeParamAttr::Len)};
TYPE_PARSER(construct<TypeParamDefStmt>(integerTypeSpec / ",", kindOrLen,
"::" >> nonemptyList("expected type parameter declarations"_err_en_US,
Parser<TypeParamDecl>{})))
TYPE_PARSER(construct<TypeParamDecl>(name, maybe("=" >> scalarIntConstantExpr)))
TYPE_PARSER(recovery(
withMessage("expected component definition"_err_en_US,
first(construct<ComponentDefStmt>(Parser<DataComponentDefStmt>{}),
construct<ComponentDefStmt>(Parser<ProcComponentDefStmt>{}),
construct<ComponentDefStmt>(indirect(compilerDirective)))),
construct<ComponentDefStmt>(inStmtErrorRecovery)))
TYPE_PARSER(construct<DataComponentDefStmt>(declarationTypeSpec,
optionalListBeforeColons(Parser<ComponentAttrSpec>{}),
nonemptyList("expected component declarations"_err_en_US,
Parser<ComponentOrFill>{})))
TYPE_PARSER(construct<ComponentAttrSpec>(accessSpec) ||
construct<ComponentAttrSpec>(allocatable) ||
construct<ComponentAttrSpec>("CODIMENSION" >> coarraySpec) ||
construct<ComponentAttrSpec>(contiguous) ||
construct<ComponentAttrSpec>("DIMENSION" >> Parser<ComponentArraySpec>{}) ||
construct<ComponentAttrSpec>(pointer) ||
extension<LanguageFeature::CUDA>(
construct<ComponentAttrSpec>(Parser<common::CUDADataAttr>{})) ||
construct<ComponentAttrSpec>(recovery(
fail<ErrorRecovery>(
"type parameter definitions must appear before component declarations"_err_en_US),
kindOrLen >> construct<ErrorRecovery>())))
TYPE_CONTEXT_PARSER("component declaration"_en_US,
construct<ComponentDecl>(name, maybe(Parser<ComponentArraySpec>{}),
maybe(coarraySpec), maybe("*" >> charLength), maybe(initialization)))
TYPE_CONTEXT_PARSER("%FILL item"_en_US,
extension<LanguageFeature::DECStructures>(
"nonstandard usage: %FILL"_port_en_US,
construct<FillDecl>(space >> sourced("%FILL" >> construct<Name>()),
maybe(Parser<ComponentArraySpec>{}), maybe("*" >> charLength))))
TYPE_PARSER(construct<ComponentOrFill>(Parser<ComponentDecl>{}) ||
construct<ComponentOrFill>(Parser<FillDecl>{}))
TYPE_PARSER(construct<ComponentArraySpec>(parenthesized(
nonemptyList("expected explicit shape specifications"_err_en_US,
explicitShapeSpec))) ||
construct<ComponentArraySpec>(parenthesized(deferredShapeSpecList)))
TYPE_CONTEXT_PARSER("PROCEDURE component definition statement"_en_US,
construct<ProcComponentDefStmt>(
"PROCEDURE" >> parenthesized(maybe(procInterface)),
localRecovery("expected PROCEDURE component attributes"_err_en_US,
"," >> nonemptyList(Parser<ProcComponentAttrSpec>{}), ok),
localRecovery("expected PROCEDURE declarations"_err_en_US,
"::" >> nonemptyList(procDecl), SkipTo<'\n'>{})))
constexpr auto noPass{construct<NoPass>("NOPASS"_tok)};
constexpr auto pass{construct<Pass>("PASS" >> maybe(parenthesized(name)))};
TYPE_PARSER(construct<ProcComponentAttrSpec>(accessSpec) ||
construct<ProcComponentAttrSpec>(noPass) ||
construct<ProcComponentAttrSpec>(pass) ||
construct<ProcComponentAttrSpec>(pointer))
constexpr auto initialDataTarget{indirect(designator)};
TYPE_PARSER(construct<Initialization>("=>" >> nullInit) ||
construct<Initialization>("=>" >> initialDataTarget) ||
construct<Initialization>("=" >> constantExpr) ||
extension<LanguageFeature::SlashInitialization>(
"nonstandard usage: /initialization/"_port_en_US,
construct<Initialization>(
"/" >> nonemptyList("expected values"_err_en_US,
indirect(Parser<DataStmtValue>{})) /
"/")))
TYPE_PARSER(construct<PrivateStmt>("PRIVATE"_tok))
TYPE_CONTEXT_PARSER("type bound procedure part"_en_US,
construct<TypeBoundProcedurePart>(statement(containsStmt),
maybe(statement(Parser<PrivateStmt>{})),
many(statement(Parser<TypeBoundProcBinding>{}))))
TYPE_CONTEXT_PARSER("type bound procedure binding"_en_US,
recovery(
first(construct<TypeBoundProcBinding>(Parser<TypeBoundProcedureStmt>{}),
construct<TypeBoundProcBinding>(Parser<TypeBoundGenericStmt>{}),
construct<TypeBoundProcBinding>(Parser<FinalProcedureStmt>{})),
construct<TypeBoundProcBinding>(
!"END"_tok >> SkipTo<'\n'>{} >> construct<ErrorRecovery>())))
TYPE_CONTEXT_PARSER("type bound PROCEDURE statement"_en_US,
"PROCEDURE" >>
(construct<TypeBoundProcedureStmt>(
construct<TypeBoundProcedureStmt::WithInterface>(
parenthesized(name),
localRecovery("expected list of binding attributes"_err_en_US,
"," >> nonemptyList(Parser<BindAttr>{}), ok),
localRecovery("expected list of binding names"_err_en_US,
"::" >> listOfNames, SkipTo<'\n'>{}))) ||
construct<TypeBoundProcedureStmt>(construct<
TypeBoundProcedureStmt::WithoutInterface>(
pure<std::list<BindAttr>>(),
nonemptyList(
"expected type bound procedure declarations"_err_en_US,
construct<TypeBoundProcDecl>(name,
maybe(extension<LanguageFeature::MissingColons>(
"type-bound procedure statement should have '::' if it has '=>'"_port_en_US,
"=>" >> name)))))) ||
construct<TypeBoundProcedureStmt>(
construct<TypeBoundProcedureStmt::WithoutInterface>(
optionalListBeforeColons(Parser<BindAttr>{}),
nonemptyList(
"expected type bound procedure declarations"_err_en_US,
Parser<TypeBoundProcDecl>{})))))
TYPE_PARSER(construct<TypeBoundProcDecl>(name, maybe("=>" >> name)))
TYPE_CONTEXT_PARSER("type bound GENERIC statement"_en_US,
construct<TypeBoundGenericStmt>("GENERIC" >> maybe("," >> accessSpec),
"::" >> indirect(genericSpec), "=>" >> listOfNames))
TYPE_PARSER(construct<BindAttr>(accessSpec) ||
construct<BindAttr>(construct<BindAttr::Deferred>("DEFERRED"_tok)) ||
construct<BindAttr>(
construct<BindAttr::Non_Overridable>("NON_OVERRIDABLE"_tok)) ||
construct<BindAttr>(noPass) || construct<BindAttr>(pass))
TYPE_CONTEXT_PARSER("FINAL statement"_en_US,
construct<FinalProcedureStmt>("FINAL" >> maybe("::"_tok) >> listOfNames))
TYPE_PARSER(construct<DerivedTypeSpec>(name,
defaulted(parenthesized(nonemptyList(
"expected type parameters"_err_en_US, Parser<TypeParamSpec>{})))))
TYPE_PARSER(construct<TypeParamSpec>(maybe(keyword / "="), typeParamValue))
TYPE_PARSER((construct<StructureConstructor>(derivedTypeSpec,
parenthesized(optionalList(Parser<ComponentSpec>{}))) ||
construct<StructureConstructor>(
construct<DerivedTypeSpec>(
name, construct<std::list<TypeParamSpec>>()),
parenthesized(optionalList(Parser<ComponentSpec>{})))) /
!"("_tok)
TYPE_PARSER(construct<ComponentSpec>(
maybe(keyword / "="), Parser<ComponentDataSource>{}))
TYPE_PARSER(construct<ComponentDataSource>(indirect(expr)))
TYPE_CONTEXT_PARSER("enum definition"_en_US,
construct<EnumDef>(statement(Parser<EnumDefStmt>{}),
some(unambiguousStatement(Parser<EnumeratorDefStmt>{})),
statement(Parser<EndEnumStmt>{})))
TYPE_PARSER(construct<EnumDefStmt>("ENUM , BIND ( C )"_tok))
TYPE_CONTEXT_PARSER("ENUMERATOR statement"_en_US,
construct<EnumeratorDefStmt>("ENUMERATOR" >> maybe("::"_tok) >>
nonemptyList("expected enumerators"_err_en_US, Parser<Enumerator>{})))
TYPE_PARSER(
construct<Enumerator>(namedConstant, maybe("=" >> scalarIntConstantExpr)))
TYPE_PARSER(recovery("END ENUM"_tok, constructEndStmtErrorRecovery) >>
construct<EndEnumStmt>())
constexpr auto entityDeclWithoutEqInit{construct<EntityDecl>(name,
maybe(arraySpec), maybe(coarraySpec), maybe("*" >> charLength),
!"="_tok >> maybe(initialization))};
TYPE_PARSER(
construct<TypeDeclarationStmt>(declarationTypeSpec,
defaulted("," >> nonemptyList(Parser<AttrSpec>{})) / "::",
nonemptyList("expected entity declarations"_err_en_US, entityDecl)) ||
construct<TypeDeclarationStmt>(declarationTypeSpec,
construct<std::list<AttrSpec>>(),
nonemptyList("expected entity declarations"_err_en_US,
entityDeclWithoutEqInit)) ||
extension<LanguageFeature::MissingColons>(
"nonstandard usage: ',' in place of '::'"_port_en_US,
construct<TypeDeclarationStmt>(declarationTypeSpec,
defaulted("," >> nonemptyList(Parser<AttrSpec>{})),
withMessage("expected entity declarations"_err_en_US,
"," >> nonemptyList(entityDecl)))))
TYPE_PARSER(construct<AttrSpec>(accessSpec) ||
construct<AttrSpec>(allocatable) ||
construct<AttrSpec>(construct<Asynchronous>("ASYNCHRONOUS"_tok)) ||
construct<AttrSpec>("CODIMENSION" >> coarraySpec) ||
construct<AttrSpec>(contiguous) ||
construct<AttrSpec>("DIMENSION" >> arraySpec) ||
construct<AttrSpec>(construct<External>("EXTERNAL"_tok)) ||
construct<AttrSpec>("INTENT" >> parenthesized(intentSpec)) ||
construct<AttrSpec>(construct<Intrinsic>("INTRINSIC"_tok)) ||
construct<AttrSpec>(languageBindingSpec) || construct<AttrSpec>(optional) ||
construct<AttrSpec>(construct<Parameter>("PARAMETER"_tok)) ||
construct<AttrSpec>(pointer) || construct<AttrSpec>(protectedAttr) ||
construct<AttrSpec>(save) ||
construct<AttrSpec>(construct<Target>("TARGET"_tok)) ||
construct<AttrSpec>(construct<Value>("VALUE"_tok)) ||
construct<AttrSpec>(construct<Volatile>("VOLATILE"_tok)) ||
extension<LanguageFeature::CUDA>(
construct<AttrSpec>(Parser<common::CUDADataAttr>{})))
TYPE_PARSER("CONSTANT" >> pure(common::CUDADataAttr::Constant) ||
"DEVICE" >> pure(common::CUDADataAttr::Device) ||
"MANAGED" >> pure(common::CUDADataAttr::Managed) ||
"PINNED" >> pure(common::CUDADataAttr::Pinned) ||
"SHARED" >> pure(common::CUDADataAttr::Shared) ||
"TEXTURE" >> pure(common::CUDADataAttr::Texture) ||
"UNIFIED" >> pure(common::CUDADataAttr::Unified))
constexpr auto objectName{name};
TYPE_PARSER(construct<EntityDecl>(objectName, maybe(arraySpec),
maybe(coarraySpec), maybe("*" >> charLength), maybe(initialization)))
TYPE_PARSER(lookAhead(name / "( )") >> construct<NullInit>(expr))
TYPE_PARSER(construct<AccessSpec>("PUBLIC" >> pure(AccessSpec::Kind::Public)) ||
construct<AccessSpec>("PRIVATE" >> pure(AccessSpec::Kind::Private)))
TYPE_PARSER(construct<LanguageBindingSpec>(
"BIND ( C" >> maybe(", NAME =" >> scalarDefaultCharConstantExpr),
(", CDEFINED" >> pure(true) || pure(false)) / ")"))
TYPE_PARSER(
construct<CoarraySpec>(bracketed(Parser<DeferredCoshapeSpecList>{})) ||
construct<CoarraySpec>(bracketed(Parser<ExplicitCoshapeSpec>{})))
inline int listLength(std::list<Success> &&xs) { return xs.size(); }
TYPE_PARSER(construct<DeferredCoshapeSpecList>(
applyFunction(listLength, nonemptyList(":"_tok))))
TYPE_PARSER(construct<ExplicitCoshapeSpec>(
many(explicitShapeSpec / ","), maybe(specificationExpr / ":") / "*"))
TYPE_PARSER(
construct<ArraySpec>(parenthesized(nonemptyList(explicitShapeSpec))) ||
construct<ArraySpec>(parenthesized(deferredShapeSpecList)) ||
construct<ArraySpec>(
parenthesized(nonemptyList(Parser<AssumedShapeSpec>{}))) ||
construct<ArraySpec>(parenthesized(Parser<AssumedSizeSpec>{})) ||
construct<ArraySpec>(parenthesized(Parser<ImpliedShapeSpec>{})) ||
construct<ArraySpec>(parenthesized(Parser<AssumedRankSpec>{})))
TYPE_PARSER(construct<ExplicitShapeSpec>(
maybe(specificationExpr / ":"), specificationExpr))
TYPE_PARSER(construct<AssumedShapeSpec>(maybe(specificationExpr) / ":"))
TYPE_PARSER(construct<DeferredShapeSpecList>(
applyFunction(listLength, nonemptyList(":"_tok))))
TYPE_PARSER(construct<AssumedImpliedSpec>(maybe(specificationExpr / ":") / "*"))
TYPE_PARSER(construct<AssumedSizeSpec>(
nonemptyList(explicitShapeSpec) / ",", assumedImpliedSpec))
TYPE_PARSER(construct<ImpliedShapeSpec>(nonemptyList(assumedImpliedSpec)))
TYPE_PARSER(construct<AssumedRankSpec>(".."_tok))
TYPE_PARSER(construct<IntentSpec>("IN OUT" >> pure(IntentSpec::Intent::InOut) ||
"IN" >> pure(IntentSpec::Intent::In) ||
"OUT" >> pure(IntentSpec::Intent::Out)))
TYPE_PARSER(construct<AccessStmt>(accessSpec,
defaulted(maybe("::"_tok) >>
nonemptyList("expected names and generic specifications"_err_en_US,
Parser<AccessId>{}))))
TYPE_PARSER(construct<AccessId>(indirect(genericSpec)))
TYPE_PARSER(construct<AllocatableStmt>("ALLOCATABLE" >> maybe("::"_tok) >>
nonemptyList(
"expected object declarations"_err_en_US, Parser<ObjectDecl>{})))
TYPE_PARSER(
construct<ObjectDecl>(objectName, maybe(arraySpec), maybe(coarraySpec)))
TYPE_PARSER(construct<AsynchronousStmt>("ASYNCHRONOUS" >> maybe("::"_tok) >>
nonemptyList("expected object names"_err_en_US, objectName)))
TYPE_PARSER(construct<BindStmt>(languageBindingSpec / maybe("::"_tok),
nonemptyList("expected bind entities"_err_en_US, Parser<BindEntity>{})))
TYPE_PARSER(construct<BindEntity>(pure(BindEntity::Kind::Object), name) ||
construct<BindEntity>("/" >> pure(BindEntity::Kind::Common), name / "/"))
TYPE_PARSER(construct<CodimensionStmt>("CODIMENSION" >> maybe("::"_tok) >>
nonemptyList("expected codimension declarations"_err_en_US,
Parser<CodimensionDecl>{})))
TYPE_PARSER(construct<CodimensionDecl>(name, coarraySpec))
TYPE_PARSER(construct<ContiguousStmt>("CONTIGUOUS" >> maybe("::"_tok) >>
nonemptyList("expected object names"_err_en_US, objectName)))
TYPE_CONTEXT_PARSER("DATA statement"_en_US,
construct<DataStmt>(
"DATA" >> nonemptySeparated(Parser<DataStmtSet>{}, maybe(","_tok))))
TYPE_PARSER(construct<DataStmtSet>(
nonemptyList(
"expected DATA statement objects"_err_en_US, Parser<DataStmtObject>{}),
withMessage("expected DATA statement value list"_err_en_US,
"/"_tok >> nonemptyList("expected DATA statement values"_err_en_US,
Parser<DataStmtValue>{})) /
"/"))
TYPE_PARSER(construct<DataStmtObject>(indirect(variable)) ||
construct<DataStmtObject>(dataImpliedDo))
TYPE_PARSER(parenthesized(construct<DataImpliedDo>(
nonemptyList(Parser<DataIDoObject>{} / lookAhead(","_tok)) / ",",
maybe(integerTypeSpec / "::"), loopBounds(scalarIntConstantExpr))))
TYPE_PARSER(construct<DataIDoObject>(scalar(indirect(designator))) ||
construct<DataIDoObject>(indirect(dataImpliedDo)))
TYPE_PARSER(construct<DataStmtValue>(
maybe(Parser<DataStmtRepeat>{} / "*"), Parser<DataStmtConstant>{}))
constexpr auto constantSubobject{constant(indirect(designator))};
TYPE_PARSER(construct<DataStmtRepeat>(intLiteralConstant) ||
construct<DataStmtRepeat>(scalar(integer(constantSubobject))))
TYPE_PARSER(sourced(first(construct<DataStmtConstant>(literalConstant),
construct<DataStmtConstant>(signedRealLiteralConstant),
construct<DataStmtConstant>(signedIntLiteralConstant),
extension<LanguageFeature::SignedComplexLiteral>(
"nonstandard usage: signed COMPLEX literal"_port_en_US,
construct<DataStmtConstant>(Parser<SignedComplexLiteralConstant>{})),
construct<DataStmtConstant>(nullInit),
construct<DataStmtConstant>(indirect(designator) / !"("_tok),
construct<DataStmtConstant>(Parser<StructureConstructor>{}))))
TYPE_CONTEXT_PARSER("DIMENSION statement"_en_US,
construct<DimensionStmt>("DIMENSION" >> maybe("::"_tok) >>
nonemptyList("expected array specifications"_err_en_US,
construct<DimensionStmt::Declaration>(name, arraySpec))))
TYPE_CONTEXT_PARSER("INTENT statement"_en_US,
construct<IntentStmt>(
"INTENT" >> parenthesized(intentSpec) / maybe("::"_tok), listOfNames))
TYPE_PARSER(
construct<OptionalStmt>("OPTIONAL" >> maybe("::"_tok) >> listOfNames))
TYPE_CONTEXT_PARSER("PARAMETER statement"_en_US,
construct<ParameterStmt>(
"PARAMETER" >> parenthesized(nonemptyList(Parser<NamedConstantDef>{}))))
TYPE_CONTEXT_PARSER("old style PARAMETER statement"_en_US,
extension<LanguageFeature::OldStyleParameter>(
"nonstandard usage: PARAMETER without parentheses"_port_en_US,
construct<OldParameterStmt>(
"PARAMETER" >> nonemptyList(Parser<NamedConstantDef>{}))))
TYPE_PARSER(construct<NamedConstantDef>(namedConstant, "=" >> constantExpr))
TYPE_PARSER(construct<PointerStmt>("POINTER" >> maybe("::"_tok) >>
nonemptyList(
"expected pointer declarations"_err_en_US, Parser<PointerDecl>{})))
TYPE_PARSER(
construct<PointerDecl>(name, maybe(parenthesized(deferredShapeSpecList))))
TYPE_PARSER(
construct<ProtectedStmt>("PROTECTED" >> maybe("::"_tok) >> listOfNames))
TYPE_PARSER(construct<SaveStmt>(
"SAVE" >> defaulted(maybe("::"_tok) >>
nonemptyList("expected SAVE entities"_err_en_US,
Parser<SavedEntity>{}))))
TYPE_PARSER(construct<SavedEntity>(pure(SavedEntity::Kind::Entity), name) ||
construct<SavedEntity>("/" >> pure(SavedEntity::Kind::Common), name / "/"))
TYPE_PARSER(construct<TargetStmt>("TARGET" >> maybe("::"_tok) >>
nonemptyList("expected objects"_err_en_US, Parser<ObjectDecl>{})))
TYPE_PARSER(construct<ValueStmt>("VALUE" >> maybe("::"_tok) >> listOfNames))
TYPE_PARSER(construct<VolatileStmt>("VOLATILE" >> maybe("::"_tok) >>
nonemptyList("expected object names"_err_en_US, objectName)))
constexpr auto implicitNameSpec{
"EXTERNAL" >> pure(ImplicitStmt::ImplicitNoneNameSpec::External) ||
"TYPE" >> pure(ImplicitStmt::ImplicitNoneNameSpec::Type)};
TYPE_CONTEXT_PARSER("IMPLICIT statement"_en_US,
construct<ImplicitStmt>(
"IMPLICIT" >> nonemptyList("expected IMPLICIT specifications"_err_en_US,
Parser<ImplicitSpec>{})) ||
construct<ImplicitStmt>("IMPLICIT NONE"_sptok >>
defaulted(parenthesized(optionalList(implicitNameSpec)))))
constexpr auto noKindSelector{construct<std::optional<KindSelector>>()};
constexpr auto implicitSpecDeclarationTypeSpecRetry{
construct<DeclarationTypeSpec>(first(
construct<IntrinsicTypeSpec>(
construct<IntegerTypeSpec>("INTEGER" >> noKindSelector)),
construct<IntrinsicTypeSpec>(
construct<IntrinsicTypeSpec::Real>("REAL" >> noKindSelector)),
construct<IntrinsicTypeSpec>(
construct<IntrinsicTypeSpec::Complex>("COMPLEX" >> noKindSelector)),
construct<IntrinsicTypeSpec>(construct<IntrinsicTypeSpec::Character>(
"CHARACTER" >> construct<std::optional<CharSelector>>())),
construct<IntrinsicTypeSpec>(construct<IntrinsicTypeSpec::Logical>(
"LOGICAL" >> noKindSelector))))};
TYPE_PARSER(construct<ImplicitSpec>(declarationTypeSpec,
parenthesized(nonemptyList(Parser<LetterSpec>{}))) ||
construct<ImplicitSpec>(implicitSpecDeclarationTypeSpecRetry,
parenthesized(nonemptyList(Parser<LetterSpec>{}))))
TYPE_PARSER(space >> (construct<LetterSpec>(letter, maybe("-" >> letter)) ||
construct<LetterSpec>(otherIdChar,
construct<std::optional<const char *>>())))
TYPE_CONTEXT_PARSER("IMPORT statement"_en_US,
construct<ImportStmt>(
"IMPORT , ONLY :" >> pure(common::ImportKind::Only), listOfNames) ||
construct<ImportStmt>(
"IMPORT , NONE" >> pure(common::ImportKind::None)) ||
construct<ImportStmt>(
"IMPORT , ALL" >> pure(common::ImportKind::All)) ||
construct<ImportStmt>(
"IMPORT" >> maybe("::"_tok) >> optionalList(name)))
TYPE_PARSER(construct<NamelistStmt>("NAMELIST" >>
nonemptySeparated(
construct<NamelistStmt::Group>("/" >> name / "/", listOfNames),
maybe(","_tok))))
TYPE_PARSER(construct<EquivalenceStmt>("EQUIVALENCE" >>
nonemptyList(
parenthesized(nonemptyList("expected EQUIVALENCE objects"_err_en_US,
Parser<EquivalenceObject>{})))))
TYPE_PARSER(construct<EquivalenceObject>(indirect(designator)))
TYPE_PARSER(
construct<CommonStmt>("COMMON" >> defaulted("/" >> maybe(name) / "/"),
nonemptyList("expected COMMON block objects"_err_en_US,
Parser<CommonBlockObject>{}),
many(maybe(","_tok) >>
construct<CommonStmt::Block>("/" >> maybe(name) / "/",
nonemptyList("expected COMMON block objects"_err_en_US,
Parser<CommonBlockObject>{})))))
TYPE_PARSER(construct<CommonBlockObject>(name, maybe(arraySpec)))
TYPE_CONTEXT_PARSER("designator"_en_US,
sourced(construct<Designator>(substring) || construct<Designator>(dataRef)))
constexpr auto percentOrDot{"%"_tok ||
extension<LanguageFeature::DECStructures>(
"nonstandard usage: component access with '.' in place of '%'"_port_en_US,
"."_tok / lookAhead(OldStructureComponentName{}))};
constexpr auto noMoreAddressing{!"("_tok >> !"["_tok >> !percentOrDot};
TYPE_CONTEXT_PARSER("variable"_en_US,
construct<Variable>(indirect(functionReference / noMoreAddressing)) ||
construct<Variable>(indirect(designator)))
TYPE_PARSER(
construct<Substring>(dataRef, parenthesized(Parser<SubstringRange>{})))
TYPE_PARSER(construct<CharLiteralConstantSubstring>(
charLiteralConstant, parenthesized(Parser<SubstringRange>{})))
TYPE_PARSER(sourced(construct<SubstringInquiry>(Parser<Substring>{}) /
("%LEN"_tok || "%KIND"_tok)))
TYPE_PARSER(construct<SubstringRange>(
maybe(scalarIntExpr), ":" >> maybe(scalarIntExpr)))
TYPE_PARSER(
construct<DataRef>(nonemptySeparated(Parser<PartRef>{}, percentOrDot)))
TYPE_PARSER(construct<PartRef>(name,
defaulted(
parenthesized(nonemptyList(Parser<SectionSubscript>{})) / !"=>"_tok),
maybe(Parser<ImageSelector>{})))
TYPE_CONTEXT_PARSER("component"_en_US,
construct<StructureComponent>(
construct<DataRef>(some(Parser<PartRef>{} / percentOrDot)), name))
constexpr auto subscript{scalarIntExpr};
TYPE_PARSER(construct<SectionSubscript>(Parser<SubscriptTriplet>{}) ||
construct<SectionSubscript>(intExpr))
TYPE_PARSER(construct<SubscriptTriplet>(
maybe(subscript), ":" >> maybe(subscript), maybe(":" >> subscript)))
constexpr auto cosubscript{scalarIntExpr};
TYPE_CONTEXT_PARSER("image selector"_en_US,
construct<ImageSelector>(
"[" >> nonemptyList(cosubscript / lookAhead(space / ",]"_ch)),
defaulted("," >> nonemptyList(Parser<ImageSelectorSpec>{})) / "]"))
TYPE_PARSER(construct<ImageSelectorSpec>(construct<ImageSelectorSpec::Stat>(
"STAT =" >> scalar(integer(indirect(variable))))) ||
construct<ImageSelectorSpec>(construct<TeamValue>("TEAM =" >> teamValue)) ||
construct<ImageSelectorSpec>(construct<ImageSelectorSpec::Team_Number>(
"TEAM_NUMBER =" >> scalarIntExpr)))
TYPE_CONTEXT_PARSER("ALLOCATE statement"_en_US,
construct<AllocateStmt>("ALLOCATE (" >> maybe(typeSpec / "::"),
nonemptyList(Parser<Allocation>{}),
defaulted("," >> nonemptyList(Parser<AllocOpt>{})) / ")"))
TYPE_PARSER(construct<AllocOpt>(
construct<AllocOpt::Mold>("MOLD =" >> indirect(expr))) ||
construct<AllocOpt>(
construct<AllocOpt::Source>("SOURCE =" >> indirect(expr))) ||
construct<AllocOpt>(statOrErrmsg) ||
extension<LanguageFeature::CUDA>(
construct<AllocOpt>(construct<AllocOpt::Stream>(
"STREAM =" >> indirect(scalarIntExpr))) ||
construct<AllocOpt>(construct<AllocOpt::Pinned>(
"PINNED =" >> indirect(scalarLogicalVariable)))))
TYPE_PARSER(construct<StatVariable>(scalar(integer(variable))))
TYPE_PARSER(construct<Allocation>(Parser<AllocateObject>{},
defaulted(parenthesized(nonemptyList(Parser<AllocateShapeSpec>{}))),
maybe(bracketed(Parser<AllocateCoarraySpec>{}))))
TYPE_PARSER(construct<AllocateObject>(structureComponent) ||
construct<AllocateObject>(name / !"="_tok))
TYPE_PARSER(construct<AllocateShapeSpec>(maybe(boundExpr / ":"), boundExpr))
TYPE_PARSER(construct<AllocateCoarraySpec>(
defaulted(nonemptyList(Parser<AllocateShapeSpec>{}) / ","),
maybe(boundExpr / ":") / "*"))
TYPE_CONTEXT_PARSER("NULLIFY statement"_en_US,
"NULLIFY" >> parenthesized(construct<NullifyStmt>(
nonemptyList(Parser<PointerObject>{}))))
TYPE_PARSER(construct<PointerObject>(structureComponent) ||
construct<PointerObject>(name))
TYPE_CONTEXT_PARSER("DEALLOCATE statement"_en_US,
construct<DeallocateStmt>(
"DEALLOCATE (" >> nonemptyList(Parser<AllocateObject>{}),
defaulted("," >> nonemptyList(statOrErrmsg)) / ")"))
TYPE_PARSER(construct<StatOrErrmsg>("STAT =" >> statVariable) ||
construct<StatOrErrmsg>("ERRMSG =" >> msgVariable))
constexpr auto ignore_tkr{
"IGNORE_TKR" >> optionalList(construct<CompilerDirective::IgnoreTKR>(
maybe(parenthesized(many(letter))), name))};
constexpr auto loopCount{
"LOOP COUNT" >> construct<CompilerDirective::LoopCount>(
parenthesized(nonemptyList(digitString64)))};
constexpr auto assumeAligned{"ASSUME_ALIGNED" >>
optionalList(construct<CompilerDirective::AssumeAligned>(
indirect(designator), ":"_tok >> digitString64))};
constexpr auto vectorAlways{
"VECTOR ALWAYS" >> construct<CompilerDirective::VectorAlways>()};
TYPE_PARSER(beginDirective >> "DIR$ "_tok >>
sourced((construct<CompilerDirective>(ignore_tkr) ||
construct<CompilerDirective>(loopCount) ||
construct<CompilerDirective>(assumeAligned) ||
construct<CompilerDirective>(vectorAlways) ||
construct<CompilerDirective>(
many(construct<CompilerDirective::NameValue>(
name, maybe(("="_tok || ":"_tok) >> digitString64))))) /
endOfStmt ||
construct<CompilerDirective>(pure<CompilerDirective::Unrecognized>()) /
SkipTo<'\n'>{}))
TYPE_PARSER(extension<LanguageFeature::CrayPointer>(
"nonstandard usage: based POINTER"_port_en_US,
construct<BasedPointerStmt>(
"POINTER" >> nonemptyList("expected POINTER associations"_err_en_US,
construct<BasedPointer>("(" >> objectName / ",",
objectName, maybe(Parser<ArraySpec>{}) / ")")))))
TYPE_PARSER(extension<LanguageFeature::CUDA>(construct<CUDAAttributesStmt>(
"ATTRIBUTES" >> parenthesized(Parser<common::CUDADataAttr>{}),
defaulted(
maybe("::"_tok) >> nonemptyList("expected names"_err_en_US, name)))))
constexpr auto structureName{maybe(sourced("/" >> name / "/"))};
TYPE_PARSER(construct<StructureStmt>("STRUCTURE" >> structureName,
localRecovery(
"entity declarations are required on a nested structure"_err_en_US,
nonemptyList(entityDecl), ok)))
constexpr auto nestedStructureDef{
CONTEXT_PARSER("nested STRUCTURE definition"_en_US,
construct<StructureDef>(statement(NestedStructureStmt{}),
many(Parser<StructureField>{}),
statement(construct<StructureDef::EndStructureStmt>(
"END STRUCTURE"_tok))))};
TYPE_PARSER(construct<StructureField>(statement(StructureComponents{})) ||
construct<StructureField>(indirect(Parser<Union>{})) ||
construct<StructureField>(indirect(nestedStructureDef)))
TYPE_CONTEXT_PARSER("STRUCTURE definition"_en_US,
extension<LanguageFeature::DECStructures>(
"nonstandard usage: STRUCTURE"_port_en_US,
construct<StructureDef>(
statement(construct<StructureStmt>(
"STRUCTURE" >> structureName, optionalList(entityDecl))),
many(Parser<StructureField>{}),
statement(construct<StructureDef::EndStructureStmt>(
"END STRUCTURE"_tok)))))
TYPE_CONTEXT_PARSER("UNION definition"_en_US,
construct<Union>(statement(construct<Union::UnionStmt>("UNION"_tok)),
many(Parser<Map>{}),
statement(construct<Union::EndUnionStmt>("END UNION"_tok))))
TYPE_CONTEXT_PARSER("MAP definition"_en_US,
construct<Map>(statement(construct<Map::MapStmt>("MAP"_tok)),
many(Parser<StructureField>{}),
statement(construct<Map::EndMapStmt>("END MAP"_tok))))
TYPE_CONTEXT_PARSER("arithmetic IF statement"_en_US,
deprecated<LanguageFeature::ArithmeticIF>(construct<ArithmeticIfStmt>(
"IF" >> parenthesized(expr), label / ",", label / ",", label)))
TYPE_CONTEXT_PARSER("ASSIGN statement"_en_US,
deprecated<LanguageFeature::Assign>(
construct<AssignStmt>("ASSIGN" >> label, "TO" >> name)))
TYPE_CONTEXT_PARSER("assigned GOTO statement"_en_US,
deprecated<LanguageFeature::AssignedGOTO>(construct<AssignedGotoStmt>(
"GO TO" >> name,
defaulted(maybe(","_tok) >>
parenthesized(nonemptyList("expected labels"_err_en_US, label))))))
TYPE_CONTEXT_PARSER("PAUSE statement"_en_US,
deprecated<LanguageFeature::Pause>(
construct<PauseStmt>("PAUSE" >> maybe(Parser<StopCode>{}))))
}