@@ 84,7 84,15 @@ namespace {
subst.strbeg = label; subst.strend = nullptr;
subst.children.resize(children.size(), lithe::node(deleted));
size_t i(0);
- for (auto &c : children) std::swap(subst[i++], *c);
+ for (auto& c : children) {
+ if (subst.src_begin == nullptr || subst.src_begin > c->src_begin) {
+ subst.src_begin = c->src_begin;
+ }
+ if (subst.src_end == nullptr || subst.src_end < c->src_end) {
+ subst.src_end = c->src_end;
+ }
+ std::swap(subst[i++], *c);
+ }
std::swap(*dest, subst);
}
};
@@ 100,6 108,8 @@ namespace {
lithe::node defn;
defn.strbeg = tag::defn;
defn.strend = nullptr;
+ defn.src_begin = i->src_begin;
+ defn.src_end = next->src_end;
defn.children.emplace_back(*i);
defn.children.emplace_back(*next);
*i = defn;
@@ 245,7 255,14 @@ namespace lithe {
"docstring", I(T(";") << O(characters("space","\t "))) << (upto_eol | T("\n")),
[](const lithe::node& n) {
if (docstrings().size()) {
- docstrings().top().children.emplace_back(n);
+ auto& t{ docstrings().top() };
+ if (t.src_begin == nullptr || t.src_begin > n.src_begin) {
+ t.src_begin = n.src_begin;
+ }
+ if (t.src_end == nullptr || t.src_end < n.src_end) {
+ t.src_end = n.src_end;
+ }
+ t.children.emplace_back(n);
}
return n;
});
@@ 146,13 146,13 @@ namespace lithe {
node complex_seq(cursor& current, cursor limit, node result, size_t i) const {
for (;i < sequence.size();++i) {
node tmp = (*sequence[i])(current, limit);
- LITHE_EXTENT_END(result,current);
if (tmp.is_error()) {
if (tmp.is_fatal()) return tmp;
else return node::error(this, current, tmp);
}
flatten_to(result.children, tmp);
}
+ LITHE_EXTENT_END(result, current);
return result;
}
@@ 279,6 279,7 @@ namespace lithe {
std::clog << indent::current() << "% Matched [" << tag << "]!\n";
}
#endif
+ assert(c.is_error() || (c.src_begin && c.src_end));
if (!insert) return c;
if (c.strbeg) {
node tmp;
@@ 663,10 664,14 @@ namespace lithe {
custom(const char *name, rule r, std::function<node(node)> process):wrapper(r, name),process(process) {
}
- node operator()(cursor& begin, cursor end) const override {
- auto tmp = wrapper::operator()(begin, end);
+ node operator()(cursor& cur, cursor end) const override {
+ auto b = cur;
+ auto tmp = wrapper::operator()(cur, end);
if (tmp.is_error()) return tmp;
- else return process(std::move(tmp));
+ assert(tmp.src_begin && tmp.src_end);
+ auto tmp2 = process(std::move(tmp));
+ assert(tmp2.is_error() || (tmp2.src_begin && tmp2.src_end));
+ return tmp2;
}
};