end = start;
parse_dup_op (dup_elem, regexp, dfa, token, syntax, err)     bin_tree_t *dup_elem;     re_string_t *regexp;     re_dfa_t *dfa;     re_token_t *token;     reg_syntax_t syntax;     reg_errcode_t *err;{  re_token_t dup_token;  bin_tree_t *tree = dup_elem, *work_tree;  int new_idx, start_idx = re_string_cur_idx (regexp);  re_token_t start_token = *token;  if (token->type == OP_OPEN_DUP_NUM)    {      int i, end, start = fetch_number (regexp, token, syntax);      bin_tree_t *elem;      if (start == -1)        start = 0; /* We treat "{,m}" as "{0,m}".  */      if (start != -2 && token->type == OP_CLOSE_DUP_NUM)        {          if (start == 0)            {              /* We treat "<re>{0}" as null string.  */              *token = fetch_token (regexp, syntax);              free_bin_tree (dup_elem);              return NULL;            }          end = start; /* We treat "{n}" as "{n,n}".  */        }      else if (BE (start == -2 || token->type != CHARACTER                   || token->opr.c != ',', 0))        /* Invalid sequence.  */        goto parse_dup_op_invalid_interval;      else        {          end = fetch_number (regexp, token, syntax);          if (BE (end == -2 || token->type != OP_CLOSE_DUP_NUM, 0))            /* Invalid sequence.  */            goto parse_dup_op_invalid_interval;        }      /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}".  */      elem = tree;      for (i = 0; i < start; ++i)        if (i != 0)          {            work_tree = duplicate_tree (elem, dfa);            tree = create_tree (tree, work_tree, CONCAT, 0);            if (BE (work_tree == NULL || tree == NULL, 0))              goto parse_dup_op_espace;          }      if (end == -1)        {          /* We treat "<re>{0,}" as "<re>*".  */          dup_token.type = OP_DUP_ASTERISK;          if (start > 0)            {              elem = duplicate_tree (elem, dfa);              new_idx = re_dfa_add_node (dfa, dup_token, 0);              work_tree = create_tree (elem, NULL, 0, new_idx);              tree = create_tree (tree, work_tree, CONCAT, 0);              if (BE (elem == NULL || new_idx == -1 || work_tree == NULL                      || tree == NULL, 0))                goto parse_dup_op_espace;            }          else            {              new_idx = re_dfa_add_node (dfa, dup_token, 0);              tree = create_tree (elem, NULL, 0, new_idx);              if (BE (new_idx == -1 || tree == NULL, 0))                goto parse_dup_op_espace;            }        }      else if (end - start > 0)        {          /* Then extract "<re>{0,m}" to "<re>?<re>?...<re>?".  */          dup_token.type = OP_DUP_QUESTION;          if (start > 0)            {              elem = duplicate_tree (elem, dfa);              new_idx = re_dfa_add_node (dfa, dup_token, 0);              elem = create_tree (elem, NULL, 0, new_idx);              tree = create_tree (tree, elem, CONCAT, 0);              if (BE (elem == NULL || new_idx == -1 || tree == NULL, 0))                goto parse_dup_op_espace;            }          else            {              new_idx = re_dfa_add_node (dfa, dup_token, 0);              tree = elem = create_tree (elem, NULL, 0, new_idx);              if (BE (new_idx == -1 || tree == NULL, 0))                goto parse_dup_op_espace;            }          for (i = 1; i < end - start; ++i)            {              work_tree = duplicate_tree (elem, dfa);              tree = create_tree (tree, work_tree, CONCAT, 0);              if (BE (work_tree == NULL || tree == NULL, 0))                return *err = REG_ESPACE, NULL;            }        }    }  else    {      new_idx = re_dfa_add_node (dfa, *token, 0);      tree = create_tree (tree, NULL, 0, new_idx);      if (BE (new_idx == -1 || tree == NULL, 0))        return *err = REG_ESPACE, NULL;    }  *token = fetch_token (regexp, syntax);  return tree; parse_dup_op_espace:  free_bin_tree (tree);  *err = REG_ESPACE;  return NULL; parse_dup_op_invalid_interval:  if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))    {      *err = REG_EBRACE;      return NULL;    }  re_string_set_index (regexp, start_idx);  *token = start_token;  token->type = CHARACTER;  return dup_elem;}