Rule *parse_file(FILE *fp) {
    char buffer[MAXLINE+1];
    Rule *curr_rule = NULL;
    RuleLL *head = malloc(sizeof(RuleLL));

    

    // Read each line until the EOF
    while(fgets(buffer, MAXLINE, fp) != NULL) {
        if (!is_comment_or_empty(buffer)) {
            // Target line
            if(buffer[0] != '\t') {
                char delim[] = " ";

                // Find if the rule already exists in head
                char* token = strtok(buffer, delim);
                curr_rule = find_rule(head, token);
                        

                // Else if the current Target is not in the head_rule, create a new rule
                if (curr_rule == NULL){
                    curr_rule = malloc(sizeof(Rule));
                    curr_rule->actions = NULL;
                    curr_rule->target = malloc(strlen(token) + 1);
                    strcpy(curr_rule->target, token);
                    insert_rule(head, curr_rule);                
                }

                // Skip the colon
                token = strtok(NULL, delim); 
                token = strtok(NULL, delim); 
                
                // Add dependencies to the current rule
                while(token != NULL) {
                    Dependency *new_dep = malloc(sizeof(Dependency));
                    // Find the rule that matches the dependency in head_rule
                    Rule *dep_rule = find_rule(head, token);

                    // If the dependency rule is found
                    if (dep_rule != NULL) {
                        new_dep->rule = dep_rule;
                    }
                    // Else, then create a new rule for the dependency
                    else{
                        new_dep->rule = malloc(sizeof(Rule));
                        // if it has trailing \n character, don't include it
                        /* if (token[strlen(token)-1] == '\n') {
                            token[strlen(token)-1] = '\0';
                        } */
                        if (token[strlen(token)-1] == '\n') {
                            new_dep->rule->target = malloc(strlen(token));
                            strcpy(new_dep->rule->target, token - 1);
                            new_dep->rule->target[strlen(token)-1] = '\0';
                        }
                        else{
                            new_dep->rule->target = malloc(strlen(token) + 1);
                            strcpy(new_dep->rule->target, token);
                        }
                        insert_rule(head, new_dep->rule);
                    }

                    // Add the dependency to the current rule
                    insert_dependency(curr_rule, new_dep);
                    token = strtok(NULL, delim);
                }

            }
            // Action line
            else {
                //printf("%s", buffer);
                int num_tokens = 0;
                char delim[] = " ";
                char* token = strtok(buffer, delim);
                while(token != NULL) {
                    num_tokens++;
                    token = strtok(NULL, delim);
                }

                // Make new token
                char *new_token = strtok(buffer, delim);
                Action *new_act = malloc(sizeof(Action));
                new_act->args = malloc(sizeof(char*)*(num_tokens+1));
                int i = 0;
                while(new_token != NULL) {
                    if(new_token[0] == '\t'){
                        new_token = new_token + 1;
                    }
                    new_act->args[i] = malloc(strlen(new_token) + 1);
                    strcpy(new_act->args[i], new_token);
                    printf("%s\n", new_token);
                    i++;
                    new_token = strtok(NULL, delim);
                }
                new_act->args[i] = NULL;

                // Add the action to the current rule
                insert_action(curr_rule, new_act);
            }
        }
    }
    if (head) {
        return head->rule;
    }
    return NULL;
}


When inserting new dependency, if it has trailing '\n' it shouldn't include it as shown in line 50. However, it fails for some cases to filter out '\n' character.