[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>
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_

View File

@ -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]

View File

@ -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_

View File

@ -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 << ')';

View File

@ -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);

View File

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

View File

@ -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 {