| 130 | bool is_nested); |
| 131 | |
| 132 | static const char * parse_sequence( |
| 133 | parse_state & state, |
| 134 | const char * src, |
| 135 | const std::string & rule_name, |
| 136 | std::vector<llama_grammar_element> & out_elements, |
| 137 | bool is_nested) { |
| 138 | size_t last_sym_start = out_elements.size(); |
| 139 | const char * pos = src; |
| 140 | while (*pos) { |
| 141 | if (*pos == '"') { // literal string |
| 142 | pos++; |
| 143 | last_sym_start = out_elements.size(); |
| 144 | while (*pos != '"') { |
| 145 | auto char_pair = parse_char(pos); |
| 146 | pos = char_pair.second; |
| 147 | out_elements.push_back({LLAMA_GRETYPE_CHAR, char_pair.first}); |
| 148 | } |
| 149 | pos = parse_space(pos + 1, is_nested); |
| 150 | } else if (*pos == '[') { // char range(s) |
| 151 | pos++; |
| 152 | enum llama_gretype start_type = LLAMA_GRETYPE_CHAR; |
| 153 | if (*pos == '^') { |
| 154 | pos++; |
| 155 | start_type = LLAMA_GRETYPE_CHAR_NOT; |
| 156 | } |
| 157 | last_sym_start = out_elements.size(); |
| 158 | while (*pos != ']') { |
| 159 | auto char_pair = parse_char(pos); |
| 160 | pos = char_pair.second; |
| 161 | enum llama_gretype type = last_sym_start < out_elements.size() |
| 162 | ? LLAMA_GRETYPE_CHAR_ALT |
| 163 | : start_type; |
| 164 | |
| 165 | out_elements.push_back({type, char_pair.first}); |
| 166 | if (pos[0] == '-' && pos[1] != ']') { |
| 167 | auto endchar_pair = parse_char(pos + 1); |
| 168 | pos = endchar_pair.second; |
| 169 | out_elements.push_back({LLAMA_GRETYPE_CHAR_RNG_UPPER, endchar_pair.first}); |
| 170 | } |
| 171 | } |
| 172 | pos = parse_space(pos + 1, is_nested); |
| 173 | } else if (is_word_char(*pos)) { // rule reference |
| 174 | const char * name_end = parse_name(pos); |
| 175 | uint32_t ref_rule_id = get_symbol_id(state, pos, name_end - pos); |
| 176 | pos = parse_space(name_end, is_nested); |
| 177 | last_sym_start = out_elements.size(); |
| 178 | out_elements.push_back({LLAMA_GRETYPE_RULE_REF, ref_rule_id}); |
| 179 | } else if (*pos == '(') { // grouping |
| 180 | // parse nested alternates into synthesized rule |
| 181 | pos = parse_space(pos + 1, true); |
| 182 | uint32_t sub_rule_id = generate_symbol_id(state, rule_name); |
| 183 | pos = parse_alternates(state, pos, rule_name, sub_rule_id, true); |
| 184 | last_sym_start = out_elements.size(); |
| 185 | // output reference to synthesized rule |
| 186 | out_elements.push_back({LLAMA_GRETYPE_RULE_REF, sub_rule_id}); |
| 187 | if (*pos != ')') { |
| 188 | throw std::runtime_error(std::string("expecting ')' at ") + pos); |
| 189 | } |
no test coverage detected