I will present one possible solution (out of 42 million options :-)  
The idea is to use an Object Oriented approach. So, a class with data and methods.
The data is the required vector of vector of float. And the methods are extraction and addition. For debug purposes, there is also an overwrite of the inserter operator. 
Please note: The tricky part is parsing the input string. Especially with white spaces that could be everywhere. For ease of use, I defined a regex for a float value. The  regex_token_iterator will extract the sub matches and copy those into a column. And this until the next ";". Looks complex, but is easy to understand in the end.
I put many comments in the code, which makes it a little bit lengthy. Anyway, it will help to understand better.
The main function will look very simple then . . .
EDIT:
Based on the recomendation of David C. Rankin, I updated the source code:
- Modify variable names to make them more readable
- Changed base data type from float to double
- Add more white spaces and line breaks for a better text structure
- Put in more comments
- New size check for addition operator
#include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <regex>
// Our test data (raw string) . We could of course also read from a file or from std::cin or any istream
std::istringstream testData(
R"#(   [   1 2    3 ; 4 5 6 7  ]
[   7  8   9;    10  11 12]
)#");
struct Matrix
{
    // The data of our matrix
    std::vector<std::vector<double>> data{};
    // Overloading the extractor operator >> for our Matrix class
    friend std::istream& operator >> (std::istream& is, Matrix& m) {
        // Read a complete line
        std::string line; 
        getline(is, line);
        // Define a regex that matches any double number
        std::regex re("([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)");
        // Set iterators. 
        // "Start" will be set to begin() or one past the end of the next semicolon 
        std::string::iterator start = line.begin(); 
        // Position of semincolon or end()
        std::string::iterator posSemicolon{};
        // Read all rows and columns
        do {
            // Set the end iterator for this loop run to the position of the semicolon (or end() )
            posSemicolon = std::find(start, line.end(), ';');
            // Add a new row
            m.data.emplace_back(std::vector<double>());
            // Read a complete line with doubles and put that as column values in the current row
            std::transform(
                std::sregex_token_iterator(start, posSemicolon, re, 1), // Search for text that matches the regex
                std::sregex_token_iterator(),                           // Search until the end (posSemicolon)
                std::back_inserter(*(std::prev(m.data.end()))),         // Put this data into the columns of the current row 
                // Convert the string matched by the regex, into a double
                [](const std::string& stringAsDouble) -> double { return stod(stringAsDouble); }
            );   
            // In case there is more input, 
            if (posSemicolon != line.end()) {
                // then continue tokenizing in the next loop run past the semicolon 
                start = posSemicolon + 1;
            }
        } while (posSemicolon != line.end());
        return is;
    }
    // For debug output purposes. Copy the data of the matrix to std::cout
    friend std::ostream& operator << (std::ostream & os, const Matrix & m) {
        std::for_each(
            m.data.begin(),                           // Iterate over all rows
            m.data.end(), 
            [&os](const std::vector<double> & row) {  // Do for all rows 
                std::copy(                            // Copy data to ostream (print)
                    row.begin(),                      // Iterate ove all columns for this row  
                    row.end(), 
                    std::ostream_iterator<double>(os, " ")); // Print
                std::cout << '\n';                    // Line break after printing a row
            }  
        );
        return os;
    }
    // Overload of the addition operator
    friend Matrix operator +(Matrix & m1, Matrix & m2) {
        // Define an empty matrix
        Matrix result{};
        // To be on the safe side, we will resize the destination matrix size 
        // to maximum values of both matrices
        // Get the max number of rows ofrom both m1 and m2
        const size_t maxRowSize = std::max(m1.data.size(), m2.data.size());
        // Set number of rows in resulting Matrix
        result.data.resize(maxRowSize);
        // Get the maximum number of columns in any of the 2 metrices m1 or m2
        const size_t maxColumnSize = std::max(
            std::max_element(
                m1.data.begin(),    // Iterate over all rows of Matrix m1
                m1.data.end(), 
                [](const std::vector<double> & dv1_1, const std::vector<double> & dv1_2) {
                    return dv1_1.size() < dv1_2.size(); 
                }
            )->size(),
            std::max_element(
                m2.data.begin(),   // Iterate over all rows of Matrix m1
                m2.data.end(), 
                [](const std::vector<double> & dv2_1, const std::vector<double> & dv2_2) {
                    return dv2_1.size() < dv2_2.size(); 
                }
            )->size()
        );
        // Iterate over all matrix elements
        // For all rows 
        for (size_t row = 0; row < maxRowSize; ++row) {
            // Resize the the number of columns in the target matrix
            result.data[row].resize(maxColumnSize);
            // Now iterate over all columns in that row
            for (size_t col = 0; col < maxColumnSize; ++col) {
                // And add the values. First check for valid row and column indices
                double m1Value = ((row < m1.data.size()) && (col < m1.data[row].size())) ? m1.data[row][col] : 0.0;
                double m2Value = ((row < m2.data.size()) && (col < m2.data[row].size())) ? m2.data[row][col] : 0.0;
                result.data[row][col] = m1Value + m2Value;
            }
        }
        return result;
    }
};
int main()
{
    // Define some matrices
    Matrix m1, m2, m3;
    // Read the test data. You can also read from std::cin or from a file
    testData >> m1 >> m2;
    // Add the Matrices
    m3 = m1 + m2;
    // Show result
    std::cout << "Matrix 1:\n" << m1 << "\nMatrix 2:\n" << m2 << "\nMatrix3 = Matrix1 + Matrix2:\n" << m3;
    return 0;
}