164ab3302SCarolineConcatto //===-- lib/Parser/io-parsers.cpp -----------------------------------------===// 264ab3302SCarolineConcatto // 364ab3302SCarolineConcatto // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 464ab3302SCarolineConcatto // See https://llvm.org/LICENSE.txt for license information. 564ab3302SCarolineConcatto // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 664ab3302SCarolineConcatto // 764ab3302SCarolineConcatto //===----------------------------------------------------------------------===// 864ab3302SCarolineConcatto 964ab3302SCarolineConcatto // Per-type parsers for I/O statements and FORMAT 1064ab3302SCarolineConcatto 1164ab3302SCarolineConcatto #include "basic-parsers.h" 1264ab3302SCarolineConcatto #include "expr-parsers.h" 1364ab3302SCarolineConcatto #include "misc-parsers.h" 1464ab3302SCarolineConcatto #include "stmt-parser.h" 1564ab3302SCarolineConcatto #include "token-parsers.h" 1664ab3302SCarolineConcatto #include "type-parser-implementation.h" 1764ab3302SCarolineConcatto #include "flang/Parser/characters.h" 1864ab3302SCarolineConcatto #include "flang/Parser/parse-tree.h" 1964ab3302SCarolineConcatto 2064ab3302SCarolineConcatto namespace Fortran::parser { 2164ab3302SCarolineConcatto // R1201 io-unit -> file-unit-number | * | internal-file-variable 2264ab3302SCarolineConcatto // R1203 internal-file-variable -> char-variable 2364ab3302SCarolineConcatto // R905 char-variable -> variable 2464ab3302SCarolineConcatto // "char-variable" is attempted first since it's not type constrained but 2564ab3302SCarolineConcatto // syntactically ambiguous with "file-unit-number", which is constrained. 26f0ffc690Speter klausler TYPE_PARSER(construct<IoUnit>(variable / lookAhead(space / ",);\n"_ch)) || 2764ab3302SCarolineConcatto construct<IoUnit>(fileUnitNumber) || construct<IoUnit>(star)) 2864ab3302SCarolineConcatto 2964ab3302SCarolineConcatto // R1202 file-unit-number -> scalar-int-expr 30*047168daSPeter Klausler TYPE_PARSER(construct<FileUnitNumber>( 31*047168daSPeter Klausler scalarIntExpr / (lookAhead(space >> ",)"_ch) || atEndOfStmt))) 3264ab3302SCarolineConcatto 3364ab3302SCarolineConcatto // R1204 open-stmt -> OPEN ( connect-spec-list ) 3464ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("OPEN statement"_en_US, 3564ab3302SCarolineConcatto construct<OpenStmt>( 3664ab3302SCarolineConcatto "OPEN (" >> nonemptyList("expected connection specifications"_err_en_US, 3764ab3302SCarolineConcatto Parser<ConnectSpec>{}) / 3864ab3302SCarolineConcatto ")")) 3964ab3302SCarolineConcatto 4064ab3302SCarolineConcatto // R1206 file-name-expr -> scalar-default-char-expr 4164ab3302SCarolineConcatto constexpr auto fileNameExpr{scalarDefaultCharExpr}; 4264ab3302SCarolineConcatto 4364ab3302SCarolineConcatto // R1205 connect-spec -> 4464ab3302SCarolineConcatto // [UNIT =] file-unit-number | ACCESS = scalar-default-char-expr | 4564ab3302SCarolineConcatto // ACTION = scalar-default-char-expr | 4664ab3302SCarolineConcatto // ASYNCHRONOUS = scalar-default-char-expr | 4764ab3302SCarolineConcatto // BLANK = scalar-default-char-expr | 4864ab3302SCarolineConcatto // DECIMAL = scalar-default-char-expr | 4964ab3302SCarolineConcatto // DELIM = scalar-default-char-expr | 5064ab3302SCarolineConcatto // ENCODING = scalar-default-char-expr | ERR = label | 5164ab3302SCarolineConcatto // FILE = file-name-expr | FORM = scalar-default-char-expr | 5264ab3302SCarolineConcatto // IOMSG = iomsg-variable | IOSTAT = scalar-int-variable | 5364ab3302SCarolineConcatto // NEWUNIT = scalar-int-variable | PAD = scalar-default-char-expr | 5464ab3302SCarolineConcatto // POSITION = scalar-default-char-expr | RECL = scalar-int-expr | 5564ab3302SCarolineConcatto // ROUND = scalar-default-char-expr | SIGN = scalar-default-char-expr | 5664ab3302SCarolineConcatto // STATUS = scalar-default-char-expr 57c9637577Speter klausler // @ | CARRIAGECONTROL = scalar-default-char-variable 58c9637577Speter klausler // | CONVERT = scalar-default-char-variable 59c9637577Speter klausler // | DISPOSE = scalar-default-char-variable 6064ab3302SCarolineConcatto constexpr auto statusExpr{construct<StatusExpr>(scalarDefaultCharExpr)}; 6164ab3302SCarolineConcatto constexpr auto errLabel{construct<ErrLabel>(label)}; 6264ab3302SCarolineConcatto 6364ab3302SCarolineConcatto TYPE_PARSER(first(construct<ConnectSpec>(maybe("UNIT ="_tok) >> fileUnitNumber), 6464ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 6564ab3302SCarolineConcatto "ACCESS =" >> pure(ConnectSpec::CharExpr::Kind::Access), 6664ab3302SCarolineConcatto scalarDefaultCharExpr)), 6764ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 6864ab3302SCarolineConcatto "ACTION =" >> pure(ConnectSpec::CharExpr::Kind::Action), 6964ab3302SCarolineConcatto scalarDefaultCharExpr)), 7064ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 7164ab3302SCarolineConcatto "ASYNCHRONOUS =" >> pure(ConnectSpec::CharExpr::Kind::Asynchronous), 7264ab3302SCarolineConcatto scalarDefaultCharExpr)), 7364ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 7464ab3302SCarolineConcatto "BLANK =" >> pure(ConnectSpec::CharExpr::Kind::Blank), 7564ab3302SCarolineConcatto scalarDefaultCharExpr)), 7664ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 7764ab3302SCarolineConcatto "DECIMAL =" >> pure(ConnectSpec::CharExpr::Kind::Decimal), 7864ab3302SCarolineConcatto scalarDefaultCharExpr)), 7964ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 8064ab3302SCarolineConcatto "DELIM =" >> pure(ConnectSpec::CharExpr::Kind::Delim), 8164ab3302SCarolineConcatto scalarDefaultCharExpr)), 8264ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 8364ab3302SCarolineConcatto "ENCODING =" >> pure(ConnectSpec::CharExpr::Kind::Encoding), 8464ab3302SCarolineConcatto scalarDefaultCharExpr)), 8564ab3302SCarolineConcatto construct<ConnectSpec>("ERR =" >> errLabel), 8664ab3302SCarolineConcatto construct<ConnectSpec>("FILE =" >> fileNameExpr), 8764ab3302SCarolineConcatto extension<LanguageFeature::FileName>( 882d8b6a47SPeter Klausler "nonstandard usage: NAME= in place of FILE="_port_en_US, 8964ab3302SCarolineConcatto construct<ConnectSpec>("NAME =" >> fileNameExpr)), 9064ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 9164ab3302SCarolineConcatto "FORM =" >> pure(ConnectSpec::CharExpr::Kind::Form), 9264ab3302SCarolineConcatto scalarDefaultCharExpr)), 9364ab3302SCarolineConcatto construct<ConnectSpec>("IOMSG =" >> msgVariable), 9464ab3302SCarolineConcatto construct<ConnectSpec>("IOSTAT =" >> statVariable), 9564ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::Newunit>( 9664ab3302SCarolineConcatto "NEWUNIT =" >> scalar(integer(variable)))), 9764ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 9864ab3302SCarolineConcatto "PAD =" >> pure(ConnectSpec::CharExpr::Kind::Pad), 9964ab3302SCarolineConcatto scalarDefaultCharExpr)), 10064ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 10164ab3302SCarolineConcatto "POSITION =" >> pure(ConnectSpec::CharExpr::Kind::Position), 10264ab3302SCarolineConcatto scalarDefaultCharExpr)), 10364ab3302SCarolineConcatto construct<ConnectSpec>( 10464ab3302SCarolineConcatto construct<ConnectSpec::Recl>("RECL =" >> scalarIntExpr)), 10564ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 10664ab3302SCarolineConcatto "ROUND =" >> pure(ConnectSpec::CharExpr::Kind::Round), 10764ab3302SCarolineConcatto scalarDefaultCharExpr)), 10864ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 10964ab3302SCarolineConcatto "SIGN =" >> pure(ConnectSpec::CharExpr::Kind::Sign), 11064ab3302SCarolineConcatto scalarDefaultCharExpr)), 11164ab3302SCarolineConcatto construct<ConnectSpec>("STATUS =" >> statusExpr), 1122d8b6a47SPeter Klausler extension<LanguageFeature::Carriagecontrol>( 1132d8b6a47SPeter Klausler "nonstandard usage: CARRIAGECONTROL="_port_en_US, 1142d8b6a47SPeter Klausler construct<ConnectSpec>( 115c9637577Speter klausler construct<ConnectSpec::CharExpr>("CARRIAGECONTROL =" >> 116c9637577Speter klausler pure(ConnectSpec::CharExpr::Kind::Carriagecontrol), 117c9637577Speter klausler scalarDefaultCharExpr))), 11864ab3302SCarolineConcatto extension<LanguageFeature::Convert>( 1192d8b6a47SPeter Klausler "nonstandard usage: CONVERT="_port_en_US, 12064ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 12164ab3302SCarolineConcatto "CONVERT =" >> pure(ConnectSpec::CharExpr::Kind::Convert), 12264ab3302SCarolineConcatto scalarDefaultCharExpr))), 12364ab3302SCarolineConcatto extension<LanguageFeature::Dispose>( 1242d8b6a47SPeter Klausler "nonstandard usage: DISPOSE="_port_en_US, 12564ab3302SCarolineConcatto construct<ConnectSpec>(construct<ConnectSpec::CharExpr>( 12664ab3302SCarolineConcatto "DISPOSE =" >> pure(ConnectSpec::CharExpr::Kind::Dispose), 12764ab3302SCarolineConcatto scalarDefaultCharExpr))))) 12864ab3302SCarolineConcatto 12964ab3302SCarolineConcatto // R1209 close-spec -> 13064ab3302SCarolineConcatto // [UNIT =] file-unit-number | IOSTAT = scalar-int-variable | 13164ab3302SCarolineConcatto // IOMSG = iomsg-variable | ERR = label | 13264ab3302SCarolineConcatto // STATUS = scalar-default-char-expr 13364ab3302SCarolineConcatto constexpr auto closeSpec{first( 13464ab3302SCarolineConcatto construct<CloseStmt::CloseSpec>(maybe("UNIT ="_tok) >> fileUnitNumber), 13564ab3302SCarolineConcatto construct<CloseStmt::CloseSpec>("IOSTAT =" >> statVariable), 13664ab3302SCarolineConcatto construct<CloseStmt::CloseSpec>("IOMSG =" >> msgVariable), 13764ab3302SCarolineConcatto construct<CloseStmt::CloseSpec>("ERR =" >> errLabel), 13864ab3302SCarolineConcatto construct<CloseStmt::CloseSpec>("STATUS =" >> statusExpr))}; 13964ab3302SCarolineConcatto 14064ab3302SCarolineConcatto // R1208 close-stmt -> CLOSE ( close-spec-list ) 14164ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("CLOSE statement"_en_US, 14264ab3302SCarolineConcatto construct<CloseStmt>("CLOSE" >> parenthesized(nonemptyList(closeSpec)))) 14364ab3302SCarolineConcatto 14464ab3302SCarolineConcatto // R1210 read-stmt -> 14564ab3302SCarolineConcatto // READ ( io-control-spec-list ) [input-item-list] | 14664ab3302SCarolineConcatto // READ format [, input-item-list] 1474acd8f7fSpeter klausler // The ambiguous READ(CVAR) is parsed as if CVAR were the unit. 1484acd8f7fSpeter klausler // As Fortran doesn't have internal unformatted I/O, it should 1494acd8f7fSpeter klausler // be parsed as if (CVAR) were a format; this is corrected by 1504acd8f7fSpeter klausler // rewriting in semantics when we know that CVAR is character. 15164ab3302SCarolineConcatto constexpr auto inputItemList{ 15264ab3302SCarolineConcatto extension<LanguageFeature::IOListLeadingComma>( 1532d8b6a47SPeter Klausler "nonstandard usage: leading comma in input item list"_port_en_US, 15464ab3302SCarolineConcatto some("," >> inputItem)) || // legacy extension: leading comma 15564ab3302SCarolineConcatto optionalList(inputItem)}; 15664ab3302SCarolineConcatto 15764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("READ statement"_en_US, 15864ab3302SCarolineConcatto construct<ReadStmt>("READ (" >> 15964ab3302SCarolineConcatto construct<std::optional<IoUnit>>(maybe("UNIT ="_tok) >> ioUnit), 16064ab3302SCarolineConcatto "," >> construct<std::optional<Format>>(format), 16164ab3302SCarolineConcatto defaulted("," >> nonemptyList(ioControlSpec)) / ")", inputItemList) || 16264ab3302SCarolineConcatto construct<ReadStmt>( 16364ab3302SCarolineConcatto "READ (" >> construct<std::optional<IoUnit>>(ioUnit), 16464ab3302SCarolineConcatto construct<std::optional<Format>>(), 16564ab3302SCarolineConcatto defaulted("," >> nonemptyList(ioControlSpec)) / ")", 16664ab3302SCarolineConcatto inputItemList) || 16764ab3302SCarolineConcatto construct<ReadStmt>("READ" >> construct<std::optional<IoUnit>>(), 16864ab3302SCarolineConcatto construct<std::optional<Format>>(), 16964ab3302SCarolineConcatto parenthesized(nonemptyList(ioControlSpec)), inputItemList) || 17064ab3302SCarolineConcatto construct<ReadStmt>("READ" >> construct<std::optional<IoUnit>>(), 17164ab3302SCarolineConcatto construct<std::optional<Format>>(format), 17264ab3302SCarolineConcatto construct<std::list<IoControlSpec>>(), many("," >> inputItem))) 17364ab3302SCarolineConcatto 17464ab3302SCarolineConcatto // R1214 id-variable -> scalar-int-variable 17564ab3302SCarolineConcatto constexpr auto idVariable{construct<IdVariable>(scalarIntVariable)}; 17664ab3302SCarolineConcatto 17764ab3302SCarolineConcatto // R1213 io-control-spec -> 17864ab3302SCarolineConcatto // [UNIT =] io-unit | [FMT =] format | [NML =] namelist-group-name | 17964ab3302SCarolineConcatto // ADVANCE = scalar-default-char-expr | 18064ab3302SCarolineConcatto // ASYNCHRONOUS = scalar-default-char-constant-expr | 18164ab3302SCarolineConcatto // BLANK = scalar-default-char-expr | 18264ab3302SCarolineConcatto // DECIMAL = scalar-default-char-expr | 18364ab3302SCarolineConcatto // DELIM = scalar-default-char-expr | END = label | EOR = label | 18464ab3302SCarolineConcatto // ERR = label | ID = id-variable | IOMSG = iomsg-variable | 18564ab3302SCarolineConcatto // IOSTAT = scalar-int-variable | PAD = scalar-default-char-expr | 18664ab3302SCarolineConcatto // POS = scalar-int-expr | REC = scalar-int-expr | 18764ab3302SCarolineConcatto // ROUND = scalar-default-char-expr | SIGN = scalar-default-char-expr | 18864ab3302SCarolineConcatto // SIZE = scalar-int-variable 18964ab3302SCarolineConcatto constexpr auto endLabel{construct<EndLabel>(label)}; 19064ab3302SCarolineConcatto constexpr auto eorLabel{construct<EorLabel>(label)}; 19164ab3302SCarolineConcatto TYPE_PARSER(first(construct<IoControlSpec>("UNIT =" >> ioUnit), 19264ab3302SCarolineConcatto construct<IoControlSpec>("FMT =" >> format), 19364ab3302SCarolineConcatto construct<IoControlSpec>("NML =" >> name), 19464ab3302SCarolineConcatto construct<IoControlSpec>( 19564ab3302SCarolineConcatto "ADVANCE =" >> construct<IoControlSpec::CharExpr>( 19664ab3302SCarolineConcatto pure(IoControlSpec::CharExpr::Kind::Advance), 19764ab3302SCarolineConcatto scalarDefaultCharExpr)), 19864ab3302SCarolineConcatto construct<IoControlSpec>(construct<IoControlSpec::Asynchronous>( 19964ab3302SCarolineConcatto "ASYNCHRONOUS =" >> scalarDefaultCharConstantExpr)), 20064ab3302SCarolineConcatto construct<IoControlSpec>("BLANK =" >> 20164ab3302SCarolineConcatto construct<IoControlSpec::CharExpr>( 20264ab3302SCarolineConcatto pure(IoControlSpec::CharExpr::Kind::Blank), scalarDefaultCharExpr)), 20364ab3302SCarolineConcatto construct<IoControlSpec>( 20464ab3302SCarolineConcatto "DECIMAL =" >> construct<IoControlSpec::CharExpr>( 20564ab3302SCarolineConcatto pure(IoControlSpec::CharExpr::Kind::Decimal), 20664ab3302SCarolineConcatto scalarDefaultCharExpr)), 20764ab3302SCarolineConcatto construct<IoControlSpec>("DELIM =" >> 20864ab3302SCarolineConcatto construct<IoControlSpec::CharExpr>( 20964ab3302SCarolineConcatto pure(IoControlSpec::CharExpr::Kind::Delim), scalarDefaultCharExpr)), 21064ab3302SCarolineConcatto construct<IoControlSpec>("END =" >> endLabel), 21164ab3302SCarolineConcatto construct<IoControlSpec>("EOR =" >> eorLabel), 21264ab3302SCarolineConcatto construct<IoControlSpec>("ERR =" >> errLabel), 21364ab3302SCarolineConcatto construct<IoControlSpec>("ID =" >> idVariable), 21464ab3302SCarolineConcatto construct<IoControlSpec>("IOMSG = " >> msgVariable), 21564ab3302SCarolineConcatto construct<IoControlSpec>("IOSTAT = " >> statVariable), 21664ab3302SCarolineConcatto construct<IoControlSpec>("PAD =" >> 21764ab3302SCarolineConcatto construct<IoControlSpec::CharExpr>( 21864ab3302SCarolineConcatto pure(IoControlSpec::CharExpr::Kind::Pad), scalarDefaultCharExpr)), 21964ab3302SCarolineConcatto construct<IoControlSpec>( 22064ab3302SCarolineConcatto "POS =" >> construct<IoControlSpec::Pos>(scalarIntExpr)), 22164ab3302SCarolineConcatto construct<IoControlSpec>( 22264ab3302SCarolineConcatto "REC =" >> construct<IoControlSpec::Rec>(scalarIntExpr)), 22364ab3302SCarolineConcatto construct<IoControlSpec>("ROUND =" >> 22464ab3302SCarolineConcatto construct<IoControlSpec::CharExpr>( 22564ab3302SCarolineConcatto pure(IoControlSpec::CharExpr::Kind::Round), scalarDefaultCharExpr)), 22664ab3302SCarolineConcatto construct<IoControlSpec>("SIGN =" >> 22764ab3302SCarolineConcatto construct<IoControlSpec::CharExpr>( 22864ab3302SCarolineConcatto pure(IoControlSpec::CharExpr::Kind::Sign), scalarDefaultCharExpr)), 22964ab3302SCarolineConcatto construct<IoControlSpec>( 23064ab3302SCarolineConcatto "SIZE =" >> construct<IoControlSpec::Size>(scalarIntVariable)))) 23164ab3302SCarolineConcatto 23264ab3302SCarolineConcatto // R1211 write-stmt -> WRITE ( io-control-spec-list ) [output-item-list] 23364ab3302SCarolineConcatto constexpr auto outputItemList{ 23464ab3302SCarolineConcatto extension<LanguageFeature::IOListLeadingComma>( 2352d8b6a47SPeter Klausler "nonstandard usage: leading comma in output item list"_port_en_US, 23664ab3302SCarolineConcatto some("," >> outputItem)) || // legacy: allow leading comma 23764ab3302SCarolineConcatto optionalList(outputItem)}; 23864ab3302SCarolineConcatto 23964ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("WRITE statement"_en_US, 24064ab3302SCarolineConcatto construct<WriteStmt>("WRITE (" >> 24164ab3302SCarolineConcatto construct<std::optional<IoUnit>>(maybe("UNIT ="_tok) >> ioUnit), 24264ab3302SCarolineConcatto "," >> construct<std::optional<Format>>(format), 24364ab3302SCarolineConcatto defaulted("," >> nonemptyList(ioControlSpec)) / ")", outputItemList) || 24464ab3302SCarolineConcatto construct<WriteStmt>( 24564ab3302SCarolineConcatto "WRITE (" >> construct<std::optional<IoUnit>>(ioUnit), 24664ab3302SCarolineConcatto construct<std::optional<Format>>(), 24764ab3302SCarolineConcatto defaulted("," >> nonemptyList(ioControlSpec)) / ")", 24864ab3302SCarolineConcatto outputItemList) || 24964ab3302SCarolineConcatto construct<WriteStmt>("WRITE" >> construct<std::optional<IoUnit>>(), 25064ab3302SCarolineConcatto construct<std::optional<Format>>(), 25164ab3302SCarolineConcatto parenthesized(nonemptyList(ioControlSpec)), outputItemList)) 25264ab3302SCarolineConcatto 25364ab3302SCarolineConcatto // R1212 print-stmt PRINT format [, output-item-list] 25464ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("PRINT statement"_en_US, 25564ab3302SCarolineConcatto construct<PrintStmt>( 25664ab3302SCarolineConcatto "PRINT" >> format, defaulted("," >> nonemptyList(outputItem)))) 25764ab3302SCarolineConcatto 25864ab3302SCarolineConcatto // R1215 format -> default-char-expr | label | * 259455ed8deSpeter klausler // deprecated(ASSIGN): | scalar-int-name 26064ab3302SCarolineConcatto TYPE_PARSER(construct<Format>(label / !"_."_ch) || 261455ed8deSpeter klausler construct<Format>(expr / !"="_tok) || construct<Format>(star)) 26264ab3302SCarolineConcatto 26364ab3302SCarolineConcatto // R1216 input-item -> variable | io-implied-do 26464ab3302SCarolineConcatto TYPE_PARSER(construct<InputItem>(variable) || 26564ab3302SCarolineConcatto construct<InputItem>(indirect(inputImpliedDo))) 26664ab3302SCarolineConcatto 26764ab3302SCarolineConcatto // R1217 output-item -> expr | io-implied-do 26864ab3302SCarolineConcatto TYPE_PARSER(construct<OutputItem>(expr) || 26964ab3302SCarolineConcatto construct<OutputItem>(indirect(outputImpliedDo))) 27064ab3302SCarolineConcatto 27164ab3302SCarolineConcatto // R1220 io-implied-do-control -> 27264ab3302SCarolineConcatto // do-variable = scalar-int-expr , scalar-int-expr [, scalar-int-expr] 27364ab3302SCarolineConcatto constexpr auto ioImpliedDoControl{loopBounds(scalarIntExpr)}; 27464ab3302SCarolineConcatto 27564ab3302SCarolineConcatto // R1218 io-implied-do -> ( io-implied-do-object-list , io-implied-do-control ) 27664ab3302SCarolineConcatto // R1219 io-implied-do-object -> input-item | output-item 27764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("input implied DO"_en_US, 27864ab3302SCarolineConcatto parenthesized( 27964ab3302SCarolineConcatto construct<InputImpliedDo>(nonemptyList(inputItem / lookAhead(","_tok)), 28064ab3302SCarolineConcatto "," >> ioImpliedDoControl))) 28164ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("output implied DO"_en_US, 28264ab3302SCarolineConcatto parenthesized(construct<OutputImpliedDo>( 28364ab3302SCarolineConcatto nonemptyList(outputItem / lookAhead(","_tok)), 28464ab3302SCarolineConcatto "," >> ioImpliedDoControl))) 28564ab3302SCarolineConcatto 28664ab3302SCarolineConcatto // R1222 wait-stmt -> WAIT ( wait-spec-list ) 28764ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("WAIT statement"_en_US, 28864ab3302SCarolineConcatto "WAIT" >> 28964ab3302SCarolineConcatto parenthesized(construct<WaitStmt>(nonemptyList(Parser<WaitSpec>{})))) 29064ab3302SCarolineConcatto 29164ab3302SCarolineConcatto // R1223 wait-spec -> 29264ab3302SCarolineConcatto // [UNIT =] file-unit-number | END = label | EOR = label | ERR = label | 29364ab3302SCarolineConcatto // ID = scalar-int-expr | IOMSG = iomsg-variable | 29464ab3302SCarolineConcatto // IOSTAT = scalar-int-variable 29564ab3302SCarolineConcatto constexpr auto idExpr{construct<IdExpr>(scalarIntExpr)}; 29664ab3302SCarolineConcatto 29764ab3302SCarolineConcatto TYPE_PARSER(first(construct<WaitSpec>(maybe("UNIT ="_tok) >> fileUnitNumber), 29864ab3302SCarolineConcatto construct<WaitSpec>("END =" >> endLabel), 29964ab3302SCarolineConcatto construct<WaitSpec>("EOR =" >> eorLabel), 30064ab3302SCarolineConcatto construct<WaitSpec>("ERR =" >> errLabel), 30164ab3302SCarolineConcatto construct<WaitSpec>("ID =" >> idExpr), 30264ab3302SCarolineConcatto construct<WaitSpec>("IOMSG =" >> msgVariable), 30364ab3302SCarolineConcatto construct<WaitSpec>("IOSTAT =" >> statVariable))) 30464ab3302SCarolineConcatto 30564ab3302SCarolineConcatto constexpr auto bareUnitNumberAsList{ 30664ab3302SCarolineConcatto applyFunction(singletonList<PositionOrFlushSpec>, 30764ab3302SCarolineConcatto construct<PositionOrFlushSpec>(fileUnitNumber))}; 30864ab3302SCarolineConcatto constexpr auto positionOrFlushSpecList{ 30964ab3302SCarolineConcatto parenthesized(nonemptyList(positionOrFlushSpec)) || bareUnitNumberAsList}; 31064ab3302SCarolineConcatto 31164ab3302SCarolineConcatto // R1224 backspace-stmt -> 31264ab3302SCarolineConcatto // BACKSPACE file-unit-number | BACKSPACE ( position-spec-list ) 31364ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("BACKSPACE statement"_en_US, 31464ab3302SCarolineConcatto construct<BackspaceStmt>("BACKSPACE" >> positionOrFlushSpecList)) 31564ab3302SCarolineConcatto 31664ab3302SCarolineConcatto // R1225 endfile-stmt -> 31764ab3302SCarolineConcatto // ENDFILE file-unit-number | ENDFILE ( position-spec-list ) 31864ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("ENDFILE statement"_en_US, 31964ab3302SCarolineConcatto construct<EndfileStmt>("END FILE" >> positionOrFlushSpecList)) 32064ab3302SCarolineConcatto 32164ab3302SCarolineConcatto // R1226 rewind-stmt -> REWIND file-unit-number | REWIND ( position-spec-list ) 32264ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("REWIND statement"_en_US, 32364ab3302SCarolineConcatto construct<RewindStmt>("REWIND" >> positionOrFlushSpecList)) 32464ab3302SCarolineConcatto 32564ab3302SCarolineConcatto // R1227 position-spec -> 32664ab3302SCarolineConcatto // [UNIT =] file-unit-number | IOMSG = iomsg-variable | 32764ab3302SCarolineConcatto // IOSTAT = scalar-int-variable | ERR = label 32864ab3302SCarolineConcatto // R1229 flush-spec -> 32964ab3302SCarolineConcatto // [UNIT =] file-unit-number | IOSTAT = scalar-int-variable | 33064ab3302SCarolineConcatto // IOMSG = iomsg-variable | ERR = label 33164ab3302SCarolineConcatto TYPE_PARSER( 33264ab3302SCarolineConcatto construct<PositionOrFlushSpec>(maybe("UNIT ="_tok) >> fileUnitNumber) || 33364ab3302SCarolineConcatto construct<PositionOrFlushSpec>("IOMSG =" >> msgVariable) || 33464ab3302SCarolineConcatto construct<PositionOrFlushSpec>("IOSTAT =" >> statVariable) || 33564ab3302SCarolineConcatto construct<PositionOrFlushSpec>("ERR =" >> errLabel)) 33664ab3302SCarolineConcatto 33764ab3302SCarolineConcatto // R1228 flush-stmt -> FLUSH file-unit-number | FLUSH ( flush-spec-list ) 33864ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("FLUSH statement"_en_US, 33964ab3302SCarolineConcatto construct<FlushStmt>("FLUSH" >> positionOrFlushSpecList)) 34064ab3302SCarolineConcatto 34164ab3302SCarolineConcatto // R1231 inquire-spec -> 34264ab3302SCarolineConcatto // [UNIT =] file-unit-number | FILE = file-name-expr | 34364ab3302SCarolineConcatto // ACCESS = scalar-default-char-variable | 34464ab3302SCarolineConcatto // ACTION = scalar-default-char-variable | 34564ab3302SCarolineConcatto // ASYNCHRONOUS = scalar-default-char-variable | 34664ab3302SCarolineConcatto // BLANK = scalar-default-char-variable | 34764ab3302SCarolineConcatto // DECIMAL = scalar-default-char-variable | 34864ab3302SCarolineConcatto // DELIM = scalar-default-char-variable | 34964ab3302SCarolineConcatto // ENCODING = scalar-default-char-variable | 35064ab3302SCarolineConcatto // ERR = label | EXIST = scalar-logical-variable | 35164ab3302SCarolineConcatto // FORM = scalar-default-char-variable | 35264ab3302SCarolineConcatto // FORMATTED = scalar-default-char-variable | 35364ab3302SCarolineConcatto // ID = scalar-int-expr | IOMSG = iomsg-variable | 35464ab3302SCarolineConcatto // IOSTAT = scalar-int-variable | 35564ab3302SCarolineConcatto // NAME = scalar-default-char-variable | 35664ab3302SCarolineConcatto // NAMED = scalar-logical-variable | 35764ab3302SCarolineConcatto // NEXTREC = scalar-int-variable | NUMBER = scalar-int-variable | 35864ab3302SCarolineConcatto // OPENED = scalar-logical-variable | 35964ab3302SCarolineConcatto // PAD = scalar-default-char-variable | 36064ab3302SCarolineConcatto // PENDING = scalar-logical-variable | POS = scalar-int-variable | 36164ab3302SCarolineConcatto // POSITION = scalar-default-char-variable | 36264ab3302SCarolineConcatto // READ = scalar-default-char-variable | 36364ab3302SCarolineConcatto // READWRITE = scalar-default-char-variable | 36464ab3302SCarolineConcatto // RECL = scalar-int-variable | ROUND = scalar-default-char-variable | 36564ab3302SCarolineConcatto // SEQUENTIAL = scalar-default-char-variable | 36664ab3302SCarolineConcatto // SIGN = scalar-default-char-variable | 36764ab3302SCarolineConcatto // SIZE = scalar-int-variable | 36864ab3302SCarolineConcatto // STREAM = scalar-default-char-variable | 36964ab3302SCarolineConcatto // STATUS = scalar-default-char-variable | 37064ab3302SCarolineConcatto // WRITE = scalar-default-char-variable 371c9637577Speter klausler // @ | CARRIAGECONTROL = scalar-default-char-variable 372c9637577Speter klausler // | CONVERT = scalar-default-char-variable 37364ab3302SCarolineConcatto // | DISPOSE = scalar-default-char-variable 37464ab3302SCarolineConcatto TYPE_PARSER(first(construct<InquireSpec>(maybe("UNIT ="_tok) >> fileUnitNumber), 37564ab3302SCarolineConcatto construct<InquireSpec>("FILE =" >> fileNameExpr), 37664ab3302SCarolineConcatto construct<InquireSpec>( 37764ab3302SCarolineConcatto "ACCESS =" >> construct<InquireSpec::CharVar>( 37864ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Access), 37964ab3302SCarolineConcatto scalarDefaultCharVariable)), 38064ab3302SCarolineConcatto construct<InquireSpec>( 38164ab3302SCarolineConcatto "ACTION =" >> construct<InquireSpec::CharVar>( 38264ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Action), 38364ab3302SCarolineConcatto scalarDefaultCharVariable)), 38464ab3302SCarolineConcatto construct<InquireSpec>( 38564ab3302SCarolineConcatto "ASYNCHRONOUS =" >> construct<InquireSpec::CharVar>( 38664ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Asynchronous), 38764ab3302SCarolineConcatto scalarDefaultCharVariable)), 38864ab3302SCarolineConcatto construct<InquireSpec>("BLANK =" >> 38964ab3302SCarolineConcatto construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Blank), 39064ab3302SCarolineConcatto scalarDefaultCharVariable)), 39164ab3302SCarolineConcatto construct<InquireSpec>( 39264ab3302SCarolineConcatto "DECIMAL =" >> construct<InquireSpec::CharVar>( 39364ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Decimal), 39464ab3302SCarolineConcatto scalarDefaultCharVariable)), 39564ab3302SCarolineConcatto construct<InquireSpec>("DELIM =" >> 39664ab3302SCarolineConcatto construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Delim), 39764ab3302SCarolineConcatto scalarDefaultCharVariable)), 39864ab3302SCarolineConcatto construct<InquireSpec>( 39964ab3302SCarolineConcatto "DIRECT =" >> construct<InquireSpec::CharVar>( 40064ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Direct), 40164ab3302SCarolineConcatto scalarDefaultCharVariable)), 40264ab3302SCarolineConcatto construct<InquireSpec>( 40364ab3302SCarolineConcatto "ENCODING =" >> construct<InquireSpec::CharVar>( 40464ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Encoding), 40564ab3302SCarolineConcatto scalarDefaultCharVariable)), 40664ab3302SCarolineConcatto construct<InquireSpec>("ERR =" >> errLabel), 40764ab3302SCarolineConcatto construct<InquireSpec>("EXIST =" >> 40864ab3302SCarolineConcatto construct<InquireSpec::LogVar>( 40964ab3302SCarolineConcatto pure(InquireSpec::LogVar::Kind::Exist), scalarLogicalVariable)), 41064ab3302SCarolineConcatto construct<InquireSpec>("FORM =" >> 41164ab3302SCarolineConcatto construct<InquireSpec::CharVar>( 41264ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Form), scalarDefaultCharVariable)), 41364ab3302SCarolineConcatto construct<InquireSpec>( 41464ab3302SCarolineConcatto "FORMATTED =" >> construct<InquireSpec::CharVar>( 41564ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Formatted), 41664ab3302SCarolineConcatto scalarDefaultCharVariable)), 41764ab3302SCarolineConcatto construct<InquireSpec>("ID =" >> idExpr), 41864ab3302SCarolineConcatto construct<InquireSpec>("IOMSG =" >> 41964ab3302SCarolineConcatto construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Iomsg), 42064ab3302SCarolineConcatto scalarDefaultCharVariable)), 42164ab3302SCarolineConcatto construct<InquireSpec>("IOSTAT =" >> 42264ab3302SCarolineConcatto construct<InquireSpec::IntVar>(pure(InquireSpec::IntVar::Kind::Iostat), 42364ab3302SCarolineConcatto scalar(integer(variable)))), 42464ab3302SCarolineConcatto construct<InquireSpec>("NAME =" >> 42564ab3302SCarolineConcatto construct<InquireSpec::CharVar>( 42664ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Name), scalarDefaultCharVariable)), 42764ab3302SCarolineConcatto construct<InquireSpec>("NAMED =" >> 42864ab3302SCarolineConcatto construct<InquireSpec::LogVar>( 42964ab3302SCarolineConcatto pure(InquireSpec::LogVar::Kind::Named), scalarLogicalVariable)), 43064ab3302SCarolineConcatto construct<InquireSpec>("NEXTREC =" >> 43164ab3302SCarolineConcatto construct<InquireSpec::IntVar>(pure(InquireSpec::IntVar::Kind::Nextrec), 43264ab3302SCarolineConcatto scalar(integer(variable)))), 43364ab3302SCarolineConcatto construct<InquireSpec>("NUMBER =" >> 43464ab3302SCarolineConcatto construct<InquireSpec::IntVar>(pure(InquireSpec::IntVar::Kind::Number), 43564ab3302SCarolineConcatto scalar(integer(variable)))), 43664ab3302SCarolineConcatto construct<InquireSpec>("OPENED =" >> 43764ab3302SCarolineConcatto construct<InquireSpec::LogVar>( 43864ab3302SCarolineConcatto pure(InquireSpec::LogVar::Kind::Opened), scalarLogicalVariable)), 43964ab3302SCarolineConcatto construct<InquireSpec>("PAD =" >> 44064ab3302SCarolineConcatto construct<InquireSpec::CharVar>( 44164ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Pad), scalarDefaultCharVariable)), 44264ab3302SCarolineConcatto construct<InquireSpec>("PENDING =" >> 44364ab3302SCarolineConcatto construct<InquireSpec::LogVar>( 44464ab3302SCarolineConcatto pure(InquireSpec::LogVar::Kind::Pending), scalarLogicalVariable)), 44564ab3302SCarolineConcatto construct<InquireSpec>("POS =" >> 44664ab3302SCarolineConcatto construct<InquireSpec::IntVar>( 44764ab3302SCarolineConcatto pure(InquireSpec::IntVar::Kind::Pos), scalar(integer(variable)))), 44864ab3302SCarolineConcatto construct<InquireSpec>( 44964ab3302SCarolineConcatto "POSITION =" >> construct<InquireSpec::CharVar>( 45064ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Position), 45164ab3302SCarolineConcatto scalarDefaultCharVariable)), 45264ab3302SCarolineConcatto construct<InquireSpec>("READ =" >> 45364ab3302SCarolineConcatto construct<InquireSpec::CharVar>( 45464ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Read), scalarDefaultCharVariable)), 45564ab3302SCarolineConcatto construct<InquireSpec>( 45664ab3302SCarolineConcatto "READWRITE =" >> construct<InquireSpec::CharVar>( 45764ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Readwrite), 45864ab3302SCarolineConcatto scalarDefaultCharVariable)), 45964ab3302SCarolineConcatto construct<InquireSpec>("RECL =" >> 46064ab3302SCarolineConcatto construct<InquireSpec::IntVar>( 46164ab3302SCarolineConcatto pure(InquireSpec::IntVar::Kind::Recl), scalar(integer(variable)))), 46264ab3302SCarolineConcatto construct<InquireSpec>("ROUND =" >> 46364ab3302SCarolineConcatto construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Round), 46464ab3302SCarolineConcatto scalarDefaultCharVariable)), 46564ab3302SCarolineConcatto construct<InquireSpec>( 46664ab3302SCarolineConcatto "SEQUENTIAL =" >> construct<InquireSpec::CharVar>( 46764ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Sequential), 46864ab3302SCarolineConcatto scalarDefaultCharVariable)), 46964ab3302SCarolineConcatto construct<InquireSpec>("SIGN =" >> 47064ab3302SCarolineConcatto construct<InquireSpec::CharVar>( 47164ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Sign), scalarDefaultCharVariable)), 47264ab3302SCarolineConcatto construct<InquireSpec>("SIZE =" >> 47364ab3302SCarolineConcatto construct<InquireSpec::IntVar>( 47464ab3302SCarolineConcatto pure(InquireSpec::IntVar::Kind::Size), scalar(integer(variable)))), 47564ab3302SCarolineConcatto construct<InquireSpec>( 47664ab3302SCarolineConcatto "STREAM =" >> construct<InquireSpec::CharVar>( 47764ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Stream), 47864ab3302SCarolineConcatto scalarDefaultCharVariable)), 47964ab3302SCarolineConcatto construct<InquireSpec>( 48064ab3302SCarolineConcatto "STATUS =" >> construct<InquireSpec::CharVar>( 48164ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Status), 48264ab3302SCarolineConcatto scalarDefaultCharVariable)), 48364ab3302SCarolineConcatto construct<InquireSpec>( 48464ab3302SCarolineConcatto "UNFORMATTED =" >> construct<InquireSpec::CharVar>( 48564ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Unformatted), 48664ab3302SCarolineConcatto scalarDefaultCharVariable)), 48764ab3302SCarolineConcatto construct<InquireSpec>("WRITE =" >> 48864ab3302SCarolineConcatto construct<InquireSpec::CharVar>(pure(InquireSpec::CharVar::Kind::Write), 48964ab3302SCarolineConcatto scalarDefaultCharVariable)), 490c9637577Speter klausler extension<LanguageFeature::Carriagecontrol>( 4912d8b6a47SPeter Klausler "nonstandard usage: CARRIAGECONTROL="_port_en_US, 492c9637577Speter klausler construct<InquireSpec>("CARRIAGECONTROL =" >> 493c9637577Speter klausler construct<InquireSpec::CharVar>( 494c9637577Speter klausler pure(InquireSpec::CharVar::Kind::Carriagecontrol), 495c9637577Speter klausler scalarDefaultCharVariable))), 4962d8b6a47SPeter Klausler extension<LanguageFeature::Convert>( 4972d8b6a47SPeter Klausler "nonstandard usage: CONVERT="_port_en_US, 4982d8b6a47SPeter Klausler construct<InquireSpec>( 49964ab3302SCarolineConcatto "CONVERT =" >> construct<InquireSpec::CharVar>( 50064ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Convert), 50164ab3302SCarolineConcatto scalarDefaultCharVariable))), 5022d8b6a47SPeter Klausler extension<LanguageFeature::Dispose>( 5032d8b6a47SPeter Klausler "nonstandard usage: DISPOSE="_port_en_US, 5042d8b6a47SPeter Klausler construct<InquireSpec>( 50564ab3302SCarolineConcatto "DISPOSE =" >> construct<InquireSpec::CharVar>( 50664ab3302SCarolineConcatto pure(InquireSpec::CharVar::Kind::Dispose), 50764ab3302SCarolineConcatto scalarDefaultCharVariable))))) 50864ab3302SCarolineConcatto 50964ab3302SCarolineConcatto // R1230 inquire-stmt -> 51064ab3302SCarolineConcatto // INQUIRE ( inquire-spec-list ) | 51164ab3302SCarolineConcatto // INQUIRE ( IOLENGTH = scalar-int-variable ) output-item-list 51264ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("INQUIRE statement"_en_US, 51364ab3302SCarolineConcatto "INQUIRE" >> 51464ab3302SCarolineConcatto (construct<InquireStmt>( 51564ab3302SCarolineConcatto parenthesized(nonemptyList(Parser<InquireSpec>{}))) || 51664ab3302SCarolineConcatto construct<InquireStmt>(construct<InquireStmt::Iolength>( 51764ab3302SCarolineConcatto parenthesized("IOLENGTH =" >> scalar(integer(variable))), 51864ab3302SCarolineConcatto nonemptyList(outputItem))))) 51964ab3302SCarolineConcatto 52064ab3302SCarolineConcatto // R1301 format-stmt -> FORMAT format-specification 52164ab3302SCarolineConcatto // 13.2.1 allows spaces to appear "at any point" within a format specification 52264ab3302SCarolineConcatto // without effect, except of course within a character string edit descriptor. 52364ab3302SCarolineConcatto TYPE_CONTEXT_PARSER("FORMAT statement"_en_US, 52464ab3302SCarolineConcatto construct<FormatStmt>("FORMAT" >> Parser<format::FormatSpecification>{})) 52564ab3302SCarolineConcatto 52664ab3302SCarolineConcatto // R1321 char-string-edit-desc 52764ab3302SCarolineConcatto // N.B. C1313 disallows any kind parameter on the character literal. 52864ab3302SCarolineConcatto constexpr auto charStringEditDesc{ 52964ab3302SCarolineConcatto space >> (charLiteralConstantWithoutKind || rawHollerithLiteral)}; 53064ab3302SCarolineConcatto 53164ab3302SCarolineConcatto // R1303 format-items -> format-item [[,] format-item]... 53264ab3302SCarolineConcatto constexpr auto formatItems{ 53364ab3302SCarolineConcatto nonemptySeparated(space >> Parser<format::FormatItem>{}, maybe(","_tok))}; 53464ab3302SCarolineConcatto 53564ab3302SCarolineConcatto // R1306 r -> digit-string 53664ab3302SCarolineConcatto constexpr DigitStringIgnoreSpaces repeat; 53764ab3302SCarolineConcatto 53864ab3302SCarolineConcatto // R1304 format-item -> 53964ab3302SCarolineConcatto // [r] data-edit-desc | control-edit-desc | char-string-edit-desc | 54064ab3302SCarolineConcatto // [r] ( format-items ) 54164ab3302SCarolineConcatto TYPE_PARSER(construct<format::FormatItem>( 54264ab3302SCarolineConcatto maybe(repeat), Parser<format::IntrinsicTypeDataEditDesc>{}) || 54364ab3302SCarolineConcatto construct<format::FormatItem>( 54464ab3302SCarolineConcatto maybe(repeat), Parser<format::DerivedTypeDataEditDesc>{}) || 54564ab3302SCarolineConcatto construct<format::FormatItem>(Parser<format::ControlEditDesc>{}) || 54664ab3302SCarolineConcatto construct<format::FormatItem>(charStringEditDesc) || 54764ab3302SCarolineConcatto construct<format::FormatItem>(maybe(repeat), parenthesized(formatItems))) 54864ab3302SCarolineConcatto 54964ab3302SCarolineConcatto // R1302 format-specification -> 55064ab3302SCarolineConcatto // ( [format-items] ) | ( [format-items ,] unlimited-format-item ) 55164ab3302SCarolineConcatto // R1305 unlimited-format-item -> * ( format-items ) 55264ab3302SCarolineConcatto // minor extension: the comma is optional before the unlimited-format-item 55364ab3302SCarolineConcatto TYPE_PARSER(parenthesized(construct<format::FormatSpecification>( 55464ab3302SCarolineConcatto defaulted(formatItems / maybe(","_tok)), 55564ab3302SCarolineConcatto "*" >> parenthesized(formatItems)) || 55664ab3302SCarolineConcatto construct<format::FormatSpecification>(defaulted(formatItems)))) 55764ab3302SCarolineConcatto // R1308 w -> digit-string 55864ab3302SCarolineConcatto // R1309 m -> digit-string 55964ab3302SCarolineConcatto // R1310 d -> digit-string 56064ab3302SCarolineConcatto // R1311 e -> digit-string 56164ab3302SCarolineConcatto constexpr auto width{repeat}; 56264ab3302SCarolineConcatto constexpr auto mandatoryWidth{construct<std::optional<int>>(width)}; 56364ab3302SCarolineConcatto constexpr auto digits{repeat}; 56464ab3302SCarolineConcatto constexpr auto noInt{construct<std::optional<int>>()}; 56564ab3302SCarolineConcatto constexpr auto mandatoryDigits{construct<std::optional<int>>("." >> width)}; 56664ab3302SCarolineConcatto 567ac776499SPeter Klausler // The extra trailing spaces in the following quoted edit descriptor token 568ac776499SPeter Klausler // parsers are intentional: they inhibit any spurious warnings about missing 569ac776499SPeter Klausler // spaces in pedantic mode that would otherwise be emitted if the edit 570ac776499SPeter Klausler // descriptor were followed by a character that could appear in an identifier. 571ac776499SPeter Klausler 57264ab3302SCarolineConcatto // R1307 data-edit-desc -> 57364ab3302SCarolineConcatto // I w [. m] | B w [. m] | O w [. m] | Z w [. m] | F w . d | 57464ab3302SCarolineConcatto // E w . d [E e] | EN w . d [E e] | ES w . d [E e] | EX w . d [E e] | 57564ab3302SCarolineConcatto // G w [. d [E e]] | L w | A [w] | D w . d | 57664ab3302SCarolineConcatto // DT [char-literal-constant] [( v-list )] 57764ab3302SCarolineConcatto // (part 1 of 2) 57864ab3302SCarolineConcatto TYPE_PARSER(construct<format::IntrinsicTypeDataEditDesc>( 57964ab3302SCarolineConcatto "I " >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) || 58064ab3302SCarolineConcatto "B " >> pure(format::IntrinsicTypeDataEditDesc::Kind::B) || 58164ab3302SCarolineConcatto "O " >> pure(format::IntrinsicTypeDataEditDesc::Kind::O) || 58264ab3302SCarolineConcatto "Z " >> pure(format::IntrinsicTypeDataEditDesc::Kind::Z), 58364ab3302SCarolineConcatto mandatoryWidth, maybe("." >> digits), noInt) || 58464ab3302SCarolineConcatto construct<format::IntrinsicTypeDataEditDesc>( 58564ab3302SCarolineConcatto "F " >> pure(format::IntrinsicTypeDataEditDesc::Kind::F) || 58664ab3302SCarolineConcatto "D " >> pure(format::IntrinsicTypeDataEditDesc::Kind::D), 58764ab3302SCarolineConcatto mandatoryWidth, mandatoryDigits, noInt) || 58864ab3302SCarolineConcatto construct<format::IntrinsicTypeDataEditDesc>( 58964ab3302SCarolineConcatto "E " >> ("N " >> pure(format::IntrinsicTypeDataEditDesc::Kind::EN) || 59064ab3302SCarolineConcatto "S " >> pure(format::IntrinsicTypeDataEditDesc::Kind::ES) || 59164ab3302SCarolineConcatto "X " >> pure(format::IntrinsicTypeDataEditDesc::Kind::EX) || 59264ab3302SCarolineConcatto pure(format::IntrinsicTypeDataEditDesc::Kind::E)), 59364ab3302SCarolineConcatto mandatoryWidth, mandatoryDigits, maybe("E " >> digits)) || 59464ab3302SCarolineConcatto construct<format::IntrinsicTypeDataEditDesc>( 595ac776499SPeter Klausler "G " >> pure(format::IntrinsicTypeDataEditDesc::Kind::G), 596ac776499SPeter Klausler mandatoryWidth, mandatoryDigits, maybe("E " >> digits)) || 59764ab3302SCarolineConcatto construct<format::IntrinsicTypeDataEditDesc>( 59864ab3302SCarolineConcatto "G " >> pure(format::IntrinsicTypeDataEditDesc::Kind::G) || 59964ab3302SCarolineConcatto "L " >> pure(format::IntrinsicTypeDataEditDesc::Kind::L), 60064ab3302SCarolineConcatto mandatoryWidth, noInt, noInt) || 60164ab3302SCarolineConcatto construct<format::IntrinsicTypeDataEditDesc>( 60264ab3302SCarolineConcatto "A " >> pure(format::IntrinsicTypeDataEditDesc::Kind::A), maybe(width), 60364ab3302SCarolineConcatto noInt, noInt) || 60464ab3302SCarolineConcatto // PGI/Intel extension: omitting width (and all else that follows) 605cfa032ceSPeter Klausler // Parse them just to get them to the I/O checker in semantics; 606cfa032ceSPeter Klausler // they are not supported by the runtime. 607cfa032ceSPeter Klausler extension<LanguageFeature::AbbreviatedEditDescriptor>(construct< 608cfa032ceSPeter Klausler format::IntrinsicTypeDataEditDesc>( 60964ab3302SCarolineConcatto "I " >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) || 61064ab3302SCarolineConcatto ("B "_tok / !letter /* don't occlude BN & BZ */) >> 61164ab3302SCarolineConcatto pure(format::IntrinsicTypeDataEditDesc::Kind::B) || 61264ab3302SCarolineConcatto "O " >> pure(format::IntrinsicTypeDataEditDesc::Kind::O) || 61364ab3302SCarolineConcatto "Z " >> pure(format::IntrinsicTypeDataEditDesc::Kind::Z) || 61464ab3302SCarolineConcatto "F " >> pure(format::IntrinsicTypeDataEditDesc::Kind::F) || 61564ab3302SCarolineConcatto ("D "_tok / !letter /* don't occlude DT, DC, & DP */) >> 61664ab3302SCarolineConcatto pure(format::IntrinsicTypeDataEditDesc::Kind::D) || 61764ab3302SCarolineConcatto "E " >> 618cfa032ceSPeter Klausler ("N " >> pure(format::IntrinsicTypeDataEditDesc::Kind::EN) || 619cfa032ceSPeter Klausler "S " >> pure(format::IntrinsicTypeDataEditDesc::Kind::ES) || 620cfa032ceSPeter Klausler "X " >> pure(format::IntrinsicTypeDataEditDesc::Kind::EX) || 62164ab3302SCarolineConcatto pure(format::IntrinsicTypeDataEditDesc::Kind::E)) || 62264ab3302SCarolineConcatto "G " >> pure(format::IntrinsicTypeDataEditDesc::Kind::G) || 62364ab3302SCarolineConcatto "L " >> pure(format::IntrinsicTypeDataEditDesc::Kind::L), 62464ab3302SCarolineConcatto noInt, noInt, noInt))) 62564ab3302SCarolineConcatto 62664ab3302SCarolineConcatto // R1307 data-edit-desc (part 2 of 2) 62764ab3302SCarolineConcatto // R1312 v -> [sign] digit-string 62864ab3302SCarolineConcatto constexpr SignedDigitStringIgnoreSpaces scaleFactor; 62964ab3302SCarolineConcatto TYPE_PARSER(construct<format::DerivedTypeDataEditDesc>( 630ac776499SPeter Klausler "D T" >> defaulted(charLiteralConstantWithoutKind), 63164ab3302SCarolineConcatto defaulted(parenthesized(nonemptyList(scaleFactor))))) 63264ab3302SCarolineConcatto 63364ab3302SCarolineConcatto // R1314 k -> [sign] digit-string 63464ab3302SCarolineConcatto constexpr PositiveDigitStringIgnoreSpaces count; 63564ab3302SCarolineConcatto 63664ab3302SCarolineConcatto // R1313 control-edit-desc -> 63764ab3302SCarolineConcatto // position-edit-desc | [r] / | : | sign-edit-desc | k P | 63864ab3302SCarolineConcatto // blank-interp-edit-desc | round-edit-desc | decimal-edit-desc | 63964ab3302SCarolineConcatto // @ \ | $ 64064ab3302SCarolineConcatto // R1315 position-edit-desc -> T n | TL n | TR n | n X 64164ab3302SCarolineConcatto // R1316 n -> digit-string 64264ab3302SCarolineConcatto // R1317 sign-edit-desc -> SS | SP | S 64364ab3302SCarolineConcatto // R1318 blank-interp-edit-desc -> BN | BZ 64464ab3302SCarolineConcatto // R1319 round-edit-desc -> RU | RD | RZ | RN | RC | RP 64564ab3302SCarolineConcatto // R1320 decimal-edit-desc -> DC | DP 64664ab3302SCarolineConcatto TYPE_PARSER(construct<format::ControlEditDesc>( 647ac776499SPeter Klausler "T L " >> pure(format::ControlEditDesc::Kind::TL) || 648ac776499SPeter Klausler "T R " >> pure(format::ControlEditDesc::Kind::TR) || 649ac776499SPeter Klausler "T " >> pure(format::ControlEditDesc::Kind::T), 65064ab3302SCarolineConcatto count) || 65164ab3302SCarolineConcatto construct<format::ControlEditDesc>(count, 65264ab3302SCarolineConcatto "X " >> pure(format::ControlEditDesc::Kind::X) || 65364ab3302SCarolineConcatto "/" >> pure(format::ControlEditDesc::Kind::Slash)) || 65464ab3302SCarolineConcatto construct<format::ControlEditDesc>( 65564ab3302SCarolineConcatto "X " >> pure(format::ControlEditDesc::Kind::X) || 65664ab3302SCarolineConcatto "/" >> pure(format::ControlEditDesc::Kind::Slash)) || 65764ab3302SCarolineConcatto construct<format::ControlEditDesc>( 65864ab3302SCarolineConcatto scaleFactor, "P " >> pure(format::ControlEditDesc::Kind::P)) || 65964ab3302SCarolineConcatto construct<format::ControlEditDesc>( 66064ab3302SCarolineConcatto ":" >> pure(format::ControlEditDesc::Kind::Colon)) || 66164ab3302SCarolineConcatto "S " >> ("S " >> construct<format::ControlEditDesc>( 66264ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::SS)) || 66364ab3302SCarolineConcatto "P " >> construct<format::ControlEditDesc>( 66464ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::SP)) || 66564ab3302SCarolineConcatto construct<format::ControlEditDesc>( 66664ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::S))) || 66764ab3302SCarolineConcatto "B " >> ("N " >> construct<format::ControlEditDesc>( 66864ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::BN)) || 66964ab3302SCarolineConcatto "Z " >> construct<format::ControlEditDesc>( 67064ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::BZ))) || 67164ab3302SCarolineConcatto "R " >> ("U " >> construct<format::ControlEditDesc>( 67264ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::RU)) || 67364ab3302SCarolineConcatto "D " >> construct<format::ControlEditDesc>( 67464ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::RD)) || 67564ab3302SCarolineConcatto "Z " >> construct<format::ControlEditDesc>( 67664ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::RZ)) || 67764ab3302SCarolineConcatto "N " >> construct<format::ControlEditDesc>( 67864ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::RN)) || 67964ab3302SCarolineConcatto "C " >> construct<format::ControlEditDesc>( 68064ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::RC)) || 68164ab3302SCarolineConcatto "P " >> construct<format::ControlEditDesc>( 68264ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::RP))) || 68364ab3302SCarolineConcatto "D " >> ("C " >> construct<format::ControlEditDesc>( 68464ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::DC)) || 68564ab3302SCarolineConcatto "P " >> construct<format::ControlEditDesc>( 68664ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::DP))) || 68764ab3302SCarolineConcatto extension<LanguageFeature::AdditionalFormats>( 6882d8b6a47SPeter Klausler "nonstandard usage: $ and \\ control edit descriptors"_port_en_US, 68964ab3302SCarolineConcatto "$" >> construct<format::ControlEditDesc>( 69064ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::Dollar)) || 69164ab3302SCarolineConcatto "\\" >> construct<format::ControlEditDesc>( 69264ab3302SCarolineConcatto pure(format::ControlEditDesc::Kind::Backslash)))) 6931f879005STim Keith } // namespace Fortran::parser 694