diff --git a/src/parsers/sequence.c b/src/parsers/sequence.c index 6377589419ea53ffdd47293a704a3d6cf405d4d4..55c0c8885573ef7779714efd49eaf64cc59ac878 100644 --- a/src/parsers/sequence.c +++ b/src/parsers/sequence.c @@ -117,28 +117,33 @@ HParser* h_sequence__v(HParser* p, va_list ap) { } HParser* h_sequence__mv(HAllocator* mm__, HParser *p, va_list ap_) { - va_list ap; - size_t len = 0; - const HParser *arg; - - assert(p != NULL); - va_copy(ap, ap_); - do { - len++; - arg = va_arg(ap, HParser *); - } while (arg); - va_end(ap); HSequence *s = h_new(HSequence, 1); - s->p_array = h_new(HParser *, len); - - va_copy(ap, ap_); - s->p_array[0] = p; - for (size_t i = 1; i < len; i++) { - s->p_array[i] = va_arg(ap, HParser *); - } while (arg); - va_end(ap); + s->len = 0; + + if(p) { + // non-empty sequence + const HParser *arg; + size_t len = 0; + va_list ap; + + va_copy(ap, ap_); + do { + len++; + arg = va_arg(ap, HParser *); + } while (arg); + va_end(ap); + s->p_array = h_new(HParser *, len); + + va_copy(ap, ap_); + s->p_array[0] = p; + for (size_t i = 1; i < len; i++) { + s->p_array[i] = va_arg(ap, HParser *); + } while (arg); + va_end(ap); + + s->len = len; + } - s->len = len; return h_new_parser(mm__, &sequence_vt, s); } diff --git a/src/t_parser.c b/src/t_parser.c index c42eca91321c241a1987b99116c8c90deefbdf64..331d2629018b40717bf49309ba0b561ce7a618a3 100644 --- a/src/t_parser.c +++ b/src/t_parser.c @@ -241,6 +241,7 @@ static void test_nothing_p(gconstpointer backend) { static void test_sequence(gconstpointer backend) { const HParser *sequence_1 = h_sequence(h_ch('a'), h_ch('b'), NULL); const HParser *sequence_2 = h_sequence(h_ch('a'), h_whitespace(h_ch('b')), NULL); + const HParser *sequence_3 = h_sequence(NULL, NULL); // second NULL is to silence GCC g_check_parse_match(sequence_1, (HParserBackend)GPOINTER_TO_INT(backend), "ab", 2, "(u0x61 u0x62)"); g_check_parse_failed(sequence_1, (HParserBackend)GPOINTER_TO_INT(backend), "a", 1); @@ -248,6 +249,7 @@ static void test_sequence(gconstpointer backend) { g_check_parse_match(sequence_2, (HParserBackend)GPOINTER_TO_INT(backend), "ab", 2, "(u0x61 u0x62)"); g_check_parse_match(sequence_2, (HParserBackend)GPOINTER_TO_INT(backend), "a b", 3, "(u0x61 u0x62)"); g_check_parse_match(sequence_2, (HParserBackend)GPOINTER_TO_INT(backend), "a b", 4, "(u0x61 u0x62)"); + g_check_parse_match(sequence_3, (HParserBackend)GPOINTER_TO_INT(backend), "", 0, "()"); } static void test_choice(gconstpointer backend) {