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>
|
#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_
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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_
|
||||||
|
|
|
@ -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 << ')';
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue