mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-28 16:11:29 +00:00
[flang] Add explanatory messages to grammar for language extensions
Extend "extension<LanguageFeature>()" to incorporate an explanatory message better than the current generic "nonstandard usage:". Differential Revision: https://reviews.llvm.org/D122035
This commit is contained in:
parent
ddca66622c
commit
2d8b6a4784
@ -65,13 +65,16 @@ constexpr auto namedIntrinsicOperator{
|
||||
".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>(
|
||||
".X." >> pure(DefinedOperator::IntrinsicOperator::NEQV)))};
|
||||
".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) ||
|
||||
@ -83,6 +86,7 @@ constexpr auto intrinsicOperator{
|
||||
"-" >> 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) ||
|
||||
@ -178,6 +182,7 @@ TYPE_CONTEXT_PARSER("declaration type spec"_en_US,
|
||||
construct<DeclarationTypeSpec>("*" >>
|
||||
construct<DeclarationTypeSpec::ClassStar>())) ||
|
||||
extension<LanguageFeature::DECStructures>(
|
||||
"nonstandard usage: STRUCTURE"_port_en_US,
|
||||
construct<DeclarationTypeSpec>(
|
||||
// As is also done for the STRUCTURE statement, the name of
|
||||
// the structure includes the surrounding slashes to avoid
|
||||
@ -202,9 +207,11 @@ TYPE_CONTEXT_PARSER("intrinsic type spec"_en_US,
|
||||
"CHARACTER" >> maybe(Parser<CharSelector>{}))),
|
||||
construct<IntrinsicTypeSpec>(construct<IntrinsicTypeSpec::Logical>(
|
||||
"LOGICAL" >> maybe(kindSelector))),
|
||||
extension<LanguageFeature::DoubleComplex>(construct<IntrinsicTypeSpec>(
|
||||
"DOUBLE COMPLEX" >> construct<IntrinsicTypeSpec::DoubleComplex>())),
|
||||
extension<LanguageFeature::Byte>(
|
||||
extension<LanguageFeature::DoubleComplex>(
|
||||
"nonstandard usage: DOUBLE COMPLEX"_port_en_US,
|
||||
construct<IntrinsicTypeSpec>("DOUBLE COMPLEX" >>
|
||||
construct<IntrinsicTypeSpec::DoubleComplex>())),
|
||||
extension<LanguageFeature::Byte>("nonstandard usage: BYTE"_port_en_US,
|
||||
construct<IntrinsicTypeSpec>(construct<IntegerTypeSpec>(
|
||||
"BYTE" >> construct<std::optional<KindSelector>>(pure(1)))))))
|
||||
|
||||
@ -215,8 +222,10 @@ TYPE_PARSER(construct<IntegerTypeSpec>("INTEGER" >> maybe(kindSelector)))
|
||||
// Legacy extension: kind-selector -> * digit-string
|
||||
TYPE_PARSER(construct<KindSelector>(
|
||||
parenthesized(maybe("KIND ="_tok) >> scalarIntConstantExpr)) ||
|
||||
extension<LanguageFeature::StarKind>(construct<KindSelector>(
|
||||
construct<KindSelector::StarSize>("*" >> digitString64 / spaceCheck))))
|
||||
extension<LanguageFeature::StarKind>(
|
||||
"nonstandard usage: TYPE*KIND syntax"_port_en_US,
|
||||
construct<KindSelector>(construct<KindSelector::StarSize>(
|
||||
"*" >> digitString64 / spaceCheck))))
|
||||
|
||||
// R707 signed-int-literal-constant -> [sign] int-literal-constant
|
||||
TYPE_PARSER(sourced(construct<SignedIntLiteralConstant>(
|
||||
@ -251,7 +260,9 @@ constexpr auto signedRealLiteralConstant{
|
||||
// Extension: Q
|
||||
// R717 exponent -> signed-digit-string
|
||||
constexpr auto exponentPart{
|
||||
("ed"_ch || extension<LanguageFeature::QuadPrecision>("q"_ch)) >>
|
||||
("ed"_ch ||
|
||||
extension<LanguageFeature::QuadPrecision>(
|
||||
"nonstandard usage: Q exponent"_port_en_US, "q"_ch)) >>
|
||||
SignedDigitString{}};
|
||||
|
||||
TYPE_CONTEXT_PARSER("REAL literal constant"_en_US,
|
||||
@ -431,6 +442,7 @@ TYPE_CONTEXT_PARSER("component declaration"_en_US,
|
||||
// The source field of the Name will be replaced with a distinct generated name.
|
||||
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>{}) ||
|
||||
@ -475,10 +487,12 @@ constexpr auto initialDataTarget{indirect(designator)};
|
||||
TYPE_PARSER(construct<Initialization>("=>" >> nullInit) ||
|
||||
construct<Initialization>("=>" >> initialDataTarget) ||
|
||||
construct<Initialization>("=" >> constantExpr) ||
|
||||
extension<LanguageFeature::SlashInitialization>(construct<Initialization>(
|
||||
"/" >> nonemptyList("expected values"_err_en_US,
|
||||
indirect(Parser<DataStmtValue>{})) /
|
||||
"/")))
|
||||
extension<LanguageFeature::SlashInitialization>(
|
||||
"nonstandard usage: /initialization/"_port_en_US,
|
||||
construct<Initialization>(
|
||||
"/" >> nonemptyList("expected values"_err_en_US,
|
||||
indirect(Parser<DataStmtValue>{})) /
|
||||
"/")))
|
||||
|
||||
// R745 private-components-stmt -> PRIVATE
|
||||
// R747 binding-private-stmt -> PRIVATE
|
||||
@ -608,10 +622,12 @@ TYPE_PARSER(
|
||||
nonemptyList("expected entity declarations"_err_en_US,
|
||||
entityDeclWithoutEqInit)) ||
|
||||
// PGI-only extension: comma in place of doubled colons
|
||||
extension<LanguageFeature::MissingColons>(construct<TypeDeclarationStmt>(
|
||||
declarationTypeSpec, defaulted("," >> nonemptyList(Parser<AttrSpec>{})),
|
||||
withMessage("expected entity declarations"_err_en_US,
|
||||
"," >> nonemptyList(entityDecl)))))
|
||||
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)))))
|
||||
|
||||
// R802 attr-spec ->
|
||||
// access-spec | ALLOCATABLE | ASYNCHRONOUS |
|
||||
@ -841,6 +857,7 @@ 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),
|
||||
@ -869,8 +886,10 @@ 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>(construct<OldParameterStmt>(
|
||||
"PARAMETER" >> nonemptyList(Parser<NamedConstantDef>{}))))
|
||||
extension<LanguageFeature::OldStyleParameter>(
|
||||
"nonstandard usage: PARAMETER without parentheses"_port_en_US,
|
||||
construct<OldParameterStmt>(
|
||||
"PARAMETER" >> nonemptyList(Parser<NamedConstantDef>{}))))
|
||||
|
||||
// R852 named-constant-def -> named-constant = constant-expr
|
||||
TYPE_PARSER(construct<NamedConstantDef>(namedConstant, "=" >> constantExpr))
|
||||
@ -1024,6 +1043,7 @@ TYPE_CONTEXT_PARSER("designator"_en_US,
|
||||
constexpr auto percentOrDot{"%"_tok ||
|
||||
// legacy VAX extension for RECORD field access
|
||||
extension<LanguageFeature::DECStructures>(
|
||||
"nonstandard usage: component access with '.' in place of '%'"_port_en_US,
|
||||
"."_tok / lookAhead(OldStructureComponentName{}))};
|
||||
|
||||
// R902 variable -> designator | function-reference
|
||||
@ -1184,10 +1204,12 @@ TYPE_PARSER(beginDirective >>
|
||||
maybe(("="_tok || ":"_tok) >> digitString64))))) /
|
||||
endDirective)
|
||||
|
||||
TYPE_PARSER(extension<LanguageFeature::CrayPointer>(construct<BasedPointerStmt>(
|
||||
"POINTER" >> nonemptyList("expected POINTER associations"_err_en_US,
|
||||
construct<BasedPointer>("(" >> objectName / ",",
|
||||
objectName, maybe(Parser<ArraySpec>{}) / ")")))))
|
||||
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>{}) / ")")))))
|
||||
|
||||
// Subtle: the name includes the surrounding slashes, which avoids
|
||||
// clashes with other uses of the name in the same scope.
|
||||
@ -1206,10 +1228,12 @@ TYPE_PARSER(construct<StructureField>(statement(StructureComponents{})) ||
|
||||
construct<StructureField>(indirect(nestedStructureDef)))
|
||||
|
||||
TYPE_CONTEXT_PARSER("STRUCTURE definition"_en_US,
|
||||
extension<LanguageFeature::DECStructures>(construct<StructureDef>(
|
||||
statement(Parser<StructureStmt>{}), many(Parser<StructureField>{}),
|
||||
statement(
|
||||
construct<StructureDef::EndStructureStmt>("END STRUCTURE"_tok)))))
|
||||
extension<LanguageFeature::DECStructures>(
|
||||
"nonstandard usage: STRUCTURE"_port_en_US,
|
||||
construct<StructureDef>(statement(Parser<StructureStmt>{}),
|
||||
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)),
|
||||
|
@ -845,7 +845,8 @@ template <LanguageFeature LF, typename PA> class NonstandardParser {
|
||||
public:
|
||||
using resultType = typename PA::resultType;
|
||||
constexpr NonstandardParser(const NonstandardParser &) = default;
|
||||
constexpr NonstandardParser(PA parser) : parser_{parser} {}
|
||||
constexpr NonstandardParser(PA parser, MessageFixedText msg)
|
||||
: parser_{parser}, message_{msg} {}
|
||||
std::optional<resultType> Parse(ParseState &state) const {
|
||||
if (UserState * ustate{state.userState()}) {
|
||||
if (!ustate->features().IsEnabled(LF)) {
|
||||
@ -855,19 +856,20 @@ public:
|
||||
auto at{state.GetLocation()};
|
||||
auto result{parser_.Parse(state)};
|
||||
if (result) {
|
||||
state.Nonstandard(CharBlock{at, std::max(state.GetLocation(), at + 1)},
|
||||
LF, "nonstandard usage"_port_en_US);
|
||||
state.Nonstandard(
|
||||
CharBlock{at, std::max(state.GetLocation(), at + 1)}, LF, message_);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
const PA parser_;
|
||||
const MessageFixedText message_;
|
||||
};
|
||||
|
||||
template <LanguageFeature LF, typename PA>
|
||||
inline constexpr auto extension(PA parser) {
|
||||
return NonstandardParser<LF, PA>(parser);
|
||||
inline constexpr auto extension(MessageFixedText feature, PA parser) {
|
||||
return NonstandardParser<LF, PA>(parser, feature);
|
||||
}
|
||||
|
||||
// If a is a parser for some deprecated or deleted language feature LF,
|
||||
|
@ -76,6 +76,7 @@ TYPE_PARSER(recovery(
|
||||
construct<ExecutionPartConstruct>(
|
||||
statement(indirect(dataStmt))),
|
||||
extension<LanguageFeature::ExecutionPartNamelist>(
|
||||
"nonstandard usage: NAMELIST in execution part"_port_en_US,
|
||||
construct<ExecutionPartConstruct>(
|
||||
statement(indirect(Parser<NamelistStmt>{})))),
|
||||
obsoleteExecutionPartConstruct))),
|
||||
|
@ -44,6 +44,7 @@ TYPE_PARSER(construct<AcSpec>(maybe(typeSpec / "::"),
|
||||
TYPE_PARSER(
|
||||
// PGI/Intel extension: accept triplets in array constructors
|
||||
extension<LanguageFeature::TripletInArrayConstructor>(
|
||||
"nonstandard usage: triplet in array constructor"_port_en_US,
|
||||
construct<AcValue>(construct<AcValue::Triplet>(scalarIntExpr,
|
||||
":" >> scalarIntExpr, maybe(":" >> scalarIntExpr)))) ||
|
||||
construct<AcValue>(indirect(expr)) ||
|
||||
@ -76,10 +77,13 @@ constexpr auto primary{instrumented("primary"_en_US,
|
||||
construct<Expr>(Parser<ArrayConstructor>{}),
|
||||
// PGI/XLF extension: COMPLEX constructor (x,y)
|
||||
extension<LanguageFeature::ComplexConstructor>(
|
||||
"nonstandard usage: generalized COMPLEX constructor"_port_en_US,
|
||||
construct<Expr>(parenthesized(
|
||||
construct<Expr::ComplexConstructor>(expr, "," >> expr)))),
|
||||
extension<LanguageFeature::PercentLOC>(construct<Expr>("%LOC" >>
|
||||
parenthesized(construct<Expr::PercentLoc>(indirect(variable)))))))};
|
||||
extension<LanguageFeature::PercentLOC>(
|
||||
"nonstandard usage: %LOC"_port_en_US,
|
||||
construct<Expr>("%LOC" >> parenthesized(construct<Expr::PercentLoc>(
|
||||
indirect(variable)))))))};
|
||||
|
||||
// R1002 level-1-expr -> [defined-unary-op] primary
|
||||
// TODO: Reasonable extension: permit multiple defined-unary-ops
|
||||
@ -87,8 +91,10 @@ 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>(
|
||||
"nonstandard usage: signed primary"_port_en_US,
|
||||
construct<Expr>(construct<Expr::UnaryPlus>("+" >> primary))),
|
||||
extension<LanguageFeature::SignedPrimary>(
|
||||
"nonstandard usage: signed primary"_port_en_US,
|
||||
construct<Expr>(construct<Expr::Negate>("-" >> primary)))))};
|
||||
|
||||
// R1004 mult-operand -> level-1-expr [power-op mult-operand]
|
||||
@ -244,6 +250,7 @@ struct Level4Expr {
|
||||
(".EQ."_tok || "=="_tok) >> applyLambda(eq, level3Expr) ||
|
||||
(".NE."_tok || "/="_tok ||
|
||||
extension<LanguageFeature::AlternativeNE>(
|
||||
"nonstandard usage: <> for /= or .NE."_port_en_US,
|
||||
"<>"_tok /* PGI/Cray extension; Cray also has .LG. */)) >>
|
||||
applyLambda(ne, level3Expr) ||
|
||||
(".GE."_tok || ">="_tok) >> applyLambda(ge, level3Expr) ||
|
||||
@ -273,6 +280,7 @@ constexpr AndOperand andOperand;
|
||||
inline constexpr auto logicalOp(const char *op, const char *abbrev) {
|
||||
return TokenStringMatch{op} ||
|
||||
extension<LanguageFeature::LogicalAbbreviations>(
|
||||
"nonstandard usage: abbreviated LOGICAL operator"_port_en_US,
|
||||
TokenStringMatch{abbrev});
|
||||
}
|
||||
|
||||
@ -356,6 +364,7 @@ struct Level5Expr {
|
||||
auto more{attempt(sourced(".EQV." >> applyLambda(eqv, equivOperand) ||
|
||||
(".NEQV."_tok ||
|
||||
extension<LanguageFeature::XOROperator>(
|
||||
"nonstandard usage: .XOR./.X. spelling of .NEQV."_port_en_US,
|
||||
logicalOp(".XOR.", ".X."))) >>
|
||||
applyLambda(neqv, equivOperand)))};
|
||||
while (std::optional<Expr> next{more.Parse(state)}) {
|
||||
@ -397,8 +406,10 @@ template <> std::optional<Expr> Parser<Expr>::Parse(ParseState &state) {
|
||||
// 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 with the dots around it.
|
||||
constexpr auto definedOpNameChar{
|
||||
letter || extension<LanguageFeature::PunctuationInNames>("$@"_ch)};
|
||||
constexpr auto definedOpNameChar{letter ||
|
||||
extension<LanguageFeature::PunctuationInNames>(
|
||||
"nonstandard usage: non-alphabetic character in defined operator"_port_en_US,
|
||||
"$@"_ch)};
|
||||
TYPE_PARSER(
|
||||
space >> construct<DefinedOpName>(sourced("."_ch >>
|
||||
some(definedOpNameChar) >> construct<Name>() / "."_ch)))
|
||||
|
@ -85,6 +85,7 @@ TYPE_PARSER(first(construct<ConnectSpec>(maybe("UNIT ="_tok) >> fileUnitNumber),
|
||||
construct<ConnectSpec>("ERR =" >> errLabel),
|
||||
construct<ConnectSpec>("FILE =" >> fileNameExpr),
|
||||
extension<LanguageFeature::FileName>(
|
||||
"nonstandard usage: NAME= in place of FILE="_port_en_US,
|
||||
construct<ConnectSpec>("NAME =" >> fileNameExpr)),
|
||||
construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
|
||||
"FORM =" >> pure(ConnectSpec::CharExpr::Kind::Form),
|
||||
@ -108,15 +109,19 @@ TYPE_PARSER(first(construct<ConnectSpec>(maybe("UNIT ="_tok) >> fileUnitNumber),
|
||||
"SIGN =" >> pure(ConnectSpec::CharExpr::Kind::Sign),
|
||||
scalarDefaultCharExpr)),
|
||||
construct<ConnectSpec>("STATUS =" >> statusExpr),
|
||||
extension<LanguageFeature::Carriagecontrol>(construct<ConnectSpec>(
|
||||
construct<ConnectSpec::CharExpr>("CARRIAGECONTROL =" >>
|
||||
pure(ConnectSpec::CharExpr::Kind::Carriagecontrol),
|
||||
scalarDefaultCharExpr))),
|
||||
extension<LanguageFeature::Carriagecontrol>(
|
||||
"nonstandard usage: CARRIAGECONTROL="_port_en_US,
|
||||
construct<ConnectSpec>(
|
||||
construct<ConnectSpec::CharExpr>("CARRIAGECONTROL =" >>
|
||||
pure(ConnectSpec::CharExpr::Kind::Carriagecontrol),
|
||||
scalarDefaultCharExpr))),
|
||||
extension<LanguageFeature::Convert>(
|
||||
"nonstandard usage: CONVERT="_port_en_US,
|
||||
construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
|
||||
"CONVERT =" >> pure(ConnectSpec::CharExpr::Kind::Convert),
|
||||
scalarDefaultCharExpr))),
|
||||
extension<LanguageFeature::Dispose>(
|
||||
"nonstandard usage: DISPOSE="_port_en_US,
|
||||
construct<ConnectSpec>(construct<ConnectSpec::CharExpr>(
|
||||
"DISPOSE =" >> pure(ConnectSpec::CharExpr::Kind::Dispose),
|
||||
scalarDefaultCharExpr)))))
|
||||
@ -145,6 +150,7 @@ TYPE_CONTEXT_PARSER("CLOSE statement"_en_US,
|
||||
// rewriting in semantics when we know that CVAR is character.
|
||||
constexpr auto inputItemList{
|
||||
extension<LanguageFeature::IOListLeadingComma>(
|
||||
"nonstandard usage: leading comma in input item list"_port_en_US,
|
||||
some("," >> inputItem)) || // legacy extension: leading comma
|
||||
optionalList(inputItem)};
|
||||
|
||||
@ -226,6 +232,7 @@ TYPE_PARSER(first(construct<IoControlSpec>("UNIT =" >> ioUnit),
|
||||
// R1211 write-stmt -> WRITE ( io-control-spec-list ) [output-item-list]
|
||||
constexpr auto outputItemList{
|
||||
extension<LanguageFeature::IOListLeadingComma>(
|
||||
"nonstandard usage: leading comma in output item list"_port_en_US,
|
||||
some("," >> outputItem)) || // legacy: allow leading comma
|
||||
optionalList(outputItem)};
|
||||
|
||||
@ -486,18 +493,23 @@ TYPE_PARSER(first(construct<InquireSpec>(maybe("UNIT ="_tok) >> fileUnitNumber),
|
||||
construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Write),
|
||||
scalarDefaultCharVariable)),
|
||||
extension<LanguageFeature::Carriagecontrol>(
|
||||
"nonstandard usage: CARRIAGECONTROL="_port_en_US,
|
||||
construct<InquireSpec>("CARRIAGECONTROL =" >>
|
||||
construct<InquireSpec::CharVar>(
|
||||
pure(InquireSpec::CharVar::Kind::Carriagecontrol),
|
||||
scalarDefaultCharVariable))),
|
||||
extension<LanguageFeature::Convert>(construct<InquireSpec>(
|
||||
"CONVERT =" >> construct<InquireSpec::CharVar>(
|
||||
pure(InquireSpec::CharVar::Kind::Convert),
|
||||
scalarDefaultCharVariable))),
|
||||
extension<LanguageFeature::Dispose>(construct<InquireSpec>(
|
||||
"DISPOSE =" >> construct<InquireSpec::CharVar>(
|
||||
pure(InquireSpec::CharVar::Kind::Dispose),
|
||||
scalarDefaultCharVariable)))))
|
||||
extension<LanguageFeature::Convert>(
|
||||
"nonstandard usage: CONVERT="_port_en_US,
|
||||
construct<InquireSpec>(
|
||||
"CONVERT =" >> construct<InquireSpec::CharVar>(
|
||||
pure(InquireSpec::CharVar::Kind::Convert),
|
||||
scalarDefaultCharVariable))),
|
||||
extension<LanguageFeature::Dispose>(
|
||||
"nonstandard usage: DISPOSE="_port_en_US,
|
||||
construct<InquireSpec>(
|
||||
"DISPOSE =" >> construct<InquireSpec::CharVar>(
|
||||
pure(InquireSpec::CharVar::Kind::Dispose),
|
||||
scalarDefaultCharVariable)))))
|
||||
|
||||
// R1230 inquire-stmt ->
|
||||
// INQUIRE ( inquire-spec-list ) |
|
||||
@ -591,6 +603,7 @@ TYPE_PARSER(construct<format::IntrinsicTypeDataEditDesc>(
|
||||
noInt, noInt) ||
|
||||
// PGI/Intel extension: omitting width (and all else that follows)
|
||||
extension<LanguageFeature::AbbreviatedEditDescriptor>(
|
||||
"nonstandard usage: abbreviated edit descriptor"_port_en_US,
|
||||
construct<format::IntrinsicTypeDataEditDesc>(
|
||||
"I" >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) ||
|
||||
("B"_tok / !letter /* don't occlude BN & BZ */) >>
|
||||
@ -673,8 +686,9 @@ TYPE_PARSER(construct<format::ControlEditDesc>(
|
||||
"P" >> construct<format::ControlEditDesc>(
|
||||
pure(format::ControlEditDesc::Kind::DP))) ||
|
||||
extension<LanguageFeature::AdditionalFormats>(
|
||||
"nonstandard usage: $ and \\ control edit descriptors"_port_en_US,
|
||||
"$" >> construct<format::ControlEditDesc>(
|
||||
pure(format::ControlEditDesc::Kind::Dollar)) ||
|
||||
"\\" >> construct<format::ControlEditDesc>(
|
||||
pure(format::ControlEditDesc::Kind::Backslash))))
|
||||
"\\" >> construct<format::ControlEditDesc>(
|
||||
pure(format::ControlEditDesc::Kind::Backslash))))
|
||||
} // namespace Fortran::parser
|
||||
|
@ -54,11 +54,13 @@ static constexpr auto globalCompilerDirective{
|
||||
// Consequently, a program unit END statement should be the last statement
|
||||
// on its line. We parse those END statements via unterminatedStatement()
|
||||
// and then skip over the end of the line here.
|
||||
TYPE_PARSER(construct<Program>(
|
||||
extension<LanguageFeature::EmptySourceFile>(skipStuffBeforeStatement >>
|
||||
!nextCh >> pure<std::list<ProgramUnit>>()) ||
|
||||
some(globalCompilerDirective || normalProgramUnit) /
|
||||
skipStuffBeforeStatement))
|
||||
TYPE_PARSER(
|
||||
construct<Program>(extension<LanguageFeature::EmptySourceFile>(
|
||||
"nonstandard usage: empty source file"_port_en_US,
|
||||
skipStuffBeforeStatement >> !nextCh >>
|
||||
pure<std::list<ProgramUnit>>()) ||
|
||||
some(globalCompilerDirective || normalProgramUnit) /
|
||||
skipStuffBeforeStatement))
|
||||
|
||||
// R504 specification-part ->
|
||||
// [use-stmt]... [import-stmt]... [implicit-part]
|
||||
@ -204,6 +206,7 @@ TYPE_CONTEXT_PARSER("main program"_en_US,
|
||||
TYPE_CONTEXT_PARSER("PROGRAM statement"_en_US,
|
||||
construct<ProgramStmt>("PROGRAM" >> name /
|
||||
maybe(extension<LanguageFeature::ProgramParentheses>(
|
||||
"nonstandard usage: parentheses in PROGRAM statement"_port_en_US,
|
||||
parenthesized(ok)))))
|
||||
|
||||
// R1403 end-program-stmt -> END [PROGRAM [program-name]]
|
||||
@ -449,10 +452,14 @@ TYPE_PARSER(construct<ActualArgSpec>(
|
||||
// Semantics sorts it all out later.
|
||||
TYPE_PARSER(construct<ActualArg>(expr) ||
|
||||
construct<ActualArg>(Parser<AltReturnSpec>{}) ||
|
||||
extension<LanguageFeature::PercentRefAndVal>(construct<ActualArg>(
|
||||
construct<ActualArg::PercentRef>("%REF" >> parenthesized(variable)))) ||
|
||||
extension<LanguageFeature::PercentRefAndVal>(construct<ActualArg>(
|
||||
construct<ActualArg::PercentVal>("%VAL" >> parenthesized(expr)))))
|
||||
extension<LanguageFeature::PercentRefAndVal>(
|
||||
"nonstandard usage: %REF"_port_en_US,
|
||||
construct<ActualArg>(construct<ActualArg::PercentRef>(
|
||||
"%REF" >> parenthesized(variable)))) ||
|
||||
extension<LanguageFeature::PercentRefAndVal>(
|
||||
"nonstandard usage: %VAL"_port_en_US,
|
||||
construct<ActualArg>(
|
||||
construct<ActualArg::PercentVal>("%VAL" >> parenthesized(expr)))))
|
||||
|
||||
// R1525 alt-return-spec -> * label
|
||||
TYPE_PARSER(construct<AltReturnSpec>(star >> label))
|
||||
@ -485,6 +492,7 @@ TYPE_CONTEXT_PARSER("FUNCTION statement"_en_US,
|
||||
construct<FunctionStmt>(many(prefixSpec), "FUNCTION" >> name,
|
||||
parenthesized(optionalList(name)), maybe(suffix)) ||
|
||||
extension<LanguageFeature::OmitFunctionDummies>(
|
||||
"nonstandard usage: FUNCTION statement without dummy argument list"_port_en_US,
|
||||
construct<FunctionStmt>( // PGI & Intel accept "FUNCTION F"
|
||||
many(prefixSpec), "FUNCTION" >> name,
|
||||
construct<std::list<Name>>(),
|
||||
|
@ -655,15 +655,20 @@ constexpr auto underscore{"_"_ch};
|
||||
// Cray and gfortran accept '$', but not as the first character.
|
||||
// Cray accepts '@' as well.
|
||||
constexpr auto otherIdChar{underscore / !"'\""_ch ||
|
||||
extension<LanguageFeature::PunctuationInNames>("$@"_ch)};
|
||||
extension<LanguageFeature::PunctuationInNames>(
|
||||
"nonstandard usage: punctuation in name"_port_en_US, "$@"_ch)};
|
||||
|
||||
constexpr auto logicalTRUE{
|
||||
(".TRUE."_tok ||
|
||||
extension<LanguageFeature::LogicalAbbreviations>(".T."_tok)) >>
|
||||
extension<LanguageFeature::LogicalAbbreviations>(
|
||||
"nonstandard usage: .T. spelling of .TRUE."_port_en_US,
|
||||
".T."_tok)) >>
|
||||
pure(true)};
|
||||
constexpr auto logicalFALSE{
|
||||
(".FALSE."_tok ||
|
||||
extension<LanguageFeature::LogicalAbbreviations>(".F."_tok)) >>
|
||||
extension<LanguageFeature::LogicalAbbreviations>(
|
||||
"nonstandard usage: .F. spelling of .FALSE."_port_en_US,
|
||||
".F."_tok)) >>
|
||||
pure(false)};
|
||||
|
||||
// deprecated: Hollerith literals
|
||||
|
Loading…
Reference in New Issue
Block a user