From 8119fe881de6fa327ee361da749e6afa3ade48bf Mon Sep 17 00:00:00 2001 From: peter klausler Date: Wed, 18 Jul 2018 12:54:30 -0700 Subject: [PATCH] [flang] Ready for merge. Original-commit: flang-compiler/f18@f39949fc7de5d319c180c3c76322df0fa462140c Reviewed-on: https://github.com/flang-compiler/f18/pull/130 --- flang/documentation/extensions.md | 2 +- flang/lib/parser/basic-parsers.h | 4 +- flang/lib/parser/features.h | 12 ++- flang/lib/parser/grammar.h | 161 ++++++++++++++++++++++---------------- 4 files changed, 106 insertions(+), 73 deletions(-) diff --git a/flang/documentation/extensions.md b/flang/documentation/extensions.md index c8bc263..5afc3e9 100644 --- a/flang/documentation/extensions.md +++ b/flang/documentation/extensions.md @@ -29,7 +29,7 @@ Extensions, deletions, and legacy features supported by default * `X` prefix/suffix as synonym for `Z` on hexadecimal literals * `B`, `O`, `Z`, and `X` accepted as suffixes as well as prefixes * Triplets allowed in array constructors -* Old-style `PARAMETER pi=3.14` statement (no parentheses) +* Old-style `PARAMETER pi=3.14` statement without parentheses * `%LOC`, `%VAL`, and `%REF` * Leading comma allowed before I/O item list * Empty parentheses allowed in `PROGRAM P()` diff --git a/flang/lib/parser/basic-parsers.h b/flang/lib/parser/basic-parsers.h index 6588be1..c3ac2db 100644 --- a/flang/lib/parser/basic-parsers.h +++ b/flang/lib/parser/basic-parsers.h @@ -1325,7 +1325,7 @@ private: const PA parser_; }; -template +template inline constexpr auto extension(const PA &parser) { return NonstandardParser(parser); } @@ -1357,7 +1357,7 @@ private: const PA parser_; }; -template +template inline constexpr auto deprecated(const PA &parser) { return DeprecatedParser(parser); } diff --git a/flang/lib/parser/features.h b/flang/lib/parser/features.h index d4aeef1..794137d 100644 --- a/flang/lib/parser/features.h +++ b/flang/lib/parser/features.h @@ -23,9 +23,15 @@ namespace Fortran::parser { ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines, FixedFormContinuationWithColumn1Ampersand, LogicalAbbreviations, XOROperator, PunctuationInNames, OptionalFreeFormSpace, BOZExtensions, - EmptyStatement, OpenMP, Extension, Deprecation) - -using LanguageFeatures = common::EnumSet; + EmptyStatement, AlternativeNE, ExecutionPartNamelist, DECStructures, + DoubleComplex, Kanji, Byte, StarKind, QuadPrecision, SlashInitialization, + TripletInArrayConstructor, MissingColons, SignedComplexLiteral, + OldStyleParameter, ComplexConstructor, PercentLOC, SignedPrimary, FileName, + Convert, Dispose, IOListLeadingComma, AbbreviatedEditDescriptor, + ProgramParentheses, PercentRefAndVal, OmitFunctionDummies, CrayPointer, + Hollerith, ArithmeticIF, Assign, AssignedGOTO, Pause, OpenMP) + +using LanguageFeatures = common::EnumSet; class LanguageFeatureControl { public: diff --git a/flang/lib/parser/grammar.h b/flang/lib/parser/grammar.h index 1cacc4a..36f682b 100644 --- a/flang/lib/parser/grammar.h +++ b/flang/lib/parser/grammar.h @@ -169,7 +169,8 @@ constexpr auto intrinsicOperator{ "+" >> pure(DefinedOperator::IntrinsicOperator::Add) || "-" >> pure(DefinedOperator::IntrinsicOperator::Subtract) || "<=" >> pure(DefinedOperator::IntrinsicOperator::LE) || - extension("<>" >> pure(DefinedOperator::IntrinsicOperator::NE)) || + extension( + "<>" >> pure(DefinedOperator::IntrinsicOperator::NE)) || "<" >> pure(DefinedOperator::IntrinsicOperator::LT) || "==" >> pure(DefinedOperator::IntrinsicOperator::EQ) || ">=" >> pure(DefinedOperator::IntrinsicOperator::GE) || @@ -414,8 +415,9 @@ TYPE_PARSER(recovery( statement(indirect(entryStmt))), construct( statement(indirect(dataStmt))), - extension(construct( - statement(indirect(Parser{}))) || + extension( + construct( + statement(indirect(Parser{}))) || obsoleteExecutionPartConstruct)))), construct(executionPartErrorRecovery))) @@ -476,8 +478,10 @@ TYPE_CONTEXT_PARSER("declaration type spec"_en_US, derivedTypeSpec)) || construct("*" >> construct())) || - extension(construct( - construct("RECORD /" >> name / "/")))) + extension( + construct( + construct( + "RECORD /" >> name / "/")))) // R704 intrinsic-type-spec -> // integer-type-spec | REAL [kind-selector] | DOUBLE PRECISION | @@ -497,12 +501,14 @@ TYPE_CONTEXT_PARSER("intrinsic type spec"_en_US, construct(construct( "LOGICAL" >> maybe(kindSelector))), construct("DOUBLE COMPLEX" >> - extension(construct())), - construct( - extension(construct( + extension( + construct())), + construct(extension( + construct( "NCHARACTER" >> maybe(Parser{})))), - extension(construct(construct( - "BYTE" >> construct>(pure(1))))))) + extension( + construct(construct( + "BYTE" >> construct>(pure(1))))))) // R705 integer-type-spec -> INTEGER [kind-selector] TYPE_PARSER(construct("INTEGER" >> maybe(kindSelector))) @@ -511,7 +517,7 @@ TYPE_PARSER(construct("INTEGER" >> maybe(kindSelector))) // Legacy extension: kind-selector -> * digit-string TYPE_PARSER(construct( parenthesized(maybe("KIND ="_tok) >> scalarIntConstantExpr)) || - extension(construct( + extension(construct( construct("*" >> digitString / spaceCheck)))) // R707 signed-int-literal-constant -> [sign] int-literal-constant @@ -547,7 +553,8 @@ constexpr auto signedRealLiteralConstant{ // Extension: Q // R717 exponent -> signed-digit-string constexpr auto exponentPart{ - ("ed"_ch || extension("q"_ch)) >> SignedDigitString{}}; + ("ed"_ch || extension("q"_ch)) >> + SignedDigitString{}}; TYPE_CONTEXT_PARSER("REAL literal constant"_en_US, space >> @@ -629,7 +636,8 @@ TYPE_CONTEXT_PARSER("CHARACTER literal constant"_en_US, charLiteralConstantWithoutKind)) // deprecated: Hollerith literals -constexpr auto rawHollerithLiteral{deprecated(HollerithLiteral{})}; +constexpr auto rawHollerithLiteral{ + deprecated(HollerithLiteral{})}; TYPE_CONTEXT_PARSER( "Hollerith"_en_US, construct(rawHollerithLiteral)) @@ -781,7 +789,7 @@ constexpr auto initialDataTarget{indirect(designator)}; TYPE_PARSER(construct("=>" >> nullInit) || construct("=>" >> initialDataTarget) || construct("=" >> constantExpr) || - extension(construct( + extension(construct( "/" >> nonemptyList(indirect(Parser{})) / "/"))) // R745 private-components-stmt -> PRIVATE @@ -922,8 +930,9 @@ TYPE_PARSER(construct( // R773 ac-value -> expr | ac-implied-do TYPE_PARSER( // PGI/Intel extension: accept triplets in array constructors - extension(construct(construct( - scalarIntExpr, ":" >> scalarIntExpr, maybe(":" >> scalarIntExpr)))) || + extension( + construct(construct(scalarIntExpr, + ":" >> scalarIntExpr, maybe(":" >> scalarIntExpr)))) || construct(indirect(expr)) || construct(indirect(Parser{}))) @@ -947,8 +956,8 @@ TYPE_PARSER(construct(declarationTypeSpec, // PGI-only extension: don't require the colons // N.B.: The standard requires the colons if the entity // declarations contain initializers. - extension(construct(declarationTypeSpec, - defaulted("," >> nonemptyList(Parser{})), + extension(construct( + declarationTypeSpec, defaulted("," >> nonemptyList(Parser{})), "," >> nonemptyList(entityDecl)))) // R802 attr-spec -> @@ -1170,7 +1179,7 @@ TYPE_PARSER(first(construct(scalar(Parser{})), construct(scalar(constantSubobject)), construct(signedRealLiteralConstant), construct(signedIntLiteralConstant), - extension( + extension( construct(Parser{})), construct(initialDataTarget))) @@ -1197,7 +1206,7 @@ TYPE_CONTEXT_PARSER("PARAMETER statement"_en_US, construct( "PARAMETER" >> parenthesized(nonemptyList(Parser{})))) TYPE_CONTEXT_PARSER("old style PARAMETER statement"_en_US, - extension(construct( + extension(construct( "PARAMETER" >> nonemptyList(Parser{})))) // R852 named-constant-def -> named-constant = constant-expr @@ -1344,7 +1353,8 @@ TYPE_CONTEXT_PARSER("designator"_en_US, constexpr auto percentOrDot{"%"_tok || // legacy VAX extension for RECORD field access - extension("."_tok / lookAhead(OldStructureComponentName{}))}; + extension( + "."_tok / lookAhead(OldStructureComponentName{}))}; // R902 variable -> designator | function-reference // This production appears to be left-recursive in the grammar via @@ -1545,9 +1555,10 @@ constexpr auto primary{instrumented("primary"_en_US, construct(Parser{}), construct(indirect(Parser{})), // occulted // PGI/XLF extension: COMPLEX constructor (x,y) - extension(construct(parenthesized( - construct(expr, "," >> expr)))), - extension(construct("%LOC" >> + extension( + construct(parenthesized( + construct(expr, "," >> expr)))), + extension(construct("%LOC" >> parenthesized(construct(indirect(variable)))))))}; // R1002 level-1-expr -> [defined-unary-op] primary @@ -1555,8 +1566,10 @@ constexpr auto primary{instrumented("primary"_en_US, constexpr auto level1Expr{first( construct(construct(definedOpName, primary)), primary, - extension(construct(construct("+" >> primary))), - extension(construct(construct("-" >> primary))))}; + extension( + construct(construct("+" >> primary))), + extension( + construct(construct("-" >> primary))))}; // R1004 mult-operand -> level-1-expr [power-op mult-operand] // R1007 power-op -> ** @@ -1697,7 +1710,7 @@ constexpr struct Level4Expr { (".LE."_tok || "<="_tok) >> applyLambda(le, level3Expr) || (".EQ."_tok || "=="_tok) >> applyLambda(eq, level3Expr) || (".NE."_tok || "/="_tok || - extension( + extension( "<>"_tok /* PGI/Cray extension; Cray also has .LG. */)) >> applyLambda(ne, level3Expr) || (".GE."_tok || ">="_tok) >> applyLambda(ge, level3Expr) || @@ -2385,7 +2398,8 @@ TYPE_PARSER(first(construct(maybe("UNIT ="_tok) >> fileUnitNumber), scalarDefaultCharExpr)), construct("ERR =" >> errLabel), construct("FILE =" >> fileNameExpr), - extension(construct("NAME =" >> fileNameExpr)), + extension( + construct("NAME =" >> fileNameExpr)), construct(construct( "FORM =" >> pure(ConnectSpec::CharExpr::Kind::Form), scalarDefaultCharExpr)), @@ -2408,9 +2422,11 @@ TYPE_PARSER(first(construct(maybe("UNIT ="_tok) >> fileUnitNumber), "SIGN =" >> pure(ConnectSpec::CharExpr::Kind::Sign), scalarDefaultCharExpr)), construct("STATUS =" >> statusExpr), - extension(construct(construct( - "CONVERT =" >> pure(ConnectSpec::CharExpr::Kind::Convert), - scalarDefaultCharExpr)) || + extension( + construct(construct( + "CONVERT =" >> pure(ConnectSpec::CharExpr::Kind::Convert), + scalarDefaultCharExpr))), + extension( construct(construct( "DISPOSE =" >> pure(ConnectSpec::CharExpr::Kind::Dispose), scalarDefaultCharExpr))))) @@ -2434,7 +2450,8 @@ TYPE_CONTEXT_PARSER("CLOSE statement"_en_US, // READ ( io-control-spec-list ) [input-item-list] | // READ format [, input-item-list] constexpr auto inputItemList{ - extension(some("," >> inputItem)) || // legacy extension: leading comma + extension( + some("," >> inputItem)) || // legacy extension: leading comma optionalList(inputItem)}; TYPE_CONTEXT_PARSER("READ statement"_en_US, @@ -2514,7 +2531,8 @@ TYPE_PARSER(first(construct("UNIT =" >> ioUnit), // R1211 write-stmt -> WRITE ( io-control-spec-list ) [output-item-list] constexpr auto outputItemList{ - extension(some("," >> outputItem)) || // legacy: allow leading comma + extension( + some("," >> outputItem)) || // legacy: allow leading comma optionalList(outputItem)}; TYPE_CONTEXT_PARSER("WRITE statement"_en_US, @@ -2861,23 +2879,26 @@ TYPE_PARSER(construct( "A" >> pure(format::IntrinsicTypeDataEditDesc::Kind::A), maybe(width), noInt, noInt) || // PGI/Intel extension: omitting width (and all else that follows) - extension(construct( - "I" >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) || - ("B"_tok / !letter /* don't occlude BN & BZ */) >> - pure(format::IntrinsicTypeDataEditDesc::Kind::B) || - "O" >> pure(format::IntrinsicTypeDataEditDesc::Kind::O) || - "Z" >> pure(format::IntrinsicTypeDataEditDesc::Kind::Z) || - "F" >> pure(format::IntrinsicTypeDataEditDesc::Kind::F) || - ("D"_tok / !letter /* don't occlude DT, DC, & DP */) >> - pure(format::IntrinsicTypeDataEditDesc::Kind::D) || - "E" >> - ("N" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EN) || - "S" >> pure(format::IntrinsicTypeDataEditDesc::Kind::ES) || - "X" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EX) || - pure(format::IntrinsicTypeDataEditDesc::Kind::E)) || - "G" >> pure(format::IntrinsicTypeDataEditDesc::Kind::G) || - "L" >> pure(format::IntrinsicTypeDataEditDesc::Kind::L), - noInt, noInt, noInt))) + extension( + construct( + "I" >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) || + ("B"_tok / !letter /* don't occlude BN & BZ */) >> + pure(format::IntrinsicTypeDataEditDesc::Kind::B) || + "O" >> pure(format::IntrinsicTypeDataEditDesc::Kind::O) || + "Z" >> pure(format::IntrinsicTypeDataEditDesc::Kind::Z) || + "F" >> pure(format::IntrinsicTypeDataEditDesc::Kind::F) || + ("D"_tok / !letter /* don't occlude DT, DC, & DP */) >> + pure(format::IntrinsicTypeDataEditDesc::Kind::D) || + "E" >> + ("N" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EN) || + "S" >> + pure(format::IntrinsicTypeDataEditDesc::Kind::ES) || + "X" >> + pure(format::IntrinsicTypeDataEditDesc::Kind::EX) || + pure(format::IntrinsicTypeDataEditDesc::Kind::E)) || + "G" >> pure(format::IntrinsicTypeDataEditDesc::Kind::G) || + "L" >> pure(format::IntrinsicTypeDataEditDesc::Kind::L), + noInt, noInt, noInt))) // R1307 data-edit-desc (part 2 of 2) // R1312 v -> [sign] digit-string @@ -2951,8 +2972,9 @@ TYPE_CONTEXT_PARSER("main program"_en_US, // R1402 program-stmt -> PROGRAM program-name // PGI allows empty parentheses after the name. TYPE_CONTEXT_PARSER("PROGRAM statement"_en_US, - construct( - "PROGRAM" >> name / maybe(extension(parenthesized(ok))))) + construct("PROGRAM" >> name / + maybe(extension( + parenthesized(ok))))) // R1403 end-program-stmt -> END [PROGRAM [program-name]] TYPE_CONTEXT_PARSER("END PROGRAM statement"_en_US, @@ -3182,9 +3204,9 @@ TYPE_PARSER(construct( TYPE_PARSER(construct(variable) / lookAhead(","_tok || ")"_tok) || construct(expr) || construct(Parser{}) || - extension(construct( + extension(construct( construct("%REF" >> parenthesized(variable)))) || - extension(construct( + extension(construct( construct("%VAL" >> parenthesized(expr))))) // R1525 alt-return-spec -> * label @@ -3217,9 +3239,11 @@ TYPE_CONTEXT_PARSER("FUNCTION subprogram"_en_US, TYPE_CONTEXT_PARSER("FUNCTION statement"_en_US, construct(many(prefixSpec), "FUNCTION" >> name, parenthesized(optionalList(name)), maybe(suffix)) || - extension(construct( // PGI & Intel accept "FUNCTION F" - many(prefixSpec), "FUNCTION" >> name, construct>(), - construct>()))) + extension( + construct( // PGI & Intel accept "FUNCTION F" + many(prefixSpec), "FUNCTION" >> name, + construct>(), + construct>()))) // R1532 suffix -> // proc-language-binding-spec [RESULT ( result-name )] | @@ -3308,9 +3332,9 @@ TYPE_PARSER(beginDirective >> sourced(construct(ivdep) || construct(ignore_tkr)) / endDirective) -TYPE_PARSER( - extension(construct("POINTER (" >> objectName / ",", - objectName, maybe(Parser{}) / ")"))) +TYPE_PARSER(extension( + construct("POINTER (" >> objectName / ",", objectName, + maybe(Parser{}) / ")"))) TYPE_PARSER(construct("STRUCTURE /" >> name / "/", pure(true), optionalList(entityDecl)) || @@ -3322,8 +3346,8 @@ TYPE_PARSER(construct(statement(StructureComponents{})) || construct(indirect(Parser{}))) TYPE_CONTEXT_PARSER("STRUCTURE definition"_en_US, - extension(construct(statement(Parser{}), - many(Parser{}), + extension(construct( + statement(Parser{}), many(Parser{}), statement( construct("END STRUCTURE"_tok))))) @@ -3338,18 +3362,21 @@ TYPE_CONTEXT_PARSER("MAP definition"_en_US, statement(construct("END MAP"_tok)))) TYPE_CONTEXT_PARSER("arithmetic IF statement"_en_US, - deprecated(construct( + deprecated(construct( "IF" >> parenthesized(expr), label / ",", label / ",", label))) TYPE_CONTEXT_PARSER("ASSIGN statement"_en_US, - deprecated(construct("ASSIGN" >> label, "TO" >> name))) + deprecated( + construct("ASSIGN" >> label, "TO" >> name))) TYPE_CONTEXT_PARSER("assigned GOTO statement"_en_US, - deprecated(construct("GO TO" >> name, - defaulted(maybe(","_tok) >> parenthesized(nonemptyList(label)))))) + deprecated( + construct("GO TO" >> name, + defaulted(maybe(","_tok) >> parenthesized(nonemptyList(label)))))) TYPE_CONTEXT_PARSER("PAUSE statement"_en_US, - deprecated(construct("PAUSE" >> maybe(Parser{})))) + deprecated( + construct("PAUSE" >> maybe(Parser{})))) // These requirement productions are defined by the Fortran standard but never // used directly by the grammar: -- 2.7.4