forked from OSchip/llvm-project
[flang] Ensure that the parse tree visitation Walk template works on FORMAT.
The classes that were segregated into format-specification.h have also been grouped into a new Fortran::format namespace. Code added to tools/f18/f18.cc to run a minimal visitor over the parse trees resulting from successful parses so that any future build problems with Walk() will be caught earlier. Rearrange Walk instances, keep format:: ones together. Original-commit: flang-compiler/f18@685ddb91ce Reviewed-on: https://github.com/flang-compiler/f18/pull/22
This commit is contained in:
parent
c88b23e04e
commit
20364f0351
|
@ -17,6 +17,7 @@
|
|||
#include <variant>
|
||||
|
||||
namespace Fortran {
|
||||
namespace format {
|
||||
|
||||
// R1307 data-edit-desc (part 1 of 2) ->
|
||||
// I w [. m] | B w [. m] | O w [. m] | Z w [. m] | F w . d |
|
||||
|
@ -129,5 +130,6 @@ struct FormatSpecification {
|
|||
: items(std::move(is)), unlimitedItems(std::move(us)) {}
|
||||
std::list<FormatItem> items, unlimitedItems;
|
||||
};
|
||||
} // namespace format
|
||||
} // namespace Fortran
|
||||
#endif // FORTRAN_FORMAT_SPECIFICATION_H_
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
#include "basic-parsers.h"
|
||||
#include "characters.h"
|
||||
#include "format-specification.h"
|
||||
#include "parse-tree.h"
|
||||
#include "token-parsers.h"
|
||||
#include "user-state.h"
|
||||
|
@ -3060,7 +3059,7 @@ TYPE_CONTEXT_PARSER("INQUIRE statement"_en_US,
|
|||
|
||||
// R1301 format-stmt -> FORMAT format-specification
|
||||
TYPE_CONTEXT_PARSER("FORMAT statement"_en_US,
|
||||
"FORMAT" >> construct<FormatStmt>{}(Parser<FormatSpecification>{}))
|
||||
"FORMAT" >> construct<FormatStmt>{}(Parser<format::FormatSpecification>{}))
|
||||
|
||||
// R1321 char-string-edit-desc
|
||||
// N.B. C1313 disallows any kind parameter on the character literal.
|
||||
|
@ -3069,7 +3068,7 @@ constexpr auto charStringEditDesc = spaces >>
|
|||
|
||||
// R1303 format-items -> format-item [[,] format-item]...
|
||||
constexpr auto formatItems =
|
||||
nonemptySeparated(Parser<FormatItem>{}, maybe(","_tok));
|
||||
nonemptySeparated(Parser<format::FormatItem>{}, maybe(","_tok));
|
||||
|
||||
// R1306 r -> digit-string
|
||||
static inline int castU64ToInt(std::uint64_t &&n) {
|
||||
|
@ -3081,20 +3080,21 @@ constexpr auto repeat = spaces >> applyFunction(castU64ToInt, digitString);
|
|||
// R1304 format-item ->
|
||||
// [r] data-edit-desc | control-edit-desc | char-string-edit-desc |
|
||||
// [r] ( format-items )
|
||||
TYPE_PARSER(construct<FormatItem>{}(
|
||||
maybe(repeat), Parser<IntrinsicTypeDataEditDesc>{}) ||
|
||||
construct<FormatItem>{}(maybe(repeat), Parser<DerivedTypeDataEditDesc>{}) ||
|
||||
construct<FormatItem>{}(Parser<ControlEditDesc>{}) ||
|
||||
construct<FormatItem>{}(charStringEditDesc) ||
|
||||
construct<FormatItem>{}(maybe(repeat), parenthesized(formatItems)))
|
||||
TYPE_PARSER(construct<format::FormatItem>{}(
|
||||
maybe(repeat), Parser<format::IntrinsicTypeDataEditDesc>{}) ||
|
||||
construct<format::FormatItem>{}(
|
||||
maybe(repeat), Parser<format::DerivedTypeDataEditDesc>{}) ||
|
||||
construct<format::FormatItem>{}(Parser<format::ControlEditDesc>{}) ||
|
||||
construct<format::FormatItem>{}(charStringEditDesc) ||
|
||||
construct<format::FormatItem>{}(maybe(repeat), parenthesized(formatItems)))
|
||||
|
||||
// R1302 format-specification ->
|
||||
// ( [format-items] ) | ( [format-items ,] unlimited-format-item )
|
||||
// R1305 unlimited-format-item -> * ( format-items )
|
||||
TYPE_PARSER(
|
||||
parenthesized(construct<FormatSpecification>{}(defaulted(formatItems)) ||
|
||||
construct<FormatSpecification>{}(
|
||||
defaulted(formatItems / ","), "*" >> parenthesized(formatItems))))
|
||||
TYPE_PARSER(parenthesized(
|
||||
construct<format::FormatSpecification>{}(defaulted(formatItems)) ||
|
||||
construct<format::FormatSpecification>{}(
|
||||
defaulted(formatItems / ","), "*" >> parenthesized(formatItems))))
|
||||
// R1308 w -> digit-string
|
||||
// R1309 m -> digit-string
|
||||
// R1310 d -> digit-string
|
||||
|
@ -3111,54 +3111,54 @@ constexpr auto mandatoryDigits = "." >> construct<std::optional<int>>{}(width);
|
|||
// G w [. d [E e]] | L w | A [w] | D w . d |
|
||||
// DT [char-literal-constant] [( v-list )]
|
||||
// (part 1 of 2)
|
||||
TYPE_PARSER(construct<IntrinsicTypeDataEditDesc>{}(
|
||||
"I" >> pure(IntrinsicTypeDataEditDesc::Kind::I) ||
|
||||
"B" >> pure(IntrinsicTypeDataEditDesc::Kind::B) ||
|
||||
"O" >> pure(IntrinsicTypeDataEditDesc::Kind::O) ||
|
||||
"Z" >> pure(IntrinsicTypeDataEditDesc::Kind::Z),
|
||||
TYPE_PARSER(construct<format::IntrinsicTypeDataEditDesc>{}(
|
||||
"I" >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) ||
|
||||
"B" >> pure(format::IntrinsicTypeDataEditDesc::Kind::B) ||
|
||||
"O" >> pure(format::IntrinsicTypeDataEditDesc::Kind::O) ||
|
||||
"Z" >> pure(format::IntrinsicTypeDataEditDesc::Kind::Z),
|
||||
mandatoryWidth, maybe("." >> digits), noInt) ||
|
||||
construct<IntrinsicTypeDataEditDesc>{}(
|
||||
"F" >> pure(IntrinsicTypeDataEditDesc::Kind::F) ||
|
||||
"D" >> pure(IntrinsicTypeDataEditDesc::Kind::D),
|
||||
construct<format::IntrinsicTypeDataEditDesc>{}(
|
||||
"F" >> pure(format::IntrinsicTypeDataEditDesc::Kind::F) ||
|
||||
"D" >> pure(format::IntrinsicTypeDataEditDesc::Kind::D),
|
||||
mandatoryWidth, mandatoryDigits, noInt) ||
|
||||
construct<IntrinsicTypeDataEditDesc>{}(
|
||||
"EN" >> pure(IntrinsicTypeDataEditDesc::Kind::EN) ||
|
||||
"ES" >> pure(IntrinsicTypeDataEditDesc::Kind::ES) ||
|
||||
"EX" >> pure(IntrinsicTypeDataEditDesc::Kind::EX) ||
|
||||
"E" >> pure(IntrinsicTypeDataEditDesc::Kind::E),
|
||||
construct<format::IntrinsicTypeDataEditDesc>{}(
|
||||
"EN" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EN) ||
|
||||
"ES" >> pure(format::IntrinsicTypeDataEditDesc::Kind::ES) ||
|
||||
"EX" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EX) ||
|
||||
"E" >> pure(format::IntrinsicTypeDataEditDesc::Kind::E),
|
||||
mandatoryWidth, mandatoryDigits, maybe("E" >> digits)) ||
|
||||
construct<IntrinsicTypeDataEditDesc>{}(
|
||||
"G" >> pure(IntrinsicTypeDataEditDesc::Kind::G), mandatoryWidth,
|
||||
construct<format::IntrinsicTypeDataEditDesc>{}(
|
||||
"G" >> pure(format::IntrinsicTypeDataEditDesc::Kind::G), mandatoryWidth,
|
||||
mandatoryDigits, maybe("E" >> digits)) ||
|
||||
construct<IntrinsicTypeDataEditDesc>{}(
|
||||
"G" >> pure(IntrinsicTypeDataEditDesc::Kind::G) ||
|
||||
"L" >> pure(IntrinsicTypeDataEditDesc::Kind::L),
|
||||
construct<format::IntrinsicTypeDataEditDesc>{}(
|
||||
"G" >> pure(format::IntrinsicTypeDataEditDesc::Kind::G) ||
|
||||
"L" >> pure(format::IntrinsicTypeDataEditDesc::Kind::L),
|
||||
mandatoryWidth, noInt, noInt) ||
|
||||
construct<IntrinsicTypeDataEditDesc>{}(
|
||||
"A" >> pure(IntrinsicTypeDataEditDesc::Kind::A), maybe(width), noInt,
|
||||
noInt) ||
|
||||
construct<format::IntrinsicTypeDataEditDesc>{}(
|
||||
"A" >> pure(format::IntrinsicTypeDataEditDesc::Kind::A), maybe(width),
|
||||
noInt, noInt) ||
|
||||
// PGI/Intel extension: omitting width (and all else that follows)
|
||||
extension(construct<IntrinsicTypeDataEditDesc>{}(
|
||||
"I" >> pure(IntrinsicTypeDataEditDesc::Kind::I) ||
|
||||
extension(construct<format::IntrinsicTypeDataEditDesc>{}(
|
||||
"I" >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) ||
|
||||
("B"_tok / !letter /* don't occlude BN & BZ */) >>
|
||||
pure(IntrinsicTypeDataEditDesc::Kind::B) ||
|
||||
"O" >> pure(IntrinsicTypeDataEditDesc::Kind::O) ||
|
||||
"Z" >> pure(IntrinsicTypeDataEditDesc::Kind::Z) ||
|
||||
"F" >> pure(IntrinsicTypeDataEditDesc::Kind::F) ||
|
||||
pure(format::IntrinsicTypeDataEditDesc::Kind::B) ||
|
||||
"O" >> pure(format::IntrinsicTypeDataEditDesc::Kind::O) ||
|
||||
"Z" >> pure(format::IntrinsicTypeDataEditDesc::Kind::Z) ||
|
||||
"F" >> pure(format::IntrinsicTypeDataEditDesc::Kind::F) ||
|
||||
("D"_tok / !letter /* don't occlude DC & DP */) >>
|
||||
pure(IntrinsicTypeDataEditDesc::Kind::D) ||
|
||||
"EN" >> pure(IntrinsicTypeDataEditDesc::Kind::EN) ||
|
||||
"ES" >> pure(IntrinsicTypeDataEditDesc::Kind::ES) ||
|
||||
"EX" >> pure(IntrinsicTypeDataEditDesc::Kind::EX) ||
|
||||
"E" >> pure(IntrinsicTypeDataEditDesc::Kind::E) ||
|
||||
"G" >> pure(IntrinsicTypeDataEditDesc::Kind::G) ||
|
||||
"L" >> pure(IntrinsicTypeDataEditDesc::Kind::L),
|
||||
pure(format::IntrinsicTypeDataEditDesc::Kind::D) ||
|
||||
"EN" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EN) ||
|
||||
"ES" >> pure(format::IntrinsicTypeDataEditDesc::Kind::ES) ||
|
||||
"EX" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EX) ||
|
||||
"E" >> pure(format::IntrinsicTypeDataEditDesc::Kind::E) ||
|
||||
"G" >> pure(format::IntrinsicTypeDataEditDesc::Kind::G) ||
|
||||
"L" >> pure(format::IntrinsicTypeDataEditDesc::Kind::L),
|
||||
noInt, noInt, noInt)))
|
||||
|
||||
// R1307 data-edit-desc (part 2 of 2)
|
||||
// R1312 v -> [sign] digit-string
|
||||
TYPE_PARSER("DT" >>
|
||||
construct<DerivedTypeDataEditDesc>{}(
|
||||
construct<format::DerivedTypeDataEditDesc>{}(
|
||||
spaces >> defaulted(charLiteralConstantWithoutKind),
|
||||
defaulted(parenthesized(nonemptyList(spaces >> signedDigitString)))))
|
||||
|
||||
|
@ -3178,32 +3178,47 @@ constexpr auto scaleFactor = spaces >>
|
|||
// R1318 blank-interp-edit-desc -> BN | BZ
|
||||
// R1319 round-edit-desc -> RU | RD | RZ | RN | RC | RP
|
||||
// R1320 decimal-edit-desc -> DC | DP
|
||||
TYPE_PARSER(
|
||||
construct<ControlEditDesc>{}("TL" >> pure(ControlEditDesc::Kind::TL) ||
|
||||
"TR" >> pure(ControlEditDesc::Kind::TR) ||
|
||||
"T" >> pure(ControlEditDesc::Kind::T),
|
||||
repeat) ||
|
||||
construct<ControlEditDesc>{}(repeat,
|
||||
"X" >> pure(ControlEditDesc::Kind::X) ||
|
||||
"/" >> pure(ControlEditDesc::Kind::Slash)) ||
|
||||
construct<ControlEditDesc>{}("X" >> pure(ControlEditDesc::Kind::X) ||
|
||||
"/" >> pure(ControlEditDesc::Kind::Slash)) ||
|
||||
construct<ControlEditDesc>{}(
|
||||
scaleFactor, "P" >> pure(ControlEditDesc::Kind::P)) ||
|
||||
":" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::Colon)) ||
|
||||
"SS" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::SS)) ||
|
||||
"SP" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::SP)) ||
|
||||
"S" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::S)) ||
|
||||
"BN" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::BN)) ||
|
||||
"BZ" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::BZ)) ||
|
||||
"RU" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RU)) ||
|
||||
"RD" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RD)) ||
|
||||
"RZ" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RZ)) ||
|
||||
"RN" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RN)) ||
|
||||
"RC" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RC)) ||
|
||||
"RP" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RP)) ||
|
||||
"DC" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::DC)) ||
|
||||
"DP" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::DP)))
|
||||
TYPE_PARSER(construct<format::ControlEditDesc>{}(
|
||||
"TL" >> pure(format::ControlEditDesc::Kind::TL) ||
|
||||
"TR" >> pure(format::ControlEditDesc::Kind::TR) ||
|
||||
"T" >> pure(format::ControlEditDesc::Kind::T),
|
||||
repeat) ||
|
||||
construct<format::ControlEditDesc>{}(repeat,
|
||||
"X" >> pure(format::ControlEditDesc::Kind::X) ||
|
||||
"/" >> pure(format::ControlEditDesc::Kind::Slash)) ||
|
||||
construct<format::ControlEditDesc>{}(
|
||||
"X" >> pure(format::ControlEditDesc::Kind::X) ||
|
||||
"/" >> pure(format::ControlEditDesc::Kind::Slash)) ||
|
||||
construct<format::ControlEditDesc>{}(
|
||||
scaleFactor, "P" >> pure(format::ControlEditDesc::Kind::P)) ||
|
||||
":" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::Colon)) ||
|
||||
"SS" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::SS)) ||
|
||||
"SP" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::SP)) ||
|
||||
"S" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::S)) ||
|
||||
"BN" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::BN)) ||
|
||||
"BZ" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::BZ)) ||
|
||||
"RU" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::RU)) ||
|
||||
"RD" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::RD)) ||
|
||||
"RZ" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::RZ)) ||
|
||||
"RN" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::RN)) ||
|
||||
"RC" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::RC)) ||
|
||||
"RP" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::RP)) ||
|
||||
"DC" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::DC)) ||
|
||||
"DP" >> construct<format::ControlEditDesc>{}(
|
||||
pure(format::ControlEditDesc::Kind::DP)))
|
||||
|
||||
// R1401 main-program ->
|
||||
// [program-stmt] [specification-part] [execution-part]
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
|
||||
#define FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
|
||||
|
||||
#include "format-specification.h"
|
||||
#include "parse-tree.h"
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
|
@ -28,6 +27,12 @@ Walk(const A &x, V &visitor) {
|
|||
}
|
||||
}
|
||||
|
||||
template<typename V> void Walk(const format::ControlEditDesc &, V &);
|
||||
template<typename V> void Walk(const format::DerivedTypeDataEditDesc &, V &);
|
||||
template<typename V> void Walk(const format::FormatItem &, V &);
|
||||
template<typename V> void Walk(const format::FormatSpecification &, V &);
|
||||
template<typename V> void Walk(const format::IntrinsicTypeDataEditDesc &, V &);
|
||||
|
||||
// Traversal of needed STL template classes (optional, list, tuple, variant)
|
||||
template<typename T, typename V>
|
||||
void Walk(const std::optional<T> &x, V &visitor) {
|
||||
|
@ -173,44 +178,6 @@ template<typename V> void Walk(const DeclarationTypeSpec::Type &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const Fortran::ControlEditDesc &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
void Walk(const Fortran::DerivedTypeDataEditDesc &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.type, visitor);
|
||||
Walk(x.parameters, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const Fortran::FormatItem &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.repeatCount, visitor);
|
||||
Walk(x.u, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const FormatSpecification &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.items, visitor);
|
||||
Walk(x.unlimitedItems, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
void Walk(const Fortran::IntrinsicTypeDataEditDesc &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
Walk(x.width, visitor);
|
||||
Walk(x.digits, visitor);
|
||||
Walk(x.exponentWidth, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const ImportStmt &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.names, visitor);
|
||||
|
@ -327,6 +294,45 @@ template<typename V> void Walk(const WriteStmt &x, V &visitor) {
|
|||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const format::ControlEditDesc &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
void Walk(const format::DerivedTypeDataEditDesc &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.type, visitor);
|
||||
Walk(x.parameters, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V> void Walk(const format::FormatItem &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.repeatCount, visitor);
|
||||
Walk(x.u, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
void Walk(const format::FormatSpecification &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.items, visitor);
|
||||
Walk(x.unlimitedItems, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
template<typename V>
|
||||
void Walk(const format::IntrinsicTypeDataEditDesc &x, V &visitor) {
|
||||
if (visitor.Pre(x)) {
|
||||
Walk(x.kind, visitor);
|
||||
Walk(x.width, visitor);
|
||||
Walk(x.digits, visitor);
|
||||
Walk(x.exponentWidth, visitor);
|
||||
visitor.Post(x);
|
||||
}
|
||||
}
|
||||
} // namespace parser
|
||||
} // namespace Fortran
|
||||
#endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
|
||||
|
|
|
@ -306,7 +306,8 @@ std::ostream &operator<<(std::ostream &o, const Rename::Names &x) { // R1411
|
|||
#undef TUPLE_FORMATTER
|
||||
|
||||
// R1302 format-specification
|
||||
std::ostream &operator<<(std::ostream &o, const FormatSpecification &x) {
|
||||
std::ostream &operator<<(
|
||||
std::ostream &o, const format::FormatSpecification &x) {
|
||||
return o << "(FormatSpecification " << x.items << ' ' << x.unlimitedItems
|
||||
<< ')';
|
||||
}
|
||||
|
@ -821,22 +822,23 @@ std::ostream &operator<<(std::ostream &o, const CaseValueRange::Range &x) {
|
|||
}
|
||||
|
||||
// R1307 data-edit-desc (part 1 of 2)
|
||||
std::ostream &operator<<(std::ostream &o, const IntrinsicTypeDataEditDesc &x) {
|
||||
std::ostream &operator<<(
|
||||
std::ostream &o, const format::IntrinsicTypeDataEditDesc &x) {
|
||||
o << "(IntrinsicTypeDataEditDesc ";
|
||||
switch (x.kind) {
|
||||
case IntrinsicTypeDataEditDesc::Kind::I: o << "I "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::B: o << "B "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::O: o << "O "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::Z: o << "Z "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::F: o << "F "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::E: o << "E "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::EN: o << "EN "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::ES: o << "ES "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::EX: o << "EX "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::G: o << "G "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::L: o << "L "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::A: o << "A "; break;
|
||||
case IntrinsicTypeDataEditDesc::Kind::D: o << "D "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::I: o << "I "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::B: o << "B "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::O: o << "O "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::Z: o << "Z "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::F: o << "F "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::E: o << "E "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::EN: o << "EN "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::ES: o << "ES "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::EX: o << "EX "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::G: o << "G "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::L: o << "L "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::A: o << "A "; break;
|
||||
case format::IntrinsicTypeDataEditDesc::Kind::D: o << "D "; break;
|
||||
default: CRASH_NO_CASE;
|
||||
}
|
||||
return o << x.width << ' ' << x.digits << ' ' << x.exponentWidth << ')';
|
||||
|
@ -855,41 +857,42 @@ std::ostream &operator<<(std::ostream &o, const WriteStmt &x) {
|
|||
}
|
||||
|
||||
// R1307 data-edit-desc (part 2 of 2)
|
||||
std::ostream &operator<<(std::ostream &o, const DerivedTypeDataEditDesc &x) {
|
||||
std::ostream &operator<<(
|
||||
std::ostream &o, const format::DerivedTypeDataEditDesc &x) {
|
||||
return o << "(DerivedTypeDataEditDesc " << x.type << ' ' << x.parameters
|
||||
<< ')';
|
||||
}
|
||||
|
||||
// R1313 control-edit-desc
|
||||
std::ostream &operator<<(std::ostream &o, const ControlEditDesc &x) {
|
||||
std::ostream &operator<<(std::ostream &o, const format::ControlEditDesc &x) {
|
||||
o << "(ControlEditDesc ";
|
||||
switch (x.kind) {
|
||||
case ControlEditDesc::Kind::T: o << "T "; break;
|
||||
case ControlEditDesc::Kind::TL: o << "TL "; break;
|
||||
case ControlEditDesc::Kind::TR: o << "TR "; break;
|
||||
case ControlEditDesc::Kind::X: o << "X "; break;
|
||||
case ControlEditDesc::Kind::Slash: o << "/ "; break;
|
||||
case ControlEditDesc::Kind::Colon: o << ": "; break;
|
||||
case ControlEditDesc::Kind::SS: o << "SS "; break;
|
||||
case ControlEditDesc::Kind::SP: o << "SP "; break;
|
||||
case ControlEditDesc::Kind::S: o << "S "; break;
|
||||
case ControlEditDesc::Kind::P: o << "P "; break;
|
||||
case ControlEditDesc::Kind::BN: o << "BN "; break;
|
||||
case ControlEditDesc::Kind::BZ: o << "BZ "; break;
|
||||
case ControlEditDesc::Kind::RU: o << "RU "; break;
|
||||
case ControlEditDesc::Kind::RD: o << "RD "; break;
|
||||
case ControlEditDesc::Kind::RN: o << "RN "; break;
|
||||
case ControlEditDesc::Kind::RC: o << "RC "; break;
|
||||
case ControlEditDesc::Kind::RP: o << "RP "; break;
|
||||
case ControlEditDesc::Kind::DC: o << "DC "; break;
|
||||
case ControlEditDesc::Kind::DP: o << "DP "; break;
|
||||
case format::ControlEditDesc::Kind::T: o << "T "; break;
|
||||
case format::ControlEditDesc::Kind::TL: o << "TL "; break;
|
||||
case format::ControlEditDesc::Kind::TR: o << "TR "; break;
|
||||
case format::ControlEditDesc::Kind::X: o << "X "; break;
|
||||
case format::ControlEditDesc::Kind::Slash: o << "/ "; break;
|
||||
case format::ControlEditDesc::Kind::Colon: o << ": "; break;
|
||||
case format::ControlEditDesc::Kind::SS: o << "SS "; break;
|
||||
case format::ControlEditDesc::Kind::SP: o << "SP "; break;
|
||||
case format::ControlEditDesc::Kind::S: o << "S "; break;
|
||||
case format::ControlEditDesc::Kind::P: o << "P "; break;
|
||||
case format::ControlEditDesc::Kind::BN: o << "BN "; break;
|
||||
case format::ControlEditDesc::Kind::BZ: o << "BZ "; break;
|
||||
case format::ControlEditDesc::Kind::RU: o << "RU "; break;
|
||||
case format::ControlEditDesc::Kind::RD: o << "RD "; break;
|
||||
case format::ControlEditDesc::Kind::RN: o << "RN "; break;
|
||||
case format::ControlEditDesc::Kind::RC: o << "RC "; break;
|
||||
case format::ControlEditDesc::Kind::RP: o << "RP "; break;
|
||||
case format::ControlEditDesc::Kind::DC: o << "DC "; break;
|
||||
case format::ControlEditDesc::Kind::DP: o << "DP "; break;
|
||||
default: CRASH_NO_CASE;
|
||||
}
|
||||
return o << x.count << ')';
|
||||
}
|
||||
|
||||
// R1304 format-item
|
||||
std::ostream &operator<<(std::ostream &o, const FormatItem &x) {
|
||||
std::ostream &operator<<(std::ostream &o, const format::FormatItem &x) {
|
||||
o << "(FormatItem " << x.repeatCount;
|
||||
std::visit([&o](const auto &y) { o << y; }, x.u);
|
||||
return o << ')';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
// that are transcribed here and referenced via their requirement numbers.
|
||||
// The representations of some productions that may also be of use in the
|
||||
// run-time I/O support library have been isolated into a distinct header file
|
||||
// (viz. format-specification.h).
|
||||
// (viz., format-specification.h).
|
||||
|
||||
#include "format-specification.h"
|
||||
#include "idioms.h"
|
||||
|
@ -118,7 +118,6 @@ struct WhereConstruct; // R1042
|
|||
struct ForallConstruct; // R1050
|
||||
struct InputImpliedDo; // R1218
|
||||
struct OutputImpliedDo; // R1218
|
||||
struct FormatItems; // R1303
|
||||
struct FunctionReference; // R1520
|
||||
struct FunctionSubprogram; // R1529
|
||||
struct SubroutineSubprogram; // R1534
|
||||
|
@ -2706,7 +2705,7 @@ struct InquireStmt {
|
|||
};
|
||||
|
||||
// R1301 format-stmt -> FORMAT format-specification
|
||||
WRAPPER_CLASS(FormatStmt, FormatSpecification);
|
||||
WRAPPER_CLASS(FormatStmt, format::FormatSpecification);
|
||||
|
||||
// R1402 program-stmt -> PROGRAM program-name
|
||||
WRAPPER_CLASS(ProgramStmt, Name);
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
#include "unparse.h"
|
||||
|
||||
#include "format-specification.h"
|
||||
#include "idioms.h"
|
||||
#include "indirection.h"
|
||||
#include "parse-tree-visitor.h"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "../../lib/parser/idioms.h"
|
||||
#include "../../lib/parser/message.h"
|
||||
#include "../../lib/parser/parse-tree.h"
|
||||
#include "../../lib/parser/parse-tree-visitor.h"
|
||||
#include "../../lib/parser/preprocessor.h"
|
||||
#include "../../lib/parser/prescan.h"
|
||||
#include "../../lib/parser/provenance.h"
|
||||
|
@ -22,9 +23,7 @@
|
|||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace {
|
||||
|
||||
std::list<std::string> argList(int argc, char *const argv[]) {
|
||||
static std::list<std::string> argList(int argc, char *const argv[]) {
|
||||
std::list<std::string> result;
|
||||
for (int j = 0; j < argc; ++j) {
|
||||
result.emplace_back(argv[j]);
|
||||
|
@ -32,14 +31,30 @@ std::list<std::string> argList(int argc, char *const argv[]) {
|
|||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace Fortran {
|
||||
namespace parser {
|
||||
constexpr auto grammar = program;
|
||||
} // namespace parser
|
||||
} // namespace Fortran
|
||||
using Fortran::parser::grammar;
|
||||
using ParseTree = typename decltype(grammar)::resultType;
|
||||
|
||||
struct MeasurementVisitor {
|
||||
template<typename A> bool Pre(const A &) { return true; }
|
||||
template<typename A> void Post(const A &) {
|
||||
++objects;
|
||||
bytes += sizeof(A);
|
||||
}
|
||||
size_t objects{0}, bytes{0};
|
||||
};
|
||||
|
||||
void MeasureParseTree(const ParseTree &program) {
|
||||
MeasurementVisitor visitor;
|
||||
Fortran::parser::Walk(program, visitor);
|
||||
std::cout << "Parse tree comprises " << visitor.objects
|
||||
<< " objects and occupies " << visitor.bytes
|
||||
<< " total bytes.\n";
|
||||
}
|
||||
|
||||
int main(int argc, char *const argv[]) {
|
||||
|
||||
|
@ -135,7 +150,7 @@ int main(int argc, char *const argv[]) {
|
|||
.Prescan(range)};
|
||||
messages.Emit(std::cerr);
|
||||
if (!prescanOk) {
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
columns = std::numeric_limits<int>::max();
|
||||
|
||||
|
@ -154,12 +169,12 @@ int main(int argc, char *const argv[]) {
|
|||
while (std::optional<char> och{state.GetNextChar()}) {
|
||||
std::cout << *och;
|
||||
}
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
std::optional<typename decltype(grammar)::resultType> result{
|
||||
grammar.Parse(&state)};
|
||||
std::optional<ParseTree> result{grammar.Parse(&state)};
|
||||
if (result.has_value() && !state.anyErrorRecovery()) {
|
||||
MeasureParseTree(*result);
|
||||
Unparse(std::cout, *result);
|
||||
return EXIT_SUCCESS;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue