| 8064 | // |
| 8065 | |
| 8066 | struct llama_grammar * llama_grammar_init( |
| 8067 | const llama_grammar_element ** rules, |
| 8068 | size_t n_rules, |
| 8069 | size_t start_rule_index) { |
| 8070 | const llama_grammar_element * pos; |
| 8071 | |
| 8072 | // copy rule definitions into vectors |
| 8073 | std::vector<std::vector<llama_grammar_element>> vec_rules(n_rules); |
| 8074 | for (size_t i = 0; i < n_rules; i++) { |
| 8075 | for (pos = rules[i]; pos->type != LLAMA_GRETYPE_END; pos++) { |
| 8076 | vec_rules[i].push_back(*pos); |
| 8077 | } |
| 8078 | vec_rules[i].push_back({LLAMA_GRETYPE_END, 0}); |
| 8079 | } |
| 8080 | |
| 8081 | // loop over alternates of start rule to build initial stacks |
| 8082 | std::vector<std::vector<const llama_grammar_element *>> stacks; |
| 8083 | pos = rules[start_rule_index]; |
| 8084 | do { |
| 8085 | std::vector<const llama_grammar_element *> stack; |
| 8086 | if (!llama_grammar_is_end_of_sequence(pos)) { |
| 8087 | // if alternate is nonempty, add to stack |
| 8088 | stack.push_back(pos); |
| 8089 | } |
| 8090 | llama_grammar_advance_stack(vec_rules, stack, stacks); |
| 8091 | while (!llama_grammar_is_end_of_sequence(pos)) { |
| 8092 | // scan to end of alternate def |
| 8093 | pos++; |
| 8094 | } |
| 8095 | if (pos->type == LLAMA_GRETYPE_ALT) { |
| 8096 | // there's another alternate def of this rule to process |
| 8097 | pos++; |
| 8098 | } else { |
| 8099 | break; |
| 8100 | } |
| 8101 | } while (true); |
| 8102 | |
| 8103 | return new llama_grammar{ std::move(vec_rules), std::move(stacks), {} }; |
| 8104 | } |
| 8105 | |
| 8106 | void llama_grammar_free(struct llama_grammar * grammar) { |
| 8107 | delete grammar; |