DBC Framework
DBC parsing and CAN signal decoding framework
Loading...
Searching...
No Matches
dbc_parser.cpp
Go to the documentation of this file.
1
12#include "dbc_parser.h"
13#include "dbc_statement_handler.h"
14
15#include "text_utils.h"
16#include <fstream>
17#include <sstream>
18#include <stdexcept>
19#include <utility>
20
21namespace {
22 DbcDiagnosticCode StatementErrorCode(const std::string &keyword) {
23 if (keyword == "SG_MUL_VAL_")
24 return DbcDiagnosticCode::UnsupportedStatement;
25 if (keyword == "VAL_")
26 return DbcDiagnosticCode::InvalidValueDescription;
27 return DbcDiagnosticCode::InvalidStatement;
28 }
29}
30
31DbcDatabase DbcParser::ParseFile(const std::string &filePath) const {
33 for (const DbcDiagnostic &diagnostic : result.diagnostics) {
34 if (diagnostic.severity == DbcDiagnosticSeverity::Error) {
35 if (diagnostic.lineNumber == 0U)
36 throw std::runtime_error(diagnostic.message);
37 throw std::runtime_error(diagnostic.filePath + ":" +
38 std::to_string(diagnostic.lineNumber) + ": " + diagnostic.message);
39 }
40 }
41 return std::move(result.database);
42}
43
44DbcParseResult DbcParser::ParseFileWithDiagnostics(const std::string &filePath) const {
45 DbcParseResult result;
46 std::ifstream input(filePath.c_str());
47 if (!input.is_open()) {
48 result.diagnostics.push_back({DbcDiagnosticSeverity::Error,
49 DbcDiagnosticCode::FileOpenError, filePath, 0U,
50 "Failed to open DBC file: " + filePath});
51 return result;
52 }
53
54 DbcDatabase database;
55 DbcParseContext context{database, nullptr};
56 const DbcStatementDispatcher dispatcher;
57 bool inNamespace = false;
58 std::size_t lineNumber = 0U;
59 std::string line;
60 while (std::getline(input, line)) {
61 ++lineNumber;
62 line = dbc_detail::TrimText(line);
63 if (line.empty())
64 continue;
65
66 std::istringstream tokens(line);
67 std::string keyword;
68 std::string argument;
69 tokens >> keyword;
70 const bool hasArgument = static_cast<bool>(tokens >> argument);
71 if (inNamespace && !hasArgument && keyword != "BO_" && keyword != "SG_" &&
72 keyword != "BS_" && keyword != "BS_:" &&
73 keyword != "BU_" && keyword != "BU_:")
74 continue; // NS_ lists syntax symbols; BO_, SG_, BS_ and BU_ end the list.
75 inNamespace = keyword == "NS_" || keyword == "NS_:";
76
77 try {
78 context.lineNumber = lineNumber;
79 if (!dispatcher.Dispatch(line, context)) {
80 result.diagnostics.push_back({DbcDiagnosticSeverity::Warning,
81 DbcDiagnosticCode::UnsupportedStatement,
82 filePath, lineNumber,
83 "Unsupported statement '" + keyword +
84 "' is ignored; decoding or metadata may be incomplete."});
85 }
86 } catch (const std::exception &error) {
87 result.diagnostics.push_back({DbcDiagnosticSeverity::Error,
88 StatementErrorCode(keyword), filePath,
89 lineNumber, error.what()});
90 return result;
91 }
92 }
93
94 if (input.bad() || !input.eof()) {
95 result.diagnostics.push_back({DbcDiagnosticSeverity::Error,
96 DbcDiagnosticCode::FileReadError, filePath, 0U,
97 "Failed to read DBC file: " + filePath});
98 return result;
99 }
100
101 try {
102 context.ResolveValueDescriptions(filePath);
103 context.ValidateMultiplexing(filePath);
104 } catch (const DbcDiagnosticError &error) {
105 result.diagnostics.push_back(error.diagnostic);
106 return result;
107 }
108 result.database = std::move(database);
109 return result;
110}
DbcParseResult ParseFileWithDiagnostics(const std::string &filePath) const
Parse with warnings and a structured first error instead of throwing.
DbcDatabase ParseFile(const std::string &filePath) const
Parse DBC file.
bool Dispatch(const std::string &line, DbcParseContext &context) const
Created: 2026-03-13 Author: Deeaitch (Dim. Himro)
Parsed DBC content stored in a simple internal form.