#include "core.h" #include "alotalot.h" #include #include 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); } 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 splitIntoLines(const std::string &str) { std::vector result = {""}; for (char ch: str) { if (ch == '\n') result.emplace_back(); else result.back() += ch; } return result; } std::string concatenateLines(const std::vector& lines) { std::string result; size_t n = lines.size(); for (size_t i = 0; i < n; i++) { if (i) result += '\n'; result += lines[i]; } return result; } void one_part_update_min_start_wsp_non_empty(const std::string& str, bool is_first, size_t& min) { std::vector 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 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); } void parse_special_file(const std::string& filename, const std::string& content, std::map& result) { // THROW("Don't know how to parse it yet"); } }