//uri = scheme ":" hier-part [ "?" query ] [ "#" fragment ] TextCursor parse_uri(TextCursor cursor) { cursor = parse_scheme(cursor); if(get_char(cursor) != ':') throw ParseError(); cursor = parse_hier_part(cursor); try { cursor = parse_query(cursor); } catch(ParseError) { } try { cursor = parse_fragment(cursor); } catch(ParseError) { } return cursor; }
int main(void) { char line[MAX_LINE_LEN]; size_t lineno = 0; while (fgets(line, sizeof(line), stdin) != 0) { LineControl ctrl; init_linectrl(&ctrl); lineno++; if (debug) printf("Line %zu: (%zu) [[%s]]\n", lineno, strlen(line), line); int extra = 0; while (parse_fragment(line, &ctrl) != 0 && fgets(line, sizeof(line), stdin) != 0) { if (debug) printf("Extra %d for line %zu: (%zu) [[%s]]\n", ++extra, lineno, strlen(line), line); } WordList *list = &ctrl.list; printf("Line %zu: length %zu, words = %zu\n", lineno, ctrl.line_length, list->num_words); size_t num_words = list->num_words; if (num_words > MAX_WORD_CNT) num_words = MAX_WORD_CNT; for (size_t i = 0; i < num_words; i++) { printf(" %zu: (%zu) %s\n", i + 1, list->words[i].length, list->words[i].word); } putchar('\n'); free_wordlist(&ctrl.list); } return 0; }
ParseResult<BaseNode> parse_fragments (iterator_t it, iterator_t it_end, int level) { std::vector<std::unique_ptr<BaseNode>> result; if (it == it_end) { return make_parse_result<ConcatNode> (std::move (result), it); } while (true) { //std::cerr << " in> " << std::string (it, it_end) << std::endl; auto frag = parse_fragment (it, it_end, level); //frag.value->dump (std::cerr); //std::cerr << "out> " << std::string (frag.next, it_end) << std::endl; result.emplace_back (std::move (frag.value)); it = frag.next; if (it == it_end) { break; } if (level == 0) { // Level 0's '}' and ',' are considered as itself if (*it == '}' || *it == ',') { result.emplace_back (std::make_unique<StringNode> (std::string { it, it + 1 })); ++it; } } else if (*it == '}' || *it == ',') { switch (result.size ()) { case 0: return ParseResult<StringNode> { std::make_unique<StringNode> (), it }; case 1: return ParseResult<BaseNode> { std::move (result[0]), it }; default: break; } return make_parse_result<ConcatNode> (std::move (result), it); } } return make_parse_result<ConcatNode> (std::move (result), it) ; }