void Node_Value_Parser::give_input(const std::string& i, Command_Value& cv,
    Moldable* bc)
{
    Node_Value tmp {};
    input = i;
    tokenize_input(input, true); // Make sure to return the iterator to
                                // the BEGINNING
    // The first token is always an action
    cv.set(Command_Flags::action, tm.current_token());

    if (Mogu_Syntax::append == cv.get(Command_Flags::action))
    {
        handle_append_command(cv,bc);
        tm.reset();
        return;
    }

    // The second token is awlays the start of the object set.
    tm.next();
    int tok = tm.current_token();
    cv.set(Command_Flags::object, tok);
    tm.next();

    while (tok != Mogu_Syntax::OUT_OF_RANGE_END)
    {
        tok = tm.current_token();
        if (tok == Mogu_Syntax::TOKEN_DELIM)
        {
            std::string string_token = tm.fetch_string();
            if (tm.is_quoted_string(string_token)) {
                tm.reset();
                return;
            }
            /* The identifier should always be the first TOKEN_DELIM
             * encountered.
             */
            if (cv.get_identifier().empty())
            {
                Node_Value tmp {};
                tmp.set_string(string_token);
                cv.set(Command_Flags::identifier, tmp);
            }
            else
            {
                /* The only other TOKEN_DELIM that should be encountered before
                 * a preposition should be an argument (ie: database hash field)
                 */
                tmp.set_string(string_token);
                cv.set(Command_Flags::arg, tmp);
            }
        }
        else if (is_state_token(tok))
        {
            tmp.set_int(tok);
            cv.set(Command_Flags::arg, tmp);
        }
        else if (is_preposition_token(tok)) {
            bool reduce {true};
            /* First, check to see if the next value is 'location' */
            tm.next();
            int tok = tm.current_token();

            if (tm.current_token() == Mogu_Syntax::location)
            {
                reduce = false;
                tm.next();
                tok = tm.current_token();
            }

            std::stringstream buf;
            while (tok != Mogu_Syntax::OUT_OF_RANGE_END)
            {
                if (tok == Mogu_Syntax::TOKEN_DELIM)
                    buf << tm.fetch_string();
                else buf << tok;
                buf << " ";
                tm.next();
                tok = tm.current_token();
            }

            std::string s{buf.str()};
            Node_Value r {};

            if (reduce)
            {
                Node_Value_Parser p {};
                p.set_user_id(user_id);
                p.set_group_id(group_id);
                p.give_input(s,r,bc);
            }
            else
            {
                r.set_string(s);
            }
            cv.set(Command_Flags::value, r);
            break; // After parsing a prepositional, there is nothing left to do.
        }
        tm.next();
    }
    tm.reset();
}
/**
 * This is the will be the entry point to your text editor.
*/
int main(int argc, char *argv[]) {
  // Checking to see if the editor is being used correctly.
  if (argc != 2) {
    print_usage_error();
    return 1;
  }
  // Setting up a docment based on the file named 'filename'.
  char *filename = get_filename(argc, argv);
  Document *document = Document_create_from_file(filename);

  // Buffer for the command and length of said buffer
  char *command = NULL;
  size_t len = 0;

  // This while loop will keep reading from stdin one line at a time
  // until the user enters 'q' (the quit command).
  int done = 0;
  while (!done) {
    getline(&command, &len, stdin);

    int command_type;

    // remove newline from the command
    char *nl = strchr(command, '\n');
    if (nl)
      *nl = 0;

    int stringlen = strlen(command);

    // if 'q' or 's' is first character only 'q' or 's' is allowed as valid
    // command
    if ((command[0] == 'q' || command[0] == 's') && stringlen != 1) {
      command_type = -1;
    } else {
      command_type = command[0];
    }

    switch (command_type) {
    case 'p':
      handle_display_command(document, command);
      break;
    case 'w':
      handle_write_command(document, command);
      break;
    case 'a':
      handle_append_command(document, command);
      break;
    case 'd':
      handle_delete_command(document, command);
      break;
    case '/':
      handle_search_command(document, command);
      break;
    case 's':
      if (strlen(command) == 1) {
        handle_save_command(document, filename);
      } else {
        invalid_command(command);
      }
      break;
    case 'q':
      done = 1;
      Document_destroy(document);
      break;
    default:
      invalid_command(command);
      break;
    }
  }

  // Need to free the buffer that we created.
  if (command) {
    free(command);
  }
}