xref: /llvm-project/flang/lib/Parser/io-parsers.cpp (revision 047168dae79cd6e0087eb86810006c635f017df6)
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