Currently WORD('1-9', '') is equivalent to WORD('1-9') because the implementation does something like "if restchars: ... else: ..."
I realise that matching a single character is something that should be accomplished using "count = 1", but I feel like this is unintuitive - if I pass an empty string for the second parameter, that should mean that I won't accept anything as a second character (which of course means that the WORD will have to be only one character in length). So, perhaps it should be instead "if restchars is None: ..."
Related: is there a reason why there is no builtin grammar that just takes a regular expression describing the token to be matched?