1
0

llama-grammar.cpp 44 KB

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