Debug
Release
tags
-f18
+./f18
*.o
*~
CMakeCache.txt
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++17")
set(SOURCES
- char-buffer.cc
- f2018-demo.cc
- idioms.cc
- message.cc
- parse-tree.cc
- position.cc
- preprocessor.cc
- prescan.cc
- source.cc
+ tools/f18/f18.cc
+ lib/parser/char-buffer.cc
+ lib/parser/idioms.cc
+ lib/parser/message.cc
+ lib/parser/parse-tree.cc
+ lib/parser/position.cc
+ lib/parser/preprocessor.cc
+ lib/parser/prescan.cc
+ lib/parser/source.cc
)
add_executable(f18 ${SOURCES})
#include <string>
namespace Fortran {
+namespace parser {
// fail<A>("...") returns a parser that never succeeds. It reports an
// error message at the current position. The result type is unused,
}
} getPosition;
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_BASIC_PARSERS_H_
#include <cstring>
namespace Fortran {
+namespace parser {
char *CharBuffer::FreeSpace(size_t *n) {
int offset{LastBlockOffset()};
}
CHECK(to == data + bytes_);
}
+} // namespace parser
} // namespace Fortran
#include <vector>
namespace Fortran {
+namespace parser {
class CharBuffer {
public:
size_t bytes_{0};
bool lastBlockEmpty_{false};
};
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_CHAR_BUFFER_H_
#include <optional>
namespace Fortran {
+namespace parser {
template<char goal> struct ExactRaw {
using resultType = char;
constexpr RawStringMatch operator""_raw(const char str[], size_t n) {
return RawStringMatch{str, n};
}
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_CHAR_PARSERS_H_
#include <optional>
namespace Fortran {
+namespace parser {
constexpr struct FixedFormPadding {
using resultType = char;
}
constexpr StatePredicateGuardParser consumedAllInput{ConsumedAllInput};
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_COOKED_CHARS_H_
#include <string>
namespace Fortran {
+namespace parser {
class CharPredicateGuardParser {
public:
return "," >> p / "::" || "::" >> construct<typename PA::resultType>{} ||
!","_tok >> construct<typename PA::resultType>{};
}
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_COOKED_TOKENS_H_
#include <string>
namespace Fortran {
+namespace parser {
class DebugParser {
public:
constexpr DebugParser operator""_debug(const char str[], size_t n) {
return DebugParser{str, n};
}
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_DEBUG_PARSER_H_
#include <utility>
namespace Fortran {
+namespace parser {
// The productions that follow are derived from the draft Fortran 2018
// standard, with some necessary modifications to remove left recursion
// is used only via scalar-int-variable
// R1030 default-char-constant-expr -> default-char-expr
// is only used via scalar-default-char-constant-expr
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_GRAMMAR_H_
#include <cstdlib>
namespace Fortran {
+namespace parser {
[[noreturn]] void die(const char *msg, ...) {
va_list ap;
std::ostream &operator<<(std::ostream &o, const std::monostate &) {
return o << "(empty variant)";
}
+} // namespace parser
} // namespace Fortran
using namespace std::string_literals; // enable "this is a std::string"s
namespace Fortran {
+namespace parser {
// Helper templates for combining a list of lambdas into an anonymous
// struct for use with std::visit() on a std::variant<> sum type.
template<typename A> bool operator!(const std::optional<A> &x) {
return !x.has_value();
}
+} // namespace parser
} // namespace Fortran
// For switch statements without default: labels.
// Formatting
namespace Fortran {
+namespace parser {
template<typename A>
std::ostream &operator<<(std::ostream &o, const std::optional<A> &x) {
if (x.has_value()) {
return std::visit(
[&o](const auto &y) -> std::ostream & { return o << y; }, x);
}
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_IDIOMS_H_
#include <utility>
namespace Fortran {
+namespace parser {
template<typename A> class Indirection {
public:
std::ostream &operator<<(std::ostream &o, const Indirection<A> &x) {
return o << *x;
}
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_INDIRECTION_H_
#include "message.h"
namespace Fortran {
+namespace parser {
std::ostream &operator<<(std::ostream &o, const Message &msg) {
if (msg.context()) {
}
return o;
}
+} // namespace parser
} // namespace Fortran
#include <string>
namespace Fortran {
+namespace parser {
class Message;
using MessageContext = std::shared_ptr<Message>;
std::ostream &operator<<(std::ostream &, const Message &);
std::ostream &operator<<(std::ostream &, const Messages &);
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_MESSAGE_H_
#include <utility>
namespace Fortran {
+namespace parser {
class UserState;
// reflected in the copy and move constructors defined at the top of this
// class definition!
};
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_PARSE_STATE_H_
#include <algorithm>
namespace Fortran {
+namespace parser {
#define UNION_FORMATTER(TYPE) \
std::ostream &operator<<(std::ostream &o, const TYPE &x) { \
std::ostream &operator<<(std::ostream &o, const Suffix &x) {
return o << "(Suffix " << x.binding << ' ' << x.resultName << ')';
}
+} // namespace parser
} // namespace Fortran
}
namespace Fortran {
+namespace parser {
// These are the unavoidable recursively-defined productions of Fortran.
// Some references to the representations of their parses require
return o << "(LoopBounds " << x.name << ' ' << x.lower << ' ' << x.upper
<< ' ' << x.step << ')';
}
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_PARSE_TREE_H_
#include "position.h"
namespace Fortran {
+namespace parser {
std::ostream &operator<<(std::ostream &o, const Position &x) {
return o << "(at line " << x.lineNumber() << ", column " << x.column() << ')';
}
+} // namespace parser
} // namespace Fortran
#include <ostream>
namespace Fortran {
+namespace parser {
class Position {
public:
};
std::ostream &operator<<(std::ostream &, const Position &);
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_POSITION_H_
#include <utility>
namespace Fortran {
+namespace parser {
bool CharPointerWithLength::IsBlank() const {
for (size_t j{0}; j < bytes_; ++j) {
}
return result;
}
+} // namespace parser
} // namespace Fortran
#include <vector>
namespace Fortran {
+namespace parser {
class CharBuffer;
class Prescanner;
const char *data_{nullptr};
size_t bytes_{0};
};
+} // namespace parser
} // namespace Fortran
// Specializations to enable std::unordered_map<CharPointerWithLength, ...>
-template<> struct std::hash<Fortran::CharPointerWithLength> {
- size_t operator()(const Fortran::CharPointerWithLength &x) const {
+template<> struct std::hash<Fortran::parser::CharPointerWithLength> {
+ size_t operator()(const Fortran::parser::CharPointerWithLength &x) const {
size_t hash{0}, bytes{x.size()};
for (size_t j{0}; j < bytes; ++j) {
hash = (hash * 31) ^ x[j];
}
};
-template<> struct std::equal_to<Fortran::CharPointerWithLength> {
- bool operator()(const Fortran::CharPointerWithLength &x,
- const Fortran::CharPointerWithLength &y) const {
+template<> struct std::equal_to<Fortran::parser::CharPointerWithLength> {
+ bool operator()(const Fortran::parser::CharPointerWithLength &x,
+ const Fortran::parser::CharPointerWithLength &y) const {
return x.size() == y.size() &&
std::memcmp(static_cast<const void *>(&x[0]),
static_cast<const void *>(&y[0]), x.size()) == 0;
};
namespace Fortran {
+namespace parser {
// Buffers a contiguous sequence of characters that has been partitioned into
// a sequence of preprocessing tokens.
std::unordered_map<CharPointerWithLength, Definition> definitions_;
std::stack<CanDeadElseAppear> ifStack_;
};
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_PREPROCESSOR_H_
#include <vector>
namespace Fortran {
+namespace parser {
CharBuffer Prescanner::Prescan(const SourceFile &source) {
sourceFile_ = &source;
out->Put('\n');
}
}
+} // namespace parser
} // namespace Fortran
#include <optional>
namespace Fortran {
+namespace parser {
class Prescanner {
public:
int delimiterNesting_{0};
Preprocessor preprocessor_;
};
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_PRESCAN_H_
// TODO: Port to Windows &c.
namespace Fortran {
+namespace parser {
SourceFile::~SourceFile() { Close(); }
}
path_.clear();
}
+} // namespace parser
} // namespace Fortran
#include <string>
namespace Fortran {
+namespace parser {
class SourceFile {
public:
const char *content_{nullptr};
size_t bytes_{0};
};
+} // namespace parser
} // namespace Fortran
#endif // FORTRAN_SOURCE_H_
#include <unordered_set>
namespace Fortran {
+namespace parser {
class UserState {
public:
using Label = std::uint64_t;
std::unordered_set<Label> doLabels_;
int nonlabelDoConstructNestingDepth_{0};
};
-}; // namespace Fortran
+} // namespace parser
+} // namespace Fortran
#endif // FORTRAN_USER_STATE_H_
// Temporary Fortran front end driver main program for development scaffolding.
-#include "basic-parsers.h"
-#include "char-buffer.h"
-#include "cooked-chars.h"
-#include "grammar.h"
-#include "idioms.h"
-#include "message.h"
-#include "parse-tree.h"
-#include "prescan.h"
-#include "source.h"
-#include "user-state.h"
+#include "../../lib/parser/basic-parsers.h"
+#include "../../lib/parser/char-buffer.h"
+#include "../../lib/parser/cooked-chars.h"
+#include "../../lib/parser/grammar.h"
+#include "../../lib/parser/idioms.h"
+#include "../../lib/parser/message.h"
+#include "../../lib/parser/parse-tree.h"
+#include "../../lib/parser/prescan.h"
+#include "../../lib/parser/source.h"
+#include "../../lib/parser/user-state.h"
#include <cerrno>
#include <cstdio>
#include <cstdlib>
} // namespace
namespace Fortran {
+namespace parser {
constexpr auto grammar = program;
+} // namespace parser
} // namespace Fortran
-using Fortran::grammar;
+using Fortran::parser::grammar;
int main(int argc, char *const argv[]) {
}
}
- Fortran::SourceFile source;
+ Fortran::parser::SourceFile source;
std::stringstream error;
if (!source.Open(path, &error)) {
std::cerr << error.str() << '\n';
size_t sourceBytes{source.bytes()};
std::unique_ptr<char[]> prescanned;
if (prescan) {
- Fortran::Messages messages;
- Fortran::Prescanner prescanner{messages};
- Fortran::CharBuffer buffer{
+ Fortran::parser::Messages messages;
+ Fortran::parser::Prescanner prescanner{messages};
+ Fortran::parser::CharBuffer buffer{
prescanner.set_fixedForm(fixedForm)
.set_enableBackslashEscapesInCharLiterals(backslashEscapes)
.set_fixedFormColumnLimit(columns)
columns = std::numeric_limits<int>::max();
}
- Fortran::ParseState state{sourceContent, sourceBytes};
+ Fortran::parser::ParseState state{sourceContent, sourceBytes};
state.set_prescanned(prescan);
state.set_inFixedForm(fixedForm);
state.set_enableBackslashEscapesInCharLiterals(backslashEscapes);
state.set_columns(columns);
state.set_enableOldDebugLines(enableOldDebugLines);
state.PushContext("source file '"s + path + "'");
- Fortran::UserState ustate;
+ Fortran::parser::UserState ustate;
state.set_userState(&ustate);
if (dumpCookedChars) {
- while (std::optional<char> och{Fortran::cookedNextChar.Parse(&state)}) {
+ while (std::optional<char>
+ och{Fortran::parser::cookedNextChar.Parse(&state)}) {
std::cout << *och;
}
return 0;
std::optional<typename decltype(grammar)::resultType> result;
#if 0
for (int j = 0; j < 1000; ++j) {
- Fortran::ParseState state1{state};
+ Fortran::parser::ParseState state1{state};
result = grammar.Parse(&state1);
if (!result) {
std::cerr << "demo FAIL in timing loop\n";