mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-23 11:43:32 +00:00
168 lines
4.3 KiB
C++
168 lines
4.3 KiB
C++
// 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 <cerrno>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <iostream>
|
|
#include <limits>
|
|
#include <list>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <unistd.h>
|
|
|
|
namespace {
|
|
|
|
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]);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
} // namespace
|
|
|
|
namespace Fortran {
|
|
constexpr auto grammar = program;
|
|
} // namespace Fortran
|
|
using Fortran::grammar;
|
|
|
|
int main(int argc, char *const argv[]) {
|
|
|
|
auto args = argList(argc, argv);
|
|
std::string progName{args.front()};
|
|
args.pop_front();
|
|
|
|
bool dumpCookedChars{false};
|
|
bool fixedForm{false};
|
|
bool backslashEscapes{true};
|
|
bool standard{false};
|
|
bool enableOldDebugLines{false};
|
|
int columns{72};
|
|
bool prescan{true};
|
|
|
|
while (!args.empty()) {
|
|
if (args.front().empty()) {
|
|
args.pop_front();
|
|
} else if (args.front().at(0) != '-' || args.front() == "-") {
|
|
break;
|
|
} else if (args.front() == "--") {
|
|
args.pop_front();
|
|
break;
|
|
} else {
|
|
std::string flag{std::move(args.front())};
|
|
args.pop_front();
|
|
if (flag == "-Mfixed") {
|
|
fixedForm = true;
|
|
} else if (flag == "-Mbackslash") {
|
|
backslashEscapes = false;
|
|
} else if (flag == "-Mstandard") {
|
|
standard = false;
|
|
} else if (flag == "-Mextend") {
|
|
columns = 132;
|
|
} else if (flag == "-fdebug-dump-cooked-chars") {
|
|
dumpCookedChars = true;
|
|
} else if (flag == "-fno-prescan") {
|
|
prescan = false;
|
|
} else if (flag == "-ed") {
|
|
enableOldDebugLines = true;
|
|
} else {
|
|
std::cerr << "unknown flag: '" << flag << "'\n";
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string path{"-"};
|
|
if (!args.empty()) {
|
|
path = std::move(args.front());
|
|
args.pop_front();
|
|
if (!args.empty()) {
|
|
std::cerr << "multiple input files\n";;
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
Fortran::SourceFile source;
|
|
std::stringstream error;
|
|
if (!source.Open(path, &error)) {
|
|
std::cerr << error.str() << '\n';
|
|
return 1;
|
|
}
|
|
|
|
const char *sourceContent{source.content()};
|
|
size_t sourceBytes{source.bytes()};
|
|
std::unique_ptr<char[]> prescanned;
|
|
if (prescan) {
|
|
Fortran::Messages messages;
|
|
Fortran::Prescanner prescanner{messages};
|
|
Fortran::CharBuffer
|
|
buffer{prescanner.
|
|
set_fixedForm(fixedForm).
|
|
set_enableBackslashEscapesInCharLiterals(backslashEscapes).
|
|
set_fixedFormColumnLimit(columns).
|
|
set_enableOldDebugLines(enableOldDebugLines).
|
|
Prescan(source)};
|
|
std::cerr << messages;
|
|
if (prescanner.anyFatalErrors()) {
|
|
return 1;
|
|
}
|
|
sourceBytes = buffer.bytes();
|
|
char *contig{new char[sourceBytes]};
|
|
buffer.CopyToContiguous(contig);
|
|
sourceContent = contig;
|
|
prescanned.reset(contig);
|
|
columns = std::numeric_limits<int>::max();
|
|
}
|
|
|
|
Fortran::ParseState state{sourceContent, sourceBytes};
|
|
state.set_prescanned(prescan);
|
|
state.set_inFixedForm(fixedForm);
|
|
state.set_enableBackslashEscapesInCharLiterals(backslashEscapes);
|
|
state.set_strictConformance(standard);
|
|
state.set_columns(columns);
|
|
state.set_enableOldDebugLines(enableOldDebugLines);
|
|
state.PushContext("source file '"s + path + "'");
|
|
Fortran::UserState ustate;
|
|
state.set_userState(&ustate);
|
|
|
|
if (dumpCookedChars) {
|
|
while (std::optional<char> och{Fortran::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};
|
|
result = grammar.Parse(&state1);
|
|
if (!result) {
|
|
std::cerr << "demo FAIL in timing loop\n";
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
result = grammar.Parse(&state);
|
|
if (result.has_value() && !state.anyErrorRecovery()) {
|
|
std::cout << "demo PASS\n" << *result << '\n';
|
|
} else {
|
|
std::cerr << "demo FAIL " << state.position() << '\n' << *state.messages();
|
|
return EXIT_FAILURE;
|
|
}
|
|
}
|