[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:
peter klausler 2018-03-01 13:23:31 -08:00
parent c88b23e04e
commit 20364f0351
7 changed files with 202 additions and 164 deletions

View File

@ -17,6 +17,7 @@
#include <variant> #include <variant>
namespace Fortran { namespace Fortran {
namespace format {
// R1307 data-edit-desc (part 1 of 2) -> // R1307 data-edit-desc (part 1 of 2) ->
// I w [. m] | B w [. m] | O w [. m] | Z w [. m] | F w . d | // 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)) {} : items(std::move(is)), unlimitedItems(std::move(us)) {}
std::list<FormatItem> items, unlimitedItems; std::list<FormatItem> items, unlimitedItems;
}; };
} // namespace format
} // namespace Fortran } // namespace Fortran
#endif // FORTRAN_FORMAT_SPECIFICATION_H_ #endif // FORTRAN_FORMAT_SPECIFICATION_H_

View File

@ -9,7 +9,6 @@
#include "basic-parsers.h" #include "basic-parsers.h"
#include "characters.h" #include "characters.h"
#include "format-specification.h"
#include "parse-tree.h" #include "parse-tree.h"
#include "token-parsers.h" #include "token-parsers.h"
#include "user-state.h" #include "user-state.h"
@ -3060,7 +3059,7 @@ TYPE_CONTEXT_PARSER("INQUIRE statement"_en_US,
// R1301 format-stmt -> FORMAT format-specification // R1301 format-stmt -> FORMAT format-specification
TYPE_CONTEXT_PARSER("FORMAT statement"_en_US, TYPE_CONTEXT_PARSER("FORMAT statement"_en_US,
"FORMAT" >> construct<FormatStmt>{}(Parser<FormatSpecification>{})) "FORMAT" >> construct<FormatStmt>{}(Parser<format::FormatSpecification>{}))
// R1321 char-string-edit-desc // R1321 char-string-edit-desc
// N.B. C1313 disallows any kind parameter on the character literal. // 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]... // R1303 format-items -> format-item [[,] format-item]...
constexpr auto formatItems = constexpr auto formatItems =
nonemptySeparated(Parser<FormatItem>{}, maybe(","_tok)); nonemptySeparated(Parser<format::FormatItem>{}, maybe(","_tok));
// R1306 r -> digit-string // R1306 r -> digit-string
static inline int castU64ToInt(std::uint64_t &&n) { static inline int castU64ToInt(std::uint64_t &&n) {
@ -3081,20 +3080,21 @@ constexpr auto repeat = spaces >> applyFunction(castU64ToInt, digitString);
// R1304 format-item -> // R1304 format-item ->
// [r] data-edit-desc | control-edit-desc | char-string-edit-desc | // [r] data-edit-desc | control-edit-desc | char-string-edit-desc |
// [r] ( format-items ) // [r] ( format-items )
TYPE_PARSER(construct<FormatItem>{}( TYPE_PARSER(construct<format::FormatItem>{}(
maybe(repeat), Parser<IntrinsicTypeDataEditDesc>{}) || maybe(repeat), Parser<format::IntrinsicTypeDataEditDesc>{}) ||
construct<FormatItem>{}(maybe(repeat), Parser<DerivedTypeDataEditDesc>{}) || construct<format::FormatItem>{}(
construct<FormatItem>{}(Parser<ControlEditDesc>{}) || maybe(repeat), Parser<format::DerivedTypeDataEditDesc>{}) ||
construct<FormatItem>{}(charStringEditDesc) || construct<format::FormatItem>{}(Parser<format::ControlEditDesc>{}) ||
construct<FormatItem>{}(maybe(repeat), parenthesized(formatItems))) construct<format::FormatItem>{}(charStringEditDesc) ||
construct<format::FormatItem>{}(maybe(repeat), parenthesized(formatItems)))
// R1302 format-specification -> // R1302 format-specification ->
// ( [format-items] ) | ( [format-items ,] unlimited-format-item ) // ( [format-items] ) | ( [format-items ,] unlimited-format-item )
// R1305 unlimited-format-item -> * ( format-items ) // R1305 unlimited-format-item -> * ( format-items )
TYPE_PARSER( TYPE_PARSER(parenthesized(
parenthesized(construct<FormatSpecification>{}(defaulted(formatItems)) || construct<format::FormatSpecification>{}(defaulted(formatItems)) ||
construct<FormatSpecification>{}( construct<format::FormatSpecification>{}(
defaulted(formatItems / ","), "*" >> parenthesized(formatItems)))) defaulted(formatItems / ","), "*" >> parenthesized(formatItems))))
// R1308 w -> digit-string // R1308 w -> digit-string
// R1309 m -> digit-string // R1309 m -> digit-string
// R1310 d -> 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 | // G w [. d [E e]] | L w | A [w] | D w . d |
// DT [char-literal-constant] [( v-list )] // DT [char-literal-constant] [( v-list )]
// (part 1 of 2) // (part 1 of 2)
TYPE_PARSER(construct<IntrinsicTypeDataEditDesc>{}( TYPE_PARSER(construct<format::IntrinsicTypeDataEditDesc>{}(
"I" >> pure(IntrinsicTypeDataEditDesc::Kind::I) || "I" >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) ||
"B" >> pure(IntrinsicTypeDataEditDesc::Kind::B) || "B" >> pure(format::IntrinsicTypeDataEditDesc::Kind::B) ||
"O" >> pure(IntrinsicTypeDataEditDesc::Kind::O) || "O" >> pure(format::IntrinsicTypeDataEditDesc::Kind::O) ||
"Z" >> pure(IntrinsicTypeDataEditDesc::Kind::Z), "Z" >> pure(format::IntrinsicTypeDataEditDesc::Kind::Z),
mandatoryWidth, maybe("." >> digits), noInt) || mandatoryWidth, maybe("." >> digits), noInt) ||
construct<IntrinsicTypeDataEditDesc>{}( construct<format::IntrinsicTypeDataEditDesc>{}(
"F" >> pure(IntrinsicTypeDataEditDesc::Kind::F) || "F" >> pure(format::IntrinsicTypeDataEditDesc::Kind::F) ||
"D" >> pure(IntrinsicTypeDataEditDesc::Kind::D), "D" >> pure(format::IntrinsicTypeDataEditDesc::Kind::D),
mandatoryWidth, mandatoryDigits, noInt) || mandatoryWidth, mandatoryDigits, noInt) ||
construct<IntrinsicTypeDataEditDesc>{}( construct<format::IntrinsicTypeDataEditDesc>{}(
"EN" >> pure(IntrinsicTypeDataEditDesc::Kind::EN) || "EN" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EN) ||
"ES" >> pure(IntrinsicTypeDataEditDesc::Kind::ES) || "ES" >> pure(format::IntrinsicTypeDataEditDesc::Kind::ES) ||
"EX" >> pure(IntrinsicTypeDataEditDesc::Kind::EX) || "EX" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EX) ||
"E" >> pure(IntrinsicTypeDataEditDesc::Kind::E), "E" >> pure(format::IntrinsicTypeDataEditDesc::Kind::E),
mandatoryWidth, mandatoryDigits, maybe("E" >> digits)) || mandatoryWidth, mandatoryDigits, maybe("E" >> digits)) ||
construct<IntrinsicTypeDataEditDesc>{}( construct<format::IntrinsicTypeDataEditDesc>{}(
"G" >> pure(IntrinsicTypeDataEditDesc::Kind::G), mandatoryWidth, "G" >> pure(format::IntrinsicTypeDataEditDesc::Kind::G), mandatoryWidth,
mandatoryDigits, maybe("E" >> digits)) || mandatoryDigits, maybe("E" >> digits)) ||
construct<IntrinsicTypeDataEditDesc>{}( construct<format::IntrinsicTypeDataEditDesc>{}(
"G" >> pure(IntrinsicTypeDataEditDesc::Kind::G) || "G" >> pure(format::IntrinsicTypeDataEditDesc::Kind::G) ||
"L" >> pure(IntrinsicTypeDataEditDesc::Kind::L), "L" >> pure(format::IntrinsicTypeDataEditDesc::Kind::L),
mandatoryWidth, noInt, noInt) || mandatoryWidth, noInt, noInt) ||
construct<IntrinsicTypeDataEditDesc>{}( construct<format::IntrinsicTypeDataEditDesc>{}(
"A" >> pure(IntrinsicTypeDataEditDesc::Kind::A), maybe(width), noInt, "A" >> pure(format::IntrinsicTypeDataEditDesc::Kind::A), maybe(width),
noInt) || noInt, noInt) ||
// PGI/Intel extension: omitting width (and all else that follows) // PGI/Intel extension: omitting width (and all else that follows)
extension(construct<IntrinsicTypeDataEditDesc>{}( extension(construct<format::IntrinsicTypeDataEditDesc>{}(
"I" >> pure(IntrinsicTypeDataEditDesc::Kind::I) || "I" >> pure(format::IntrinsicTypeDataEditDesc::Kind::I) ||
("B"_tok / !letter /* don't occlude BN & BZ */) >> ("B"_tok / !letter /* don't occlude BN & BZ */) >>
pure(IntrinsicTypeDataEditDesc::Kind::B) || pure(format::IntrinsicTypeDataEditDesc::Kind::B) ||
"O" >> pure(IntrinsicTypeDataEditDesc::Kind::O) || "O" >> pure(format::IntrinsicTypeDataEditDesc::Kind::O) ||
"Z" >> pure(IntrinsicTypeDataEditDesc::Kind::Z) || "Z" >> pure(format::IntrinsicTypeDataEditDesc::Kind::Z) ||
"F" >> pure(IntrinsicTypeDataEditDesc::Kind::F) || "F" >> pure(format::IntrinsicTypeDataEditDesc::Kind::F) ||
("D"_tok / !letter /* don't occlude DC & DP */) >> ("D"_tok / !letter /* don't occlude DC & DP */) >>
pure(IntrinsicTypeDataEditDesc::Kind::D) || pure(format::IntrinsicTypeDataEditDesc::Kind::D) ||
"EN" >> pure(IntrinsicTypeDataEditDesc::Kind::EN) || "EN" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EN) ||
"ES" >> pure(IntrinsicTypeDataEditDesc::Kind::ES) || "ES" >> pure(format::IntrinsicTypeDataEditDesc::Kind::ES) ||
"EX" >> pure(IntrinsicTypeDataEditDesc::Kind::EX) || "EX" >> pure(format::IntrinsicTypeDataEditDesc::Kind::EX) ||
"E" >> pure(IntrinsicTypeDataEditDesc::Kind::E) || "E" >> pure(format::IntrinsicTypeDataEditDesc::Kind::E) ||
"G" >> pure(IntrinsicTypeDataEditDesc::Kind::G) || "G" >> pure(format::IntrinsicTypeDataEditDesc::Kind::G) ||
"L" >> pure(IntrinsicTypeDataEditDesc::Kind::L), "L" >> pure(format::IntrinsicTypeDataEditDesc::Kind::L),
noInt, noInt, noInt))) noInt, noInt, noInt)))
// R1307 data-edit-desc (part 2 of 2) // R1307 data-edit-desc (part 2 of 2)
// R1312 v -> [sign] digit-string // R1312 v -> [sign] digit-string
TYPE_PARSER("DT" >> TYPE_PARSER("DT" >>
construct<DerivedTypeDataEditDesc>{}( construct<format::DerivedTypeDataEditDesc>{}(
spaces >> defaulted(charLiteralConstantWithoutKind), spaces >> defaulted(charLiteralConstantWithoutKind),
defaulted(parenthesized(nonemptyList(spaces >> signedDigitString))))) defaulted(parenthesized(nonemptyList(spaces >> signedDigitString)))))
@ -3178,32 +3178,47 @@ constexpr auto scaleFactor = spaces >>
// R1318 blank-interp-edit-desc -> BN | BZ // R1318 blank-interp-edit-desc -> BN | BZ
// R1319 round-edit-desc -> RU | RD | RZ | RN | RC | RP // R1319 round-edit-desc -> RU | RD | RZ | RN | RC | RP
// R1320 decimal-edit-desc -> DC | DP // R1320 decimal-edit-desc -> DC | DP
TYPE_PARSER( TYPE_PARSER(construct<format::ControlEditDesc>{}(
construct<ControlEditDesc>{}("TL" >> pure(ControlEditDesc::Kind::TL) || "TL" >> pure(format::ControlEditDesc::Kind::TL) ||
"TR" >> pure(ControlEditDesc::Kind::TR) || "TR" >> pure(format::ControlEditDesc::Kind::TR) ||
"T" >> pure(ControlEditDesc::Kind::T), "T" >> pure(format::ControlEditDesc::Kind::T),
repeat) || repeat) ||
construct<ControlEditDesc>{}(repeat, construct<format::ControlEditDesc>{}(repeat,
"X" >> pure(ControlEditDesc::Kind::X) || "X" >> pure(format::ControlEditDesc::Kind::X) ||
"/" >> pure(ControlEditDesc::Kind::Slash)) || "/" >> pure(format::ControlEditDesc::Kind::Slash)) ||
construct<ControlEditDesc>{}("X" >> pure(ControlEditDesc::Kind::X) || construct<format::ControlEditDesc>{}(
"/" >> pure(ControlEditDesc::Kind::Slash)) || "X" >> pure(format::ControlEditDesc::Kind::X) ||
construct<ControlEditDesc>{}( "/" >> pure(format::ControlEditDesc::Kind::Slash)) ||
scaleFactor, "P" >> pure(ControlEditDesc::Kind::P)) || construct<format::ControlEditDesc>{}(
":" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::Colon)) || scaleFactor, "P" >> pure(format::ControlEditDesc::Kind::P)) ||
"SS" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::SS)) || ":" >> construct<format::ControlEditDesc>{}(
"SP" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::SP)) || pure(format::ControlEditDesc::Kind::Colon)) ||
"S" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::S)) || "SS" >> construct<format::ControlEditDesc>{}(
"BN" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::BN)) || pure(format::ControlEditDesc::Kind::SS)) ||
"BZ" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::BZ)) || "SP" >> construct<format::ControlEditDesc>{}(
"RU" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RU)) || pure(format::ControlEditDesc::Kind::SP)) ||
"RD" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RD)) || "S" >> construct<format::ControlEditDesc>{}(
"RZ" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RZ)) || pure(format::ControlEditDesc::Kind::S)) ||
"RN" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RN)) || "BN" >> construct<format::ControlEditDesc>{}(
"RC" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RC)) || pure(format::ControlEditDesc::Kind::BN)) ||
"RP" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::RP)) || "BZ" >> construct<format::ControlEditDesc>{}(
"DC" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::DC)) || pure(format::ControlEditDesc::Kind::BZ)) ||
"DP" >> construct<ControlEditDesc>{}(pure(ControlEditDesc::Kind::DP))) "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 -> // R1401 main-program ->
// [program-stmt] [specification-part] [execution-part] // [program-stmt] [specification-part] [execution-part]

