Your first task is to implement parse_file, so that it reads a makefile and constructs a corresponding linked data structure.
Rule *parse_file(FILE *fp) {
    Rule *rhead = NULL;
    Rule *rcurr = NULL;

    Dependency *dhead = NULL;
    Dependency *dcurr = NULL;

    Action *ahead = NULL;
    Action *acurr = NULL;

    char curr_line[MAXLINE];
    char *token;

    while(fgets(curr_line, MAXLINE, fp)!= NULL){
        // ignore empty line and comments
        if(is_comment_or_empty(curr_line)){
            continue;
        }

        // checking if target line
        if ((token = strtok(curr_line, " :\n")) != NULL){
            Rule *rule = create_rule(token);

            // if this is the first rule, replace
            if(rhead == NULL){
                rhead = rule;
                rcurr = rule;
            }
            // otherwise, append to the next rule
            else{
                rcurr->next_rule = rule;
                rcurr = rule;
            }
        }

        // add dependencies to current rule, will not execute if token is NULL
        add_dependencies(rcurr, dhead, dcurr, token);

        // if line starts with a tab, create a new action
        if((token = strtok(curr_line, "\n")) != NULL && strcmp(token, "\t") == 0){
            int max_args = 0;

            Action *act = create_action(token, curr_line, &max_args);

            add_arguments(act, token, max_args);

            // add to current Rule's list
            if(ahead == NULL){
                ahead = act;
                acurr = act;
            }
            else{
                acurr->next_act = act;
                acurr = act;
            }
        }
    }
    fclose(fp);
    return rhead;
}