2024-08-10 20:56:07 +00:00
|
|
|
#include "core.h"
|
|
|
|
#include "alotalot.h"
|
|
|
|
#include <vector>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
namespace nytl {
|
|
|
|
size_t first_nw_char(const std::string& str) {
|
|
|
|
size_t i = 0;
|
|
|
|
for (; i < str.size(); i++)
|
|
|
|
if (!isSPACE(str[i]))
|
|
|
|
break;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool is_space_only(const std::string& str) {
|
|
|
|
return first_nw_char(str) == str.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
void rstrip(std::string& str) {
|
|
|
|
while (!str.empty() && isSPACE(str.back()))
|
|
|
|
str.resize(str.size() - 1);
|
|
|
|
}
|
|
|
|
|
2024-08-12 22:06:50 +00:00
|
|
|
std::string clement_lstrip(const std::string& str) {
|
|
|
|
size_t gone = 0;
|
|
|
|
size_t n = str.size();
|
|
|
|
for (size_t i = 0; i < n; i++) {
|
|
|
|
if (str[i] == '\n') {
|
|
|
|
gone = i + 1;
|
|
|
|
} else if (!isSPACE(str[i])) {
|
|
|
|
return str.substr(gone);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
int peep(ParsingContext &ctx) {
|
|
|
|
if (ctx.text.size() <= ctx.pos)
|
|
|
|
return EOFVAL;
|
|
|
|
return ctx.text[ctx.pos];
|
|
|
|
}
|
|
|
|
|
|
|
|
void advance(ParsingContext& ctx) {
|
|
|
|
if (ctx.text[ctx.pos] == '\n') {
|
|
|
|
ctx.line++;
|
|
|
|
ctx.column = 0;
|
|
|
|
} else {
|
|
|
|
ctx.column++;
|
|
|
|
}
|
|
|
|
ctx.pos++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void skip(ParsingContext& ctx) {
|
|
|
|
ASSERT(ctx.pos < ctx.text.size(), "Unexpected EOF");
|
|
|
|
advance(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void skip(ParsingContext& ctx, char ch) {
|
|
|
|
ASSERT(ctx.pos < ctx.text.size(), "Unexpected EOF");
|
|
|
|
ASSERT(ctx.text[ctx.pos] == ch, "Unexpected character");
|
|
|
|
advance(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void skipWhitespace(ParsingContext &ctx) {
|
|
|
|
while (peep(ctx) > 0 && isSPACE((char)peep(ctx)))
|
|
|
|
skip(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<std::string> splitIntoLines(const std::string &str) {
|
2024-08-13 09:16:05 +00:00
|
|
|
std::vector<std::string> result = {""};
|
2024-08-12 22:06:50 +00:00
|
|
|
for (char ch: str) {
|
|
|
|
if (ch == '\n')
|
|
|
|
result.emplace_back();
|
|
|
|
else
|
|
|
|
result.back() += ch;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string concatenateLines(const std::vector<std::string>& lines) {
|
|
|
|
std::string result;
|
2024-08-10 20:56:07 +00:00
|
|
|
size_t n = lines.size();
|
|
|
|
for (size_t i = 0; i < n; i++) {
|
2024-08-12 22:06:50 +00:00
|
|
|
if (i)
|
|
|
|
result += '\n';
|
|
|
|
result += lines[i];
|
2024-08-10 20:56:07 +00:00
|
|
|
}
|
2024-08-12 22:06:50 +00:00
|
|
|
return result;
|
2024-08-10 20:56:07 +00:00
|
|
|
}
|
|
|
|
|
2024-08-13 09:16:05 +00:00
|
|
|
void one_part_update_min_start_wsp_non_empty(const std::string& str, bool is_first, size_t& min) {
|
|
|
|
std::vector<std::string> lines = splitIntoLines(str);
|
|
|
|
size_t L = lines.size();
|
|
|
|
for (size_t i = is_first ? 0 : 1; i < L; i++) {
|
|
|
|
size_t first_nw = first_nw_char(lines[i]);
|
|
|
|
if (first_nw < lines[i].size())
|
|
|
|
min = std::min(min, first_nw);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string one_part_cut_excess_tab(const std::string& str, bool is_first, size_t cut) {
|
|
|
|
std::vector<std::string> lines = splitIntoLines(str);
|
|
|
|
size_t L = lines.size();
|
|
|
|
for (size_t i = is_first ? 0 : 1; i < L; i++) {
|
|
|
|
if (!is_space_only(lines[i]))
|
|
|
|
lines[i] = lines[i].substr(cut);
|
|
|
|
}
|
|
|
|
return concatenateLines(lines);
|
|
|
|
}
|
|
|
|
|
|
|
|
void parse_bare_file(const std::string& filename, const std::string& content,
|
|
|
|
global_elem_set_t& result)
|
|
|
|
{
|
|
|
|
ASSERT(result.count(filename) == 0, "Repeated element " + filename);
|
|
|
|
std::string P = clement_lstrip(content);
|
|
|
|
rstrip(P);
|
|
|
|
size_t cut = 9999999999999;
|
|
|
|
one_part_update_min_start_wsp_non_empty(P, true, cut);
|
|
|
|
P = one_part_cut_excess_tab(P, true, cut);
|
|
|
|
Element& el = result[filename];
|
|
|
|
el.parts = {ElementPart{element_part_types::code}};
|
|
|
|
el.parts[0].when_code.lines = mv(P);
|
|
|
|
}
|
|
|
|
|
2024-08-10 20:56:07 +00:00
|
|
|
void parse_special_file(const std::string& filename, const std::string& content,
|
|
|
|
std::map<std::string, Element>& result)
|
|
|
|
{
|
2024-08-13 09:16:05 +00:00
|
|
|
// THROW("Don't know how to parse it yet");
|
2024-08-10 20:56:07 +00:00
|
|
|
}
|
|
|
|
}
|