diff --git a/sandbox/parse_fp/Makefile b/sandbox/parse_fp/Makefile index 16465360..1144ba38 100644 --- a/sandbox/parse_fp/Makefile +++ b/sandbox/parse_fp/Makefile @@ -1,2 +1,2 @@ all: - clang++-17 -O2 -g -stdlib=libc++ parse_fp.cc + g++ -O2 -g -I../../src/external/fast_float/include parse_fp.cc -o parse_fp -pthread diff --git a/sandbox/parse_fp/parse_fp.cc b/sandbox/parse_fp/parse_fp.cc index 92f75d35..72040c22 100644 --- a/sandbox/parse_fp/parse_fp.cc +++ b/sandbox/parse_fp/parse_fp.cc @@ -8,7 +8,7 @@ #include -#include "fast_float.h" +#include "fast_float/fast_float.h" std::string gen_floatarray(size_t n, bool delim_at_end) { @@ -34,6 +34,131 @@ std::string gen_floatarray(size_t n, bool delim_at_end) { return ss.str(); } +std::string gen_float2array(size_t n, bool delim_at_end) { + std::stringstream ss; + std::random_device rd; + std::mt19937 engine(rd()); + std::uniform_real_distribution<> dist(-10000.0, 10000.0); + + ss << "["; + for (size_t i = 0; i < n; i++) { + double f1 = dist(engine); + double f2 = dist(engine); + ss << "(" << std::to_string(f1) << ", " << std::to_string(f2) << ")"; + if (delim_at_end) { + ss << ","; + } else if (i < (n-1)) { + ss << ","; + } + } + ss << "]"; + + return ss.str(); +} + +std::string gen_float3array(size_t n, bool delim_at_end) { + std::stringstream ss; + std::random_device rd; + std::mt19937 engine(rd()); + std::uniform_real_distribution<> dist(-10000.0, 10000.0); + + ss << "["; + for (size_t i = 0; i < n; i++) { + double f1 = dist(engine); + double f2 = dist(engine); + double f3 = dist(engine); + ss << "(" << std::to_string(f1) << ", " << std::to_string(f2) << ", " << std::to_string(f3) << ")"; + if (delim_at_end) { + ss << ","; + } else if (i < (n-1)) { + ss << ","; + } + } + ss << "]"; + + return ss.str(); +} + +std::string gen_float4array(size_t n, bool delim_at_end) { + std::stringstream ss; + std::random_device rd; + std::mt19937 engine(rd()); + std::uniform_real_distribution<> dist(-10000.0, 10000.0); + + ss << "["; + for (size_t i = 0; i < n; i++) { + double f1 = dist(engine); + double f2 = dist(engine); + double f3 = dist(engine); + double f4 = dist(engine); + ss << "(" << std::to_string(f1) << ", " << std::to_string(f2) << ", " << std::to_string(f3) << ", " << std::to_string(f4) << ")"; + if (delim_at_end) { + ss << ","; + } else if (i < (n-1)) { + ss << ","; + } + } + ss << "]"; + + return ss.str(); +} + +std::string gen_matrix3d_array(size_t n, bool delim_at_end) { + std::stringstream ss; + std::random_device rd; + std::mt19937 engine(rd()); + std::uniform_real_distribution<> dist(-10000.0, 10000.0); + + ss << "["; + for (size_t i = 0; i < n; i++) { + ss << "("; + for (int j = 0; j < 9; j++) { + double f = dist(engine); + ss << std::to_string(f); + if (j < 8) { + ss << ", "; + } + } + ss << ")"; + if (delim_at_end) { + ss << ","; + } else if (i < (n-1)) { + ss << ","; + } + } + ss << "]"; + + return ss.str(); +} + +std::string gen_matrix4d_array(size_t n, bool delim_at_end) { + std::stringstream ss; + std::random_device rd; + std::mt19937 engine(rd()); + std::uniform_real_distribution<> dist(-10000.0, 10000.0); + + ss << "["; + for (size_t i = 0; i < n; i++) { + ss << "("; + for (int j = 0; j < 16; j++) { + double f = dist(engine); + ss << std::to_string(f); + if (j < 15) { + ss << ", "; + } + } + ss << ")"; + if (delim_at_end) { + ss << ","; + } else if (i < (n-1)) { + ss << ","; + } + } + ss << "]"; + + return ss.str(); +} + struct Lexer { void init(const char *_p_begin, const char *_p_end, size_t row = 0, size_t column = 0) { @@ -63,10 +188,10 @@ struct Lexer { curr++; } } - rows_++; + row_++; column_ = 0; } else if (s == '\n') { - rows_++; + row_++; column_ = 0; } } @@ -97,10 +222,10 @@ struct Lexer { curr++; } } - rows_++; + row_++; column_ = 0; } else if (s == '\n') { - rows_++; + row_++; column_ = 0; } } @@ -118,7 +243,7 @@ struct Lexer { column_++; if ((*result == '\r') || (*result == '\n')) { - rows_++; + row_++; column_ = 0; } @@ -142,7 +267,7 @@ struct Lexer { curr++; if ((c == '\r') || (c == '\n')) { - rows_++; + row_++; column_ = 0; } @@ -247,6 +372,16 @@ struct vec_lex_span fp_lex_span vspans[N]; }; +struct matrix3d_lex_span +{ + fp_lex_span mspans[9]; // 3x3 = 9 elements +}; + +struct matrix4d_lex_span +{ + fp_lex_span mspans[16]; // 4x4 = 16 elements +}; + // '[' + fp0 + "," + fp1 + ", " ... ']' // allow_delim_at_last is true: '[' + fp0 + "," + fp1 + ", " ... "," + ']' bool lex_float_array( @@ -379,7 +514,423 @@ bool lex_vec2_array( const char vec_open_paren = '(', const char vec_close_paren = ')') { - return false; + // '(' + { + char c; + if (!lexer.char1(&c)) { + err = "Input too short for vector.\n"; + return false; + } + + if (c != vec_open_paren) { + err = "Vector does not begin with open parenthesis character.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + // Parse first float + { + result.vspans[0].p_begin = lexer.curr; + uint16_t length{0}; + bool truncated{false}; + + if (!lexer.lex_float(length, truncated)) { + lexer.push_error("First element is not a floating point literal."); + err = lexer.get_error(); + return false; + } + + result.vspans[0].length = length; + + if (truncated) { + if (!lexer.skip_until_delim_or_close_paren(',', vec_close_paren)) { + lexer.push_error("Failed to seek to delimiter or closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } + } + + lexer.skip_whitespaces(); + + // ',' + { + char c; + if (!lexer.char1(&c)) { + err = "Expected comma delimiter.\n"; + return false; + } + + if (c != ',') { + err = "Expected comma delimiter between vector elements.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + // Parse second float + { + result.vspans[1].p_begin = lexer.curr; + uint16_t length{0}; + bool truncated{false}; + + if (!lexer.lex_float(length, truncated)) { + lexer.push_error("Second element is not a floating point literal."); + err = lexer.get_error(); + return false; + } + + result.vspans[1].length = length; + + if (truncated) { + if (!lexer.skip_until_delim_or_close_paren(',', vec_close_paren)) { + lexer.push_error("Failed to seek to delimiter or closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } + } + + lexer.skip_whitespaces(); + + // ')' + { + char c; + if (!lexer.char1(&c)) { + err = "Expected closing parenthesis.\n"; + return false; + } + + if (c != vec_close_paren) { + err = "Expected closing parenthesis for vector.\n"; + return false; + } + } + + return true; +} + +bool lex_vec3_array( + Lexer &lexer, + std::string &err, + vec_lex_span<3> &result, + const char vec_open_paren = '(', + const char vec_close_paren = ')') { + + // '(' + { + char c; + if (!lexer.char1(&c)) { + err = "Input too short for vector.\n"; + return false; + } + + if (c != vec_open_paren) { + err = "Vector does not begin with open parenthesis character.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + // Parse three floats + for (int i = 0; i < 3; i++) { + result.vspans[i].p_begin = lexer.curr; + uint16_t length{0}; + bool truncated{false}; + + if (!lexer.lex_float(length, truncated)) { + lexer.push_error("Element " + std::to_string(i) + " is not a floating point literal."); + err = lexer.get_error(); + return false; + } + + result.vspans[i].length = length; + + if (truncated) { + if (!lexer.skip_until_delim_or_close_paren(',', vec_close_paren)) { + lexer.push_error("Failed to seek to delimiter or closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } + + lexer.skip_whitespaces(); + + if (i < 2) { // Need comma after first two elements + char c; + if (!lexer.char1(&c)) { + err = "Expected comma delimiter.\n"; + return false; + } + + if (c != ',') { + err = "Expected comma delimiter between vector elements.\n"; + return false; + } + + lexer.skip_whitespaces(); + } + } + + // ')' + { + char c; + if (!lexer.char1(&c)) { + err = "Expected closing parenthesis.\n"; + return false; + } + + if (c != vec_close_paren) { + err = "Expected closing parenthesis for vector.\n"; + return false; + } + } + + return true; +} + +bool lex_vec4_array( + Lexer &lexer, + std::string &err, + vec_lex_span<4> &result, + const char vec_open_paren = '(', + const char vec_close_paren = ')') { + + // '(' + { + char c; + if (!lexer.char1(&c)) { + err = "Input too short for vector.\n"; + return false; + } + + if (c != vec_open_paren) { + err = "Vector does not begin with open parenthesis character.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + // Parse four floats + for (int i = 0; i < 4; i++) { + result.vspans[i].p_begin = lexer.curr; + uint16_t length{0}; + bool truncated{false}; + + if (!lexer.lex_float(length, truncated)) { + lexer.push_error("Element " + std::to_string(i) + " is not a floating point literal."); + err = lexer.get_error(); + return false; + } + + result.vspans[i].length = length; + + if (truncated) { + if (!lexer.skip_until_delim_or_close_paren(',', vec_close_paren)) { + lexer.push_error("Failed to seek to delimiter or closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } + + lexer.skip_whitespaces(); + + if (i < 3) { // Need comma after first three elements + char c; + if (!lexer.char1(&c)) { + err = "Expected comma delimiter.\n"; + return false; + } + + if (c != ',') { + err = "Expected comma delimiter between vector elements.\n"; + return false; + } + + lexer.skip_whitespaces(); + } + } + + // ')' + { + char c; + if (!lexer.char1(&c)) { + err = "Expected closing parenthesis.\n"; + return false; + } + + if (c != vec_close_paren) { + err = "Expected closing parenthesis for vector.\n"; + return false; + } + } + + return true; +} + +bool lex_matrix3d_array( + Lexer &lexer, + std::string &err, + matrix3d_lex_span &result, + const char matrix_open_paren = '(', + const char matrix_close_paren = ')') { + + // '(' + { + char c; + if (!lexer.char1(&c)) { + err = "Input too short for matrix3d.\n"; + return false; + } + + if (c != matrix_open_paren) { + err = "Matrix3d does not begin with open parenthesis character.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + // Parse nine floats + for (int i = 0; i < 9; i++) { + result.mspans[i].p_begin = lexer.curr; + uint16_t length{0}; + bool truncated{false}; + + if (!lexer.lex_float(length, truncated)) { + lexer.push_error("Element " + std::to_string(i) + " is not a floating point literal."); + err = lexer.get_error(); + return false; + } + + result.mspans[i].length = length; + + if (truncated) { + if (!lexer.skip_until_delim_or_close_paren(',', matrix_close_paren)) { + lexer.push_error("Failed to seek to delimiter or closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } + + lexer.skip_whitespaces(); + + if (i < 8) { // Need comma after first eight elements + char c; + if (!lexer.char1(&c)) { + err = "Expected comma delimiter.\n"; + return false; + } + + if (c != ',') { + err = "Expected comma delimiter between matrix elements.\n"; + return false; + } + + lexer.skip_whitespaces(); + } + } + + // ')' + { + char c; + if (!lexer.char1(&c)) { + err = "Expected closing parenthesis.\n"; + return false; + } + + if (c != matrix_close_paren) { + err = "Expected closing parenthesis for matrix3d.\n"; + return false; + } + } + + return true; +} + +bool lex_matrix4d_array( + Lexer &lexer, + std::string &err, + matrix4d_lex_span &result, + const char matrix_open_paren = '(', + const char matrix_close_paren = ')') { + + // '(' + { + char c; + if (!lexer.char1(&c)) { + err = "Input too short for matrix4d.\n"; + return false; + } + + if (c != matrix_open_paren) { + err = "Matrix4d does not begin with open parenthesis character.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + // Parse sixteen floats + for (int i = 0; i < 16; i++) { + result.mspans[i].p_begin = lexer.curr; + uint16_t length{0}; + bool truncated{false}; + + if (!lexer.lex_float(length, truncated)) { + lexer.push_error("Element " + std::to_string(i) + " is not a floating point literal."); + err = lexer.get_error(); + return false; + } + + result.mspans[i].length = length; + + if (truncated) { + if (!lexer.skip_until_delim_or_close_paren(',', matrix_close_paren)) { + lexer.push_error("Failed to seek to delimiter or closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } + + lexer.skip_whitespaces(); + + if (i < 15) { // Need comma after first fifteen elements + char c; + if (!lexer.char1(&c)) { + err = "Expected comma delimiter.\n"; + return false; + } + + if (c != ',') { + err = "Expected comma delimiter between matrix elements.\n"; + return false; + } + + lexer.skip_whitespaces(); + } + } + + // ')' + { + char c; + if (!lexer.char1(&c)) { + err = "Expected closing parenthesis.\n"; + return false; + } + + if (c != matrix_close_paren) { + err = "Expected closing parenthesis for matrix4d.\n"; + return false; + } + } + + return true; } @@ -488,6 +1039,418 @@ bool lex_float2_array( return true; } +bool lex_float3_array( + const char *p_begin, + const char *p_end, + std::vector> &result, + std::string &err, + bool allow_delim_at_last = true, + const char delim = ',', + const char arr_open_paren = '[', + const char arr_close_paren = ']', + const char vec_open_paren = '(', + const char vec_close_paren = ')') { + + if (p_begin >= p_end) { + err = "Invalid input\n"; + return false; + } + + Lexer lexer; + lexer.init(p_begin, p_end); + + // '[' + { + char c; + if (!lexer.char1(&c)) { + err = "Input too short.\n"; + return false; + } + + if (c != arr_open_paren) { + err = "Input does not begin with open parenthesis character.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + while (!lexer.eof()) { + + bool prev_is_delim = false; + + // is ','? + { + char c; + if (!lexer.look_char1(&c)) { + lexer.push_error("Invalid character found."); + err = lexer.get_error(); + return false; + } + + if (c == delim) { + // Array element starts with delimiter, e.g. '[ ,' + if (result.empty()) { + lexer.push_error("Array element starts with the delimiter character."); + err = lexer.get_error(); + return false; + } + prev_is_delim = true; + lexer.consume_char1(); + } + + lexer.skip_whitespaces(); + } + + // is ']'? + { + char c; + if (!lexer.look_char1(&c)) { + lexer.push_error("Failed to read a character."); + err = lexer.get_error(); + return false; + } + + if (c == arr_close_paren) { + if (prev_is_delim) { + if (allow_delim_at_last) { + // ok + return true; + } else { + lexer.push_error("Delimiter character is not allowed before the closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } else { + // ok + return true; + } + } + } + + vec_lex_span<3> v_sp; + if (!lex_vec3_array(lexer, err, v_sp, vec_open_paren, vec_close_paren)) { + err = lexer.get_error(); + return false; + } + + result.emplace_back(std::move(v_sp)); + + lexer.skip_whitespaces(); + } + + return true; +} + +bool lex_float4_array( + const char *p_begin, + const char *p_end, + std::vector> &result, + std::string &err, + bool allow_delim_at_last = true, + const char delim = ',', + const char arr_open_paren = '[', + const char arr_close_paren = ']', + const char vec_open_paren = '(', + const char vec_close_paren = ')') { + + if (p_begin >= p_end) { + err = "Invalid input\n"; + return false; + } + + Lexer lexer; + lexer.init(p_begin, p_end); + + // '[' + { + char c; + if (!lexer.char1(&c)) { + err = "Input too short.\n"; + return false; + } + + if (c != arr_open_paren) { + err = "Input does not begin with open parenthesis character.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + while (!lexer.eof()) { + + bool prev_is_delim = false; + + // is ','? + { + char c; + if (!lexer.look_char1(&c)) { + lexer.push_error("Invalid character found."); + err = lexer.get_error(); + return false; + } + + if (c == delim) { + // Array element starts with delimiter, e.g. '[ ,' + if (result.empty()) { + lexer.push_error("Array element starts with the delimiter character."); + err = lexer.get_error(); + return false; + } + prev_is_delim = true; + lexer.consume_char1(); + } + + lexer.skip_whitespaces(); + } + + // is ']'? + { + char c; + if (!lexer.look_char1(&c)) { + lexer.push_error("Failed to read a character."); + err = lexer.get_error(); + return false; + } + + if (c == arr_close_paren) { + if (prev_is_delim) { + if (allow_delim_at_last) { + // ok + return true; + } else { + lexer.push_error("Delimiter character is not allowed before the closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } else { + // ok + return true; + } + } + } + + vec_lex_span<4> v_sp; + if (!lex_vec4_array(lexer, err, v_sp, vec_open_paren, vec_close_paren)) { + err = lexer.get_error(); + return false; + } + + result.emplace_back(std::move(v_sp)); + + lexer.skip_whitespaces(); + } + + return true; +} + +bool lex_matrix3d_array_parser( + const char *p_begin, + const char *p_end, + std::vector &result, + std::string &err, + bool allow_delim_at_last = true, + const char delim = ',', + const char arr_open_paren = '[', + const char arr_close_paren = ']', + const char matrix_open_paren = '(', + const char matrix_close_paren = ')') { + + if (p_begin >= p_end) { + err = "Invalid input\n"; + return false; + } + + Lexer lexer; + lexer.init(p_begin, p_end); + + // '[' + { + char c; + if (!lexer.char1(&c)) { + err = "Input too short.\n"; + return false; + } + + if (c != arr_open_paren) { + err = "Input does not begin with open parenthesis character.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + while (!lexer.eof()) { + + bool prev_is_delim = false; + + // is ','? + { + char c; + if (!lexer.look_char1(&c)) { + lexer.push_error("Invalid character found."); + err = lexer.get_error(); + return false; + } + + if (c == delim) { + // Array element starts with delimiter, e.g. '[ ,' + if (result.empty()) { + lexer.push_error("Array element starts with the delimiter character."); + err = lexer.get_error(); + return false; + } + prev_is_delim = true; + lexer.consume_char1(); + } + + lexer.skip_whitespaces(); + } + + // is ']'? + { + char c; + if (!lexer.look_char1(&c)) { + lexer.push_error("Failed to read a character."); + err = lexer.get_error(); + return false; + } + + if (c == arr_close_paren) { + if (prev_is_delim) { + if (allow_delim_at_last) { + // ok + return true; + } else { + lexer.push_error("Delimiter character is not allowed before the closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } else { + // ok + return true; + } + } + } + + matrix3d_lex_span m_sp; + if (!lex_matrix3d_array(lexer, err, m_sp, matrix_open_paren, matrix_close_paren)) { + err = lexer.get_error(); + return false; + } + + result.emplace_back(std::move(m_sp)); + + lexer.skip_whitespaces(); + } + + return true; +} + +bool lex_matrix4d_array_parser( + const char *p_begin, + const char *p_end, + std::vector &result, + std::string &err, + bool allow_delim_at_last = true, + const char delim = ',', + const char arr_open_paren = '[', + const char arr_close_paren = ']', + const char matrix_open_paren = '(', + const char matrix_close_paren = ')') { + + if (p_begin >= p_end) { + err = "Invalid input\n"; + return false; + } + + Lexer lexer; + lexer.init(p_begin, p_end); + + // '[' + { + char c; + if (!lexer.char1(&c)) { + err = "Input too short.\n"; + return false; + } + + if (c != arr_open_paren) { + err = "Input does not begin with open parenthesis character.\n"; + return false; + } + } + + lexer.skip_whitespaces(); + + while (!lexer.eof()) { + + bool prev_is_delim = false; + + // is ','? + { + char c; + if (!lexer.look_char1(&c)) { + lexer.push_error("Invalid character found."); + err = lexer.get_error(); + return false; + } + + if (c == delim) { + // Array element starts with delimiter, e.g. '[ ,' + if (result.empty()) { + lexer.push_error("Array element starts with the delimiter character."); + err = lexer.get_error(); + return false; + } + prev_is_delim = true; + lexer.consume_char1(); + } + + lexer.skip_whitespaces(); + } + + // is ']'? + { + char c; + if (!lexer.look_char1(&c)) { + lexer.push_error("Failed to read a character."); + err = lexer.get_error(); + return false; + } + + if (c == arr_close_paren) { + if (prev_is_delim) { + if (allow_delim_at_last) { + // ok + return true; + } else { + lexer.push_error("Delimiter character is not allowed before the closing parenthesis character."); + err = lexer.get_error(); + return false; + } + } else { + // ok + return true; + } + } + } + + matrix4d_lex_span m_sp; + if (!lex_matrix4d_array(lexer, err, m_sp, matrix_open_paren, matrix_close_paren)) { + err = lexer.get_error(); + return false; + } + + result.emplace_back(std::move(m_sp)); + + lexer.skip_whitespaces(); + } + + return true; +} + bool do_parse( uint32_t nthreads, const std::vector &spans, @@ -556,11 +1519,11 @@ bool do_parse( int main(int argc, char **argv) { - std::vector lex_results; - uint32_t nthreads = 1; bool delim_at_end = true; - size_t n = 1024*1024*32; + size_t n = 1024*16; // Smaller default for testing + int test_type = 0; // 0: float, 1: float2, 2: float3, 3: float4, 4: matrix3d, 5: matrix4d + if (argc > 1) { n = std::stoi(argv[1]); } @@ -570,33 +1533,151 @@ int main(int argc, char **argv) if (argc > 3) { nthreads = std::stoi(argv[3]); } - lex_results.reserve(n); - - std::string input = gen_floatarray(n, delim_at_end); - //std::cout << input << "\n"; - - auto start = std::chrono::steady_clock::now(); - - std::string err; - if (!lex_float_array(input.c_str(), input.c_str() + input.size(), lex_results, err)) { - std::cerr << "parse error\n"; - std::cerr << err << "\n"; - return -1; + if (argc > 4) { + test_type = std::stoi(argv[4]); } - auto end = std::chrono::steady_clock::now(); - std::cout << "n elems " << lex_results.size() << "\n"; - std::cout << "size " << input.size() << "\n"; + std::cout << "Testing "; + switch (test_type) { + case 0: std::cout << "float array"; break; + case 1: std::cout << "float2 array"; break; + case 2: std::cout << "float3 array"; break; + case 3: std::cout << "float4 array"; break; + case 4: std::cout << "matrix3d array"; break; + case 5: std::cout << "matrix4d array"; break; + default: std::cout << "float array (default)"; test_type = 0; break; + } + std::cout << " with " << n << " elements\n"; - std::cout << "lex time: " << std::chrono::duration_cast(end - start).count() << " [ms]\n"; - + if (test_type == 0) { + // Test float array (original) + std::vector lex_results; + lex_results.reserve(n); - std::vector parse_results; - parse_results.reserve(n); + std::string input = gen_floatarray(n, delim_at_end); + auto start = std::chrono::steady_clock::now(); + + std::string err; + if (!lex_float_array(input.c_str(), input.c_str() + input.size(), lex_results, err)) { + std::cerr << "parse error\n"; + std::cerr << err << "\n"; + return -1; + } + auto end = std::chrono::steady_clock::now(); + + std::cout << "n elems " << lex_results.size() << "\n"; + std::cout << "size " << input.size() << "\n"; + std::cout << "lex time: " << std::chrono::duration_cast(end - start).count() << " [ms]\n"; + + std::vector parse_results; + parse_results.reserve(n); + do_parse(nthreads, lex_results, parse_results); + + } else if (test_type == 1) { + // Test float2 array + std::vector> lex_results; + lex_results.reserve(n); + + std::string input = gen_float2array(n, delim_at_end); + std::cout << "Sample input: " << input.substr(0, 200) << "...\n"; + + auto start = std::chrono::steady_clock::now(); + std::string err; + if (!lex_float2_array(input.c_str(), input.c_str() + input.size(), lex_results, err)) { + std::cerr << "parse error\n"; + std::cerr << err << "\n"; + return -1; + } + auto end = std::chrono::steady_clock::now(); + + std::cout << "n float2 vectors: " << lex_results.size() << "\n"; + std::cout << "size " << input.size() << "\n"; + std::cout << "lex time: " << std::chrono::duration_cast(end - start).count() << " [ms]\n"; + + } else if (test_type == 2) { + // Test float3 array + std::vector> lex_results; + lex_results.reserve(n); + + std::string input = gen_float3array(n, delim_at_end); + std::cout << "Sample input: " << input.substr(0, 200) << "...\n"; + + auto start = std::chrono::steady_clock::now(); + std::string err; + if (!lex_float3_array(input.c_str(), input.c_str() + input.size(), lex_results, err)) { + std::cerr << "parse error\n"; + std::cerr << err << "\n"; + return -1; + } + auto end = std::chrono::steady_clock::now(); + + std::cout << "n float3 vectors: " << lex_results.size() << "\n"; + std::cout << "size " << input.size() << "\n"; + std::cout << "lex time: " << std::chrono::duration_cast(end - start).count() << " [ms]\n"; + + } else if (test_type == 3) { + // Test float4 array + std::vector> lex_results; + lex_results.reserve(n); + + std::string input = gen_float4array(n, delim_at_end); + std::cout << "Sample input: " << input.substr(0, 200) << "...\n"; + + auto start = std::chrono::steady_clock::now(); + std::string err; + if (!lex_float4_array(input.c_str(), input.c_str() + input.size(), lex_results, err)) { + std::cerr << "parse error\n"; + std::cerr << err << "\n"; + return -1; + } + auto end = std::chrono::steady_clock::now(); + + std::cout << "n float4 vectors: " << lex_results.size() << "\n"; + std::cout << "size " << input.size() << "\n"; + std::cout << "lex time: " << std::chrono::duration_cast(end - start).count() << " [ms]\n"; + + } else if (test_type == 4) { + // Test matrix3d array + std::vector lex_results; + lex_results.reserve(n); + + std::string input = gen_matrix3d_array(n, delim_at_end); + std::cout << "Sample input: " << input.substr(0, 200) << "...\n"; + + auto start = std::chrono::steady_clock::now(); + std::string err; + if (!lex_matrix3d_array_parser(input.c_str(), input.c_str() + input.size(), lex_results, err)) { + std::cerr << "parse error\n"; + std::cerr << err << "\n"; + return -1; + } + auto end = std::chrono::steady_clock::now(); + + std::cout << "n matrix3d matrices: " << lex_results.size() << "\n"; + std::cout << "size " << input.size() << "\n"; + std::cout << "lex time: " << std::chrono::duration_cast(end - start).count() << " [ms]\n"; + + } else if (test_type == 5) { + // Test matrix4d array + std::vector lex_results; + lex_results.reserve(n); + + std::string input = gen_matrix4d_array(n, delim_at_end); + std::cout << "Sample input: " << input.substr(0, 200) << "...\n"; + + auto start = std::chrono::steady_clock::now(); + std::string err; + if (!lex_matrix4d_array_parser(input.c_str(), input.c_str() + input.size(), lex_results, err)) { + std::cerr << "parse error\n"; + std::cerr << err << "\n"; + return -1; + } + auto end = std::chrono::steady_clock::now(); + + std::cout << "n matrix4d matrices: " << lex_results.size() << "\n"; + std::cout << "size " << input.size() << "\n"; + std::cout << "lex time: " << std::chrono::duration_cast(end - start).count() << " [ms]\n"; + } - do_parse(nthreads, lex_results, parse_results); - //for (const auto &fp : parse_results) { - // std::cout << std::to_string(fp) << "\n"; - //} return 0; }