// R725 logical-literal-constant ->
// .TRUE. [_ kind-param] | .FALSE. [_ kind-param]
// Also accept .T. and .F. as extensions.
-TYPE_PARSER(
- construct<LogicalLiteralConstant>(
- (".TRUE."_tok ||
- extension<LanguageFeature::LogicalAbbreviations>(".T."_tok)) >>
- pure(true),
- maybe(underscore >> kindParam)) ||
+TYPE_PARSER(construct<LogicalLiteralConstant>(
+ logicalTRUE, maybe(underscore >> kindParam)) ||
construct<LogicalLiteralConstant>(
- (".FALSE."_tok ||
- extension<LanguageFeature::LogicalAbbreviations>(".F."_tok)) >>
- pure(false),
- maybe(underscore >> kindParam)))
+ logicalFALSE, maybe(underscore >> kindParam)))
// R726 derived-type-def ->
// derived-type-stmt [type-param-def-stmt]...
// R1002 level-1-expr -> [defined-unary-op] primary
// TODO: Reasonable extension: permit multiple defined-unary-ops
-constexpr auto level1Expr{sourced(first(
- construct<Expr>(construct<Expr::DefinedUnary>(definedOpName, primary)),
- primary,
- extension<LanguageFeature::SignedPrimary>(
- construct<Expr>(construct<Expr::UnaryPlus>("+" >> primary))),
- extension<LanguageFeature::SignedPrimary>(
- construct<Expr>(construct<Expr::Negate>("-" >> primary)))))};
+constexpr auto level1Expr{sourced(
+ first(primary, // must come before define op to resolve .TRUE._8 ambiguity
+ construct<Expr>(construct<Expr::DefinedUnary>(definedOpName, primary)),
+ extension<LanguageFeature::SignedPrimary>(
+ construct<Expr>(construct<Expr::UnaryPlus>("+" >> primary))),
+ extension<LanguageFeature::SignedPrimary>(
+ construct<Expr>(construct<Expr::Negate>("-" >> primary)))))};
// R1004 mult-operand -> level-1-expr [power-op mult-operand]
// R1007 power-op -> **
TYPE_PARSER(space >> sourced(rawName >> construct<Name>()))
constexpr auto keyword{construct<Keyword>(name)};
+constexpr auto logicalTRUE{
+ (".TRUE."_tok ||
+ extension<LanguageFeature::LogicalAbbreviations>(".T."_tok)) >>
+ pure(true)};
+constexpr auto logicalFALSE{
+ (".FALSE."_tok ||
+ extension<LanguageFeature::LogicalAbbreviations>(".F."_tok)) >>
+ pure(false)};
+
// R1003 defined-unary-op -> . letter [letter]... .
// R1023 defined-binary-op -> . letter [letter]... .
// R1414 local-defined-operator -> defined-unary-op | defined-binary-op
// R1415 use-defined-operator -> defined-unary-op | defined-binary-op
+// C1003 A defined operator must be distinct from logical literal constants
+// and intrinsic operator names; this is handled by attempting their parses
+// first, and by name resolution on their definitions, for best errors.
// N.B. The name of the operator is captured without the periods around it.
constexpr auto definedOpNameChar{
letter || extension<LanguageFeature::PunctuationInNames>("$@"_ch)};