| 1515 | }; |
| 1516 | |
| 1517 | static struct llama_sampler * llama_sampler_init_grammar_impl( |
| 1518 | const struct llama_vocab * vocab, |
| 1519 | const char * grammar_str, |
| 1520 | const char * grammar_root, |
| 1521 | bool lazy, |
| 1522 | const char ** trigger_words, |
| 1523 | size_t num_trigger_words, |
| 1524 | const llama_token * trigger_tokens, |
| 1525 | size_t num_trigger_tokens, |
| 1526 | const char ** trigger_patterns, |
| 1527 | size_t num_trigger_patterns) { |
| 1528 | auto * ctx = new llama_sampler_grammar; |
| 1529 | |
| 1530 | if (grammar_str != nullptr && grammar_str[0] != '\0') { |
| 1531 | // TODO: remove trigger_words support. |
| 1532 | if (trigger_words != nullptr && num_trigger_words > 0) { |
| 1533 | GGML_ASSERT(trigger_patterns == nullptr && num_trigger_patterns == 0); |
| 1534 | std::string trigger_pattern("[\\s\\S]*?("); |
| 1535 | for (size_t i = 0; i < num_trigger_words; ++i) { |
| 1536 | static const std::regex special_chars("[.^$|()*+?\\[\\]{}\\\\]"); |
| 1537 | if (i > 0) { |
| 1538 | trigger_pattern += "|"; |
| 1539 | } |
| 1540 | trigger_pattern += std::regex_replace(trigger_words[i], special_chars, "\\$0"); |
| 1541 | } |
| 1542 | trigger_pattern += ")[\\s\\S]*"; |
| 1543 | auto trigger_pattern_c = trigger_pattern.c_str(); |
| 1544 | trigger_patterns = &trigger_pattern_c; |
| 1545 | num_trigger_patterns = 1; |
| 1546 | } |
| 1547 | *ctx = { |
| 1548 | /* .vocab = */ vocab, |
| 1549 | /* .grammar_str = */ grammar_str, |
| 1550 | /* .grammar_root = */ grammar_root, |
| 1551 | /* .grammar = */ llama_grammar_init_impl(vocab, grammar_str, grammar_root, lazy, trigger_patterns, num_trigger_patterns, trigger_tokens, num_trigger_tokens), |
| 1552 | }; |
| 1553 | if (!ctx->grammar) { |
| 1554 | delete ctx; |
| 1555 | return nullptr; |
| 1556 | } |
| 1557 | } else { |
| 1558 | *ctx = { |
| 1559 | /* .vocab = */ vocab, |
| 1560 | /* .grammar_str = */ {}, |
| 1561 | /* .grammar_root = */ {}, |
| 1562 | /* .grammar = */ nullptr, |
| 1563 | }; |
| 1564 | } |
| 1565 | |
| 1566 | return llama_sampler_init( |
| 1567 | /* .iface = */ &llama_sampler_grammar_i, |
| 1568 | /* .ctx = */ ctx |
| 1569 | ); |
| 1570 | } |
| 1571 | |
| 1572 | struct llama_sampler * llama_sampler_init_grammar( |
| 1573 | const struct llama_vocab * vocab, |
no test coverage detected