NodeVector Parser::parse() { std::vector<Token> tokens = tokenize(); std::deque<NodePtr> stack; stack.push_back(std::make_shared<Node>(CMD, "ROOT")); NodePtr lastCompleted = nullptr; while (tokens.size() && stack.size()) { NodePtr node; Token tok = tokens.front(); tokens.erase(tokens.begin()); if (tok.type == TokType::RAW) { node = std::make_shared<Node>(TEXT, tok.str); stack.back()->addChild(node); } else if (tok.type == TokType::CMD_BEG) { node = std::make_shared<Node>(CMD, tok.str); stack.push_back(node); } else if (tok.type == TokType::CMD_CNT) { node = std::make_shared<TmpNode>(TMP, ""); ((TmpNode*)node.get())->setParent(lastCompleted); stack.push_back(node); } else if (tok.type == TokType::CMD_END) { node = stack.back(); stack.pop_back(); if (!stack.size()) throw std::runtime_error("Too many CMD_ENDs"); if (node->getType() == TMP) { if (!lastCompleted) throw std::runtime_error("Noone to absorb children"); NodePtr parent = ((TmpNode*)node.get())->getParent(); parent->absorb(node->getChildren(), 1); } else { if (node->getType() == CMD) lastCompleted = node; stack.back()->addChild(node); } } } if (tokens.size()) throw std::runtime_error("Unconsomed tokens"); if (stack.size() != 1) throw std::runtime_error("Invalid format - !1 stack elems"); NodeVector vec = stack.front()->getChildren(0); return vec; }
static Surface renderRoot(NodePtr node) { Surface surf; Surface root; Surface radical; root = render(node->getChildren(0)); NodePtr fakeSqrt = std::make_shared<Node>(CMD, "sqrt"); fakeSqrt->absorb(node->getChildren(1), 0); radical = renderSqrt(fakeSqrt); surf.addSurface(root.getBox().w - 1, radical); surf.addSurface(0, root, 1); return surf; }