diff --git a/examples/base64_sem1.c b/examples/base64_sem1.c
index 8de31db638c9e497659b4c17fd786af63d772e5f..9d1012fbed0cf09d444802b15d7f5e8e4d1e0a5f 100644
--- a/examples/base64_sem1.c
+++ b/examples/base64_sem1.c
@@ -13,50 +13,11 @@
 // base64_sem2.c for an alternative approach using a single top-level action.
 
 #include "../src/hammer.h"
+#include "../src/glue.h"
 #include "../src/internal.h"    // for h_carray functions (XXX ?!)
 #include <assert.h>
 
 
-#define H_RULE(rule, def) const HParser *rule = def
-#define H_ARULE(rule, def) const HParser *rule = h_action(def, act_ ## rule)
-
-
-///
-// Semantic action helpers.
-// These might be candidates for inclusion in the library.
-///
-
-// The action equivalent of h_ignore.
-const HParsedToken *act_ignore(const HParseResult *p)
-{
-    return NULL;
-}
-
-// Helper to build HAction's that pick one index out of a sequence.
-const HParsedToken *act_index(int i, const HParseResult *p)
-{
-    if(!p) return NULL;
-
-    const HParsedToken *tok = p->ast;
-
-    if(!tok || tok->token_type != TT_SEQUENCE)
-        return NULL;
-
-    const HCountedArray *seq = tok->seq;
-    size_t n = seq->used;
-
-    if(i<0 || (size_t)i>=n)
-        return NULL;
-    else
-        return tok->seq->elements[i];
-}
-
-const HParsedToken *act_index0(const HParseResult *p)
-{
-    return act_index(0, p);
-}
-
-
 ///
 // Semantic actions for the grammar below, each corresponds to an "ARULE".
 // They must be named act_<rulename>.
@@ -84,11 +45,13 @@ const HParsedToken *act_bsfdig(const HParseResult *p)
     return res;
 }
 
+H_ACT_APPLY(act_index0, h_act_index, 0);
+
 #define act_bsfdig_4bit  act_bsfdig
 #define act_bsfdig_2bit  act_bsfdig
 
-#define act_equals       act_ignore
-#define act_ws           act_ignore
+#define act_equals       h_act_ignore
+#define act_ws           h_act_ignore
 
 #define act_document     act_index0
 
@@ -124,20 +87,9 @@ const HParsedToken *act_base64_n(int n, const HParseResult *p)
     return res;
 }
 
-const HParsedToken *act_base64_3(const HParseResult *p)
-{
-    return act_base64_n(3, p);
-}
-
-const HParsedToken *act_base64_2(const HParseResult *p)
-{
-    return act_base64_n(2, p);
-}
-
-const HParsedToken *act_base64_1(const HParseResult *p)
-{
-    return act_base64_n(1, p);
-}
+H_ACT_APPLY(act_base64_3, act_base64_n, 3);
+H_ACT_APPLY(act_base64_2, act_base64_n, 2);
+H_ACT_APPLY(act_base64_1, act_base64_n, 1);
 
 // Helper to concatenate two arrays.
 void carray_concat(HCountedArray *a, const HCountedArray *b)
diff --git a/examples/base64_sem2.c b/examples/base64_sem2.c
index 11b0660a0fba3d877b51cf8477904becc6382e0c..4b886c6bd85de40d68b4bb0490dda732abac9d47 100644
--- a/examples/base64_sem2.c
+++ b/examples/base64_sem2.c
@@ -14,50 +14,11 @@
 // transformation.
 
 #include "../src/hammer.h"
+#include "../src/glue.h"
 #include "../src/internal.h"    // for h_carray functions (XXX ?!)
 #include <assert.h>
 
 
-#define H_RULE(rule, def) const HParser *rule = def
-#define H_ARULE(rule, def) const HParser *rule = h_action(def, act_ ## rule)
-
-
-///
-// Semantic action helpers.
-// These might be candidates for inclusion in the library.
-///
-
-// The action equivalent of h_ignore.
-const HParsedToken *act_ignore(const HParseResult *p)
-{
-    return NULL;
-}
-
-// Helper to build HAction's that pick one index out of a sequence.
-const HParsedToken *act_index(int i, const HParseResult *p)
-{
-    if(!p) return NULL;
-
-    const HParsedToken *tok = p->ast;
-
-    if(!tok || tok->token_type != TT_SEQUENCE)
-        return NULL;
-
-    const HCountedArray *seq = tok->seq;
-    size_t n = seq->used;
-
-    if(i<0 || (size_t)i>=n)
-        return NULL;
-    else
-        return tok->seq->elements[i];
-}
-
-const HParsedToken *act_index0(const HParseResult *p)
-{
-    return act_index(0, p);
-}
-
-
 ///
 // Semantic actions for the grammar below, each corresponds to an "ARULE".
 // They must be named act_<rulename>.
@@ -150,7 +111,9 @@ const HParsedToken *act_base64(const HParseResult *p)
     return res;
 }
 
-#define act_ws           act_ignore
+H_ACT_APPLY(act_index0, h_act_index, 0);
+
+#define act_ws           h_act_ignore
 #define act_document     act_index0