FLANG
format-specification.h
1//===-- include/flang/Parser/format-specification.h -------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef FORTRAN_PARSER_FORMAT_SPECIFICATION_H_
10#define FORTRAN_PARSER_FORMAT_SPECIFICATION_H_
11
12// Represent parses of Fortran format specifications from FORMAT statements
13// and character literals in formatted I/O statements at compilation time
14// as well as from character variables and expressions at run time.
15// From requirement productions R1302-R1321 of the Fortran 2018 draft
16// standard (q.v.), extended with Hollerith. These structures have been
17// isolated so that they may be used in the run-time without introducing
18// dependences on other parts of the compiler's source code.
19// TODO: support Q formatting extension?
20
21#include "flang/Common/idioms.h"
22#include <cinttypes>
23#include <list>
24#include <optional>
25#include <string>
26#include <variant>
27
28namespace Fortran::format {
29
30// R1307 data-edit-desc (part 1 of 2) ->
31// I w [. m] | B w [. m] | O w [. m] | Z w [. m] | F w . d |
32// E w . d [E e] | EN w . d [E e] | ES w . d [E e] | EX w . d [E e] |
33// G w [. d [E e]] | L w | A [w] | D w . d
34// R1308 w -> digit-string
35// R1309 m -> digit-string
36// R1310 d -> digit-string
37// R1311 e -> digit-string
38struct IntrinsicTypeDataEditDesc {
39 enum class Kind { I, B, O, Z, F, E, EN, ES, EX, G, L, A, D };
40 IntrinsicTypeDataEditDesc() = delete;
41 IntrinsicTypeDataEditDesc(IntrinsicTypeDataEditDesc &&) = default;
42 IntrinsicTypeDataEditDesc &operator=(IntrinsicTypeDataEditDesc &&) = default;
43 IntrinsicTypeDataEditDesc(Kind &&k, std::optional<int> &&w,
44 std::optional<int> &&d, std::optional<int> &&e)
45 : kind{k}, width{std::move(w)}, digits{std::move(d)}, exponentWidth{
46 std::move(e)} {}
47 Kind kind;
48 std::optional<int> width; // w
49 std::optional<int> digits; // m or d
50 std::optional<int> exponentWidth; // e
51};
52
53// R1307 data-edit-desc (part 2 of 2) ->
54// DT [char-literal-constant] [( v-list )]
55// R1312 v -> [sign] digit-string
56struct DerivedTypeDataEditDesc {
57 DerivedTypeDataEditDesc() = delete;
58 DerivedTypeDataEditDesc(DerivedTypeDataEditDesc &&) = default;
59 DerivedTypeDataEditDesc &operator=(DerivedTypeDataEditDesc &&) = default;
60 DerivedTypeDataEditDesc(std::string &&t, std::list<std::int64_t> &&p)
61 : type{std::move(t)}, parameters{std::move(p)} {}
62 std::string type;
63 std::list<std::int64_t> parameters;
64};
65
66// R1313 control-edit-desc ->
67// position-edit-desc | [r] / | : | sign-edit-desc | k P |
68// blank-interp-edit-desc | round-edit-desc | decimal-edit-desc |
69// @ \ | $
70// R1315 position-edit-desc -> T n | TL n | TR n | n X
71// R1316 n -> digit-string
72// R1317 sign-edit-desc -> SS | SP | S
73// R1318 blank-interp-edit-desc -> BN | BZ
74// R1319 round-edit-desc -> RU | RD | RZ | RN | RC | RP
75// R1320 decimal-edit-desc -> DC | DP
76struct ControlEditDesc {
77 enum class Kind {
78 T,
79 TL,
80 TR,
81 X,
82 Slash,
83 Colon,
84 SS,
85 SP,
86 S,
87 P,
88 BN,
89 BZ,
90 RU,
91 RD,
92 RZ,
93 RN,
94 RC,
95 RP,
96 DC,
97 DP,
98 LZ, // F202X: processor-dependent leading zero, default
99 LZS, // F202X: suppress leading zeros
100 LZP, // F202X: print leading zero
101 Dollar, // extension: inhibit newline on output
102 Backslash, // ditto, but only on terminals
103 };
104 ControlEditDesc() = delete;
105 ControlEditDesc(ControlEditDesc &&) = default;
106 ControlEditDesc &operator=(ControlEditDesc &&) = default;
107 explicit ControlEditDesc(Kind k) : kind{k} {}
108 ControlEditDesc(Kind k, std::int64_t ct) : kind{k}, count{ct} {}
109 ControlEditDesc(std::int64_t ct, Kind k) : kind{k}, count{ct} {}
110 Kind kind;
111 std::int64_t count{1}; // r, k, or n
112};
113
114// R1304 format-item ->
115// [r] data-edit-desc | control-edit-desc | char-string-edit-desc |
116// [r] ( format-items )
117// R1306 r -> digit-string
118// R1321 char-string-edit-desc
119struct FormatItem {
120 FormatItem() = delete;
121 FormatItem(FormatItem &&) = default;
122 FormatItem &operator=(FormatItem &&) = default;
123 template <typename A, typename = common::NoLvalue<A>>
124 FormatItem(std::optional<std::uint64_t> &&r, A &&x)
125 : repeatCount{std::move(r)}, u{std::move(x)} {}
126 template <typename A, typename = common::NoLvalue<A>>
127 explicit FormatItem(A &&x) : u{std::move(x)} {}
128 std::optional<std::uint64_t> repeatCount;
130 ControlEditDesc, std::string, std::list<FormatItem>>
131 u;
132};
133
134// R1302 format-specification ->
135// ( [format-items] ) | ( [format-items ,] unlimited-format-item )
136// R1303 format-items -> format-item [[,] format-item]...
137// R1305 unlimited-format-item -> * ( format-items )
138struct FormatSpecification {
139 FormatSpecification() = delete;
140 FormatSpecification(FormatSpecification &&) = default;
141 FormatSpecification &operator=(FormatSpecification &&) = default;
142 explicit FormatSpecification(std::list<FormatItem> &&is)
143 : items(std::move(is)) {}
144 FormatSpecification(std::list<FormatItem> &&is, std::list<FormatItem> &&us)
145 : items(std::move(is)), unlimitedItems(std::move(us)) {}
146 std::list<FormatItem> items, unlimitedItems;
147};
148} // namespace Fortran::format
149#endif // FORTRAN_PARSER_FORMAT_SPECIFICATION_H_
Definition format-specification.h:76
Definition format-specification.h:56
Definition format-specification.h:38