| 248 | } |
| 249 | |
| 250 | static const char * parse_rule(parse_state & state, const char * src) { |
| 251 | const char * name_end = parse_name(src); |
| 252 | const char * pos = parse_space(name_end, false); |
| 253 | size_t name_len = name_end - src; |
| 254 | uint32_t rule_id = get_symbol_id(state, src, name_len); |
| 255 | const std::string name(src, name_len); |
| 256 | |
| 257 | if (!(pos[0] == ':' && pos[1] == ':' && pos[2] == '=')) { |
| 258 | throw std::runtime_error(std::string("expecting ::= at ") + pos); |
| 259 | } |
| 260 | pos = parse_space(pos + 3, true); |
| 261 | |
| 262 | pos = parse_alternates(state, pos, name, rule_id, false); |
| 263 | |
| 264 | if (*pos == '\r') { |
| 265 | pos += pos[1] == '\n' ? 2 : 1; |
| 266 | } else if (*pos == '\n') { |
| 267 | pos++; |
| 268 | } else if (*pos) { |
| 269 | throw std::runtime_error(std::string("expecting newline or end at ") + pos); |
| 270 | } |
| 271 | return parse_space(pos, true); |
| 272 | } |
| 273 | |
| 274 | parse_state parse(const char * src) { |
| 275 | try { |
no test coverage detected