iu9-ca-web-chat/src/http_server/new_york_transit_line/parser.cpp

145 lines
4.0 KiB
C++
Raw Normal View History

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 "";
}
2024-08-10 20:56:07 +00:00
void parse_bare_file(const std::string& filename, const std::string& content,
2024-08-12 22:06:50 +00:00
global_elem_set_t& result)
2024-08-10 20:56:07 +00:00
{
ASSERT(result.count(filename) == 0, "Repeated element " + filename);
std::vector<std::string> lines;
bool had_nw_line = false;
size_t smallest_tab;
std::string current_line;
auto finish = [&]() {
size_t tab_sz = first_nw_char(current_line);
if (tab_sz == current_line.size()) {
if (had_nw_line)
lines.emplace_back();
} else {
if (had_nw_line) {
if (smallest_tab > tab_sz)
smallest_tab = tab_sz;
} else {
smallest_tab = tab_sz;
had_nw_line = true;
}
lines.push_back(current_line);
}
current_line.clear();
};
for (char ch: content) {
if (ch == '\n') {
finish();
} else {
current_line += ch;
}
}
finish();
while (!lines.empty() && lines.back().empty())
lines.pop_back();
for (std::string& line: lines) {
if (!line.empty()) {
assert(line.size() > smallest_tab);
line = line.substr(smallest_tab);
}
}
Element& el = result[filename];
el.parts = {ElementPart{element_part_types::code}};
2024-08-12 22:06:50 +00:00
std::string lines_cat = concatenateLines(lines);
el.parts[0].when_code.lines = mv(lines_cat);
}
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) {
std::vector<std::string> result;
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
}
void parse_special_file(const std::string& filename, const std::string& content,
std::map<std::string, Element>& result)
{
THROW("Don't know how to parse it yet");
2024-08-10 20:56:07 +00:00
}
}