Warning: This file is not a C or C++ file. It does not have highlighting.
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 | |
28 | namespace 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 |
38 | struct 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 |
56 | struct 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 |
76 | struct 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 | Dollar, // extension: inhibit newline on output |
99 | Backslash, // ditto, but only on terminals |
100 | }; |
101 | ControlEditDesc() = delete; |
102 | ControlEditDesc(ControlEditDesc &&) = default; |
103 | ControlEditDesc &operator=(ControlEditDesc &&) = default; |
104 | explicit ControlEditDesc(Kind k) : kind{k} {} |
105 | ControlEditDesc(Kind k, std::int64_t ct) : kind{k}, count{ct} {} |
106 | ControlEditDesc(std::int64_t ct, Kind k) : kind{k}, count{ct} {} |
107 | Kind kind; |
108 | std::int64_t count{1}; // r, k, or n |
109 | }; |
110 | |
111 | // R1304 format-item -> |
112 | // [r] data-edit-desc | control-edit-desc | char-string-edit-desc | |
113 | // [r] ( format-items ) |
114 | // R1306 r -> digit-string |
115 | // R1321 char-string-edit-desc |
116 | struct FormatItem { |
117 | FormatItem() = delete; |
118 | FormatItem(FormatItem &&) = default; |
119 | FormatItem &operator=(FormatItem &&) = default; |
120 | template <typename A, typename = common::NoLvalue<A>> |
121 | FormatItem(std::optional<std::uint64_t> &&r, A &&x) |
122 | : repeatCount{std::move(r)}, u{std::move(x)} {} |
123 | template <typename A, typename = common::NoLvalue<A>> |
124 | explicit FormatItem(A &&x) : u{std::move(x)} {} |
125 | std::optional<std::uint64_t> repeatCount; |
126 | std::variant<IntrinsicTypeDataEditDesc, DerivedTypeDataEditDesc, |
127 | ControlEditDesc, std::string, std::list<FormatItem>> |
128 | u; |
129 | }; |
130 | |
131 | // R1302 format-specification -> |
132 | // ( [format-items] ) | ( [format-items ,] unlimited-format-item ) |
133 | // R1303 format-items -> format-item [[,] format-item]... |
134 | // R1305 unlimited-format-item -> * ( format-items ) |
135 | struct FormatSpecification { |
136 | FormatSpecification() = delete; |
137 | FormatSpecification(FormatSpecification &&) = default; |
138 | FormatSpecification &operator=(FormatSpecification &&) = default; |
139 | explicit FormatSpecification(std::list<FormatItem> &&is) |
140 | : items(std::move(is)) {} |
141 | FormatSpecification(std::list<FormatItem> &&is, std::list<FormatItem> &&us) |
142 | : items(std::move(is)), unlimitedItems(std::move(us)) {} |
143 | std::list<FormatItem> items, unlimitedItems; |
144 | }; |
145 | } // namespace Fortran::format |
146 | #endif // FORTRAN_PARSER_FORMAT_SPECIFICATION_H_ |
147 |
Warning: This file is not a C or C++ file. It does not have highlighting.