closes #4 Refactor DBC parsing into TypeFactory statement handlers

This commit is contained in:
deeaitch committed 2026-10-01 14:01:31 -04:00
1 parent 3bd9339baf
commit 88b5883dda
9 files changed
+511 -349

No files matched your search

+4 -1
View File
@@ -33,7 +33,7 @@ Run from the repository root:
```sh
g++ -std=c++17 -Wall -Wextra -Wpedantic -Werror -I. \
tests/dbc_parser_test.cpp dbc_parser.cpp -o /tmp/dbc_parser_test
tests/dbc_parser_test.cpp dbc_parser.cpp dbc_statement_handler.cpp -o /tmp/dbc_parser_test
/tmp/dbc_parser_test
```
@@ -45,3 +45,6 @@ boundaries, missing fields, malformed and overflowing numbers, reserved ID bits,
error paths and line numbers, and integration with signals and comments.
Temporary DBC fixtures are created in the system temporary directory and removed
automatically.
Dispatch tests also verify exact keyword matching, handler construction and reuse,
unknown statements, and independent parsing sessions, including recovery after errors.
+39
View File
@@ -1,4 +1,5 @@
#include "dbc_parser.h"
#include "dbc_statement_handler.h"
#include <chrono>
#include <filesystem>
@@ -19,6 +20,17 @@ struct Fixture {
}
};
class CountingHandler : public DbcStatementHandler {
public:
inline static int instances = 0;
inline static int calls = 0;
CountingHandler() { ++instances; }
void Handle (const std::string &, DbcParseContext &context) const override {
++calls;
context.database.frames.emplace_back();
}
};
int main() {
Fixture fixture;
int failures = 0;
@@ -88,6 +100,33 @@ int main() {
check (std::string (error.what()).find (fixture.path.string() + ":2: ") == 0U,
"Signal error location");
}
DbcDatabase dispatchDatabase;
DbcParseContext context {dispatchDatabase, nullptr};
DbcStatementDispatcher dispatcher;
dispatcher.RegisterType<CountingHandler> ("TEST_");
check (dispatcher.Dispatch ("TEST_ first", context) &&
dispatcher.Dispatch ("TEST_ second", context) &&
CountingHandler::instances == 1 && CountingHandler::calls == 2 &&
dispatchDatabase.frames.size() == 2U, "Factory dispatch and handler reuse");
check (!dispatcher.Dispatch ("TEST_OTHER data", context) &&
!dispatcher.Dispatch ("BO_TX_BU_ 1 : ECU;", context) &&
!dispatcher.Dispatch ("VAL_ 1 Speed 0 \"Stopped\";", context) &&
CountingHandler::calls == 2, "Exact and unknown keyword dispatch");
const DbcParser parser;
fixture.Write ("BO_ 1 First: 8 ECU\n");
check (parser.ParseFile (fixture.path.string()).frames.size() == 1U, "First parse");
fixture.Write ("SG_ Speed : invalid\n");
try {
parser.ParseFile (fixture.path.string());
check (false, "Independent parse context");
} catch (const std::runtime_error &error) {
check (std::string (error.what()).find ("Signal found before any frame") !=
std::string::npos, "Independent parse context");
}
fixture.Write ("BO_ 2 Second: 8 ECU\n");
const auto recovered = parser.ParseFile (fixture.path.string());
check (recovered.frames.size() == 1U && recovered.frames[0].canId == 2U,
"Fresh parse after error");
if (failures != 0) return 1;
std::cout << "All " << count << " parser cases passed.\n";
return 0;
+2 -2
View File
@@ -3,5 +3,5 @@ TARGET = dbc_parser_test
CONFIG += console c++17
CONFIG -= app_bundle qt
INCLUDEPATH += ..
SOURCES += dbc_parser_test.cpp ../dbc_parser.cpp
HEADERS += ../dbc_parser.h ../dbc_database.h ../frame_info.h ../signal_info.h
SOURCES += dbc_parser_test.cpp ../dbc_parser.cpp ../dbc_statement_handler.cpp
HEADERS += ../dbc_statement_handler.h ../typefactory.h ../dbc_parser.h ../dbc_database.h ../frame_info.h ../signal_info.h