#include <stdio.h>
#include <string.h>
#include <regex.h>

struct token_t {
  char *name;
  char *pattern;
  regex_t regex;
};

#define TOKEN_ENTRY(name, regex) { #name, regex }
#define ARRAYOF(array) (sizeof(array) / sizeof(*array))

struct token_t g_token[] = {
  TOKEN_ENTRY(number, "^[-+]?[0-9]+$"),
  TOKEN_ENTRY(string, ".*"),
};

int initialize_token()
{
  int index;
  for (index = 0; index < ARRAYOF(g_token); index++)
    if (regcomp(&g_token[index].regex, g_token[index].pattern,
                REG_EXTENDED | REG_NEWLINE) < 0)
      return -1;
  return 0;
}

void finalize_token()
{
  int index;
  for (index = 0; index < ARRAYOF(g_token); index++)
    regfree(&g_token[index].regex);
}

int get_token_index(char *string)
{
  regmatch_t match[1];
  int index;
  for (index = 0; index < ARRAYOF(g_token); index++)
    if (!regexec(&g_token[index].regex, string, 1, match, 0))
      return index;
  return -1;
}

char *get_token_name(char *string)
{
  int index;
  index = get_token_index(string);
  return index != -1 ? g_token[index].name : "null";
}

#define print(string) printf(string " = %s\n", get_token_name(string))

void do_run_while_ctrl_d()
{
  static char buffer[BUFSIZ];
  char *ptr;

  buffer[sizeof(buffer) - 1] = '\0';
  while (fgets(buffer, sizeof(buffer), stdin) != NULL) {
    ptr = strchr(buffer, '\n');
    if (ptr == NULL) {
      fprintf(stderr, "Too long string (buffer size = %u)\n",
              (unsigned int) sizeof(buffer) - 1);
      return;
    }
    *ptr = '\0';
    printf("%s\n", get_token_name(buffer));
  }
}

int main(int argc, char *argv[])
{
  initialize_token();
  do_run_while_ctrl_d();
  finalize_token();
  return 0;
}
