diff --git a/src/backends/ll.c b/src/backends/ll.c
index e560c962fc32171d822743c11a53842c514d5ebf..d791517cd617a161fef9c1a92247d62b14685758 100644
--- a/src/backends/ll.c
+++ b/src/backends/ll.c
@@ -17,8 +17,13 @@ typedef struct HCFGrammar_ {
   HArena      *arena;
 } HCFGrammar;
 
-typedef int HCFTerminal;
-static HCFTerminal end_token = -1;
+// mapping input bytes or end to tokens
+// we want to use these, cast to void *, as elements in hashsets
+// therefore we must avoid 0 as a token value because NULL means "not in set".
+typedef uintptr_t HCFToken;
+static inline HCFToken char_token(char c) { return (0x100 | c); }
+static inline char token_char(HCFToken t) { return (0xFF & t); }
+static HCFToken end_token = 0x200;
 
 bool h_eq_ptr(const void *p, const void *q) { return (p==q); }
 HHashValue h_hash_ptr(const void *p) { return (uintptr_t)p; }
@@ -210,16 +215,16 @@ HHashSet *h_first_symbol(HCFGrammar *g, const HCFChoice *x)
 
   switch(x->type) {
   case HCF_END:
-    h_hashset_put(ret, (void *)(intptr_t)end_token);
+    h_hashset_put(ret, (void *)end_token);
     break;
   case HCF_CHAR:
-    h_hashset_put(ret, (void *)(intptr_t)x->chr);
+    h_hashset_put(ret, (void *)char_token(x->chr));
     break;
   case HCF_CHARSET:
     c=0;
     do {
       if(charset_isset(x->charset, c))
-        h_hashset_put(ret, (void *)(intptr_t)c);
+        h_hashset_put(ret, (void *)char_token(c));
     } while(c++ < 255);
     break;
   case HCF_CHOICE:
@@ -532,15 +537,14 @@ void h_pprint_tokenset(FILE *file, const HCFGrammar *g, const HHashSet *set, int
     for(hte = &set->contents[i]; hte; hte = hte->next) {
       if(hte->key == NULL)
         continue;
-      HCFTerminal a = (intptr_t)hte->key;
-      // BUG this ignores tokens with value 0!
+      HCFToken a = (HCFToken)hte->key;
       
-      if(a == '$')
-        fputs("\\$", file);
-      else if(a == end_token)
+      if(a == end_token)
         fputc('$', file);
+      else if(token_char(a) == '$')
+        fputs("\\$", file);
       else
-        pprint_char(file, a);
+        pprint_char(file, token_char(a));
     }
   }