[flang] Use "..."_en_US for messages.
authorpeter klausler <pklausler@nvidia.com>
Tue, 20 Feb 2018 17:57:30 +0000 (09:57 -0800)
committerpeter klausler <pklausler@nvidia.com>
Tue, 20 Feb 2018 17:57:30 +0000 (09:57 -0800)
Original-commit: flang-compiler/f18@fffa8815762a7fa449863a6fa0f7c4b72bd0d4e4
Reviewed-on: https://github.com/flang-compiler/f18/pull/14
Tree-same-pre-rewrite: false

flang/lib/parser/basic-parsers.h
flang/lib/parser/grammar.h
flang/lib/parser/message.cc
flang/lib/parser/message.h
flang/lib/parser/parse-state.h
flang/lib/parser/preprocessor.cc
flang/lib/parser/preprocessor.h
flang/lib/parser/prescan.cc
flang/lib/parser/prescan.h
flang/lib/parser/token-parsers.h

index 91e44a5..5a97d62 100644 (file)
@@ -28,7 +28,7 @@
 namespace Fortran {
 namespace parser {
 
-// fail<A>("..."_msg) returns a parser that never succeeds.  It reports an
+// fail<A>("..."_en_US) returns a parser that never succeeds.  It reports an
 // error message at the current position.  The result type is unused,
 // but might have to be specified at the point of call for satisfy
 // the type checker.  The state remains valid.
@@ -36,19 +36,19 @@ template<typename A> class FailParser {
 public:
   using resultType = A;
   constexpr FailParser(const FailParser &) = default;
-  constexpr explicit FailParser(MessageText t) : text_{t} {}
+  constexpr explicit FailParser(MessageFixedText t) : text_{t} {}
   std::optional<A> Parse(ParseState *state) const {
     state->PutMessage(text_);
     return {};
   }
 
 private:
-  const MessageText text_;
+  const MessageFixedText text_;
 };
 
 class Success {};  // for when one must return something that's present
 
-template<typename A = Success> inline constexpr auto fail(MessageText t) {
+template<typename A = Success> inline constexpr auto fail(MessageFixedText t) {
   return FailParser<A>{t};
 }
 
@@ -148,13 +148,13 @@ template<typename PA> inline constexpr auto lookAhead(const PA &p) {
   return LookAheadParser<PA>{p};
 }
 
-// If a is a parser, inContext("..."_msg, a) runs it in a nested message
+// If a is a parser, inContext("..."_en_US, a) runs it in a nested message
 // context.
 template<typename PA> class MessageContextParser {
 public:
   using resultType = typename PA::resultType;
   constexpr MessageContextParser(const MessageContextParser &) = default;
-  constexpr MessageContextParser(MessageText t, const PA &p)
+  constexpr MessageContextParser(MessageFixedText t, const PA &p)
     : text_{t}, parser_{p} {}
   std::optional<resultType> Parse(ParseState *state) const {
     state->PushContext(text_);
@@ -164,12 +164,12 @@ public:
   }
 
 private:
-  const MessageText text_;
+  const MessageFixedText text_;
   const PA parser_;
 };
 
 template<typename PA>
-inline constexpr auto inContext(MessageText context, const PA &parser) {
+inline constexpr auto inContext(MessageFixedText context, const PA &parser) {
   return MessageContextParser{context, parser};
 }
 
@@ -1189,7 +1189,7 @@ constexpr struct NextCharParser {
   std::optional<char> Parse(ParseState *state) const {
     std::optional<char> ch{state->GetNextChar()};
     if (!ch) {
-      state->PutMessage("end of file"_msg);
+      state->PutMessage("end of file"_en_US);
     }
     return ch;
   }
@@ -1211,7 +1211,7 @@ public:
     auto result = parser_.Parse(state);
     if (result) {
       if (state->warnOnNonstandardUsage()) {
-        state->PutMessage(at, "nonstandard usage"_msg);
+        state->PutMessage(at, "nonstandard usage"_en_US);
       }
     }
     return result;
@@ -1241,7 +1241,7 @@ public:
     auto result = parser_.Parse(state);
     if (result) {
       if (state->warnOnDeprecatedUsage()) {
-        state->PutMessage(at, "deprecated usage"_msg);
+        state->PutMessage(at, "deprecated usage"_en_US);
       }
     }
     return result;
index 843b716..6c0f1ed 100644 (file)
@@ -184,7 +184,7 @@ template<typename PA> inline constexpr auto unterminatedStatement(const PA &p) {
 }
 
 constexpr auto endOfLine = CharMatch<'\n'>{} / skipMany("\n"_tok) ||
-    fail<char>("expected end of line"_msg);
+    fail<char>("expected end of line"_en_US);
 
 constexpr auto endOfStmt = spaces >>
     (CharMatch<';'>{} / skipMany(";"_tok) / maybe(endOfLine) || endOfLine);
@@ -196,7 +196,7 @@ template<typename PA> inline constexpr auto statement(const PA &p) {
 // R507 declaration-construct ->
 //        specification-construct | data-stmt | format-stmt |
 //        entry-stmt | stmt-function-stmt
-TYPE_CONTEXT_PARSER("declaration construct"_msg,
+TYPE_CONTEXT_PARSER("declaration construct"_en_US,
     construct<DeclarationConstruct>{}(specificationConstruct) ||
         construct<DeclarationConstruct>{}(statement(indirect(dataStmt))) ||
         construct<DeclarationConstruct>{}(statement(indirect(formatStmt))) ||
@@ -208,7 +208,7 @@ TYPE_CONTEXT_PARSER("declaration construct"_msg,
 //        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"_msg,
+TYPE_CONTEXT_PARSER("specification construct"_en_US,
     construct<SpecificationConstruct>{}(indirect(Parser<DerivedTypeDef>{})) ||
         construct<SpecificationConstruct>{}(indirect(Parser<EnumDef>{})) ||
         construct<SpecificationConstruct>{}(
@@ -389,7 +389,7 @@ TYPE_PARSER(construct<ProgramUnit>{}(indirect(functionSubprogram)) ||
 // R504 specification-part ->
 //         [use-stmt]... [import-stmt]... [implicit-part]
 //         [declaration-construct]...
-TYPE_CONTEXT_PARSER("specification part"_msg,
+TYPE_CONTEXT_PARSER("specification part"_en_US,
     construct<SpecificationPart>{}(many(statement(indirect(Parser<UseStmt>{}))),
         many(statement(indirect(Parser<ImportStmt>{}))), implicitPart,
         many(declarationConstruct)))
@@ -398,7 +398,7 @@ TYPE_CONTEXT_PARSER("specification part"_msg,
 // TODO: Can overshoot; any trailing PARAMETER, FORMAT, & ENTRY
 // statements after the last IMPLICIT should be transferred to the
 // list of declaration-constructs.
-TYPE_CONTEXT_PARSER("implicit part"_msg,
+TYPE_CONTEXT_PARSER("implicit part"_en_US,
     construct<ImplicitPart>{}(many(Parser<ImplicitPartStmt>{})))
 
 // R506 implicit-part-stmt ->
@@ -416,7 +416,7 @@ constexpr auto internalSubprogram =
     endOfStmt;
 
 // R511 internal-subprogram-part -> contains-stmt [internal-subprogram]...
-TYPE_CONTEXT_PARSER("internal subprogram part"_msg,
+TYPE_CONTEXT_PARSER("internal subprogram part"_en_US,
     construct<InternalSubprogramPart>{}(statement(containsStmt),
         many(startNewSubprogram >> internalSubprogram)))
 
@@ -544,7 +544,7 @@ constexpr auto executionPartErrorRecovery = skipMany("\n"_tok) >>
 // R510 execution-part-construct ->
 //        executable-construct | format-stmt | entry-stmt | data-stmt
 // Extension (PGI/Intel): also accept NAMELIST in execution part
-TYPE_CONTEXT_PARSER("execution part construct"_msg,
+TYPE_CONTEXT_PARSER("execution part construct"_en_US,
     recovery(construct<ExecutionPartConstruct>{}(executableConstruct) ||
             construct<ExecutionPartConstruct>{}(
                 statement(indirect(formatStmt))) ||
@@ -558,7 +558,7 @@ TYPE_CONTEXT_PARSER("execution part construct"_msg,
 
 // R509 execution-part -> executable-construct [execution-part-construct]...
 constexpr auto executionPart =
-    inContext("execution part"_msg, many(executionPartConstruct));
+    inContext("execution part"_en_US, many(executionPartConstruct));
 
 // R602 underscore -> _
 constexpr CharMatch<'_'> underscore;
@@ -616,7 +616,7 @@ TYPE_PARSER(construct<TypeParamValue>{}(scalarIntExpr) ||
 // the other is below in R703 declaration-type-spec.  Look-ahead is required
 // 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"_msg,
+TYPE_CONTEXT_PARSER("type spec"_en_US,
     construct<TypeSpec>{}(intrinsicTypeSpec / lookAhead("::"_tok || ")"_tok)) ||
         construct<TypeSpec>{}(derivedTypeSpec))
 
@@ -628,7 +628,7 @@ TYPE_CONTEXT_PARSER("type spec"_msg,
 // for TYPE (...), rather than putting the alternatives within it, which
 // would fail on "TYPE(real_derived)" with a misrecognition of "real" as an
 // intrinsic-type-spec.
-TYPE_CONTEXT_PARSER("declaration type spec"_msg,
+TYPE_CONTEXT_PARSER("declaration type spec"_en_US,
     construct<DeclarationTypeSpec>{}(intrinsicTypeSpec) ||
         "TYPE" >>
             (parenthesized(
@@ -652,7 +652,7 @@ TYPE_CONTEXT_PARSER("declaration type spec"_msg,
 //        COMPLEX [kind-selector] | CHARACTER [char-selector] |
 //        LOGICAL [kind-selector]
 // Extensions: DOUBLE COMPLEX, NCHARACTER, BYTE
-TYPE_CONTEXT_PARSER("intrinsic type spec"_msg,
+TYPE_CONTEXT_PARSER("intrinsic type spec"_en_US,
     construct<IntrinsicTypeSpec>{}(integerTypeSpec) ||
         "REAL" >>
             construct<IntrinsicTypeSpec>{}(
@@ -738,7 +738,7 @@ constexpr auto signedRealLiteralConstant = spaces >>
 //        digit-string exponent-letter exponent [_ kind-param]
 // R715 significand -> digit-string . [digit-string] | . digit-string
 // N.B. Preceding spaces are not skipped.
-TYPE_CONTEXT_PARSER("REAL literal constant"_msg,
+TYPE_CONTEXT_PARSER("REAL literal constant"_en_US,
     construct<RealLiteralConstant>{}(some(digit),
         CharMatch<'.'>{} >>
             !(some(letter) >> CharMatch<'.'>{}) >>  // don't misinterpret 1.AND.
@@ -760,9 +760,9 @@ inline constexpr bool isEorD(char ch) {
 inline constexpr bool isQ(char ch) { return tolower(ch) == 'q'; }
 
 constexpr CharPredicateGuardParser exponentEorD{
-    isEorD, "expected exponent letter"_msg};
+    isEorD, "expected exponent letter"_en_US};
 constexpr CharPredicateGuardParser exponentQ{
-    isQ, "expected exponent letter"_msg};
+    isQ, "expected exponent letter"_en_US};
 
 // R717 exponent -> signed-digit-string
 // Not a complete token.
@@ -770,7 +770,7 @@ TYPE_PARSER(construct<ExponentPart>{}(
     extension(exponentQ) || exponentEorD, signedDigitString))
 
 // R718 complex-literal-constant -> ( real-part , imag-part )
-TYPE_CONTEXT_PARSER("COMPLEX literal constant"_msg,
+TYPE_CONTEXT_PARSER("COMPLEX literal constant"_en_US,
     parenthesized(construct<ComplexLiteralConstant>{}(
         Parser<ComplexPart>{} / ",", Parser<ComplexPart>{})))
 
@@ -826,7 +826,7 @@ constexpr auto charLiteralConstantWithoutKind =
     CharMatch<'\''>{} >> CharLiteral<'\''>{} ||
     CharMatch<'"'>{} >> CharLiteral<'"'>{};
 
-TYPE_CONTEXT_PARSER("CHARACTER literal constant"_msg,
+TYPE_CONTEXT_PARSER("CHARACTER literal constant"_en_US,
     construct<CharLiteralConstant>{}(
         kindParam / underscore, charLiteralConstantWithoutKind) ||
         construct<CharLiteralConstant>{}(construct<std::optional<KindParam>>{},
@@ -839,8 +839,8 @@ TYPE_CONTEXT_PARSER("CHARACTER literal constant"_msg,
 // deprecated: Hollerith literals
 constexpr auto rawHollerithLiteral = deprecated(HollerithLiteral{});
 
-TYPE_CONTEXT_PARSER(
-    "Hollerith"_msg, construct<HollerithLiteralConstant>{}(rawHollerithLiteral))
+TYPE_CONTEXT_PARSER("Hollerith"_en_US,
+    construct<HollerithLiteralConstant>{}(rawHollerithLiteral))
 
 // R725 logical-literal-constant -> .TRUE. | .FALSE.
 // Also accept .T. and .F. as extensions.
@@ -855,7 +855,7 @@ TYPE_PARSER(".TRUE." >> construct<LogicalLiteralConstant>{}(pure(true)) ||
 //        [private-or-sequence]... [component-part]
 //        [type-bound-procedure-part] end-type-stmt
 // R735 component-part -> [component-def-stmt]...
-TYPE_CONTEXT_PARSER("derived type definition"_msg,
+TYPE_CONTEXT_PARSER("derived type definition"_en_US,
     construct<DerivedTypeDef>{}(statement(Parser<DerivedTypeStmt>{}),
         many(statement(Parser<TypeParamDefStmt>{})),
         many(statement(Parser<PrivateOrSequence>{})),
@@ -866,7 +866,7 @@ TYPE_CONTEXT_PARSER("derived type definition"_msg,
 // R727 derived-type-stmt ->
 //        TYPE [[, type-attr-spec-list] ::] type-name [(
 //        type-param-name-list )]
-TYPE_CONTEXT_PARSER("TYPE statement"_msg,
+TYPE_CONTEXT_PARSER("TYPE statement"_en_US,
     "TYPE" >> construct<DerivedTypeStmt>{}(
                   optionalBeforeColons(nonemptyList(Parser<TypeAttrSpec>{})),
                   name, defaulted(parenthesized(nonemptyList(name)))))
@@ -938,7 +938,7 @@ TYPE_PARSER(construct<ComponentAttrSpec>{}(accessSpec) ||
 //        component-name [( component-array-spec )]
 //        [lbracket coarray-spec rbracket] [* char-length]
 //        [component-initialization]
-TYPE_CONTEXT_PARSER("component declaration"_msg,
+TYPE_CONTEXT_PARSER("component declaration"_en_US,
     construct<ComponentDecl>{}(name, maybe(Parser<ComponentArraySpec>{}),
         maybe(coarraySpec), maybe("*" >> charLength), maybe(initialization)))
 
@@ -952,7 +952,7 @@ TYPE_PARSER(construct<ComponentArraySpec>{}(
 // R741 proc-component-def-stmt ->
 //        PROCEDURE ( [proc-interface] ) , proc-component-attr-spec-list
 //          :: proc-decl-list
-TYPE_CONTEXT_PARSER("PROCEDURE component definition statement"_msg,
+TYPE_CONTEXT_PARSER("PROCEDURE component definition statement"_en_US,
     "PROCEDURE" >>
         construct<ProcComponentDefStmt>{}(parenthesized(maybe(procInterface)),
             "," >> nonemptyList(Parser<ProcComponentAttrSpec>{}) / "::",
@@ -988,7 +988,7 @@ 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"_msg,
+TYPE_CONTEXT_PARSER("type bound procedure part"_en_US,
     construct<TypeBoundProcedurePart>{}(statement(containsStmt),
         maybe(statement(Parser<PrivateStmt>{})),
         many(statement(Parser<TypeBoundProcBinding>{}))))
@@ -1004,7 +1004,7 @@ TYPE_PARSER(
 // 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"_msg,
+TYPE_CONTEXT_PARSER("type bound PROCEDURE statement"_en_US,
     "PROCEDURE" >>
         (construct<TypeBoundProcedureStmt>{}(
              construct<TypeBoundProcedureStmt::WithInterface>{}(
@@ -1021,7 +1021,7 @@ 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"_msg,
+TYPE_CONTEXT_PARSER("type bound GENERIC statement"_en_US,
     "GENERIC" >> construct<TypeBoundGenericStmt>{}(maybe("," >> accessSpec),
                      "::" >> indirect(genericSpec), "=>" >> nonemptyList(name)))
 
@@ -1034,7 +1034,7 @@ TYPE_PARSER(construct<BindAttr>{}(accessSpec) ||
     construct<BindAttr>{}(noPass) || construct<BindAttr>{}(pass))
 
 // R753 final-procedure-stmt -> FINAL [::] final-subroutine-name-list
-TYPE_CONTEXT_PARSER("FINAL statement"_msg,
+TYPE_CONTEXT_PARSER("FINAL statement"_en_US,
     "FINAL" >> maybe("::"_tok) >>
         construct<FinalProcedureStmt>{}(nonemptyList(name)))
 
@@ -1065,7 +1065,7 @@ 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"_msg,
+TYPE_CONTEXT_PARSER("enum definition"_en_US,
     construct<EnumDef>{}(statement(Parser<EnumDefStmt>{}),
         some(statement(Parser<EnumeratorDefStmt>{})),
         statement(Parser<EndEnumStmt>{})))
@@ -1074,7 +1074,7 @@ TYPE_CONTEXT_PARSER("enum definition"_msg,
 TYPE_PARSER("ENUM , BIND ( C )" >> construct<EnumDefStmt>{})
 
 // R761 enumerator-def-stmt -> ENUMERATOR [::] enumerator-list
-TYPE_CONTEXT_PARSER("ENUMERATOR statement"_msg,
+TYPE_CONTEXT_PARSER("ENUMERATOR statement"_en_US,
     construct<EnumeratorDefStmt>{}(
         "ENUMERATOR" >> maybe("::"_tok) >> nonemptyList(Parser<Enumerator>{})))
 
@@ -1103,7 +1103,7 @@ template<typename PA> inline constexpr auto loopBounds(const PA &p) {
 }
 
 // R769 array-constructor -> (/ ac-spec /) | lbracket ac-spec rbracket
-TYPE_CONTEXT_PARSER("array constructor"_msg,
+TYPE_CONTEXT_PARSER("array constructor"_en_US,
     construct<ArrayConstructor>{}(
         "(/" >> Parser<AcSpec>{} / "/)" || bracketed(Parser<AcSpec>{})))
 
@@ -1310,7 +1310,7 @@ TYPE_PARSER("CONTIGUOUS" >> maybe("::"_tok) >>
     construct<ContiguousStmt>{}(nonemptyList(objectName)))
 
 // R837 data-stmt -> DATA data-stmt-set [[,] data-stmt-set]...
-TYPE_CONTEXT_PARSER("DATA statement"_msg,
+TYPE_CONTEXT_PARSER("DATA statement"_en_US,
     "DATA" >> construct<DataStmt>{}(
                   nonemptySeparated(Parser<DataStmtSet>{}, maybe(","_tok))))
 
@@ -1370,13 +1370,13 @@ TYPE_PARSER(construct<DataStmtConstant>{}(Parser<StructureConstructor>{}) ||
 // R848 dimension-stmt ->
 //        DIMENSION [::] array-name ( array-spec )
 //        [, array-name ( array-spec )]...
-TYPE_CONTEXT_PARSER("DIMENSION statement"_msg,
+TYPE_CONTEXT_PARSER("DIMENSION statement"_en_US,
     "DIMENSION" >> maybe("::"_tok) >>
         construct<DimensionStmt>{}(nonemptyList(
             construct<DimensionStmt::Declaration>{}(name, arraySpec))))
 
 // R849 intent-stmt -> INTENT ( intent-spec ) [::] dummy-arg-name-list
-TYPE_CONTEXT_PARSER("INTENT statement"_msg,
+TYPE_CONTEXT_PARSER("INTENT statement"_en_US,
     "INTENT" >>
         construct<IntentStmt>{}(
             parenthesized(intentSpec) / maybe("::"_tok), nonemptyList(name)))
@@ -1387,7 +1387,7 @@ TYPE_PARSER("OPTIONAL" >> maybe("::"_tok) >>
 
 // R851 parameter-stmt -> PARAMETER ( named-constant-def-list )
 // Legacy extension: omitted parentheses
-TYPE_CONTEXT_PARSER("PARAMETER statement"_msg,
+TYPE_CONTEXT_PARSER("PARAMETER statement"_en_US,
     "PARAMETER" >>
         construct<ParameterStmt>{}(
             parenthesized(nonemptyList(Parser<NamedConstantDef>{})) ||
@@ -1438,7 +1438,7 @@ constexpr auto implicitNameSpec = "EXTERNAL" >>
 // R863 implicit-stmt ->
 //        IMPLICIT implicit-spec-list |
 //        IMPLICIT NONE [( [implicit-name-spec-list] )]
-TYPE_CONTEXT_PARSER("IMPLICIT statement"_msg,
+TYPE_CONTEXT_PARSER("IMPLICIT statement"_en_US,
     "IMPLICIT" >>
         (construct<ImplicitStmt>{}(nonemptyList(Parser<ImplicitSpec>{})) ||
             construct<ImplicitStmt>{}("NONE" >>
@@ -1481,7 +1481,7 @@ TYPE_PARSER(spaces >> (construct<LetterSpec>{}(letter, maybe("-" >> letter)) ||
 // R867 import-stmt ->
 //        IMPORT [[::] import-name-list] |
 //        IMPORT , ONLY : import-name-list | IMPORT , NONE | IMPORT , ALL
-TYPE_CONTEXT_PARSER("IMPORT statement"_msg,
+TYPE_CONTEXT_PARSER("IMPORT statement"_en_US,
     "IMPORT" >>
         (construct<ImportStmt>{}(
              ", ONLY :" >> pure(ImportStmt::Kind::Only), nonemptyList(name)) ||
@@ -1711,7 +1711,7 @@ TYPE_PARSER("STAT =" >>
 
 // R927 allocate-stmt ->
 //        ALLOCATE ( [type-spec ::] allocation-list [, alloc-opt-list] )
-TYPE_CONTEXT_PARSER("ALLOCATE statement"_msg,
+TYPE_CONTEXT_PARSER("ALLOCATE statement"_en_US,
     "ALLOCATE" >>
         parenthesized(construct<AllocateStmt>{}(maybe(typeSpec / "::"),
             nonemptyList(Parser<Allocation>{}),
@@ -1763,7 +1763,7 @@ TYPE_PARSER(construct<AllocateCoarraySpec>{}(
     maybe(boundExpr / ":") / "*"))
 
 // R939 nullify-stmt -> NULLIFY ( pointer-object-list )
-TYPE_CONTEXT_PARSER("NULLIFY statement"_msg,
+TYPE_CONTEXT_PARSER("NULLIFY statement"_en_US,
     "NULLIFY" >> parenthesized(construct<NullifyStmt>{}(
                      nonemptyList(Parser<PointerObject>{}))))
 
@@ -1774,7 +1774,7 @@ TYPE_PARSER(construct<PointerObject>{}(structureComponent) ||
 
 // R941 deallocate-stmt ->
 //        DEALLOCATE ( allocate-object-list [, dealloc-opt-list] )
-TYPE_CONTEXT_PARSER("DEALLOCATE statement"_msg,
+TYPE_CONTEXT_PARSER("DEALLOCATE statement"_en_US,
     "DEALLOCATE" >> parenthesized(construct<DeallocateStmt>{}(
                         nonemptyList(Parser<AllocateObject>{}),
                         defaulted("," >> nonemptyList(statOrErrmsg)))))
@@ -2087,7 +2087,7 @@ template<> std::optional<Expr> Parser<Expr>::Parse(ParseState *state) {
 TYPE_PARSER(construct<SpecificationExpr>{}(scalarIntExpr))
 
 // R1032 assignment-stmt -> variable = expr
-TYPE_CONTEXT_PARSER("assignment statement"_msg,
+TYPE_CONTEXT_PARSER("assignment statement"_en_US,
     construct<AssignmentStmt>{}(variable / "=", expr))
 
 // R1033 pointer-assignment-stmt ->
@@ -2101,7 +2101,7 @@ TYPE_CONTEXT_PARSER("assignment statement"_msg,
 // A distinction can't be made at the time of the initial parse between
 // data-pointer-object and proc-pointer-object, or between data-target
 // and proc-target.
-TYPE_CONTEXT_PARSER("pointer assignment statement"_msg,
+TYPE_CONTEXT_PARSER("pointer assignment statement"_en_US,
     construct<PointerAssignmentStmt>{}(variable,
         parenthesized(nonemptyList(Parser<BoundsRemapping>{})), "=>" >> expr) ||
         construct<PointerAssignmentStmt>{}(variable,
@@ -2121,7 +2121,7 @@ TYPE_PARSER(construct<BoundsRemapping>{}(boundExpr / ":", boundExpr))
 // 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"_msg,
+TYPE_CONTEXT_PARSER("WHERE statement"_en_US,
     "WHERE" >>
         construct<WhereStmt>{}(parenthesized(logicalExpr), assignmentStmt))
 
@@ -2129,7 +2129,7 @@ TYPE_CONTEXT_PARSER("WHERE statement"_msg,
 //         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"_msg,
+TYPE_CONTEXT_PARSER("WHERE construct"_en_US,
     construct<WhereConstruct>{}(statement(Parser<WhereConstructStmt>{}),
         many(whereBodyConstruct),
         many(construct<WhereConstruct::MaskedElsewhere>{}(
@@ -2140,7 +2140,7 @@ TYPE_CONTEXT_PARSER("WHERE construct"_msg,
         statement(Parser<EndWhereStmt>{})))
 
 // R1043 where-construct-stmt -> [where-construct-name :] WHERE ( mask-expr )
-TYPE_CONTEXT_PARSER("WHERE construct statement"_msg,
+TYPE_CONTEXT_PARSER("WHERE construct statement"_en_US,
     construct<WhereConstructStmt>{}(
         maybe(name / ":"), "WHERE" >> parenthesized(logicalExpr)))
 
@@ -2152,28 +2152,28 @@ TYPE_PARSER(construct<WhereBodyConstruct>{}(statement(assignmentStmt)) ||
 
 // R1047 masked-elsewhere-stmt ->
 //         ELSEWHERE ( mask-expr ) [where-construct-name]
-TYPE_CONTEXT_PARSER("masked ELSEWHERE statement"_msg,
+TYPE_CONTEXT_PARSER("masked ELSEWHERE statement"_en_US,
     "ELSEWHERE" >> construct<MaskedElsewhereStmt>{}(
                        parenthesized(logicalExpr), maybe(name)))
 
 // R1048 elsewhere-stmt -> ELSEWHERE [where-construct-name]
-TYPE_CONTEXT_PARSER("ELSEWHERE statement"_msg,
+TYPE_CONTEXT_PARSER("ELSEWHERE statement"_en_US,
     "ELSEWHERE" >> construct<ElsewhereStmt>{}(maybe(name)))
 
 // R1049 end-where-stmt -> ENDWHERE [where-construct-name]
-TYPE_CONTEXT_PARSER("END WHERE statement"_msg,
+TYPE_CONTEXT_PARSER("END WHERE statement"_en_US,
     "END WHERE" >> construct<EndWhereStmt>{}(maybe(name)))
 
 // R1050 forall-construct ->
 //         forall-construct-stmt [forall-body-construct]... end-forall-stmt
-TYPE_CONTEXT_PARSER("FORALL construct"_msg,
+TYPE_CONTEXT_PARSER("FORALL construct"_en_US,
     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"_msg,
+TYPE_CONTEXT_PARSER("FORALL construct statement"_en_US,
     construct<ForallConstructStmt>{}(
         maybe(name / ":"), "FORALL" >> indirect(concurrentHeader)))
 
@@ -2191,11 +2191,11 @@ TYPE_PARSER(construct<ForallAssignmentStmt>{}(assignmentStmt) ||
     construct<ForallAssignmentStmt>{}(pointerAssignmentStmt))
 
 // R1054 end-forall-stmt -> END FORALL [forall-construct-name]
-TYPE_CONTEXT_PARSER("END FORALL statement"_msg,
+TYPE_CONTEXT_PARSER("END FORALL statement"_en_US,
     "END FORALL" >> construct<EndForallStmt>{}(maybe(name)))
 
 // R1055 forall-stmt -> FORALL concurrent-header forall-assignment-stmt
-TYPE_CONTEXT_PARSER("FORALL statement"_msg,
+TYPE_CONTEXT_PARSER("FORALL statement"_en_US,
     "FORALL" >> construct<ForallStmt>{}(
                     indirect(concurrentHeader), forallAssignmentStmt))
 
@@ -2203,13 +2203,13 @@ TYPE_CONTEXT_PARSER("FORALL statement"_msg,
 constexpr auto block = many(executionPartConstruct);
 
 // R1102 associate-construct -> associate-stmt block end-associate-stmt
-TYPE_CONTEXT_PARSER("ASSOCIATE construct"_msg,
+TYPE_CONTEXT_PARSER("ASSOCIATE construct"_en_US,
     construct<AssociateConstruct>{}(statement(Parser<AssociateStmt>{}), block,
         statement(Parser<EndAssociateStmt>{})))
 
 // R1103 associate-stmt ->
 //        [associate-construct-name :] ASSOCIATE ( association-list )
-TYPE_CONTEXT_PARSER("ASSOCIATE statement"_msg,
+TYPE_CONTEXT_PARSER("ASSOCIATE statement"_en_US,
     construct<AssociateStmt>{}(maybe(name / ":"),
         "ASSOCIATE" >> parenthesized(nonemptyList(Parser<Association>{}))))
 
@@ -2225,7 +2225,7 @@ 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"_msg,
+TYPE_CONTEXT_PARSER("BLOCK construct"_en_US,
     construct<BlockConstruct>{}(statement(Parser<BlockStmt>{}),
         Parser<BlockSpecificationPart>{},  // can be empty
         block, statement(Parser<EndBlockStmt>{})))
@@ -2249,14 +2249,14 @@ TYPE_PARSER(construct<BlockSpecificationPart>{}(specificationPart))
 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"_msg,
+TYPE_CONTEXT_PARSER("CHANGE TEAM construct"_en_US,
     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"_msg,
+TYPE_CONTEXT_PARSER("CHANGE TEAM statement"_en_US,
     construct<ChangeTeamStmt>{}(maybe(name / ":"),
         "CHANGE TEAM (" >> teamVariable,
         defaulted("," >> nonemptyList(Parser<CoarrayAssociation>{})),
@@ -2269,19 +2269,19 @@ TYPE_PARSER(construct<CoarrayAssociation>{}(
 
 // R1114 end-change-team-stmt ->
 //         END TEAM [( [sync-stat-list] )] [team-construct-name]
-TYPE_CONTEXT_PARSER("END CHANGE TEAM statement"_msg,
+TYPE_CONTEXT_PARSER("END CHANGE TEAM statement"_en_US,
     "END TEAM" >>
         construct<EndChangeTeamStmt>{}(
             defaulted(parenthesized(optionalList(statOrErrmsg))), maybe(name)))
 
 // R1117 critical-stmt ->
 //         [critical-construct-name :] CRITICAL [( [sync-stat-list] )]
-TYPE_CONTEXT_PARSER("CRITICAL statement"_msg,
+TYPE_CONTEXT_PARSER("CRITICAL statement"_en_US,
     construct<CriticalStmt>{}(maybe(name / ":"),
         "CRITICAL" >> defaulted(parenthesized(optionalList(statOrErrmsg)))))
 
 // R1116 critical-construct -> critical-stmt block end-critical-stmt
-TYPE_CONTEXT_PARSER("CRITICAL construct"_msg,
+TYPE_CONTEXT_PARSER("CRITICAL construct"_en_US,
     construct<CriticalConstruct>{}(statement(Parser<CriticalStmt>{}), block,
         statement(Parser<EndCriticalStmt>{})))
 
@@ -2310,7 +2310,7 @@ constexpr struct LeaveDoConstruct {
   }
 } leaveDoConstruct;
 
-TYPE_CONTEXT_PARSER("DO construct"_msg,
+TYPE_CONTEXT_PARSER("DO construct"_en_US,
     construct<DoConstruct>{}(
         statement(Parser<NonLabelDoStmt>{}) / enterNonlabelDoConstruct, block,
         statement(endDoStmt) / leaveDoConstruct))
@@ -2349,7 +2349,7 @@ TYPE_PARSER(
 //         [,] WHILE ( scalar-logical-expr ) |
 //         [,] CONCURRENT concurrent-header concurrent-locality
 // R1129 concurrent-locality -> [locality-spec]...
-TYPE_CONTEXT_PARSER("loop control"_msg,
+TYPE_CONTEXT_PARSER("loop control"_en_US,
     maybe(","_tok) >>
         (construct<LoopControl>{}(loopBounds(scalarIntExpr)) ||
             "WHILE" >>
@@ -2359,21 +2359,21 @@ TYPE_CONTEXT_PARSER("loop control"_msg,
                     concurrentHeader, many(Parser<LocalitySpec>{})))))
 
 // R1121 label-do-stmt -> [do-construct-name :] DO label [loop-control]
-TYPE_CONTEXT_PARSER("label DO statement"_msg,
+TYPE_CONTEXT_PARSER("label DO statement"_en_US,
     construct<LabelDoStmt>{}(
         maybe(name / ":"), "DO" >> label, maybe(loopControl)))
 
 // R1122 nonlabel-do-stmt -> [do-construct-name :] DO [loop-control]
-TYPE_CONTEXT_PARSER("nonlabel DO statement"_msg,
+TYPE_CONTEXT_PARSER("nonlabel DO statement"_en_US,
     construct<NonLabelDoStmt>{}(maybe(name / ":"), "DO" >> maybe(loopControl)))
 
 // R1132 end-do-stmt -> END DO [do-construct-name]
 TYPE_CONTEXT_PARSER(
-    "END DO statement"_msg, "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"_msg, "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]...
@@ -2383,7 +2383,7 @@ TYPE_CONTEXT_PARSER(
 //         ELSE IF ( scalar-logical-expr ) THEN [if-construct-name]
 // R1137 else-stmt -> ELSE [if-construct-name]
 // R1138 end-if-stmt -> END IF [if-construct-name]
-TYPE_CONTEXT_PARSER("IF construct"_msg,
+TYPE_CONTEXT_PARSER("IF construct"_en_US,
     construct<IfConstruct>{}(
         statement(construct<IfThenStmt>{}(maybe(name / ":"),
             "IF" >> parenthesized(scalarLogicalExpr) / "THEN")),
@@ -2398,12 +2398,12 @@ TYPE_CONTEXT_PARSER("IF construct"_msg,
         statement(construct<EndIfStmt>{}("END IF" >> maybe(name)))))
 
 // R1139 if-stmt -> IF ( scalar-logical-expr ) action-stmt
-TYPE_CONTEXT_PARSER("IF statement"_msg,
+TYPE_CONTEXT_PARSER("IF statement"_en_US,
     "IF" >> construct<IfStmt>{}(parenthesized(scalarLogicalExpr), actionStmt))
 
 // R1140 case-construct ->
 //         select-case-stmt [case-stmt block]... end-select-stmt
-TYPE_CONTEXT_PARSER("SELECT CASE construct"_msg,
+TYPE_CONTEXT_PARSER("SELECT CASE construct"_en_US,
     construct<CaseConstruct>{}(statement(Parser<SelectCaseStmt>{}),
         many(construct<CaseConstruct::Case>{}(
             statement(Parser<CaseStmt>{}), block)),
@@ -2411,12 +2411,12 @@ TYPE_CONTEXT_PARSER("SELECT CASE construct"_msg,
 
 // R1141 select-case-stmt -> [case-construct-name :] SELECT CASE ( case-expr
 // ) R1144 case-expr -> scalar-expr
-TYPE_CONTEXT_PARSER("SELECT CASE statement"_msg,
+TYPE_CONTEXT_PARSER("SELECT CASE statement"_en_US,
     construct<SelectCaseStmt>{}(
         maybe(name / ":"), "SELECT CASE" >> parenthesized(scalar(expr))))
 
 // R1142 case-stmt -> CASE case-selector [case-construct-name]
-TYPE_CONTEXT_PARSER("CASE statement"_msg,
+TYPE_CONTEXT_PARSER("CASE statement"_en_US,
     "CASE" >> construct<CaseStmt>{}(Parser<CaseSelector>{}, maybe(name)))
 
 // R1143 end-select-stmt -> END SELECT [case-construct-name]
@@ -2446,7 +2446,7 @@ TYPE_PARSER(construct<CaseValueRange>{}(construct<CaseValueRange::Range>{}(
 // R1148 select-rank-construct ->
 //         select-rank-stmt [select-rank-case-stmt block]...
 //         end-select-rank-stmt
-TYPE_CONTEXT_PARSER("SELECT RANK construct"_msg,
+TYPE_CONTEXT_PARSER("SELECT RANK construct"_en_US,
     construct<SelectRankConstruct>{}(statement(Parser<SelectRankStmt>{}),
         many(construct<SelectRankConstruct::RankCase>{}(
             statement(Parser<SelectRankCaseStmt>{}), block)),
@@ -2455,7 +2455,7 @@ TYPE_CONTEXT_PARSER("SELECT RANK construct"_msg,
 // R1149 select-rank-stmt ->
 //         [select-construct-name :] SELECT RANK
 //         ( [associate-name =>] selector )
-TYPE_CONTEXT_PARSER("SELECT RANK statement"_msg,
+TYPE_CONTEXT_PARSER("SELECT RANK statement"_en_US,
     construct<SelectRankStmt>{}(maybe(name / ":"),
         "SELECT RANK (" >> maybe(name / "=>"), selector / ")"))
 
@@ -2463,7 +2463,7 @@ TYPE_CONTEXT_PARSER("SELECT RANK statement"_msg,
 //         RANK ( scalar-int-constant-expr ) [select-construct-name] |
 //         RANK ( * ) [select-construct-name] |
 //         RANK DEFAULT [select-construct-name]
-TYPE_CONTEXT_PARSER("RANK case statement"_msg,
+TYPE_CONTEXT_PARSER("RANK case statement"_en_US,
     "RANK" >> (construct<SelectRankCaseStmt>{}(
                   parenthesized(construct<SelectRankCaseStmt::Rank>{}(
                                     scalarIntConstantExpr) ||
@@ -2473,7 +2473,7 @@ TYPE_CONTEXT_PARSER("RANK case statement"_msg,
 
 // R1152 select-type-construct ->
 //         select-type-stmt [type-guard-stmt block]... end-select-type-stmt
-TYPE_CONTEXT_PARSER("SELECT TYPE construct"_msg,
+TYPE_CONTEXT_PARSER("SELECT TYPE construct"_en_US,
     construct<SelectTypeConstruct>{}(statement(Parser<SelectTypeStmt>{}),
         many(construct<SelectTypeConstruct::TypeCase>{}(
             statement(Parser<TypeGuardStmt>{}), block)),
@@ -2482,7 +2482,7 @@ TYPE_CONTEXT_PARSER("SELECT TYPE construct"_msg,
 // R1153 select-type-stmt ->
 //         [select-construct-name :] SELECT TYPE
 //         ( [associate-name =>] selector )
-TYPE_CONTEXT_PARSER("SELECT TYPE statement"_msg,
+TYPE_CONTEXT_PARSER("SELECT TYPE statement"_en_US,
     construct<SelectTypeStmt>{}(maybe(name / ":"),
         "SELECT TYPE (" >> maybe(name / "=>"), selector / ")"))
 
@@ -2490,7 +2490,7 @@ TYPE_CONTEXT_PARSER("SELECT TYPE statement"_msg,
 //         TYPE IS ( type-spec ) [select-construct-name] |
 //         CLASS IS ( derived-type-spec ) [select-construct-name] |
 //         CLASS DEFAULT [select-construct-name]
-TYPE_CONTEXT_PARSER("type guard statement"_msg,
+TYPE_CONTEXT_PARSER("type guard statement"_en_US,
     construct<TypeGuardStmt>{}("TYPE IS" >>
                 parenthesized(construct<TypeGuardStmt::Guard>{}(typeSpec)) ||
             "CLASS IS" >> parenthesized(construct<TypeGuardStmt::Guard>{}(
@@ -2500,21 +2500,21 @@ TYPE_CONTEXT_PARSER("type guard statement"_msg,
 
 // R1156 exit-stmt -> EXIT [construct-name]
 TYPE_CONTEXT_PARSER(
-    "EXIT statement"_msg, "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"_msg, "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"_msg,
+TYPE_CONTEXT_PARSER("computed GOTO statement"_en_US,
     "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"_msg,
+TYPE_CONTEXT_PARSER("STOP statement"_en_US,
     construct<StopStmt>{}("STOP" >> pure(StopStmt::Kind::Stop) ||
             "ERROR STOP" >> pure(StopStmt::Kind::ErrorStop),
         maybe(Parser<StopCode>{}), maybe(", QUIET =" >> scalarLogicalExpr)))
@@ -2524,37 +2524,37 @@ TYPE_PARSER(construct<StopCode>{}(scalarDefaultCharExpr) ||
     construct<StopCode>{}(scalarIntExpr))
 
 // R1164 sync-all-stmt -> SYNC ALL [( [sync-stat-list] )]
-TYPE_CONTEXT_PARSER("SYNC ALL statement"_msg,
+TYPE_CONTEXT_PARSER("SYNC ALL statement"_en_US,
     "SYNC ALL" >> 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"_msg,
+TYPE_CONTEXT_PARSER("SYNC IMAGES statement"_en_US,
     "SYNC IMAGES" >> 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"_msg,
+TYPE_CONTEXT_PARSER("SYNC MEMORY statement"_en_US,
     "SYNC MEMORY" >> construct<SyncMemoryStmt>{}(
                          defaulted(parenthesized(optionalList(statOrErrmsg)))))
 
 // R1169 sync-team-stmt -> SYNC TEAM ( team-variable [, sync-stat-list] )
-TYPE_CONTEXT_PARSER("SYNC TEAM statement"_msg,
+TYPE_CONTEXT_PARSER("SYNC TEAM statement"_en_US,
     "SYNC TEAM" >> 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"_msg,
+TYPE_CONTEXT_PARSER("EVENT POST statement"_en_US,
     "EVENT POST" >> 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"_msg,
+TYPE_CONTEXT_PARSER("EVENT WAIT statement"_en_US,
     "EVENT WAIT" >>
         parenthesized(construct<EventWaitStmt>{}(scalar(variable),
             defaulted(
@@ -2570,7 +2570,7 @@ TYPE_PARSER(construct<EventWaitStmt::EventWaitSpec>{}(untilSpec) ||
 // 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"_msg,
+TYPE_CONTEXT_PARSER("FORM TEAM statement"_en_US,
     "FORM TEAM" >>
         parenthesized(construct<FormTeamStmt>{}(scalarIntExpr,
             "," >> teamVariable,
@@ -2586,7 +2586,7 @@ TYPE_PARSER(
 constexpr auto lockVariable = scalar(variable);
 
 // R1178 lock-stmt -> LOCK ( lock-variable [, lock-stat-list] )
-TYPE_CONTEXT_PARSER("LOCK statement"_msg,
+TYPE_CONTEXT_PARSER("LOCK statement"_en_US,
     "LOCK" >>
         parenthesized(construct<LockStmt>{}(lockVariable,
             defaulted("," >> nonemptyList(Parser<LockStmt::LockStat>{})))))
@@ -2597,7 +2597,7 @@ TYPE_PARSER("ACQUIRED_LOCK =" >>
     construct<LockStmt::LockStat>{}(statOrErrmsg))
 
 // R1180 unlock-stmt -> UNLOCK ( lock-variable [, sync-stat-list] )
-TYPE_CONTEXT_PARSER("UNLOCK statement"_msg,
+TYPE_CONTEXT_PARSER("UNLOCK statement"_en_US,
     "UNLOCK" >> parenthesized(construct<UnlockStmt>{}(lockVariable,
                     defaulted("," >> nonemptyList(statOrErrmsg)))))
 
@@ -2610,7 +2610,7 @@ TYPE_PARSER(construct<IoUnit>{}(fileUnitNumber) || construct<IoUnit>{}(star) ||
 TYPE_PARSER(construct<FileUnitNumber>{}(scalarIntExpr / !"="_tok))
 
 // R1204 open-stmt -> OPEN ( connect-spec-list )
-TYPE_CONTEXT_PARSER("OPEN statement"_msg,
+TYPE_CONTEXT_PARSER("OPEN statement"_en_US,
     "OPEN" >> parenthesized(
                   construct<OpenStmt>{}(nonemptyList(Parser<ConnectSpec>{}))))
 
@@ -2697,7 +2697,7 @@ constexpr auto closeSpec = maybe("UNIT ="_tok) >>
     "STATUS =" >> construct<CloseStmt::CloseSpec>{}(statusExpr);
 
 // R1208 close-stmt -> CLOSE ( close-spec-list )
-TYPE_CONTEXT_PARSER("CLOSE statement"_msg,
+TYPE_CONTEXT_PARSER("CLOSE statement"_en_US,
     "CLOSE" >> construct<CloseStmt>{}(parenthesized(nonemptyList(closeSpec))))
 
 // R1210 read-stmt ->
@@ -2707,7 +2707,7 @@ constexpr auto inputItemList =
     extension(some("," >> inputItem)) ||  // legacy extension: leading comma
     optionalList(inputItem);
 
-TYPE_CONTEXT_PARSER("READ statement"_msg,
+TYPE_CONTEXT_PARSER("READ statement"_en_US,
     "READ" >>
         ("(" >> construct<ReadStmt>{}(construct<std::optional<IoUnit>>{}(
                                           maybe("UNIT ="_tok) >> ioUnit),
@@ -2793,7 +2793,7 @@ constexpr auto outputItemList =
     extension(some("," >> outputItem)) ||  // legacy: allow leading comma
     optionalList(outputItem);
 
-TYPE_CONTEXT_PARSER("WRITE statement"_msg,
+TYPE_CONTEXT_PARSER("WRITE statement"_en_US,
     "WRITE" >>
         (construct<WriteStmt>{}("(" >> construct<std::optional<IoUnit>>{}(
                                            maybe("UNIT ="_tok) >> ioUnit),
@@ -2810,7 +2810,7 @@ TYPE_CONTEXT_PARSER("WRITE statement"_msg,
                 parenthesized(nonemptyList(ioControlSpec)), outputItemList)))
 
 // R1212 print-stmt PRINT format [, output-item-list]
-TYPE_CONTEXT_PARSER("PRINT statement"_msg,
+TYPE_CONTEXT_PARSER("PRINT statement"_en_US,
     "PRINT" >> construct<PrintStmt>{}(
                    format, defaulted("," >> nonemptyList(outputItem))))
 
@@ -2832,17 +2832,17 @@ 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"_msg,
+TYPE_CONTEXT_PARSER("input implied DO"_en_US,
     parenthesized(construct<InputImpliedDo>{}(
         nonemptyList(inputItem / lookAhead(","_tok)),
         "," >> ioImpliedDoControl)))
-TYPE_CONTEXT_PARSER("output implied DO"_msg,
+TYPE_CONTEXT_PARSER("output implied DO"_en_US,
     parenthesized(construct<OutputImpliedDo>{}(
         nonemptyList(outputItem / lookAhead(","_tok)),
         "," >> ioImpliedDoControl)))
 
 // R1222 wait-stmt -> WAIT ( wait-spec-list )
-TYPE_CONTEXT_PARSER("WAIT statement"_msg,
+TYPE_CONTEXT_PARSER("WAIT statement"_en_US,
     "WAIT" >>
         parenthesized(construct<WaitStmt>{}(nonemptyList(Parser<WaitSpec>{}))))
 
@@ -2862,20 +2862,20 @@ TYPE_PARSER(maybe("UNIT ="_tok) >> construct<WaitSpec>{}(fileUnitNumber) ||
 
 // R1224 backspace-stmt ->
 //         BACKSPACE file-unit-number | BACKSPACE ( position-spec-list )
-TYPE_CONTEXT_PARSER("BACKSPACE statement"_msg,
+TYPE_CONTEXT_PARSER("BACKSPACE statement"_en_US,
     "BACKSPACE" >> (construct<BackspaceStmt>{}(fileUnitNumber) ||
                        construct<BackspaceStmt>{}(
                            parenthesized(nonemptyList(positionOrFlushSpec)))))
 
 // R1225 endfile-stmt ->
 //         ENDFILE file-unit-number | ENDFILE ( position-spec-list )
-TYPE_CONTEXT_PARSER("ENDFILE statement"_msg,
+TYPE_CONTEXT_PARSER("ENDFILE statement"_en_US,
     "ENDFILE" >> (construct<EndfileStmt>{}(fileUnitNumber) ||
                      construct<EndfileStmt>{}(
                          parenthesized(nonemptyList(positionOrFlushSpec)))))
 
 // R1226 rewind-stmt -> REWIND file-unit-number | REWIND ( position-spec-list )
-TYPE_CONTEXT_PARSER("REWIND statement"_msg,
+TYPE_CONTEXT_PARSER("REWIND statement"_en_US,
     "REWIND" >> (construct<RewindStmt>{}(fileUnitNumber) ||
                     construct<RewindStmt>{}(
                         parenthesized(nonemptyList(positionOrFlushSpec)))))
@@ -2893,7 +2893,7 @@ TYPE_PARSER(
     "ERR =" >> construct<PositionOrFlushSpec>{}(errLabel))
 
 // R1228 flush-stmt -> FLUSH file-unit-number | FLUSH ( flush-spec-list )
-TYPE_CONTEXT_PARSER("FLUSH statement"_msg,
+TYPE_CONTEXT_PARSER("FLUSH statement"_en_US,
     "FLUSH" >> (construct<FlushStmt>{}(fileUnitNumber) ||
                    construct<FlushStmt>{}(
                        parenthesized(nonemptyList(positionOrFlushSpec)))))
@@ -3031,7 +3031,7 @@ TYPE_PARSER(maybe("UNIT ="_tok) >> construct<InquireSpec>{}(fileUnitNumber) ||
 // R1230 inquire-stmt ->
 //         INQUIRE ( inquire-spec-list ) |
 //         INQUIRE ( IOLENGTH = scalar-int-variable ) output-item-list
-TYPE_CONTEXT_PARSER("INQUIRE statement"_msg,
+TYPE_CONTEXT_PARSER("INQUIRE statement"_en_US,
     "INQUIRE" >>
         (construct<InquireStmt>{}(
              parenthesized(nonemptyList(Parser<InquireSpec>{}))) ||
@@ -3188,33 +3188,33 @@ TYPE_PARSER(
 //         [program-stmt] [specification-part] [execution-part]
 //         [internal-subprogram-part] end-program-stmt
 // R1402 program-stmt -> PROGRAM program-name
-TYPE_CONTEXT_PARSER("main program"_msg,
+TYPE_CONTEXT_PARSER("main program"_en_US,
     construct<MainProgram>{}(maybe(statement("PROGRAM" >> name)),
         specificationPart, executionPart, maybe(internalSubprogramPart),
         unterminatedStatement(endProgramStmt)))
 
 // R1403 end-program-stmt -> END [PROGRAM [program-name]]
-TYPE_CONTEXT_PARSER("END PROGRAM statement"_msg,
+TYPE_CONTEXT_PARSER("END PROGRAM statement"_en_US,
     "END" >> construct<EndProgramStmt>{}(defaulted("PROGRAM" >> maybe(name))))
 
 // R1404 module ->
 //         module-stmt [specification-part] [module-subprogram-part]
 //         end-module-stmt
-TYPE_CONTEXT_PARSER("module"_msg,
+TYPE_CONTEXT_PARSER("module"_en_US,
     construct<Module>{}(statement(Parser<ModuleStmt>{}), specificationPart,
         maybe(Parser<ModuleSubprogramPart>{}),
         unterminatedStatement(Parser<EndModuleStmt>{})))
 
 // R1405 module-stmt -> MODULE module-name
 TYPE_CONTEXT_PARSER(
-    "MODULE statement"_msg, "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"_msg,
+TYPE_CONTEXT_PARSER("END MODULE statement"_en_US,
     "END" >> construct<EndModuleStmt>{}(defaulted("MODULE" >> maybe(name))))
 
 // R1407 module-subprogram-part -> contains-stmt [module-subprogram]...
-TYPE_CONTEXT_PARSER("module subprogram part"_msg,
+TYPE_CONTEXT_PARSER("module subprogram part"_en_US,
     construct<ModuleSubprogramPart>{}(statement(containsStmt),
         many(startNewSubprogram >> Parser<ModuleSubprogram>{})))
 
@@ -3257,13 +3257,13 @@ TYPE_PARSER(construct<Only>{}(Parser<Rename>{}) ||
 // R1416 submodule ->
 //         submodule-stmt [specification-part] [module-subprogram-part]
 //         end-submodule-stmt
-TYPE_CONTEXT_PARSER("submodule"_msg,
+TYPE_CONTEXT_PARSER("submodule"_en_US,
     construct<Submodule>{}(statement(Parser<SubmoduleStmt>{}),
         specificationPart, maybe(Parser<ModuleSubprogramPart>{}),
         statement(Parser<EndSubmoduleStmt>{})))
 
 // R1417 submodule-stmt -> SUBMODULE ( parent-identifier ) submodule-name
-TYPE_CONTEXT_PARSER("SUBMODULE statement"_msg,
+TYPE_CONTEXT_PARSER("SUBMODULE statement"_en_US,
     "SUBMODULE" >> construct<SubmoduleStmt>{}(
                        parenthesized(Parser<ParentIdentifier>{}), name))
 
@@ -3271,21 +3271,21 @@ TYPE_CONTEXT_PARSER("SUBMODULE statement"_msg,
 TYPE_PARSER(construct<ParentIdentifier>{}(name, maybe(":" >> name)))
 
 // R1419 end-submodule-stmt -> END [SUBMODULE [submodule-name]]
-TYPE_CONTEXT_PARSER("END SUBMODULE statement"_msg,
+TYPE_CONTEXT_PARSER("END SUBMODULE statement"_en_US,
     "END" >>
         construct<EndSubmoduleStmt>{}(defaulted("SUBMODULE" >> maybe(name))))
 
 // R1420 block-data -> block-data-stmt [specification-part] end-block-data-stmt
-TYPE_CONTEXT_PARSER("BLOCK DATA subprogram"_msg,
+TYPE_CONTEXT_PARSER("BLOCK DATA subprogram"_en_US,
     construct<BlockData>{}(statement(Parser<BlockDataStmt>{}),
         specificationPart, unterminatedStatement(Parser<EndBlockDataStmt>{})))
 
 // R1421 block-data-stmt -> BLOCK DATA [block-data-name]
-TYPE_CONTEXT_PARSER("BLOCK DATA statement"_msg,
+TYPE_CONTEXT_PARSER("BLOCK DATA statement"_en_US,
     "BLOCK DATA" >> construct<BlockDataStmt>{}(maybe(name)))
 
 // R1422 end-block-data-stmt -> END [BLOCK DATA [block-data-name]]
-TYPE_CONTEXT_PARSER("END BLOCK DATA statement"_msg,
+TYPE_CONTEXT_PARSER("END BLOCK DATA statement"_en_US,
     "END" >>
         construct<EndBlockDataStmt>{}(defaulted("BLOCK DATA" >> maybe(name))))
 
@@ -3310,7 +3310,7 @@ TYPE_PARSER(
 // R1505 interface-body ->
 //         function-stmt [specification-part] end-function-stmt |
 //         subroutine-stmt [specification-part] end-subroutine-stmt
-TYPE_CONTEXT_PARSER("interface body"_msg,
+TYPE_CONTEXT_PARSER("interface body"_en_US,
     construct<InterfaceBody>{}(
         construct<InterfaceBody::Function>{}(statement(functionStmt),
             indirect(specificationPart), statement(endFunctionStmt))) ||
@@ -3402,7 +3402,7 @@ TYPE_PARSER("INTRINSIC" >> maybe("::"_tok) >>
 template<>
 std::optional<FunctionReference> Parser<FunctionReference>::Parse(
     ParseState *state) {
-  state->PushContext("function reference"_msg);
+  state->PushContext("function reference"_en_US);
   std::optional<Variable> var{variable.Parse(state)};
   if (var.has_value()) {
     if (auto funcref = std::get_if<Indirection<FunctionReference>>(&var->u)) {
@@ -3419,7 +3419,7 @@ std::optional<FunctionReference> Parser<FunctionReference>::Parse(
         return {FunctionReference{std::move(call.value())}};
       }
     }
-    state->PutMessage("expected (arguments)"_msg);
+    state->PutMessage("expected (arguments)"_en_US);
   }
   state->PopContext();
   return {};
@@ -3428,7 +3428,7 @@ std::optional<FunctionReference> Parser<FunctionReference>::Parse(
 // R1521 call-stmt -> CALL procedure-designator [( [actual-arg-spec-list] )]
 template<> std::optional<CallStmt> Parser<CallStmt>::Parse(ParseState *state) {
   static constexpr auto parser =
-      inContext("CALL statement"_msg, "CALL" >> variable);
+      inContext("CALL statement"_en_US, "CALL" >> variable);
   std::optional<Variable> var{parser.Parse(state)};
   if (var.has_value()) {
     if (auto funcref = std::get_if<Indirection<FunctionReference>>(&var->u)) {
@@ -3487,7 +3487,7 @@ TYPE_PARSER(construct<PrefixSpec>{}(declarationTypeSpec) ||
 // R1529 function-subprogram ->
 //         function-stmt [specification-part] [execution-part]
 //         [internal-subprogram-part] end-function-stmt
-TYPE_CONTEXT_PARSER("FUNCTION subprogram"_msg,
+TYPE_CONTEXT_PARSER("FUNCTION subprogram"_en_US,
     construct<FunctionSubprogram>{}(statement(functionStmt), specificationPart,
         executionPart, maybe(internalSubprogramPart),
         unterminatedStatement(endFunctionStmt)))
@@ -3496,7 +3496,7 @@ TYPE_CONTEXT_PARSER("FUNCTION subprogram"_msg,
 //         [prefix] FUNCTION function-name ( [dummy-arg-name-list] ) [suffix]
 // R1526 prefix -> prefix-spec [prefix-spec]...
 // R1531 dummy-arg-name -> name
-TYPE_CONTEXT_PARSER("FUNCTION statement"_msg,
+TYPE_CONTEXT_PARSER("FUNCTION statement"_en_US,
     construct<FunctionStmt>{}(many(prefixSpec), "FUNCTION" >> name,
         parenthesized(optionalList(name)), maybe(suffix)) ||
         extension(construct<FunctionStmt>{}(  // PGI & Intel accept "FUNCTION F"
@@ -3518,7 +3518,7 @@ TYPE_PARSER(
 // R1534 subroutine-subprogram ->
 //         subroutine-stmt [specification-part] [execution-part]
 //         [internal-subprogram-part] end-subroutine-stmt
-TYPE_CONTEXT_PARSER("SUBROUTINE subprogram"_msg,
+TYPE_CONTEXT_PARSER("SUBROUTINE subprogram"_en_US,
     construct<SubroutineSubprogram>{}(statement(subroutineStmt),
         specificationPart, executionPart, maybe(internalSubprogramPart),
         unterminatedStatement(endSubroutineStmt)))
@@ -3543,17 +3543,17 @@ TYPE_PARSER("END" >>
 // R1538 separate-module-subprogram ->
 //         mp-subprogram-stmt [specification-part] [execution-part]
 //         [internal-subprogram-part] end-mp-subprogram-stmt
-TYPE_CONTEXT_PARSER("separate module subprogram"_msg,
+TYPE_CONTEXT_PARSER("separate module subprogram"_en_US,
     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"_msg,
+TYPE_CONTEXT_PARSER("MODULE PROCEDURE statement"_en_US,
     construct<MpSubprogramStmt>{}("MODULE PROCEDURE" >> name))
 
 // R1540 end-mp-subprogram-stmt -> END [PROCEDURE [procedure-name]]
-TYPE_CONTEXT_PARSER("END PROCEDURE statement"_msg,
+TYPE_CONTEXT_PARSER("END PROCEDURE statement"_en_US,
     "END" >>
         construct<EndMpSubprogramStmt>{}(defaulted("PROCEDURE" >> maybe(name))))
 
@@ -3565,7 +3565,7 @@ TYPE_PARSER("ENTRY" >>
             construct<std::optional<Suffix>>{})))
 
 // R1542 return-stmt -> RETURN [scalar-int-expr]
-TYPE_CONTEXT_PARSER("RETURN statement"_msg,
+TYPE_CONTEXT_PARSER("RETURN statement"_en_US,
     "RETURN" >> construct<ReturnStmt>{}(maybe(scalarIntExpr)))
 
 // R1543 contains-stmt -> CONTAINS
@@ -3595,35 +3595,35 @@ TYPE_PARSER(
     construct<StructureField>{}(indirect(Parser<Union>{})) ||
     construct<StructureField>{}(indirect(Parser<StructureDef>{})))
 
-TYPE_CONTEXT_PARSER("STRUCTURE definition"_msg,
+TYPE_CONTEXT_PARSER("STRUCTURE definition"_en_US,
     extension(construct<StructureDef>{}(statement(Parser<StructureStmt>{}),
         many(Parser<StructureField>{}),
         statement(
             "END STRUCTURE" >> construct<StructureDef::EndStructureStmt>{}))))
 
-TYPE_CONTEXT_PARSER("UNION definition"_msg,
+TYPE_CONTEXT_PARSER("UNION definition"_en_US,
     construct<Union>{}(statement("UNION" >> construct<Union::UnionStmt>{}),
         many(Parser<Map>{}),
         statement("END UNION" >> construct<Union::EndUnionStmt>{})))
 
-TYPE_CONTEXT_PARSER("MAP definition"_msg,
+TYPE_CONTEXT_PARSER("MAP definition"_en_US,
     construct<Map>{}(statement("MAP" >> construct<Map::MapStmt>{}),
         many(Parser<StructureField>{}),
         statement("END MAP" >> construct<Map::EndMapStmt>{})))
 
-TYPE_CONTEXT_PARSER("arithmetic IF statement"_msg,
+TYPE_CONTEXT_PARSER("arithmetic IF statement"_en_US,
     deprecated("IF" >> construct<ArithmeticIfStmt>{}(parenthesized(expr),
                            label / ",", label / ",", label)))
 
-TYPE_CONTEXT_PARSER("ASSIGN statement"_msg,
+TYPE_CONTEXT_PARSER("ASSIGN statement"_en_US,
     deprecated("ASSIGN" >> construct<AssignStmt>{}(label, "TO" >> name)))
 
-TYPE_CONTEXT_PARSER("assigned GOTO statement"_msg,
+TYPE_CONTEXT_PARSER("assigned GOTO statement"_en_US,
     deprecated("GO TO" >>
         construct<AssignedGotoStmt>{}(name,
             defaulted(maybe(","_tok) >> parenthesized(nonemptyList(label))))))
 
-TYPE_CONTEXT_PARSER("PAUSE statement"_msg,
+TYPE_CONTEXT_PARSER("PAUSE statement"_en_US,
     deprecated("PAUSE" >> construct<PauseStmt>{}(maybe(Parser<StopCode>{}))))
 
 // These requirement productions are defined by the Fortran standard but never
index e07d231..67591c2 100644 (file)
@@ -3,7 +3,7 @@
 namespace Fortran {
 namespace parser {
 
-std::ostream &operator<<(std::ostream &o, const MessageText &t) {
+std::ostream &operator<<(std::ostream &o, const MessageFixedText &t) {
   for (size_t j{0}; j < t.size(); ++j) {
     o << t.str()[j];
   }
index 4932a3d..f4f9830 100644 (file)
 namespace Fortran {
 namespace parser {
 
-class Message;
-using MessageContext = std::shared_ptr<Message>;
-
-class MessageText {
+// Use "..."_en_US literals to define the static text of a message.
+class MessageFixedText {
 public:
-  MessageText() {}
-  constexpr MessageText(const char str[], size_t n) : str_{str}, bytes_{n} {}
-  constexpr MessageText(const MessageText &) = default;
-  MessageText(MessageText &&) = default;
-  constexpr MessageText &operator=(const MessageText &) = default;
-  MessageText &operator=(MessageText &&) = default;
+  MessageFixedText() {}
+  constexpr MessageFixedText(const char str[], size_t n)
+    : str_{str}, bytes_{n} {}
+  constexpr MessageFixedText(const MessageFixedText &) = default;
+  MessageFixedText(MessageFixedText &&) = default;
+  constexpr MessageFixedText &operator=(const MessageFixedText &) = default;
+  MessageFixedText &operator=(MessageFixedText &&) = default;
 
   const char *str() const { return str_; }
   size_t size() const { return bytes_; }
@@ -38,17 +37,20 @@ private:
   size_t bytes_{0};
 };
 
-constexpr MessageText operator""_msg(const char str[], size_t n) {
-  return MessageText{str, n};
+constexpr MessageFixedText operator""_en_US(const char str[], size_t n) {
+  return MessageFixedText{str, n};
 }
 
-std::ostream &operator<<(std::ostream &, const MessageText &);
+std::ostream &operator<<(std::ostream &, const MessageFixedText &);
+
+class Message;
+using MessageContext = std::shared_ptr<Message>;
 
 class Message {
 public:
   Message() {}
   Message(const Message &) = default;
-  Message(Provenance p, MessageText t, MessageContext c = nullptr)
+  Message(Provenance p, MessageFixedText t, MessageContext c = nullptr)
     : provenance_{p}, text_{t}, context_{c} {}
   Message(Message &&) = default;
   Message &operator=(const Message &that) = default;
@@ -59,12 +61,8 @@ public:
   }
 
   Provenance provenance() const { return provenance_; }
-  MessageText text() const { return text_; }
+  MessageFixedText text() const { return text_; }
   std::string extra() const { return extra_; }
-  Message &set_extra(std::string &&s) {
-    extra_ = std::move(s);
-    return *this;
-  }
   MessageContext context() const { return context_; }
 
   Message &operator+=(std::string s) {
@@ -77,7 +75,7 @@ public:
 
 private:
   Provenance provenance_;
-  MessageText text_;
+  MessageFixedText text_;
   std::string extra_;
   MessageContext context_;
 };
index cab3021..e6a79d3 100644 (file)
@@ -115,7 +115,7 @@ public:
   }
   Provenance GetProvenance() const { return GetProvenance(p_); }
 
-  MessageContext &PushContext(MessageText text) {
+  MessageContext &PushContext(MessageFixedText text) {
     context_ = std::make_shared<Message>(GetProvenance(), text, context_);
     return context_;
   }
@@ -126,11 +126,11 @@ public:
     }
   }
 
-  Message &PutMessage(MessageText t) { return PutMessage(p_, t); }
-  Message &PutMessage(const char *at, MessageText t) {
+  Message &PutMessage(MessageFixedText t) { return PutMessage(p_, t); }
+  Message &PutMessage(const char *at, MessageFixedText t) {
     return PutMessage(GetProvenance(at), t);
   }
-  Message &PutMessage(Provenance at, MessageText t) {
+  Message &PutMessage(Provenance at, MessageFixedText t) {
     return messages_.Put(Message{at, t, context_});
   }
 
index 7b08d9f..d07be68 100644 (file)
@@ -1,6 +1,6 @@
-#include "message.h"
 #include "preprocessor.h"
 #include "idioms.h"
+#include "message.h"
 #include "prescan.h"
 #include <algorithm>
 #include <cctype>
@@ -371,7 +371,7 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
     return true;
   }
   if (dir[j].ToString() != "#") {
-    prescanner->Complain("missing '#'"_msg);
+    prescanner->Complain("missing '#'"_en_US);
     return false;
   }
   j = SkipBlanks(dir, j + 1, tokens);
@@ -393,7 +393,7 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
   }
   if (dirName == "define") {
     if (nameToken.empty()) {
-      prescanner->Complain("#define: missing or invalid name"_msg);
+      prescanner->Complain("#define: missing or invalid name"_en_US);
       return false;
     }
     nameToken = SaveTokenAsName(nameToken);
@@ -409,14 +409,15 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
             isVariadic = true;
           } else {
             if (an.empty() || !IsIdentifierFirstCharacter(an[0])) {
-              prescanner->Complain("#define: missing or invalid argument name"_msg);
+              prescanner->Complain(
+                  "#define: missing or invalid argument name"_en_US);
               return false;
             }
             argName.push_back(an);
           }
           j = SkipBlanks(dir, j + 1, tokens);
           if (j == tokens) {
-            prescanner->Complain("#define: malformed argument list"_msg);
+            prescanner->Complain("#define: malformed argument list"_en_US);
             return false;
           }
           std::string punc{dir[j].ToString()};
@@ -424,18 +425,19 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
             break;
           }
           if (punc != ",") {
-            prescanner->Complain("#define: malformed argument list"_msg);
+            prescanner->Complain("#define: malformed argument list"_en_US);
             return false;
           }
           j = SkipBlanks(dir, j + 1, tokens);
           if (j == tokens || isVariadic) {
-            prescanner->Complain("#define: malformed argument list"_msg);
+            prescanner->Complain("#define: malformed argument list"_en_US);
             return false;
           }
         }
         if (std::set<std::string>(argName.begin(), argName.end()).size() !=
             argName.size()) {
-          prescanner->Complain("#define: argument names are not distinct"_msg);
+          prescanner->Complain(
+              "#define: argument names are not distinct"_en_US);
           return false;
         }
       }
@@ -451,12 +453,12 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
   }
   if (dirName == "undef") {
     if (nameToken.empty()) {
-      prescanner->Complain("# missing or invalid name"_msg);
+      prescanner->Complain("# missing or invalid name"_en_US);
       return false;
     }
     j = SkipBlanks(dir, j + 1, tokens);
     if (j != tokens) {
-      prescanner->Complain("#undef: excess tokens at end of directive"_msg);
+      prescanner->Complain("#undef: excess tokens at end of directive"_en_US);
       return false;
     }
     definitions_.erase(nameToken);
@@ -464,12 +466,13 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
   }
   if (dirName == "ifdef" || dirName == "ifndef") {
     if (nameToken.empty()) {
-      prescanner->Complain("#"_msg) += dirName + ": missing name";
+      prescanner->Complain("#"_en_US) += dirName + ": missing name";
       return false;
     }
     j = SkipBlanks(dir, j + 1, tokens);
     if (j != tokens) {
-      prescanner->Complain("#"_msg) += dirName + ": excess tokens at end of directive";
+      prescanner->Complain("#"_en_US) +=
+          dirName + ": excess tokens at end of directive";
       return false;
     }
     if (IsNameDefined(nameToken) == (dirName == "ifdef")) {
@@ -487,16 +490,17 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
   }
   if (dirName == "else") {
     if (j != tokens) {
-      prescanner->Complain("#else: excess tokens at end of directive"_msg);
+      prescanner->Complain("#else: excess tokens at end of directive"_en_US);
       return false;
     }
     if (ifStack_.empty()) {
-      prescanner->Complain("#else: not nested within #if, #ifdef, or #ifndef"_msg);
+      prescanner->Complain(
+          "#else: not nested within #if, #ifdef, or #ifndef"_en_US);
       return false;
     }
     if (ifStack_.top() != CanDeadElseAppear::Yes) {
       prescanner->Complain(
-          "#else: already appeared within this #if, #ifdef, or #ifndef"_msg);
+          "#else: already appeared within this #if, #ifdef, or #ifndef"_en_US);
       return false;
     }
     ifStack_.pop();
@@ -504,12 +508,13 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
   }
   if (dirName == "elif") {
     if (ifStack_.empty()) {
-      prescanner->Complain("#elif: not nested within #if, #ifdef, or #ifndef"_msg);
+      prescanner->Complain(
+          "#elif: not nested within #if, #ifdef, or #ifndef"_en_US);
       return false;
     }
     if (ifStack_.top() != CanDeadElseAppear::Yes) {
       prescanner->Complain("#elif: #else previously appeared within this "
-                           "#if, #ifdef, or #ifndef"_msg);
+                           "#if, #ifdef, or #ifndef"_en_US);
       return false;
     }
     ifStack_.pop();
@@ -517,33 +522,34 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
   }
   if (dirName == "endif") {
     if (j != tokens) {
-      prescanner->Complain("#endif: excess tokens at end of directive"_msg);
+      prescanner->Complain("#endif: excess tokens at end of directive"_en_US);
       return false;
     }
     if (ifStack_.empty()) {
-      prescanner->Complain("#endif: no #if, #ifdef, or #ifndef"_msg);
+      prescanner->Complain("#endif: no #if, #ifdef, or #ifndef"_en_US);
       return false;
     }
     ifStack_.pop();
     return true;
   }
   if (dirName == "error") {
-    prescanner->Complain("#error: "_msg) += dir.ToString();
+    prescanner->Complain("#error: "_en_US) += dir.ToString();
     return false;
   }
   if (dirName == "warning") {
-    prescanner->Complain("#warning: "_msg) += dir.ToString();
+    prescanner->Complain("#warning: "_en_US) += dir.ToString();
     return true;
   }
   if (dirName == "include") {
     if (j == tokens) {
-      prescanner->Complain("#include: missing name of file to include"_msg);
+      prescanner->Complain("#include: missing name of file to include"_en_US);
       return false;
     }
     std::string include;
     if (dir[j].ToString() == "<") {
       if (dir[tokens - 1].ToString() != ">") {
-        prescanner->Complain("#include: expected '>' at end of directive"_msg);
+        prescanner->Complain(
+            "#include: expected '>' at end of directive"_en_US);
         return false;
       }
       TokenSequence braced{dir, j + 1, tokens - j - 2};
@@ -553,24 +559,25 @@ bool Preprocessor::Directive(const TokenSequence &dir, Prescanner *prescanner) {
         include.substr(include.size() - 1, 1) == "\"") {
       include = include.substr(1, include.size() - 2);
     } else {
-      prescanner->Complain("#include: expected name of file to include"_msg);
+      prescanner->Complain("#include: expected name of file to include"_en_US);
       return false;
     }
     if (include.empty()) {
-      prescanner->Complain("#include: empty include file name"_msg);
+      prescanner->Complain("#include: empty include file name"_en_US);
       return false;
     }
     std::stringstream error;
     const SourceFile *included{allSources_->Open(include, &error)};
     if (included == nullptr) {
-      prescanner->Complain("#include: "_msg) += error.str();
+      prescanner->Complain("#include: "_en_US) += error.str();
       return false;
     }
     ProvenanceRange fileRange{
         allSources_->AddIncludedFile(*included, dir.GetProvenanceRange())};
     return Prescanner{*prescanner}.Prescan(fileRange);
   }
-  prescanner->Complain("#"_msg) += dirName + ": unknown or unimplemented directive";
+  prescanner->Complain("#"_en_US) +=
+      dirName + ": unknown or unimplemented directive";
   return false;
 }
 
@@ -608,7 +615,7 @@ bool Preprocessor::SkipDisabledConditionalCode(const std::string &dirName,
       }
     }
   }
-  prescanner->Complain("#"_msg) += dirName + ": missing #endif";
+  prescanner->Complain("#"_en_US) += dirName + ": missing #endif";
   return false;
 }
 
@@ -630,7 +637,7 @@ bool Preprocessor::SkipDisabledConditionalCode(const std::string &dirName,
 //  1: ? :
 //  0: ,
 static std::int64_t ExpressionValue(const TokenSequence &token,
-    int minimumPrecedence, size_t *atToken, MessageText *error) {
+    int minimumPrecedence, size_t *atToken, MessageFixedText *error) {
   enum Operator {
     PARENS,
     CONST,
@@ -708,7 +715,7 @@ static std::int64_t ExpressionValue(const TokenSequence &token,
 
   size_t tokens{token.size()};
   if (*atToken >= tokens) {
-    *error = "incomplete expression"_msg;
+    *error = "incomplete expression"_en_US;
     return 0;
   }
   std::string t{token[*atToken].ToString()};
@@ -723,7 +730,7 @@ static std::int64_t ExpressionValue(const TokenSequence &token,
     size_t consumed{0};
     left = std::stoll(t, &consumed);
     if (consumed < t.size()) {
-      *error = "uninterpretable numeric constant '"_msg;
+      *error = "uninterpretable numeric constant '"_en_US;
     }
   } else if (IsIdentifierFirstCharacter(t[0])) {
     // undefined macro name -> zero
@@ -743,12 +750,12 @@ static std::int64_t ExpressionValue(const TokenSequence &token,
     if (it != opNameMap.end()) {
       op = it->second;
     } else {
-      *error = "operand expected in expression"_msg;
+      *error = "operand expected in expression"_en_US;
       return 0;
     }
   }
   if (precedence[op] < minimumPrecedence && error->empty()) {
-    *error = "operator precedence error"_msg;
+    *error = "operator precedence error"_en_US;
   }
   ++*atToken;
   if (op != CONST && error->empty()) {
@@ -758,7 +765,7 @@ static std::int64_t ExpressionValue(const TokenSequence &token,
       if (*atToken < tokens && token[*atToken].ToString() == ")") {
         ++*atToken;
       } else if (error->empty()) {
-        *error = "')' missing from expression"_msg;
+        *error = "')' missing from expression"_en_US;
       }
       break;
     case NOTZERO: left = !left; break;
@@ -795,7 +802,7 @@ static std::int64_t ExpressionValue(const TokenSequence &token,
   switch (op) {
   case POWER:
     if (left == 0 && right < 0) {
-      *error = "0 ** negative power"_msg;
+      *error = "0 ** negative power"_en_US;
     }
     if (left == 0 || left == 1 || right == 1) {
       return left;
@@ -807,7 +814,7 @@ static std::int64_t ExpressionValue(const TokenSequence &token,
       std::int64_t power{1};
       for (; right > 0; --right) {
         if ((power * left) / left != power) {
-          *error = "overflow in exponentation"_msg;
+          *error = "overflow in exponentation"_en_US;
           return 0;
         }
         power *= left;
@@ -819,39 +826,39 @@ static std::int64_t ExpressionValue(const TokenSequence &token,
       return 0;
     }
     if ((left * right) / left != right) {
-      *error = "overflow in multiplication"_msg;
+      *error = "overflow in multiplication"_en_US;
     }
     return left * right;
   case DIVIDE:
     if (right == 0) {
-      *error = "division by zero"_msg;
+      *error = "division by zero"_en_US;
       return 0;
     }
     return left / right;
   case MODULUS:
     if (right == 0) {
-      *error = "modulus by zero"_msg;
+      *error = "modulus by zero"_en_US;
       return 0;
     }
     return left % right;
   case ADD:
     if ((left < 0) == (right < 0) && (left < 0) != (left + right < 0)) {
-      *error = "overflow in addition"_msg;
+      *error = "overflow in addition"_en_US;
     }
     return left + right;
   case SUBTRACT:
     if ((left < 0) != (right < 0) && (left < 0) == (left - right < 0)) {
-      *error = "overflow in subtraction"_msg;
+      *error = "overflow in subtraction"_en_US;
     }
     return left - right;
   case LEFTSHIFT:
     if (right < 0 || right > 64) {
-      *error = "bad left shift count"_msg;
+      *error = "bad left shift count"_en_US;
     }
     return right >= 64 ? 0 : left << right;
   case RIGHTSHIFT:
     if (right < 0 || right > 64) {
-      *error = "bad right shift count"_msg;
+      *error = "bad right shift count"_en_US;
     }
     return right >= 64 ? 0 : left >> right;
   case BITAND:
@@ -869,7 +876,7 @@ static std::int64_t ExpressionValue(const TokenSequence &token,
   case NEQV: return -(!left != !right);
   case SELECT:
     if (*atToken >= tokens || token[*atToken].ToString() != ":") {
-      *error = "':' required in selection expression"_msg;
+      *error = "':' required in selection expression"_en_US;
       return left;
     } else {
       ++*atToken;
@@ -909,13 +916,14 @@ bool Preprocessor::IsIfPredicateTrue(const TokenSequence &expr, size_t first,
   TokenSequence expr3{ReplaceMacros(expr2, *prescanner)};
   TokenSequence expr4{StripBlanks(expr3, 0, expr3.size())};
   size_t atToken{0};
-  MessageText error;
+  MessageFixedText error;
   bool result{ExpressionValue(expr4, 0, &atToken, &error) != 0};
   if (!error.empty()) {
     prescanner->Complain(error);
   } else if (atToken < expr4.size()) {
-    prescanner->Complain(atToken == 0 ? "could not parse any expression"_msg
-                                      : "excess characters after expression"_msg);
+    prescanner->Complain(atToken == 0
+            ? "could not parse any expression"_en_US
+            : "excess characters after expression"_en_US);
   }
   return result;
 }
index 8872761..8f5ecf6 100644 (file)
@@ -74,7 +74,8 @@ private:
   CharPointerWithLength SaveTokenAsName(const CharPointerWithLength &);
   bool IsNameDefined(const CharPointerWithLength &);
   TokenSequence ReplaceMacros(const TokenSequence &, const Prescanner &);
-  bool SkipDisabledConditionalCode(const std::string &, IsElseActive, Prescanner *);
+  bool SkipDisabledConditionalCode(
+      const std::string &, IsElseActive, Prescanner *);
   bool IsIfPredicateTrue(
       const TokenSequence &expr, size_t first, size_t exprTokens, Prescanner *);
 
index 828dba8..0e93d36 100644 (file)
@@ -88,7 +88,7 @@ std::optional<TokenSequence> Prescanner::NextTokenizedLine() {
   return {std::move(tokens)};
 }
 
-Message &Prescanner::Complain(MessageText text) {
+Message &Prescanner::Complain(MessageFixedText text) {
   return messages_->Put({GetCurrentProvenance(), text});
 }
 
@@ -414,14 +414,15 @@ bool Prescanner::IncludeLine(const char *p) {
     path += *p;
   }
   if (*p != quote) {
-    messages_->Put({GetProvenance(p), "malformed path name string"_msg});
+    messages_->Put({GetProvenance(p), "malformed path name string"_en_US});
     anyFatalErrors_ = true;
     return true;
   }
   for (++p; *p == ' ' || *p == '\t'; ++p) {
   }
   if (*p != '\n' && *p != '!') {
-    messages_->Put({GetProvenance(p), "excess characters after path name"_msg});
+    messages_->Put(
+        {GetProvenance(p), "excess characters after path name"_en_US});
   }
   std::stringstream error;
   Provenance provenance{GetProvenance(start)};
@@ -435,7 +436,7 @@ bool Prescanner::IncludeLine(const char *p) {
     allSources->PopSearchPathDirectory();
   }
   if (included == nullptr) {
-    messages_->Put({provenance, "INCLUDE: "_msg}) += error.str();
+    messages_->Put({provenance, "INCLUDE: "_en_US}) += error.str();
     anyFatalErrors_ = true;
     return true;
   }
index 5d944c5..eb66194 100644 (file)
@@ -49,7 +49,7 @@ public:
   // Callbacks for use by Preprocessor.
   std::optional<TokenSequence> NextTokenizedLine();
   Provenance GetCurrentProvenance() const { return GetProvenance(at_); }
-  Message &Complain(MessageText);
+  Message &Complain(MessageFixedText);
 
 private:
   void BeginSourceLine(const char *at) {
index a988f59..07edf1f 100644 (file)
@@ -23,7 +23,7 @@ public:
   using resultType = char;
   constexpr CharPredicateGuardParser(
       const CharPredicateGuardParser &) = default;
-  constexpr CharPredicateGuardParser(bool (*f)(char), MessageText t)
+  constexpr CharPredicateGuardParser(bool (*f)(char), MessageFixedText t)
     : predicate_{f}, text_{t} {}
   std::optional<char> Parse(ParseState *state) const {
     auto at = state->GetLocation();
@@ -38,7 +38,7 @@ public:
 
 private:
   bool (*const predicate_)(char);
-  const MessageText text_;
+  const MessageFixedText text_;
 };
 
 static inline constexpr bool IsDecimalDigit(char ch) { return isdigit(ch); }
@@ -55,10 +55,11 @@ static inline constexpr bool IsLetter(char ch) { return isalpha(ch); }
 
 static inline constexpr char ToLower(char &&ch) { return tolower(ch); }
 
-constexpr CharPredicateGuardParser digit{IsDecimalDigit, "expected digit"_msg};
+constexpr CharPredicateGuardParser digit{
+    IsDecimalDigit, "expected digit"_en_US};
 
 constexpr auto letter = applyFunction(
-    ToLower, CharPredicateGuardParser{IsLetter, "expected letter"_msg});
+    ToLower, CharPredicateGuardParser{IsLetter, "expected letter"_en_US});
 
 template<char good> class CharMatch {
 public:
@@ -71,7 +72,11 @@ public:
       result.reset();
     }
     if (!result) {
-      state->PutMessage(at, "expected '"_msg) += std::string{good} + '\'';
+      if (good == '\n') {
+        state->PutMessage(at, "expected end of line"_en_US);
+      } else {
+        state->PutMessage(at, "expected '"_en_US) += std::string{good} + '\'';
+      }
     }
     return {result};
   }
@@ -128,7 +133,7 @@ public:
       } else if (*ch == tolower(*p)) {
         ch.reset();
       } else {
-        state->PutMessage(at, "expected '"_msg) += str_ + '\'';
+        state->PutMessage(at, "expected '"_en_US) += str_ + '\'';
         return {};
       }
     }
@@ -195,7 +200,7 @@ struct CharLiteralChar {
     }
     char ch{*och};
     if (ch == '\n') {
-      state->PutMessage(at, "unclosed character constant"_msg);
+      state->PutMessage(at, "unclosed character constant"_en_US);
       return {};
     }
     if (ch != '\\' || !state->enableBackslashEscapesInCharLiterals()) {
@@ -216,14 +221,14 @@ struct CharLiteralChar {
     case '\'':
     case '\\': return {Result::Escaped(ch)};
     case '\n':
-      state->PutMessage(at, "unclosed character constant"_msg);
+      state->PutMessage(at, "unclosed character constant"_en_US);
       return {};
     default:
       if (IsOctalDigit(ch)) {
         ch -= '0';
         for (int j = (ch > 3 ? 1 : 2); j-- > 0;) {
           static constexpr auto octalDigit = attempt(CharPredicateGuardParser{
-              IsOctalDigit, "expected octal digit"_msg});
+              IsOctalDigit, "expected octal digit"_en_US});
           if ((och = octalDigit.Parse(state)).has_value()) {
             ch = 8 * ch + *och - '0';
           }
@@ -232,13 +237,13 @@ struct CharLiteralChar {
         ch = 0;
         for (int j = 0; j++ < 2;) {
           static constexpr auto hexDigit = attempt(CharPredicateGuardParser{
-              IsHexadecimalDigit, "expected hexadecimal digit"_msg});
+              IsHexadecimalDigit, "expected hexadecimal digit"_en_US});
           if ((och = hexDigit.Parse(state)).has_value()) {
             ch = 16 * ch + HexadecimalDigitValue(*och);
           }
         }
       } else {
-        state->PutMessage(at, "bad escaped character"_msg);
+        state->PutMessage(at, "bad escaped character"_en_US);
       }
       return {Result::Escaped(ch)};
     }
@@ -323,7 +328,7 @@ struct BOZLiteral {
     }
 
     if (content.empty()) {
-      state->PutMessage(at, "no digit in BOZ literal"_msg);
+      state->PutMessage(at, "no digit in BOZ literal"_en_US);
       return {};
     }
 
@@ -331,13 +336,13 @@ struct BOZLiteral {
     for (auto digit : content) {
       digit = HexadecimalDigitValue(digit);
       if ((digit >> *shift) > 0) {
-        state->PutMessage(at, "bad digit in BOZ literal"_msg);
+        state->PutMessage(at, "bad digit in BOZ literal"_en_US);
         return {};
       }
       std::uint64_t was{value};
       value <<= *shift;
       if ((value >> *shift) != was) {
-        state->PutMessage(at, "excessive digits in BOZ literal"_msg);
+        state->PutMessage(at, "excessive digits in BOZ literal"_en_US);
         return {};
       }
       value |= digit;
@@ -370,7 +375,7 @@ struct DigitString {
       value += digitValue;
     }
     if (overflow) {
-      state->PutMessage(at, "overflow in decimal literal"_msg);
+      state->PutMessage(at, "overflow in decimal literal"_en_US);
     }
     return {value};
   }
@@ -397,7 +402,7 @@ struct HollerithLiteral {
       std::optional<char> ch{nextChar.Parse(state)};
       if (!ch || !isprint(*ch)) {
         state->PutMessage(
-            at, "insufficient or bad characters in Hollerith"_msg);
+            at, "insufficient or bad characters in Hollerith"_en_US);
         return {};
       }
       content += *ch;