in lang/c++/impl/parsing/Symbol.hh [486:608]
void skip(Decoder &d) {
const size_t sz = parsingStack.size();
if (sz == 0) {
throw Exception("Nothing to skip!");
}
while (parsingStack.size() >= sz) {
Symbol &t = parsingStack.top();
// std::cout << "skip: " << Symbol::toString(t.kind()) << '\n';
switch (t.kind()) {
case Symbol::Kind::Null:
d.decodeNull();
break;
case Symbol::Kind::Bool:
d.decodeBool();
break;
case Symbol::Kind::Int:
d.decodeInt();
break;
case Symbol::Kind::Long:
d.decodeLong();
break;
case Symbol::Kind::Float:
d.decodeFloat();
break;
case Symbol::Kind::Double:
d.decodeDouble();
break;
case Symbol::Kind::String:
d.skipString();
break;
case Symbol::Kind::Bytes:
d.skipBytes();
break;
case Symbol::Kind::ArrayStart: {
parsingStack.pop();
size_t n = d.skipArray();
processImplicitActions();
assertMatch(Symbol::Kind::Repeater, parsingStack.top().kind());
if (n == 0) {
break;
}
Symbol &t2 = parsingStack.top();
auto *p = t2.extrap<RepeaterInfo>();
std::get<0>(*p).push(n);
continue;
}
case Symbol::Kind::ArrayEnd:
break;
case Symbol::Kind::MapStart: {
parsingStack.pop();
size_t n = d.skipMap();
processImplicitActions();
assertMatch(Symbol::Kind::Repeater, parsingStack.top().kind());
if (n == 0) {
break;
}
Symbol &t2 = parsingStack.top();
auto *p2 = t2.extrap<RepeaterInfo>();
std::get<0>(*p2).push(n);
continue;
}
case Symbol::Kind::MapEnd:
break;
case Symbol::Kind::Fixed: {
parsingStack.pop();
Symbol &t2 = parsingStack.top();
d.decodeFixed(t2.extra<size_t>());
} break;
case Symbol::Kind::Enum:
parsingStack.pop();
d.decodeEnum();
break;
case Symbol::Kind::Union: {
parsingStack.pop();
size_t n = d.decodeUnionIndex();
selectBranch(n);
continue;
}
case Symbol::Kind::Repeater: {
auto *p = t.extrap<RepeaterInfo>();
std::stack<ssize_t> &ns = std::get<0>(*p);
if (ns.empty()) {
throw Exception(
"Empty item count stack in repeater skip");
}
ssize_t &n = ns.top();
if (n == 0) {
n = std::get<1>(*p) ? d.arrayNext()
: d.mapNext();
}
if (n != 0) {
--n;
append(std::get<3>(*p));
continue;
} else {
ns.pop();
}
break;
}
case Symbol::Kind::Indirect: {
ProductionPtr pp =
t.extra<ProductionPtr>();
parsingStack.pop();
append(pp);
}
continue;
case Symbol::Kind::Symbolic: {
ProductionPtr pp(
t.extra<std::weak_ptr<Production>>());
parsingStack.pop();
append(pp);
}
continue;
default: {
std::ostringstream oss;
oss << "Don't know how to skip "
<< Symbol::toString(t.kind());
throw Exception(oss.str());
}
}
parsingStack.pop();
}
}