Skip to content

Commit f2030e3

Browse files
author
Olivier Chafik
committed
grammars: handle x{n} and fix x{n,n}
1 parent 0160469 commit f2030e3

File tree

1 file changed

+26
-13
lines changed

1 file changed

+26
-13
lines changed

common/grammar-parser.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,8 @@ namespace grammar_parser {
199199
sub_rule.push_back({LLAMA_GRETYPE_RULE_REF, star_rule_id});
200200
} else {
201201
uint32_t last_rec_rule_id = 0;
202-
for (int i = 0, n = max_times - min_times; i < n; i++) {
202+
auto n_opt = max_times - min_times;
203+
for (int i = 0; i < n_opt; i++) {
203204
uint32_t rec_rule_id = generate_symbol_id(state, rule_name + "_" + std::to_string(i + 1));
204205
if (i == 0) {
205206
add_rule(state, rec_rule_id, {
@@ -217,7 +218,9 @@ namespace grammar_parser {
217218
}
218219
last_rec_rule_id = rec_rule_id;
219220
}
220-
sub_rule.push_back({LLAMA_GRETYPE_RULE_REF, last_rec_rule_id});
221+
if (n_opt > 0) {
222+
sub_rule.push_back({LLAMA_GRETYPE_RULE_REF, last_rec_rule_id});
223+
}
221224
}
222225
sub_rule.push_back({LLAMA_GRETYPE_END, 0});
223226
add_rule(state, sub_rule_id, sub_rule);
@@ -291,24 +294,34 @@ namespace grammar_parser {
291294
pos = parse_space(pos + 1, is_nested);
292295
size_t min_times = 0;
293296
int max_times = -1;
297+
294298
if (is_digit_char(*pos)) {
295299
const char * int_end = parse_int(pos);
296300
min_times = std::stoul(std::string(pos, int_end - pos));
297301
pos = parse_space(int_end, is_nested);
302+
} else if (*pos != ',') {
303+
throw std::runtime_error(std::string("expecting an int or ',' at ") + pos);
298304
}
299-
if (*pos != ',') {
305+
306+
if (*pos == '}') {
307+
max_times = min_times;
308+
pos = parse_space(pos + 1, is_nested);
309+
} else if (*pos == ',') {
310+
pos = parse_space(pos + 1, is_nested);
311+
312+
if (is_digit_char(*pos)) {
313+
const char * int_end = parse_int(pos);
314+
max_times = std::stoul(std::string(pos, int_end - pos));
315+
pos = parse_space(int_end, is_nested);
316+
}
317+
318+
if (*pos != '}') {
319+
throw std::runtime_error(std::string("expecting '}' at ") + pos);
320+
}
321+
pos = parse_space(pos + 1, is_nested);
322+
} else {
300323
throw std::runtime_error(std::string("expecting ',' at ") + pos);
301324
}
302-
pos = parse_space(pos + 1, is_nested);
303-
if (is_digit_char(*pos)) {
304-
const char * int_end = parse_int(pos);
305-
max_times = std::stoul(std::string(pos, int_end - pos));
306-
pos = parse_space(int_end, is_nested);
307-
}
308-
if (*pos != '}') {
309-
throw std::runtime_error(std::string("expecting '}' at ") + pos);
310-
}
311-
pos = parse_space(pos + 1, is_nested);
312325
handle_repetitions(min_times, max_times);
313326
} else {
314327
break;

0 commit comments

Comments
 (0)