Index: uspace/app/bithenge/blob.h
===================================================================
--- uspace/app/bithenge/blob.h	(revision 0caaaa0055efb2a5487b877b87dd4fa1094d049b)
+++ uspace/app/bithenge/blob.h	(revision e3f2765d1f9f4db04f79955850663d979327ea95)
@@ -149,4 +149,20 @@
 }
 
+/** Check whether the blob is empty.
+ *
+ * @memberof bithenge_blob_t
+ * @param self The blob.
+ * @param[out] out Holds whether the blob is empty.
+ * @return EOK on success or an error code from errno.h. */
+static inline int bithenge_blob_empty(bithenge_blob_t *self, bool *out)
+{
+	assert(self);
+	assert(self->base.blob_ops);
+	aoff64_t size;
+	int rc = bithenge_blob_size(self, &size);
+	*out = size == 0;
+	return rc;
+}
+
 /** Cast a blob node to a generic node.
  * @memberof bithenge_blob_t
Index: uspace/app/bithenge/script.c
===================================================================
--- uspace/app/bithenge/script.c	(revision 0caaaa0055efb2a5487b877b87dd4fa1094d049b)
+++ uspace/app/bithenge/script.c	(revision e3f2765d1f9f4db04f79955850663d979327ea95)
@@ -661,7 +661,10 @@
 {
 	expect(state, TOKEN_REPEAT);
-	expect(state, '(');
-	bithenge_expression_t *expr = parse_expression(state);
-	expect(state, ')');
+	bithenge_expression_t *expr = NULL;
+	if (state->token == '(') {
+		next_token(state);
+		expr = parse_expression(state);
+		expect(state, ')');
+	}
 	expect(state, '{');
 	bithenge_transform_t *xform = parse_transform(state);
Index: uspace/app/bithenge/sequence.c
===================================================================
--- uspace/app/bithenge/sequence.c	(revision 0caaaa0055efb2a5487b877b87dd4fa1094d049b)
+++ uspace/app/bithenge/sequence.c	(revision e3f2765d1f9f4db04f79955850663d979327ea95)
@@ -51,4 +51,5 @@
 	aoff64_t *ends;
 	size_t num_ends;
+	bool end_on_empty;
 	bithenge_int_t num_xforms;
 } seq_node_t;
@@ -94,4 +95,19 @@
 		}
 
+		if (self->end_on_empty) {
+			bool empty;
+			rc = bithenge_blob_empty(
+			    bithenge_node_as_blob(subblob_node), &empty);
+			if (rc == EOK && empty) {
+				self->num_xforms = self->num_ends;
+				rc = ENOENT;
+			}
+			if (rc != EOK) {
+				bithenge_transform_dec_ref(subxform);
+				bithenge_node_dec_ref(subblob_node);
+				return rc;
+			}
+		}
+
 		bithenge_blob_t *subblob = bithenge_node_as_blob(subblob_node);
 		aoff64_t field_size;
@@ -102,4 +118,12 @@
 		if (rc != EOK)
 			return rc;
+
+		if (self->num_xforms == -1) {
+			aoff64_t *new_ends = realloc(self->ends,
+			    (self->num_ends + 1)*sizeof(*new_ends));
+			if (!new_ends)
+				return ENOMEM;
+			self->ends = new_ends;
+		}
 
 		prev_offset = self->ends[self->num_ends] =
@@ -135,4 +159,19 @@
 		}
 
+		if (self->end_on_empty) {
+			bool empty;
+			rc = bithenge_blob_empty(
+			    bithenge_node_as_blob(blob_node), &empty);
+			if (rc == EOK && empty) {
+				self->num_xforms = self->num_ends;
+				rc = ENOENT;
+			}
+			if (rc != EOK) {
+				bithenge_transform_dec_ref(subxform);
+				bithenge_node_dec_ref(blob_node);
+				return rc;
+			}
+		}
+
 		aoff64_t size;
 		rc = bithenge_transform_prefix_apply(subxform, &self->scope,
@@ -143,4 +182,11 @@
 			return rc;
 
+		if (self->num_xforms == -1) {
+			aoff64_t *new_ends = realloc(self->ends,
+			    (self->num_ends + 1)*sizeof(*new_ends));
+			if (!new_ends)
+				return ENOMEM;
+			self->ends = new_ends;
+		}
 		self->ends[self->num_ends++] = start_pos + size;
 	} else {
@@ -198,15 +244,19 @@
 
 static int seq_node_init(seq_node_t *self, const seq_node_ops_t *ops,
-    bithenge_scope_t *scope, bithenge_blob_t *blob, bithenge_int_t num_xforms)
+    bithenge_scope_t *scope, bithenge_blob_t *blob, bithenge_int_t num_xforms,
+    bool end_on_empty)
 {
 	self->ops = ops;
-	self->ends = malloc(sizeof(*self->ends) * num_xforms);
-	if (!self->ends) {
-		return ENOMEM;
-	}
+	if (num_xforms != -1) {
+		self->ends = malloc(sizeof(*self->ends) * num_xforms);
+		if (!self->ends)
+			return ENOMEM;
+	} else
+		self->ends = NULL;
 	bithenge_blob_inc_ref(blob);
 	self->blob = blob;
 	self->num_xforms = num_xforms;
 	self->num_ends = 0;
+	self->end_on_empty = end_on_empty;
 	bithenge_scope_init(&self->scope);
 	int rc = bithenge_scope_copy(&self->scope, scope);
@@ -405,5 +455,5 @@
 
 	rc = seq_node_init(struct_as_seq(node), &struct_node_seq_ops, scope,
-	    blob, self->num_subtransforms);
+	    blob, self->num_subtransforms, false);
 	if (rc != EOK) {
 		free(node);
@@ -582,8 +632,12 @@
 	repeat_node_t *self = node_as_repeat(base);
 
-	for (bithenge_int_t i = 0; i < self->count; i++) {
+	for (bithenge_int_t i = 0; self->count == -1 || i < self->count; i++) {
 		bithenge_node_t *subxform_result;
 		rc = seq_node_subtransform(repeat_as_seq(self),
 		    &subxform_result, i);
+		if (rc != EOK && self->count == -1) {
+			rc = EOK;
+			break;
+		}
 		if (rc != EOK)
 			return rc;
@@ -624,5 +678,5 @@
 	bithenge_int_t index = bithenge_integer_node_value(key);
 	bithenge_node_dec_ref(key);
-	if (index < 0 || index >= self->count)
+	if (index < 0 || (self->count != -1 && index >= self->count))
 		return ENOENT;
 	return seq_node_subtransform(repeat_as_seq(self), out, index);
@@ -660,17 +714,20 @@
     bool prefix)
 {
-	bithenge_int_t count;
-	bithenge_node_t *count_node;
-	int rc = bithenge_expression_evaluate(self->expr, scope, &count_node);
-	if (rc != EOK)
-		return rc;
-	if (bithenge_node_type(count_node) != BITHENGE_NODE_INTEGER) {
+	bithenge_int_t count = -1;
+	if (self->expr != NULL) {
+		bithenge_node_t *count_node;
+		int rc = bithenge_expression_evaluate(self->expr, scope,
+		    &count_node);
+		if (rc != EOK)
+			return rc;
+		if (bithenge_node_type(count_node) != BITHENGE_NODE_INTEGER) {
+			bithenge_node_dec_ref(count_node);
+			return EINVAL;
+		}
+		count = bithenge_integer_node_value(count_node);
 		bithenge_node_dec_ref(count_node);
-		return EINVAL;
-	}
-	count = bithenge_integer_node_value(count_node);
-	bithenge_node_dec_ref(count_node);
-	if (count < 0)
-		return EINVAL;
+		if (count < 0)
+			return EINVAL;
+	}
 
 	repeat_node_t *node = malloc(sizeof(*node));
@@ -678,5 +735,5 @@
 		return ENOMEM;
 
-	rc = bithenge_init_internal_node(repeat_as_node(node),
+	int rc = bithenge_init_internal_node(repeat_as_node(node),
 	    &repeat_node_ops);
 	if (rc != EOK) {
@@ -686,5 +743,5 @@
 
 	rc = seq_node_init(repeat_as_seq(node), &repeat_node_seq_ops, scope,
-	    blob, count);
+	    blob, count, count == -1);
 	if (rc != EOK) {
 		free(node);
@@ -700,4 +757,14 @@
 }
 
+static int repeat_transform_apply(bithenge_transform_t *base,
+    bithenge_scope_t *scope, bithenge_node_t *in, bithenge_node_t **out)
+{
+	repeat_transform_t *self = transform_as_repeat(base);
+	if (bithenge_node_type(in) != BITHENGE_NODE_BLOB)
+		return EINVAL;
+	return repeat_transform_make_node(self, out, scope,
+	    bithenge_node_as_blob(in), false);
+}
+
 static int repeat_transform_prefix_apply(bithenge_transform_t *base,
     bithenge_scope_t *scope, bithenge_blob_t *blob, bithenge_node_t **out_node,
@@ -710,8 +777,20 @@
 
 	bithenge_int_t count = node_as_repeat(*out_node)->count;
-	rc = seq_node_field_offset(node_as_seq(*out_node), out_size, count);
-	if (rc != EOK) {
-		bithenge_node_dec_ref(*out_node);
-		return rc;
+	if (count != -1) {
+		rc = seq_node_field_offset(node_as_seq(*out_node), out_size, count);
+		if (rc != EOK) {
+			bithenge_node_dec_ref(*out_node);
+			return rc;
+		}
+	} else {
+		*out_size = 0;
+		for (count = 1; ; count++) {
+			aoff64_t size;
+			rc = seq_node_field_offset(node_as_seq(*out_node),
+			    &size, count);
+			if (rc != EOK)
+				break;
+			*out_size = size;
+		}
 	}
 	return EOK;
@@ -727,4 +806,5 @@
 
 static const bithenge_transform_ops_t repeat_transform_ops = {
+	.apply = repeat_transform_apply,
 	.prefix_apply = repeat_transform_prefix_apply,
 	.destroy = repeat_transform_destroy,
Index: uspace/dist/src/bithenge/test-repeat.bh
===================================================================
--- uspace/dist/src/bithenge/test-repeat.bh	(revision 0caaaa0055efb2a5487b877b87dd4fa1094d049b)
+++ uspace/dist/src/bithenge/test-repeat.bh	(revision e3f2765d1f9f4db04f79955850663d979327ea95)
@@ -1,3 +1,3 @@
-transform main = struct {
+transform with_count = struct {
 	.none <- repeat(0) { uint8 };
 	.one <- repeat(1) { uint8 };
@@ -5,2 +5,12 @@
 	.many <- repeat(.count) { uint8 };
 };
+
+transform without_count = struct {
+	.error <- repeat { uint8 <- zero_terminated };
+	.end <- repeat { uint8 };
+};
+
+transform main = struct {
+	.with_count <- with_count;
+	.without_count <- without_count;
+};
