llama-grammar.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164
  1. /**
  2. * llama.cpp - commit 40c6d79fb52f995f47507fedfeaae2ac05d9b35c - do not edit this file
  3. *
  4. * MIT License
  5. *
  6. * Copyright (c) 2023-2024 The ggml authors
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in all
  16. * copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24. * SOFTWARE.
  25. */
  26. #include "llama-grammar.h"
  27. #include "llama-vocab.h"
  28. #include "llama-sampling.h"
  29. #include <cmath>
  30. #include <algorithm>
  31. #include <stdexcept>
  32. //
  33. // helpers
  34. //
  35. // NOTE: assumes valid utf8 (but checks for overrun)
  36. static std::pair<uint32_t, const char *> decode_utf8(const char * src) {
  37. static const int lookup[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 3, 4 };
  38. uint8_t first_byte = static_cast<uint8_t>(*src);
  39. uint8_t highbits = first_byte >> 4;
  40. int len = lookup[highbits];
  41. uint8_t mask = (1 << (8 - len)) - 1;
  42. uint32_t value = first_byte & mask;
  43. const char * end = src + len; // may overrun!
  44. const char * pos = src + 1;
  45. for ( ; pos < end && *pos; pos++) {
  46. value = (value << 6) + (static_cast<uint8_t>(*pos) & 0x3F);
  47. }
  48. return std::make_pair(value, pos);
  49. }
  50. static std::pair<std::vector<uint32_t>, llama_partial_utf8> decode_utf8(
  51. const std::string & src,
  52. llama_partial_utf8 partial_start) {
  53. static const int lookup[] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 3, 4 };
  54. const char * pos = src.c_str();
  55. std::vector<uint32_t> code_points;
  56. // common english strings have the same number of codepoints and bytes. `+ 1` for the terminating 0.
  57. code_points.reserve(src.size() + 1);
  58. uint32_t value = partial_start.value;
  59. int n_remain = partial_start.n_remain;
  60. // continue previous decode, if applicable
  61. while (*pos != 0 && n_remain > 0) {
  62. uint8_t next_byte = static_cast<uint8_t>(*pos);
  63. if ((next_byte >> 6) != 2) {
  64. // invalid sequence, abort
  65. code_points.push_back(0);
  66. return std::make_pair(std::move(code_points), llama_partial_utf8{ 0, -1 });
  67. }
  68. value = (value << 6) + (next_byte & 0x3F);
  69. ++pos;
  70. --n_remain;
  71. }
  72. if (partial_start.n_remain > 0 && n_remain == 0) {
  73. code_points.push_back(value);
  74. }
  75. // decode any subsequent utf-8 sequences, which may end in an incomplete one
  76. while (*pos != 0) {
  77. uint8_t first_byte = static_cast<uint8_t>(*pos);
  78. uint8_t highbits = first_byte >> 4;
  79. n_remain = lookup[highbits] - 1;
  80. if (n_remain < 0) {
  81. // invalid sequence, abort
  82. code_points.clear();
  83. code_points.push_back(0);
  84. return std::make_pair(std::move(code_points), llama_partial_utf8{ 0, n_remain });
  85. }
  86. uint8_t mask = (1 << (7 - n_remain)) - 1;
  87. value = first_byte & mask;
  88. ++pos;
  89. while (*pos != 0 && n_remain > 0) {
  90. value = (value << 6) + (static_cast<uint8_t>(*pos) & 0x3F);
  91. ++pos;
  92. --n_remain;
  93. }
  94. if (n_remain == 0) {
  95. code_points.push_back(value);
  96. }
  97. }
  98. code_points.push_back(0);
  99. return std::make_pair(std::move(code_points), llama_partial_utf8{ value, n_remain });
  100. }
  101. static bool is_digit_char(char c) {
  102. return '0' <= c && c <= '9';
  103. }
  104. static bool is_word_char(char c) {
  105. return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '-' || is_digit_char(c);
  106. }
  107. static std::pair<uint32_t, const char *> parse_hex(const char * src, int size) {
  108. const char * pos = src;
  109. const char * end = src + size;
  110. uint32_t value = 0;
  111. for ( ; pos < end && *pos; pos++) {
  112. value <<= 4;
  113. char c = *pos;
  114. if ('a' <= c && c <= 'f') {
  115. value += c - 'a' + 10;
  116. } else if ('A' <= c && c <= 'F') {
  117. value += c - 'A' + 10;
  118. } else if ('0' <= c && c <= '9') {
  119. value += c - '0';
  120. } else {
  121. break;
  122. }
  123. }
  124. if (pos != end) {
  125. throw std::runtime_error("expecting " + std::to_string(size) + " hex chars at " + src);
  126. }
  127. return std::make_pair(value, pos);
  128. }
  129. static const char * parse_space(const char * src, bool newline_ok) {
  130. const char * pos = src;
  131. while (*pos == ' ' || *pos == '\t' || *pos == '#' ||
  132. (newline_ok && (*pos == '\r' || *pos == '\n'))) {
  133. if (*pos == '#') {
  134. while (*pos && *pos != '\r' && *pos != '\n') {
  135. pos++;
  136. }
  137. } else {
  138. pos++;
  139. }
  140. }
  141. return pos;
  142. }
  143. static const char * parse_name(const char * src) {
  144. const char * pos = src;
  145. while (is_word_char(*pos)) {
  146. pos++;
  147. }
  148. if (pos == src) {
  149. throw std::runtime_error(std::string("expecting name at ") + src);
  150. }
  151. return pos;
  152. }
  153. static const char * parse_int(const char * src) {
  154. const char * pos = src;
  155. while (is_digit_char(*pos)) {
  156. pos++;
  157. }
  158. if (pos == src) {
  159. throw std::runtime_error(std::string("expecting integer at ") + src);
  160. }
  161. return pos;
  162. }
  163. static std::pair<uint32_t, const char *> parse_char(const char * src) {
  164. if (*src == '\\') {
  165. switch (src[1]) {
  166. case 'x': return parse_hex(src + 2, 2);
  167. case 'u': return parse_hex(src + 2, 4);
  168. case 'U': return parse_hex(src + 2, 8);
  169. case 't': return std::make_pair('\t', src + 2);
  170. case 'r': return std::make_pair('\r', src + 2);
  171. case 'n': return std::make_pair('\n', src + 2);
  172. case '\\':
  173. case '"':
  174. case '[':
  175. case ']':
  176. return std::make_pair(src[1], src + 2);
  177. default:
  178. throw std::runtime_error(std::string("unknown escape at ") + src);
  179. }
  180. } else if (*src) {
  181. return decode_utf8(src);
  182. }
  183. throw std::runtime_error("unexpected end of input");
  184. }
  185. static void print_grammar_char(FILE * file, uint32_t c) {
  186. if (0x20 <= c && c <= 0x7f) {
  187. fprintf(file, "%c", static_cast<char>(c));
  188. } else {
  189. // cop out of encoding UTF-8
  190. fprintf(file, "<U+%04X>", c);
  191. }
  192. }
  193. static bool is_char_element(llama_grammar_element elem) {
  194. switch (elem.type) {
  195. case LLAMA_GRETYPE_CHAR: return true;
  196. case LLAMA_GRETYPE_CHAR_NOT: return true;
  197. case LLAMA_GRETYPE_CHAR_ALT: return true;
  198. case LLAMA_GRETYPE_CHAR_RNG_UPPER: return true;
  199. case LLAMA_GRETYPE_CHAR_ANY: return true;
  200. default: return false;
  201. }
  202. }
  203. static void print_rule_binary(FILE * file, const llama_grammar_rule & rule) {
  204. for (auto elem : rule) {
  205. switch (elem.type) {
  206. case LLAMA_GRETYPE_END: fprintf(file, "END"); break;
  207. case LLAMA_GRETYPE_ALT: fprintf(file, "ALT"); break;
  208. case LLAMA_GRETYPE_RULE_REF: fprintf(file, "RULE_REF"); break;
  209. case LLAMA_GRETYPE_CHAR: fprintf(file, "CHAR"); break;
  210. case LLAMA_GRETYPE_CHAR_NOT: fprintf(file, "CHAR_NOT"); break;
  211. case LLAMA_GRETYPE_CHAR_RNG_UPPER: fprintf(file, "CHAR_RNG_UPPER"); break;
  212. case LLAMA_GRETYPE_CHAR_ALT: fprintf(file, "CHAR_ALT"); break;
  213. case LLAMA_GRETYPE_CHAR_ANY: fprintf(file, "CHAR_ANY"); break;
  214. }
  215. switch (elem.type) {
  216. case LLAMA_GRETYPE_END:
  217. case LLAMA_GRETYPE_ALT:
  218. case LLAMA_GRETYPE_RULE_REF:
  219. fprintf(file, "(%u) ", elem.value);
  220. break;
  221. case LLAMA_GRETYPE_CHAR:
  222. case LLAMA_GRETYPE_CHAR_NOT:
  223. case LLAMA_GRETYPE_CHAR_RNG_UPPER:
  224. case LLAMA_GRETYPE_CHAR_ALT:
  225. case LLAMA_GRETYPE_CHAR_ANY:
  226. fprintf(file, "(\"");
  227. print_grammar_char(file, elem.value);
  228. fprintf(file, "\") ");
  229. break;
  230. }
  231. }
  232. fprintf(file, "\n");
  233. }
  234. static void print_rule(
  235. FILE * file,
  236. uint32_t rule_id,
  237. const llama_grammar_rule & rule,
  238. const std::map<uint32_t, std::string> & symbol_id_names) {
  239. if (rule.empty() || rule.back().type != LLAMA_GRETYPE_END) {
  240. throw std::runtime_error(
  241. "malformed rule, does not end with LLAMA_GRETYPE_END: " + std::to_string(rule_id));
  242. }
  243. fprintf(file, "%s ::= ", symbol_id_names.at(rule_id).c_str());
  244. for (size_t i = 0, end = rule.size() - 1; i < end; i++) {
  245. llama_grammar_element elem = rule[i];
  246. switch (elem.type) {
  247. case LLAMA_GRETYPE_END:
  248. throw std::runtime_error(
  249. "unexpected end of rule: " + std::to_string(rule_id) + "," +
  250. std::to_string(i));
  251. case LLAMA_GRETYPE_ALT:
  252. fprintf(file, "| ");
  253. break;
  254. case LLAMA_GRETYPE_RULE_REF:
  255. fprintf(file, "%s ", symbol_id_names.at(elem.value).c_str());
  256. break;
  257. case LLAMA_GRETYPE_CHAR:
  258. fprintf(file, "[");
  259. print_grammar_char(file, elem.value);
  260. break;
  261. case LLAMA_GRETYPE_CHAR_NOT:
  262. fprintf(file, "[^");
  263. print_grammar_char(file, elem.value);
  264. break;
  265. case LLAMA_GRETYPE_CHAR_RNG_UPPER:
  266. if (i == 0 || !is_char_element(rule[i - 1])) {
  267. throw std::runtime_error(
  268. "LLAMA_GRETYPE_CHAR_RNG_UPPER without preceding char: " +
  269. std::to_string(rule_id) + "," + std::to_string(i));
  270. }
  271. fprintf(file, "-");
  272. print_grammar_char(file, elem.value);
  273. break;
  274. case LLAMA_GRETYPE_CHAR_ALT:
  275. if (i == 0 || !is_char_element(rule[i - 1])) {
  276. throw std::runtime_error(
  277. "LLAMA_GRETYPE_CHAR_ALT without preceding char: " +
  278. std::to_string(rule_id) + "," + std::to_string(i));
  279. }
  280. print_grammar_char(file, elem.value);
  281. break;
  282. case LLAMA_GRETYPE_CHAR_ANY:
  283. fprintf(file, ".");
  284. break;
  285. }
  286. if (is_char_element(elem)) {
  287. switch (rule[i + 1].type) {
  288. case LLAMA_GRETYPE_CHAR_ALT:
  289. case LLAMA_GRETYPE_CHAR_RNG_UPPER:
  290. case LLAMA_GRETYPE_CHAR_ANY:
  291. break;
  292. default:
  293. fprintf(file, "] ");
  294. }
  295. }
  296. }
  297. fprintf(file, "\n");
  298. }
  299. //
  300. // implementation
  301. //
  302. uint32_t llama_grammar_parser::get_symbol_id(const char * src, size_t len) {
  303. uint32_t next_id = static_cast<uint32_t>(symbol_ids.size());
  304. auto result = symbol_ids.emplace(std::string(src, len), next_id);
  305. return result.first->second;
  306. }
  307. uint32_t llama_grammar_parser::generate_symbol_id(const std::string & base_name) {
  308. uint32_t next_id = static_cast<uint32_t>(symbol_ids.size());
  309. symbol_ids[base_name + '_' + std::to_string(next_id)] = next_id;
  310. return next_id;
  311. }
  312. void llama_grammar_parser::add_rule(uint32_t rule_id, const llama_grammar_rule & rule) {
  313. if (rules.size() <= rule_id) {
  314. rules.resize(rule_id + 1);
  315. }
  316. rules[rule_id] = rule;
  317. }
  318. const char * llama_grammar_parser::parse_alternates(
  319. const char * src,
  320. const std::string & rule_name,
  321. uint32_t rule_id,
  322. bool is_nested) {
  323. llama_grammar_rule rule;
  324. const char * pos = parse_sequence(src, rule_name, rule, is_nested);
  325. while (*pos == '|') {
  326. rule.push_back({LLAMA_GRETYPE_ALT, 0});
  327. pos = parse_space(pos + 1, true);
  328. pos = parse_sequence(pos, rule_name, rule, is_nested);
  329. }
  330. rule.push_back({LLAMA_GRETYPE_END, 0});
  331. add_rule(rule_id, rule);
  332. return pos;
  333. }
  334. const char * llama_grammar_parser::parse_sequence(
  335. const char * src,
  336. const std::string & rule_name,
  337. llama_grammar_rule & rule,
  338. bool is_nested) {
  339. size_t last_sym_start = rule.size();
  340. const char * pos = src;
  341. auto handle_repetitions = [&](int min_times, int max_times) {
  342. if (last_sym_start == rule.size()) {
  343. throw std::runtime_error(std::string("expecting preceding item to */+/?/{ at ") + pos);
  344. }
  345. // apply transformation to previous symbol (last_sym_start to end) according to
  346. // the following rewrite rules:
  347. // S{m,n} --> S S S (m times) S'(n-m)
  348. // S'(x) ::= S S'(x-1) |
  349. // (... n-m definitions of these S' rules ...)
  350. // S'(1) ::= S |
  351. // S{m,} --> S S S (m times) S'
  352. // S' ::= S S' |
  353. // S* --> S{0,}
  354. // --> S' ::= S S' |
  355. // S+ --> S{1,}
  356. // --> S S'
  357. // S' ::= S S' |
  358. // S? --> S{0,1}
  359. // --> S'
  360. // S' ::= S |
  361. llama_grammar_rule prev_rule(rule.begin() + last_sym_start, rule.end());
  362. if (min_times == 0) {
  363. rule.resize(last_sym_start);
  364. } else {
  365. // Repeat the previous elements (min_times - 1) times
  366. for (int i = 1; i < min_times; i++) {
  367. rule.insert(rule.end(), prev_rule.begin(), prev_rule.end());
  368. }
  369. }
  370. uint32_t last_rec_rule_id = 0;
  371. auto n_opt = max_times < 0 ? 1 : max_times - min_times;
  372. llama_grammar_rule rec_rule(prev_rule);
  373. for (int i = 0; i < n_opt; i++) {
  374. rec_rule.resize(prev_rule.size());
  375. uint32_t rec_rule_id = generate_symbol_id( rule_name);
  376. if (i > 0 || max_times < 0) {
  377. rec_rule.push_back({LLAMA_GRETYPE_RULE_REF, max_times < 0 ? rec_rule_id : last_rec_rule_id});
  378. }
  379. rec_rule.push_back({LLAMA_GRETYPE_ALT, 0});
  380. rec_rule.push_back({LLAMA_GRETYPE_END, 0});
  381. add_rule( rec_rule_id, rec_rule);
  382. last_rec_rule_id = rec_rule_id;
  383. }
  384. if (n_opt > 0) {
  385. rule.push_back({LLAMA_GRETYPE_RULE_REF, last_rec_rule_id});
  386. }
  387. };
  388. while (*pos) {
  389. if (*pos == '"') { // literal string
  390. pos++;
  391. last_sym_start = rule.size();
  392. while (*pos != '"') {
  393. if (!*pos) {
  394. throw std::runtime_error("unexpected end of input");
  395. }
  396. auto char_pair = parse_char(pos);
  397. pos = char_pair.second;
  398. rule.push_back({LLAMA_GRETYPE_CHAR, char_pair.first});
  399. }
  400. pos = parse_space(pos + 1, is_nested);
  401. } else if (*pos == '[') { // char range(s)
  402. pos++;
  403. enum llama_gretype start_type = LLAMA_GRETYPE_CHAR;
  404. if (*pos == '^') {
  405. pos++;
  406. start_type = LLAMA_GRETYPE_CHAR_NOT;
  407. }
  408. last_sym_start = rule.size();
  409. while (*pos != ']') {
  410. if (!*pos) {
  411. throw std::runtime_error("unexpected end of input");
  412. }
  413. auto char_pair = parse_char(pos);
  414. pos = char_pair.second;
  415. enum llama_gretype type = last_sym_start < rule.size()
  416. ? LLAMA_GRETYPE_CHAR_ALT
  417. : start_type;
  418. rule.push_back({type, char_pair.first});
  419. if (pos[0] == '-' && pos[1] != ']') {
  420. if (!pos[1]) {
  421. throw std::runtime_error("unexpected end of input");
  422. }
  423. auto endchar_pair = parse_char(pos + 1);
  424. pos = endchar_pair.second;
  425. rule.push_back({LLAMA_GRETYPE_CHAR_RNG_UPPER, endchar_pair.first});
  426. }
  427. }
  428. pos = parse_space(pos + 1, is_nested);
  429. } else if (is_word_char(*pos)) { // rule reference
  430. const char * name_end = parse_name(pos);
  431. uint32_t ref_rule_id = get_symbol_id(pos, name_end - pos);
  432. pos = parse_space(name_end, is_nested);
  433. last_sym_start = rule.size();
  434. rule.push_back({LLAMA_GRETYPE_RULE_REF, ref_rule_id});
  435. } else if (*pos == '(') { // grouping
  436. // parse nested alternates into synthesized rule
  437. pos = parse_space(pos + 1, true);
  438. uint32_t sub_rule_id = generate_symbol_id(rule_name);
  439. pos = parse_alternates(pos, rule_name, sub_rule_id, true);
  440. last_sym_start = rule.size();
  441. // output reference to synthesized rule
  442. rule.push_back({LLAMA_GRETYPE_RULE_REF, sub_rule_id});
  443. if (*pos != ')') {
  444. throw std::runtime_error(std::string("expecting ')' at ") + pos);
  445. }
  446. pos = parse_space(pos + 1, is_nested);
  447. } else if (*pos == '.') { // any char
  448. last_sym_start = rule.size();
  449. rule.push_back({LLAMA_GRETYPE_CHAR_ANY, 0});
  450. pos = parse_space(pos + 1, is_nested);
  451. } else if (*pos == '*') {
  452. pos = parse_space(pos + 1, is_nested);
  453. handle_repetitions(0, -1);
  454. } else if (*pos == '+') {
  455. pos = parse_space(pos + 1, is_nested);
  456. handle_repetitions(1, -1);
  457. } else if (*pos == '?') {
  458. pos = parse_space(pos + 1, is_nested);
  459. handle_repetitions(0, 1);
  460. } else if (*pos == '{') {
  461. pos = parse_space(pos + 1, is_nested);
  462. if (!is_digit_char(*pos)) {
  463. throw std::runtime_error(std::string("expecting an int at ") + pos);
  464. }
  465. const char * int_end = parse_int(pos);
  466. int min_times = std::stoul(std::string(pos, int_end - pos));
  467. pos = parse_space(int_end, is_nested);
  468. int max_times = -1;
  469. if (*pos == '}') {
  470. max_times = min_times;
  471. pos = parse_space(pos + 1, is_nested);
  472. } else if (*pos == ',') {
  473. pos = parse_space(pos + 1, is_nested);
  474. if (is_digit_char(*pos)) {
  475. const char * int_end = parse_int(pos);
  476. max_times = std::stoul(std::string(pos, int_end - pos));
  477. pos = parse_space(int_end, is_nested);
  478. }
  479. if (*pos != '}') {
  480. throw std::runtime_error(std::string("expecting '}' at ") + pos);
  481. }
  482. pos = parse_space(pos + 1, is_nested);
  483. } else {
  484. throw std::runtime_error(std::string("expecting ',' at ") + pos);
  485. }
  486. handle_repetitions(min_times, max_times);
  487. } else {
  488. break;
  489. }
  490. }
  491. return pos;
  492. }
  493. const char * llama_grammar_parser::parse_rule(const char * src) {
  494. const char * name_end = parse_name(src);
  495. const char * pos = parse_space(name_end, false);
  496. size_t name_len = name_end - src;
  497. uint32_t rule_id = get_symbol_id(src, name_len);
  498. const std::string name(src, name_len);
  499. if (!(pos[0] == ':' && pos[1] == ':' && pos[2] == '=')) {
  500. throw std::runtime_error(std::string("expecting ::= at ") + pos);
  501. }
  502. pos = parse_space(pos + 3, true);
  503. pos = parse_alternates(pos, name, rule_id, false);
  504. if (*pos == '\r') {
  505. pos += pos[1] == '\n' ? 2 : 1;
  506. } else if (*pos == '\n') {
  507. pos++;
  508. } else if (*pos) {
  509. throw std::runtime_error(std::string("expecting newline or end at ") + pos);
  510. }
  511. return parse_space(pos, true);
  512. }
  513. bool llama_grammar_parser::parse(const char * src) {
  514. try {
  515. const char * pos = parse_space(src, true);
  516. while (*pos) {
  517. pos = parse_rule(pos);
  518. }
  519. // Validate the state to ensure that all rules are defined
  520. for (const auto & rule : rules) {
  521. if (rule.empty()) {
  522. throw std::runtime_error("Undefined rule");
  523. }
  524. for (const auto & elem : rule) {
  525. if (elem.type == LLAMA_GRETYPE_RULE_REF) {
  526. // Ensure that the rule at that location exists
  527. if (elem.value >= rules.size() || rules[elem.value].empty()) {
  528. // Get the name of the rule that is missing
  529. for (const auto & kv : symbol_ids) {
  530. if (kv.second == elem.value) {
  531. throw std::runtime_error("Undefined rule identifier '" + kv.first + "'");
  532. }
  533. }
  534. }
  535. }
  536. }
  537. }
  538. } catch (const std::exception & err) {
  539. fprintf(stderr, "%s: error parsing grammar: %s\n", __func__, err.what());
  540. rules.clear();
  541. return false;
  542. }
  543. return true;
  544. }
  545. void llama_grammar_parser::print(FILE * file) {
  546. try {
  547. std::map<uint32_t, std::string> symbol_id_names;
  548. for (const auto & kv : symbol_ids) {
  549. symbol_id_names[kv.second] = kv.first;
  550. }
  551. for (size_t i = 0, end = rules.size(); i < end; i++) {
  552. // fprintf(file, "%zu: ", i);
  553. // print_rule_binary(file, rules[i]);
  554. print_rule(file, uint32_t(i), rules[i], symbol_id_names);
  555. // fprintf(file, "\n");
  556. }
  557. } catch (const std::exception & err) {
  558. fprintf(stderr, "\n%s: error printing grammar: %s\n", __func__, err.what());
  559. }
  560. }
  561. llama_grammar_stack llama_grammar_parser::c_rules() const {
  562. llama_grammar_stack ret;
  563. ret.reserve(rules.size());
  564. for (const auto & rule : rules) {
  565. ret.push_back(rule.data());
  566. }
  567. return ret;
  568. }
  569. // returns true iff pos points to the end of one of the definitions of a rule
  570. static bool llama_grammar_is_end_of_sequence(const llama_grammar_element * pos) {
  571. switch (pos->type) {
  572. case LLAMA_GRETYPE_END: return true; // NOLINT
  573. case LLAMA_GRETYPE_ALT: return true; // NOLINT
  574. default: return false;
  575. }
  576. }
  577. // returns true iff chr satisfies the char range at pos (regular or inverse range)
  578. // asserts that pos is pointing to a char range element
  579. static std::pair<bool, const llama_grammar_element *> llama_grammar_match_char(
  580. const llama_grammar_element * pos,
  581. const uint32_t chr) {
  582. bool found = false;
  583. bool is_positive_char = pos->type == LLAMA_GRETYPE_CHAR || pos->type == LLAMA_GRETYPE_CHAR_ANY;
  584. GGML_ASSERT(is_positive_char || pos->type == LLAMA_GRETYPE_CHAR_NOT); // NOLINT
  585. do {
  586. if (pos[1].type == LLAMA_GRETYPE_CHAR_RNG_UPPER) {
  587. // inclusive range, e.g. [a-z]
  588. found = found || (pos->value <= chr && chr <= pos[1].value);
  589. pos += 2;
  590. } else if (pos->type == LLAMA_GRETYPE_CHAR_ANY) {
  591. // Any character matches "."
  592. found = true;
  593. pos += 1;
  594. } else {
  595. // exact char match, e.g. [a] or "a"
  596. found = found || pos->value == chr;
  597. pos += 1;
  598. }
  599. } while (pos->type == LLAMA_GRETYPE_CHAR_ALT);
  600. return std::make_pair(found == is_positive_char, pos);
  601. }
  602. // returns true iff some continuation of the given partial UTF-8 sequence could satisfy the char
  603. // range at pos (regular or inverse range)
  604. // asserts that pos is pointing to a char range element
  605. static bool llama_grammar_match_partial_char(
  606. const llama_grammar_element * pos,
  607. const llama_partial_utf8 partial_utf8) {
  608. bool is_positive_char = pos->type == LLAMA_GRETYPE_CHAR || pos->type == LLAMA_GRETYPE_CHAR_ANY;
  609. GGML_ASSERT(is_positive_char || pos->type == LLAMA_GRETYPE_CHAR_NOT);
  610. uint32_t partial_value = partial_utf8.value;
  611. int n_remain = partial_utf8.n_remain;
  612. // invalid sequence or 7-bit char split across 2 bytes (overlong)
  613. if (n_remain < 0 || (n_remain == 1 && partial_value < 2)) {
  614. return false;
  615. }
  616. // range of possible code points this partial UTF-8 sequence could complete to
  617. uint32_t low = partial_value << (n_remain * 6);
  618. uint32_t high = low | ((1 << (n_remain * 6)) - 1);
  619. if (low == 0) {
  620. if (n_remain == 2) {
  621. low = 1 << 11;
  622. } else if (n_remain == 3) {
  623. low = 1 << 16;
  624. }
  625. }
  626. do {
  627. if (pos[1].type == LLAMA_GRETYPE_CHAR_RNG_UPPER) {
  628. // inclusive range, e.g. [a-z]
  629. if (pos->value <= high && low <= pos[1].value) {
  630. return is_positive_char;
  631. }
  632. pos += 2;
  633. } else if (pos->type == LLAMA_GRETYPE_CHAR_ANY) {
  634. // Any character matches "."
  635. return true;
  636. } else {
  637. // exact char match, e.g. [a] or "a"
  638. if (low <= pos->value && pos->value <= high) {
  639. return is_positive_char;
  640. }
  641. pos += 1;
  642. }
  643. } while (pos->type == LLAMA_GRETYPE_CHAR_ALT);
  644. return !is_positive_char;
  645. }
  646. // transforms a grammar pushdown stack into N possible stacks, all ending
  647. // at a character range (terminal element)
  648. static void llama_grammar_advance_stack(
  649. const llama_grammar_rules & rules,
  650. const llama_grammar_stack & stack,
  651. llama_grammar_stacks & new_stacks) {
  652. if (stack.empty()) {
  653. if (std::find(new_stacks.begin(), new_stacks.end(), stack) == new_stacks.end()) {
  654. new_stacks.emplace_back(stack);
  655. }
  656. return;
  657. }
  658. const llama_grammar_element * pos = stack.back();
  659. switch (pos->type) {
  660. case LLAMA_GRETYPE_RULE_REF: {
  661. const size_t rule_id = static_cast<size_t>(pos->value);
  662. const llama_grammar_element * subpos = rules[rule_id].data();
  663. do {
  664. // init new stack without the top (pos)
  665. llama_grammar_stack new_stack(stack.begin(), stack.end() - 1);
  666. if (!llama_grammar_is_end_of_sequence(pos + 1)) {
  667. // if this rule ref is followed by another element, add that to stack
  668. new_stack.push_back(pos + 1);
  669. }
  670. if (!llama_grammar_is_end_of_sequence(subpos)) {
  671. // if alternate is nonempty, add to stack
  672. new_stack.push_back(subpos);
  673. }
  674. llama_grammar_advance_stack(rules, new_stack, new_stacks);
  675. while (!llama_grammar_is_end_of_sequence(subpos)) {
  676. // scan to end of alternate def
  677. subpos++;
  678. }
  679. if (subpos->type == LLAMA_GRETYPE_ALT) {
  680. // there's another alternate def of this rule to process
  681. subpos++;
  682. } else {
  683. break;
  684. }
  685. } while (true);
  686. break;
  687. }
  688. case LLAMA_GRETYPE_CHAR:
  689. case LLAMA_GRETYPE_CHAR_NOT:
  690. case LLAMA_GRETYPE_CHAR_ANY:
  691. if (std::find(new_stacks.begin(), new_stacks.end(), stack) == new_stacks.end()) {
  692. // only add the stack if it's not a duplicate of one we already have
  693. new_stacks.emplace_back(stack);
  694. }
  695. break;
  696. default:
  697. // end of alternate (LLAMA_GRETYPE_END, LLAMA_GRETYPE_ALT) or middle of char range
  698. // (LLAMA_GRETYPE_CHAR_ALT, LLAMA_GRETYPE_CHAR_RNG_UPPER); stack should never be left on
  699. // those
  700. GGML_ABORT("fatal error");
  701. }
  702. }
  703. static llama_grammar_candidates llama_grammar_reject_candidates(
  704. const llama_grammar_rules & rules,
  705. const llama_grammar_stacks & stacks,
  706. const llama_grammar_candidates & candidates) {
  707. GGML_ASSERT(!stacks.empty()); // REVIEW
  708. if (candidates.empty()) {
  709. return {};
  710. }
  711. auto rejects = llama_grammar_reject_candidates_for_stack(rules, stacks.front(), candidates);
  712. for (size_t i = 1, size = stacks.size(); i < size; ++i) {
  713. rejects = llama_grammar_reject_candidates_for_stack(rules, stacks[i], rejects);
  714. }
  715. return rejects;
  716. }
  717. static bool llama_grammar_detect_left_recursion(
  718. const llama_grammar_rules & rules,
  719. size_t rule_index,
  720. std::vector<bool> * rules_visited,
  721. std::vector<bool> * rules_in_progress,
  722. std::vector<bool> * rules_may_be_empty) {
  723. if ((*rules_in_progress)[rule_index]) {
  724. return true;
  725. }
  726. (*rules_in_progress)[rule_index] = true;
  727. const llama_grammar_rule & rule = rules[rule_index];
  728. // First check if the rule might produce the empty string. This could be done combined with the second
  729. // step but it's more readable as two steps.
  730. bool at_rule_start = true;
  731. for (size_t i = 0; i < rule.size(); i++) {
  732. if (llama_grammar_is_end_of_sequence(&rule[i])) {
  733. if (at_rule_start) {
  734. (*rules_may_be_empty)[rule_index] = true;
  735. break;
  736. }
  737. at_rule_start = true;
  738. } else {
  739. at_rule_start = false;
  740. }
  741. }
  742. // Second, recurse into leftmost nonterminals (or next-leftmost as long as the previous nonterminal may
  743. // be empty)
  744. bool recurse_into_nonterminal = true;
  745. for (size_t i = 0; i < rule.size(); i++) {
  746. if (rule[i].type == LLAMA_GRETYPE_RULE_REF && recurse_into_nonterminal) {
  747. if (llama_grammar_detect_left_recursion(rules, (size_t)rule[i].value, rules_visited, rules_in_progress, rules_may_be_empty)) {
  748. return true;
  749. }
  750. if (!((*rules_may_be_empty)[(size_t)rule[i].value])) {
  751. recurse_into_nonterminal = false;
  752. }
  753. } else if (llama_grammar_is_end_of_sequence(&rule[i])) {
  754. recurse_into_nonterminal = true;
  755. } else {
  756. recurse_into_nonterminal = false;
  757. }
  758. }
  759. (*rules_in_progress)[rule_index] = false;
  760. (*rules_visited)[rule_index] = true;
  761. return false;
  762. }
  763. const llama_grammar_rules & llama_grammar_get_rules(const struct llama_grammar * grammar) {
  764. return grammar->rules;
  765. }
  766. llama_grammar_stacks & llama_grammar_get_stacks(struct llama_grammar * grammar) {
  767. return grammar->stacks;
  768. }
  769. void llama_grammar_accept(
  770. const llama_grammar_rules & rules,
  771. const llama_grammar_stacks & stacks,
  772. const uint32_t chr,
  773. llama_grammar_stacks & stacks_new) {
  774. stacks_new.clear();
  775. stacks_new.reserve(stacks.size());
  776. for (const auto & stack : stacks) {
  777. if (stack.empty()) {
  778. continue;
  779. }
  780. auto match = llama_grammar_match_char(stack.back(), chr);
  781. if (match.first) {
  782. const llama_grammar_element * pos = match.second;
  783. // update top of stack to next element, if any
  784. llama_grammar_stack new_stack(stack.begin(), stack.end() - 1);
  785. if (!llama_grammar_is_end_of_sequence(pos)) {
  786. new_stack.push_back(pos);
  787. }
  788. llama_grammar_advance_stack(rules, new_stack, stacks_new);
  789. }
  790. }
  791. }
  792. llama_grammar_candidates llama_grammar_reject_candidates_for_stack(
  793. const llama_grammar_rules & rules,
  794. const llama_grammar_stack & stack,
  795. const llama_grammar_candidates & candidates) {
  796. llama_grammar_candidates rejects;
  797. rejects.reserve(candidates.size());
  798. if (stack.empty()) {
  799. for (const auto & tok : candidates) {
  800. if (*tok.code_points != 0 || tok.partial_utf8.n_remain != 0) {
  801. rejects.push_back(tok);
  802. }
  803. }
  804. return rejects;
  805. }
  806. const llama_grammar_element * stack_pos = stack.back();
  807. llama_grammar_candidates next_candidates;
  808. next_candidates.reserve(candidates.size());
  809. for (const auto & tok : candidates) {
  810. if (*tok.code_points == 0) {
  811. // reached end of full codepoints in token, reject iff it ended in a partial sequence
  812. // that cannot satisfy this position in grammar
  813. if (tok.partial_utf8.n_remain != 0 &&
  814. !llama_grammar_match_partial_char(stack_pos, tok.partial_utf8)) {
  815. rejects.push_back(tok);
  816. }
  817. } else if (llama_grammar_match_char(stack_pos, *tok.code_points).first) {
  818. next_candidates.push_back({ tok.index, tok.code_points + 1, tok.partial_utf8 });
  819. } else {
  820. rejects.push_back(tok);
  821. }
  822. }
  823. const auto * stack_pos_after = llama_grammar_match_char(stack_pos, 0).second;
  824. // update top of stack to next element, if any
  825. llama_grammar_stack stack_after(stack.begin(), stack.end() - 1);
  826. if (!llama_grammar_is_end_of_sequence(stack_pos_after)) {
  827. stack_after.push_back(stack_pos_after);
  828. }
  829. llama_grammar_stacks next_stacks;
  830. llama_grammar_advance_stack(rules, stack_after, next_stacks);
  831. auto next_rejects = llama_grammar_reject_candidates(rules, next_stacks, next_candidates);
  832. for (const auto & tok : next_rejects) {
  833. rejects.push_back({ tok.index, tok.code_points - 1, tok.partial_utf8 });
  834. }
  835. return rejects;
  836. }
  837. ////////////////////
  838. struct llama_grammar * llama_grammar_init_impl(
  839. const struct llama_vocab * vocab,
  840. const llama_grammar_element ** rules,
  841. size_t n_rules,
  842. size_t start_rule_index) {
  843. const llama_grammar_element * pos;
  844. // copy rule definitions into vectors
  845. llama_grammar_rules vec_rules(n_rules);
  846. for (size_t i = 0; i < n_rules; i++) {
  847. for (pos = rules[i]; pos->type != LLAMA_GRETYPE_END; pos++) {
  848. vec_rules[i].push_back(*pos);
  849. }
  850. vec_rules[i].push_back({LLAMA_GRETYPE_END, 0});
  851. }
  852. // Check for left recursion
  853. std::vector<bool> rules_visited(n_rules);
  854. std::vector<bool> rules_in_progress(n_rules);
  855. std::vector<bool> rules_may_be_empty(n_rules);
  856. for (size_t i = 0; i < n_rules; i++) {
  857. if (rules_visited[i]) {
  858. continue;
  859. }
  860. if (llama_grammar_detect_left_recursion(vec_rules, i, &rules_visited, &rules_in_progress, &rules_may_be_empty)) {
  861. LLAMA_LOG_ERROR("unsupported grammar, left recursion detected for nonterminal at index %zu", i);
  862. return nullptr;
  863. }
  864. }
  865. // loop over alternates of start rule to build initial stacks
  866. llama_grammar_stacks stacks;
  867. pos = vec_rules[start_rule_index].data();
  868. do {
  869. llama_grammar_stack stack;
  870. if (!llama_grammar_is_end_of_sequence(pos)) {
  871. // if alternate is nonempty, add to stack
  872. stack.push_back(pos);
  873. }
  874. llama_grammar_advance_stack(vec_rules, stack, stacks);
  875. while (!llama_grammar_is_end_of_sequence(pos)) {
  876. // scan to end of alternate def
  877. pos++;
  878. }
  879. if (pos->type == LLAMA_GRETYPE_ALT) {
  880. // there's another alternate def of this rule to process
  881. pos++;
  882. } else {
  883. break;
  884. }
  885. } while (true);
  886. // Important: vec_rules has to be moved here, not copied, because stacks contains
  887. // pointers to elements of vec_rules. If vec_rules were copied into llama_grammar
  888. // then the pointers would be invalidated when the local vec_rules goes out of scope.
  889. return new llama_grammar { vocab, std::move(vec_rules), std::move(stacks), {}, };
  890. }
  891. struct llama_grammar * llama_grammar_init_impl(const struct llama_vocab * vocab, const char * grammar_str, const char * grammar_root) {
  892. llama_grammar_parser parser;
  893. // if there is a grammar, parse it
  894. if (!parser.parse(grammar_str)) {
  895. return nullptr;
  896. }
  897. // will be empty (default) if there are parse errors
  898. if (parser.rules.empty()) {
  899. fprintf(stderr, "%s: failed to parse grammar\n", __func__);
  900. return nullptr;
  901. }
  902. // Ensure that there is a "root" node.
  903. if (parser.symbol_ids.find("root") == parser.symbol_ids.end()) {
  904. fprintf(stderr, "%s: grammar does not contain a 'root' symbol\n", __func__);
  905. return nullptr;
  906. }
  907. std::vector<const llama_grammar_element *> grammar_rules(parser.c_rules());
  908. const size_t n_rules = grammar_rules.size();
  909. const size_t start_rule_index = parser.symbol_ids.at(grammar_root);
  910. const llama_grammar_element * pos;
  911. // copy rule definitions into vectors
  912. llama_grammar_rules vec_rules(n_rules);
  913. for (size_t i = 0; i < n_rules; i++) {
  914. for (pos = grammar_rules[i]; pos->type != LLAMA_GRETYPE_END; pos++) {
  915. vec_rules[i].push_back(*pos);
  916. }
  917. vec_rules[i].push_back({LLAMA_GRETYPE_END, 0});
  918. }
  919. // Check for left recursion
  920. std::vector<bool> rules_visited(n_rules);
  921. std::vector<bool> rules_in_progress(n_rules);
  922. std::vector<bool> rules_may_be_empty(n_rules);
  923. for (size_t i = 0; i < n_rules; i++) {
  924. if (rules_visited[i]) {
  925. continue;
  926. }
  927. if (llama_grammar_detect_left_recursion(vec_rules, i, &rules_visited, &rules_in_progress, &rules_may_be_empty)) {
  928. LLAMA_LOG_ERROR("unsupported grammar, left recursion detected for nonterminal at index %zu", i);
  929. return nullptr;
  930. }
  931. }
  932. // loop over alternates of start rule to build initial stacks
  933. llama_grammar_stacks stacks;
  934. pos = vec_rules[start_rule_index].data();
  935. do {
  936. llama_grammar_stack stack;
  937. if (!llama_grammar_is_end_of_sequence(pos)) {
  938. // if alternate is nonempty, add to stack
  939. stack.push_back(pos);
  940. }
  941. llama_grammar_advance_stack(vec_rules, stack, stacks);
  942. while (!llama_grammar_is_end_of_sequence(pos)) {
  943. // scan to end of alternate def
  944. pos++;
  945. }
  946. if (pos->type == LLAMA_GRETYPE_ALT) {
  947. // there's another alternate def of this rule to process
  948. pos++;
  949. } else {
  950. break;
  951. }
  952. } while (true);
  953. // Important: vec_rules has to be moved here, not copied, because stacks contains
  954. // pointers to elements of vec_rules. If vec_rules were copied into llama_grammar
  955. // then the pointers would be invalidated when the local vec_rules goes out of scope.
  956. return new llama_grammar { vocab, std::move(vec_rules), std::move(stacks), {}, };
  957. }
  958. void llama_grammar_free_impl(struct llama_grammar * grammar) {
  959. if (grammar == nullptr) {
  960. return;
  961. }
  962. delete grammar;
  963. }
  964. struct llama_grammar * llama_grammar_clone_impl(const struct llama_grammar & grammar) {
  965. llama_grammar * result = new llama_grammar { grammar.vocab, grammar.rules, grammar.stacks, grammar.partial_utf8, };
  966. // redirect elements in stacks to point to new rules
  967. for (size_t is = 0; is < result->stacks.size(); is++) {
  968. for (size_t ie = 0; ie < result->stacks[is].size(); ie++) {
  969. for (size_t ir0 = 0; ir0 < grammar.rules.size(); ir0++) {
  970. for (size_t ir1 = 0; ir1 < grammar.rules[ir0].size(); ir1++) {
  971. if (grammar.stacks[is][ie] == &grammar.rules[ir0][ir1]) {
  972. result->stacks[is][ie] = &result->rules[ir0][ir1];
  973. }
  974. }
  975. }
  976. }
  977. }
  978. return result;
  979. }
  980. void llama_grammar_apply_impl(const struct llama_grammar & grammar, llama_token_data_array * cur_p) {
  981. GGML_ASSERT(grammar.vocab != nullptr);
  982. bool allow_eog = false;
  983. for (const auto & stack : grammar.stacks) {
  984. if (stack.empty()) {
  985. allow_eog = true;
  986. break;
  987. }
  988. }
  989. std::vector<std::pair<std::vector<uint32_t>, llama_partial_utf8>> candidates_decoded;
  990. candidates_decoded.reserve(cur_p->size);
  991. llama_grammar_candidates candidates_grammar;
  992. candidates_grammar.reserve(cur_p->size);
  993. for (size_t i = 0; i < cur_p->size; ++i) {
  994. const llama_token id = cur_p->data[i].id;
  995. const std::string & piece = grammar.vocab->cache_token_to_piece.at(id);
  996. if (llama_token_is_eog_impl(*grammar.vocab, id)) {
  997. if (!allow_eog) {
  998. cur_p->data[i].logit = -INFINITY;
  999. }
  1000. } else if (piece.empty() || piece[0] == 0) {
  1001. cur_p->data[i].logit = -INFINITY;
  1002. } else {
  1003. candidates_decoded.push_back(decode_utf8(piece, grammar.partial_utf8));
  1004. candidates_grammar.push_back({ i, candidates_decoded.back().first.data(), candidates_decoded.back().second });
  1005. }
  1006. }
  1007. const auto rejects = llama_grammar_reject_candidates(grammar.rules, grammar.stacks, candidates_grammar);
  1008. for (const auto & reject : rejects) {
  1009. cur_p->data[reject.index].logit = -INFINITY;
  1010. }
  1011. }
  1012. void llama_grammar_accept_impl(struct llama_grammar & grammar, llama_token token) {
  1013. GGML_ASSERT(grammar.vocab != nullptr);
  1014. if (llama_token_is_eog_impl(*grammar.vocab, token)) {
  1015. for (const auto & stack : grammar.stacks) {
  1016. if (stack.empty()) {
  1017. return;
  1018. }
  1019. }
  1020. GGML_ABORT("fatal error");
  1021. }
  1022. const std::string & piece = grammar.vocab->cache_token_to_piece.at(token);
  1023. // Note terminating 0 in decoded string
  1024. const auto decoded = decode_utf8(piece, grammar.partial_utf8);
  1025. const auto & code_points = decoded.first;
  1026. llama_grammar_stacks stacks_new;
  1027. for (auto it = code_points.begin(), end = code_points.end() - 1; it != end; ++it) {
  1028. llama_grammar_accept(grammar.rules, grammar.stacks, *it, stacks_new);
  1029. grammar.stacks = std::move(stacks_new);
  1030. }
  1031. grammar.partial_utf8 = decoded.second;
  1032. GGML_ASSERT(!grammar.stacks.empty());
  1033. }