View File

@ -1,7 +1,6 @@
#ifndef FORTRAN_PARSER_PARSE_TREE_VISITOR_H_ #ifndef FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
#define FORTRAN_PARSER_PARSE_TREE_VISITOR_H_ #define FORTRAN_PARSER_PARSE_TREE_VISITOR_H_
#include "format-specification.h"
#include "parse-tree.h" #include "parse-tree.h"
#include <optional> #include <optional>
#include <tuple> #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) // Traversal of needed STL template classes (optional, list, tuple, variant)
template<typename T, typename V> template<typename T, typename V>
void Walk(const std::optional<T> &x, V &visitor) { 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); 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) { template<typename V> void Walk(const ImportStmt &x, V &visitor) {
if (visitor.Pre(x)) { if (visitor.Pre(x)) {
Walk(x.names, visitor); Walk(x.names, visitor);
@ -327,6 +294,45 @@ template<typename V> void Walk(const WriteStmt &x, V &visitor) {
visitor.Post(x); 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 parser
} // namespace Fortran } // namespace Fortran
#endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_ #endif // FORTRAN_PARSER_PARSE_TREE_VISITOR_H_

View File

@ -306,7 +306,8 @@ std::ostream &operator<<(std::ostream &o, const Rename::Names &x) { // R1411
#undef TUPLE_FORMATTER #undef TUPLE_FORMATTER
// R1302 format-specification // 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 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) // 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 "; o << "(IntrinsicTypeDataEditDesc ";
switch (x.kind) { switch (x.kind) {
case IntrinsicTypeDataEditDesc::Kind::I: o << "I "; break; case format::IntrinsicTypeDataEditDesc::Kind::I: o << "I "; break;
case IntrinsicTypeDataEditDesc::Kind::B: o << "B "; break; case format::IntrinsicTypeDataEditDesc::Kind::B: o << "B "; break;
case IntrinsicTypeDataEditDesc::Kind::O: o << "O "; break; case format::IntrinsicTypeDataEditDesc::Kind::O: o << "O "; break;
case IntrinsicTypeDataEditDesc::Kind::Z: o << "Z "; break; case format::IntrinsicTypeDataEditDesc::Kind::Z: o << "Z "; break;
case IntrinsicTypeDataEditDesc::Kind::F: o << "F "; break; case format::IntrinsicTypeDataEditDesc::Kind::F: o << "F "; break;
case IntrinsicTypeDataEditDesc::Kind::E: o << "E "; break; case format::IntrinsicTypeDataEditDesc::Kind::E: o << "E "; break;
case IntrinsicTypeDataEditDesc::Kind::EN: o << "EN "; break; case format::IntrinsicTypeDataEditDesc::Kind::EN: o << "EN "; break;
case IntrinsicTypeDataEditDesc::Kind::ES: o << "ES "; break; case format::IntrinsicTypeDataEditDesc::Kind::ES: o << "ES "; break;
case IntrinsicTypeDataEditDesc::Kind::EX: o << "EX "; break; case format::IntrinsicTypeDataEditDesc::Kind::EX: o << "EX "; break;
case IntrinsicTypeDataEditDesc::Kind::G: o << "G "; break; case format::IntrinsicTypeDataEditDesc::Kind::G: o << "G "; break;
case IntrinsicTypeDataEditDesc::Kind::L: o << "L "; break; case format::IntrinsicTypeDataEditDesc::Kind::L: o << "L "; break;
case IntrinsicTypeDataEditDesc::Kind::A: o << "A "; break; case format::IntrinsicTypeDataEditDesc::Kind::A: o << "A "; break;
case IntrinsicTypeDataEditDesc::Kind::D: o << "D "; break; case format::IntrinsicTypeDataEditDesc::Kind::D: o << "D "; break;
default: CRASH_NO_CASE; default: CRASH_NO_CASE;
} }
return o << x.width << ' ' << x.digits << ' ' << x.exponentWidth << ')'; 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) // 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 return o << "(DerivedTypeDataEditDesc " << x.type << ' ' << x.parameters
<< ')'; << ')';
} }
// R1313 control-edit-desc // 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 "; o << "(ControlEditDesc ";
switch (x.kind) { switch (x.kind) {
case ControlEditDesc::Kind::T: o << "T "; break; case format::ControlEditDesc::Kind::T: o << "T "; break;
case ControlEditDesc::Kind::TL: o << "TL "; break; case format::ControlEditDesc::Kind::TL: o << "TL "; break;
case ControlEditDesc::Kind::TR: o << "TR "; break; case format::ControlEditDesc::Kind::TR: o << "TR "; break;
case ControlEditDesc::Kind::X: o << "X "; break; case format::ControlEditDesc::Kind::X: o << "X "; break;
case ControlEditDesc::Kind::Slash: o << "/ "; break; case format::ControlEditDesc::Kind::Slash: o << "/ "; break;
case ControlEditDesc::Kind::Colon: o << ": "; break; case format::ControlEditDesc::Kind::Colon: o << ": "; break;
case ControlEditDesc::Kind::SS: o << "SS "; break; case format::ControlEditDesc::Kind::SS: o << "SS "; break;
case ControlEditDesc::Kind::SP: o << "SP "; break; case format::ControlEditDesc::Kind::SP: o << "SP "; break;
case ControlEditDesc::Kind::S: o << "S "; break; case format::ControlEditDesc::Kind::S: o << "S "; break;
case ControlEditDesc::Kind::P: o << "P "; break; case format::ControlEditDesc::Kind::P: o << "P "; break;
case ControlEditDesc::Kind::BN: o << "BN "; break; case format::ControlEditDesc::Kind::BN: o << "BN "; break;
case ControlEditDesc::Kind::BZ: o << "BZ "; break; case format::ControlEditDesc::Kind::BZ: o << "BZ "; break;
case ControlEditDesc::Kind::RU: o << "RU "; break; case format::ControlEditDesc::Kind::RU: o << "RU "; break;
case ControlEditDesc::Kind::RD: o << "RD "; break; case format::ControlEditDesc::Kind::RD: o << "RD "; break;
case ControlEditDesc::Kind::RN: o << "RN "; break; case format::ControlEditDesc::Kind::RN: o << "RN "; break;
case ControlEditDesc::Kind::RC: o << "RC "; break; case format::ControlEditDesc::Kind::RC: o << "RC "; break;
case ControlEditDesc::Kind::RP: o << "RP "; break; case format::ControlEditDesc::Kind::RP: o << "RP "; break;
case ControlEditDesc::Kind::DC: o << "DC "; break; case format::ControlEditDesc::Kind::DC: o << "DC "; break;
case ControlEditDesc::Kind::DP: o << "DP "; break; case format::ControlEditDesc::Kind::DP: o << "DP "; break;
default: CRASH_NO_CASE; default: CRASH_NO_CASE;
} }
return o << x.count << ')'; return o << x.count << ')';
} }
// R1304 format-item // 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; o << "(FormatItem " << x.repeatCount;
std::visit([&o](const auto &y) { o << y; }, x.u); std::visit([&o](const auto &y) { o << y; }, x.u);
return o << ')'; return o << ')';

View File

@ -7,7 +7,7 @@
// that are transcribed here and referenced via their requirement numbers. // that are transcribed here and referenced via their requirement numbers.
// The representations of some productions that may also be of use in the // 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 // 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 "format-specification.h"
#include "idioms.h" #include "idioms.h"
@ -118,7 +118,6 @@ struct WhereConstruct; // R1042
struct ForallConstruct; // R1050 struct ForallConstruct; // R1050
struct InputImpliedDo; // R1218 struct InputImpliedDo; // R1218
struct OutputImpliedDo; // R1218 struct OutputImpliedDo; // R1218
struct FormatItems; // R1303
struct FunctionReference; // R1520 struct FunctionReference; // R1520
struct FunctionSubprogram; // R1529 struct FunctionSubprogram; // R1529
struct SubroutineSubprogram; // R1534 struct SubroutineSubprogram; // R1534
@ -2706,7 +2705,7 @@ struct InquireStmt {
}; };
// R1301 format-stmt -> FORMAT format-specification // R1301 format-stmt -> FORMAT format-specification
WRAPPER_CLASS(FormatStmt, FormatSpecification); WRAPPER_CLASS(FormatStmt, format::FormatSpecification);
// R1402 program-stmt -> PROGRAM program-name // R1402 program-stmt -> PROGRAM program-name
WRAPPER_CLASS(ProgramStmt, Name); WRAPPER_CLASS(ProgramStmt, Name);

View File

@ -1,6 +1,4 @@
#include "unparse.h" #include "unparse.h"
#include "format-specification.h"
#include "idioms.h" #include "idioms.h"
#include "indirection.h" #include "indirection.h"
#include "parse-tree-visitor.h" #include "parse-tree-visitor.h"

View File

@ -4,6 +4,7 @@
#include "../../lib/parser/idioms.h" #include "../../lib/parser/idioms.h"
#include "../../lib/parser/message.h" #include "../../lib/parser/message.h"
#include "../../lib/parser/parse-tree.h" #include "../../lib/parser/parse-tree.h"
#include "../../lib/parser/parse-tree-visitor.h"
#include "../../lib/parser/preprocessor.h" #include "../../lib/parser/preprocessor.h"
#include "../../lib/parser/prescan.h" #include "../../lib/parser/prescan.h"
#include "../../lib/parser/provenance.h" #include "../../lib/parser/provenance.h"
@ -22,9 +23,7 @@
#include <string> #include <string>
#include <unistd.h> #include <unistd.h>
namespace { static std::list<std::string> argList(int argc, char *const argv[]) {
std::list<std::string> argList(int argc, char *const argv[]) {
std::list<std::string> result; std::list<std::string> result;
for (int j = 0; j < argc; ++j) { for (int j = 0; j < argc; ++j) {
result.emplace_back(argv[j]); result.emplace_back(argv[j]);
@ -32,14 +31,30 @@ std::list<std::string> argList(int argc, char *const argv[]) {
return result; return result;
} }
} // namespace
namespace Fortran { namespace Fortran {
namespace parser { namespace parser {
constexpr auto grammar = program; constexpr auto grammar = program;
} // namespace parser } // namespace parser
} // namespace Fortran } // namespace Fortran
using Fortran::parser::grammar; 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[]) { int main(int argc, char *const argv[]) {
@ -135,7 +150,7 @@ int main(int argc, char *const argv[]) {
.Prescan(range)}; .Prescan(range)};
messages.Emit(std::cerr); messages.Emit(std::cerr);
if (!prescanOk) { if (!prescanOk) {
return 1; return EXIT_FAILURE;
} }
columns = std::numeric_limits<int>::max(); columns = std::numeric_limits<int>::max();
@ -154,12 +169,12 @@ int main(int argc, char *const argv[]) {
while (std::optional<char> och{state.GetNextChar()}) { while (std::optional<char> och{state.GetNextChar()}) {
std::cout << *och; std::cout << *och;
} }
return 0; return EXIT_SUCCESS;
} }
std::optional<typename decltype(grammar)::resultType> result{ std::optional<ParseTree> result{grammar.Parse(&state)};
grammar.Parse(&state)};
if (result.has_value() && !state.anyErrorRecovery()) { if (result.has_value() && !state.anyErrorRecovery()) {
MeasureParseTree(*result);
Unparse(std::cout, *result); Unparse(std::cout, *result);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} else { } else {