diff --git a/src/backends/packrat.c b/src/backends/packrat.c
index 276dfd171f4c8a13ab68953a69f5bbd733c522ab..e561b7ef2e00fa970f17b2889137a22640e20903 100644
--- a/src/backends/packrat.c
+++ b/src/backends/packrat.c
@@ -285,5 +285,10 @@ HParseResult *h_packrat_parse(HAllocator* mm__, const HParser* parser, HInputStr
 HParserBackendVTable h__packrat_backend_vtable = {
   .compile = h_packrat_compile,
   .parse = h_packrat_parse,
-  .free = h_packrat_free
+  .free = h_packrat_free,
+  /* Name/param resolution functions */
+  .backend_short_name = "packrat",
+  .backend_description = "Packrat parser with Warth's recursion",
+  .get_description_with_params = h_get_description_with_no_params,
+  .get_short_name_with_params = h_get_short_name_with_no_params
 };
diff --git a/src/backends/regex.c b/src/backends/regex.c
index 9646ddd59343cacbd1cc53645161c88d70c15f78..2b6cf95d77098dc5e4561b9ac5a01a47610d8845 100644
--- a/src/backends/regex.c
+++ b/src/backends/regex.c
@@ -449,7 +449,12 @@ static HParseResult *h_regex_parse(HAllocator* mm__, const HParser* parser, HInp
 HParserBackendVTable h__regex_backend_vtable = {
   .compile = h_regex_compile,
   .parse = h_regex_parse,
-  .free = h_regex_free
+  .free = h_regex_free,
+  /* Name/param resolution functions */
+  .backend_short_name = "regex",
+  .backend_description = "Regular expression matcher (broken)",
+  .get_description_with_params = h_get_description_with_no_params,
+  .get_short_name_with_params = h_get_short_name_with_no_params
 };
 
 #ifndef NDEBUG
diff --git a/src/hammer.c b/src/hammer.c
index 2d34f9e041ea189e1ed39159e28135c35f539b50..ba4928e62099bb47a29804287040b7bebb3c0c6d 100644
--- a/src/hammer.c
+++ b/src/hammer.c
@@ -269,6 +269,42 @@ char * h_get_descriptive_text_for_backend_with_params(
       &system_allocator, be_with_params);
 }
 
+/* Helpers for the above for backends with no params */
+
+static char * h_get_backend_text_with_no_params(HAllocator *mm__,
+                                                HParserBackend be,
+                                                int description) {
+  char *text = NULL;
+  const char *src = NULL;
+  int size;
+
+  if (!(mm__ != NULL && be != PB_INVALID &&
+        be >= PB_MIN && be <= PB_MAX)) goto done;
+
+  src = description ?
+    backends[be]->backend_description :
+    backends[be]->backend_short_name;
+
+  if (src) {
+    size = strlen(src) + 1;
+    text = h_new(char, size);
+    if (text) strncpy(text, src, size);
+  }
+
+ done:
+  return text;
+}
+
+char * h_get_description_with_no_params(HAllocator *mm__,
+                                        HParserBackend be, void *params) {
+  return h_get_backend_text_with_no_params(mm__, be, 1);
+}
+
+char * h_get_short_name_with_no_params(HAllocator *mm__,
+                                           HParserBackend be, void *params) {
+  return h_get_backend_text_with_no_params(mm__, be, 0);
+}
+
 #define DEFAULT_ENDIANNESS (BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN)
 
 HParseResult* h_parse(const HParser* parser, const uint8_t* input, size_t length) {
diff --git a/src/internal.h b/src/internal.h
index 4fc9eb989ebd40e44f62ef3b90c164984b1e69da..df720151d58beb7c4ee0a22e1d2434f704c61477 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -351,6 +351,16 @@ extern HParserBackendVTable h__glr_backend_vtable;
 
 // TODO(thequux): Set symbol visibility for these functions so that they aren't exported.
 
+/*
+ * Helper functions for backend with params names and descriptions for
+ * backends which take no params.
+ */
+
+char * h_get_description_with_no_params(HAllocator *mm__,
+                                        HParserBackend be, void *params);
+char * h_get_short_name_with_no_params(HAllocator *mm__,
+                                       HParserBackend be, void *params);
+
 int64_t h_read_bits(HInputStream* state, int count, char signed_p);
 static inline size_t h_input_stream_pos(HInputStream* state) {
   return state->index * 8 + state->bit_offset + state->margin;