MCPcopy Create free account
hub / github.com/FastFlowLM/FastFlowLM / parseTemplate

Method parseTemplate

src/include/minja/minja.hpp:2548–2684  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2546 }
2547
2548 std::shared_ptr<TemplateNode> parseTemplate(
2549 const TemplateTokenIterator & begin,
2550 TemplateTokenIterator & it,
2551 const TemplateTokenIterator & end,
2552 bool fully = false) const {
2553 std::vector<std::shared_ptr<TemplateNode>> children;
2554 while (it != end) {
2555 const auto start = it;
2556 const auto & token = *(it++);
2557 if (auto if_token = dynamic_cast<IfTemplateToken*>(token.get())) {
2558 std::vector<std::pair<std::shared_ptr<Expression>, std::shared_ptr<TemplateNode>>> cascade;
2559 cascade.emplace_back(std::move(if_token->condition), parseTemplate(begin, it, end));
2560
2561 while (it != end && (*it)->type == TemplateToken::Type::Elif) {
2562 auto elif_token = dynamic_cast<ElifTemplateToken*>((*(it++)).get());
2563 cascade.emplace_back(std::move(elif_token->condition), parseTemplate(begin, it, end));
2564 }
2565
2566 if (it != end && (*it)->type == TemplateToken::Type::Else) {
2567 cascade.emplace_back(nullptr, parseTemplate(begin, ++it, end));
2568 }
2569 if (it == end || (*(it++))->type != TemplateToken::Type::EndIf) {
2570 throw unterminated(**start);
2571 }
2572 children.emplace_back(std::make_shared<IfNode>(token->location, std::move(cascade)));
2573 } else if (auto for_token = dynamic_cast<ForTemplateToken*>(token.get())) {
2574 auto body = parseTemplate(begin, it, end);
2575 auto else_body = std::shared_ptr<TemplateNode>();
2576 if (it != end && (*it)->type == TemplateToken::Type::Else) {
2577 else_body = parseTemplate(begin, ++it, end);
2578 }
2579 if (it == end || (*(it++))->type != TemplateToken::Type::EndFor) {
2580 throw unterminated(**start);
2581 }
2582 children.emplace_back(std::make_shared<ForNode>(token->location, std::move(for_token->var_names), std::move(for_token->iterable), std::move(for_token->condition), std::move(body), for_token->recursive, std::move(else_body)));
2583 } else if (dynamic_cast<GenerationTemplateToken*>(token.get())) {
2584 auto body = parseTemplate(begin, it, end);
2585 if (it == end || (*(it++))->type != TemplateToken::Type::EndGeneration) {
2586 throw unterminated(**start);
2587 }
2588 // Treat as a no-op, as our scope is templates for inference, not training (`{% generation %}` wraps generated tokens for masking).
2589 children.emplace_back(std::move(body));
2590 } else if (auto text_token = dynamic_cast<TextTemplateToken*>(token.get())) {
2591 SpaceHandling pre_space = (it - 1) != begin ? (*(it - 2))->post_space : SpaceHandling::Keep;
2592 SpaceHandling post_space = it != end ? (*it)->pre_space : SpaceHandling::Keep;
2593
2594 auto text = text_token->text;
2595 if (post_space == SpaceHandling::Strip) {
2596 static std::regex trailing_space_regex(R"(\s+$)");
2597 text = std::regex_replace(text, trailing_space_regex, "");
2598 } else if (options.lstrip_blocks && it != end) {
2599 auto i = text.size();
2600 while (i > 0 && (text[i - 1] == ' ' || text[i - 1] == '\t')) i--;
2601 if ((i == 0 && (it - 1) == begin) || (i > 0 && text[i - 1] == '\n')) {
2602 text.resize(i);
2603 }
2604 }
2605 if (pre_space == SpaceHandling::Strip) {

Callers 1

parseMethod · 0.80

Calls 5

eraseMethod · 0.80
getMethod · 0.45
sizeMethod · 0.45
resizeMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected