why segmentation fault?
Rule *parse_file(FILE *fp) {
    Rule *ds = malloc(sizeof(Rule));

    char *line = malloc(sizeof(char) * MAXLINE);

    while (fgets(line, MAXLINE, fp)) {
        if (!is_comment_or_empty(line) && line[0] != '\n') {
            char *line_cpy = malloc(sizeof(char) * MAXLINE);
            strcpy(line_cpy, line);

            char *ch = " \t";
            // Array length
            char *curr_token1 = strtok(line_cpy, ch);
            int len = 1;
            while (curr_token1 != NULL) {
                curr_token1 = strtok(NULL, ch);
                len += 1;
            }

            char **arr = malloc(sizeof(char *) * len);
            // Array
            char *curr_token2 = strtok(line, ch);
            arr[0] = curr_token2;
            int i = 1;
            while (curr_token2 != NULL) {
                curr_token2 = strtok(NULL, ch);
                arr[i] = curr_token2;
                i += 1;
            }

            // Rules
            else {
                Rule *curr_rule = malloc(sizeof(Rule));
                curr_rule->target = malloc(sizeof(char) * MAXLINE);
                strcpy(curr_rule->target, arr[0]);

                if (ds == NULL) {
                    ds = curr_rule;
                } else {
                    Rule *prev_rule = ds;
                    while (prev_rule->next_rule != NULL) {
                        prev_rule = prev_rule->next_rule;
                    }

                    prev_rule->next_rule = curr_rule;
                }
            }
        }
    }

    return ds;
}

int is_comment_or_empty(const char *line) {
    for (int i = 0; i < strlen(line); i++) {
        if (line[i] == '#') {
            return 1;
        }
        if (line[i] != '\t' && line[i] != ' ') {
            return 0;
        }
    }
    return 1;
}