Commit 88f4fb08 authored by Dubský Jan's avatar Dubský Jan
Browse files

Solution 1.02

parent 53819d9b
......@@ -8,54 +8,52 @@
namespace macrosol {
void macroprocessor_impl::apply_defines(std::string_view token, std::back_insert_iterator<std::string> out) {
void macroprocessor_impl::apply_defines(std::string_view token, std::back_insert_iterator<std::string>& out) {
auto it = defines.find(token);
if (it == defines.end()) {
std::copy(token.begin(), token.end(), out);
out = std::copy(token.begin(), token.end(), out);
*out = ' ';
return;
}
// std::string_view(&t.front(), t.length())
for (auto&& t : it->second) apply_defines(t, out);
for (auto&& t : it->second) {
apply_defines(t, out);
}
}
bool macroprocessor_impl::process(const std::string& s, std::string& output) {
auto tokens = parse_tokens(s);
assert(tokens.size() > 0);
assert((s.find("=") == std::string::npos) || (tokens[1] == "="));
if (tokens.size() == 0) {
output = "";
return true;
}
if (tokens.size() > 1 && tokens[1] == "=") {
auto it = defines.find(tokens[0]);
if (it != defines.end()) it->second.update(tokens);
else {
macro m(tokens);
defines.insert({m.get_left_view(), std::move(m)});
auto view = m.get_left_view();
defines.emplace(std::move(view), std::move(m));
}
return false;
}
assert(output.size() == 0);
for (auto&& t : tokens) apply_defines(t, std::back_insert_iterator(output));
auto out = std::back_insert_iterator(output);
for (auto&& t : tokens) apply_defines(t, out);
if (output.size()) output.pop_back();
return true;
}
std::string::const_iterator macroprocessor_impl::word_begin(std::string::const_iterator begin, std::string::const_iterator end) {
for (; begin != end; ++begin) {
if (*begin != ' ') return begin;
}
return end;
}
std::string::const_iterator macroprocessor_impl::word_end(std::string::const_iterator begin, std::string::const_iterator end) {
for (; begin != end; ++begin) {
if (*begin == ' ' || *begin == '=') return begin;
}
return end;
}
std::vector<std::string_view> macroprocessor_impl::parse_tokens(const std::string& s) {
std::vector<std::string_view> ret;
for (auto it = s.begin(), end = s.end(); it != end;) {
auto b = word_begin(it, end);
auto b = it;
while (*b == ' ') ++b;
if (b == end) break;
auto e = word_end(b, end);
auto e = b + 1;
while (*e != ' ' && *e != '=' && e != end) ++e;
size_t len = e - b;
if (*b == '=' && len > 1) {
ret.emplace_back(&(*b), 1);
......@@ -71,16 +69,41 @@ std::vector<std::string_view> macroprocessor_impl::parse_tokens(const std::strin
macroprocessor_impl::macro::macro(const std::vector<std::string_view>& tokens) {
assert(tokens.size() > 1);
assert(tokens[1] == "=");
this->left = tokens.front();
this->left_len = tokens.front().size();
this->left = new char[left_len + 1];
tokens.front().copy(left, left_len);
left[left_len] = 0;
assert(tokens.front() == left);
update(tokens);
}
void macroprocessor_impl::macro::update(const std::vector<std::string_view>& tokens) {
assert(tokens.size() > 1);
assert(tokens[0] == left);
assert(tokens[0] == std::string(left));
assert(tokens[1] == "=");
right.resize(tokens.size() - 2);
std::copy(tokens.begin() + 2, tokens.end(), right.begin());
}
macroprocessor_impl::macro::macro(macro&& m) {
this->left = m.left;
this->left_len = m.left_len;
m.left = 0;
m.left_len = 0;
this->right = std::move(m.right);
}
macroprocessor_impl::macro& macroprocessor_impl::macro::operator=(macro&& m) {
this->left = m.left;
this->left_len = m.left_len;
m.left = 0;
m.left_len = 0;
this->right = std::move(m.right);
return *this;
}
macroprocessor_impl::macro::~macro() {
delete[] left;
}
} // namespace macrosol
......@@ -38,22 +38,26 @@ private:
class macro {
public:
macro(const std::vector<std::string_view>& tokens);
macro(macro&& m);
macro& operator =(macro&& m);
macro(macro& m) = delete;
macro& operator=(macro& m) = delete;
~macro();
void update(const std::vector<std::string_view>& tokens);
inline std::string_view get_left_view() const { return left; }
inline std::string_view get_left_view() const { return std::string_view(left, left_len); }
inline auto begin() const { return right.cbegin(); }
inline auto end() const { return right.cend(); }
private:
std::string left;
char* left;
size_t left_len;
std::vector<std::string> right;
};
std::unordered_map<std::string_view, macro> defines;
std::vector<std::string_view> parse_tokens(const std::string& s);
std::string::const_iterator word_begin(std::string::const_iterator begin, std::string::const_iterator end);
std::string::const_iterator word_end(std::string::const_iterator begin, std::string::const_iterator end);
void apply_defines(std::string_view token, std::back_insert_iterator<std::string> out);
void apply_defines(std::string_view token, std::back_insert_iterator<std::string>& out);
};
template <typename policy>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment