Why am I getting compilation errors
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "pmake.h"

Rule *parse_file(FILE *fp) {
    Rule *first_rule = NULL;
    Rule *curr_rule = NULL;
    char line[MAXLINE];

    // Read and process each line of the given file.
    while (fgets(line, MAXLINE, fp) != NULL) {
        if (is_comment_or_empty(line) == 0) {
            if (line[0] == '\t') {  // line is an action

            } else {  // line is a target
                char *token;

                // Get the target for the rule
                token = strtok(line, " ");

                // TODO check to see if there is a rule by that target already
                // otherwise make a new rule
                Rule *new_rule = find_rule(first_rule, token);

                // Rule *new_rule = malloc(sizeof(Rule));
                new_rule->target = malloc(strlen(token) + 1);
                strcpy(new_rule->target, token);

                // Get the dependencies
                new_rule->dependencies = NULL;  // Initialize to NULL
                strtok(NULL, " ");              // Skip the ':'
                while ((token = strtok(NULL, " ")) != NULL) {
                    // search for an existing rule by target token, otherwise
                    // make a new one that is empty except for the target and insert it
                    // after the current node
                }

                // Add new rule to the end of the linked list
                if (first_rule == NULL) {
                    first_rule = new_rule;
                } else {
                    // change to add the new rule
                    curr_rule->next_rule = new_rule;
                }
                curr_rule = new_rule;
            }
        }
    }
    return first_rule;
}

Rule *find_rule(Rule *head, char *target) {
    Rule *curr_rule = head;
    while (curr_rule != NULL && strcmp(curr_rule->target, target) != 0) {
        curr_rule = curr_rule->next_rule;
    }
    return curr_rule;
}

void print_actions(Action *act) {
    while (act != NULL) {
        if (act->args == NULL) {
            fprintf(stderr, "ERROR: action with NULL args\n");
            act = act->next_act;
            continue;
        }
        printf("\t");

        int i = 0;
        while (act->args[i] != NULL) {
            printf("%s ", act->args[i]);
            i++;
        }
        printf("\n");
        act = act->next_act;
    }
}

void print_rules(Rule *rules) {
    Rule *cur = rules;

    while (cur != NULL) {
        if (cur->dependencies || cur->actions) {
            // Print target
            printf("%s : ", cur->target);

            // Print dependencies
            Dependency *dep = cur->dependencies;
            while (dep != NULL) {
                if (dep->rule->target == NULL) {
                    fprintf(stderr, "ERROR: dependency with NULL rule\n");
                }
                printf("%s ", dep->rule->target);
                dep = dep->next_dep;
            }
            printf("\n");

            // Print actions
            print_actions(cur->actions);
        }
        cur = cur->next_rule;
    }
}

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;
}

char *args_to_string(char **args, char *buffer, int size) {
    buffer[0] = '\0';
    int i = 0;
    while (args[i] != NULL) {
        strncat(buffer, args[i], size - strlen(buffer));
        strncat(buffer, " ", size - strlen(buffer));
        i++;
    }
    return buffer;
}
