-
Notifications
You must be signed in to change notification settings - Fork 5
parse VAL_ attribute #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6ab9cd7
2c3d828
f9eb281
61857a8
531ef66
12ae90f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,120 @@ const auto unitPattern = "\"(.*)\""; // Random string | |
const auto receiverPattern = "([\\w\\,]+|Vector__XXX)*"; | ||
const auto whiteSpace = "\\s"; | ||
|
||
enum VALToken { Identifier = 0, CANId, SignalName, Value, Description }; | ||
|
||
struct VALObject { | ||
uint32_t can_id; | ||
std::string signal_name; | ||
std::vector<libdbc::Signal::SignalValueDescriptions> vd; | ||
}; | ||
|
||
bool parseVal(const std::string& str, VALObject& obj) { | ||
obj.signal_name = ""; | ||
obj.vd.clear(); | ||
auto state = Identifier; | ||
const char* a = str.data(); | ||
libdbc::Signal::SignalValueDescriptions vd; | ||
for (;;) { | ||
switch (state) { | ||
case Identifier: { | ||
if (*a != 'V') | ||
return false; | ||
a++; | ||
if (*a != 'A') | ||
return false; | ||
a++; | ||
if (*a != 'L') | ||
return false; | ||
a++; | ||
if (*a != '_') | ||
return false; | ||
a++; | ||
if (*a != ' ') | ||
return false; | ||
a++; // skip whitespace | ||
state = CANId; | ||
break; | ||
} | ||
case CANId: { | ||
std::string can_id_str; | ||
while (*a >= '0' && *a <= '9') { | ||
can_id_str += *a; | ||
a++; | ||
} | ||
if (can_id_str.empty()) | ||
return false; | ||
obj.can_id = std::stoul(can_id_str); | ||
if (*a != ' ') | ||
return false; | ||
a++; // skip whitespace | ||
state = SignalName; | ||
break; | ||
} | ||
case SignalName: { | ||
if ((*a >= 'a' && *a <= 'z') || (*a >= 'A' && *a <= 'Z') || *a == '_') | ||
obj.signal_name += *a; | ||
else | ||
return false; | ||
a++; | ||
while ((*a >= 'a' && *a <= 'z') || (*a >= 'A' && *a <= 'Z') || *a == '_' || (*a >= '0' && *a <= '9')) { | ||
obj.signal_name += *a; | ||
a++; | ||
} | ||
if (*a != ' ') | ||
return false; | ||
a++; // skip whitespace | ||
state = Value; | ||
break; | ||
} | ||
case Value: { | ||
std::string value_str; | ||
while (*a >= '0' && *a <= '9') { | ||
value_str += *a; | ||
a++; | ||
} | ||
if (*a == ';') { | ||
if (value_str.empty()) | ||
return true; | ||
return false; | ||
} | ||
if (value_str.empty()) | ||
return false; | ||
|
||
if (*a != ' ') | ||
return false; | ||
a++; // skip whitespace | ||
vd.value = (uint32_t)std::stoul(value_str); | ||
state = Description; | ||
break; | ||
} | ||
case Description: { | ||
std::string desc; | ||
if (*a != '"') | ||
return false; | ||
a++; | ||
while (*a != '"' && *a != 0) { | ||
desc += *a; | ||
a++; | ||
} | ||
if (*a == 0) | ||
return false; | ||
a++; | ||
if (*a != ' ') | ||
return false; | ||
a++; // skip whitespace | ||
|
||
vd.description = desc; | ||
obj.vd.push_back(vd); | ||
|
||
state = Value; | ||
break; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
} // anonymous namespace | ||
|
||
namespace libdbc { | ||
|
@@ -123,6 +237,9 @@ void DbcParser::parse_dbc_nodes(std::istream& file_stream) { | |
void DbcParser::parse_dbc_messages(const std::vector<std::string>& lines) { | ||
std::smatch match; | ||
|
||
std::vector<VALObject> sv; | ||
|
||
VALObject obj; | ||
Comment on lines
+240
to
+242
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This come back to the comment before that the message shouldn't be parsing this. Maybe the val should be found first then passed to the signal to find the ones it needs? I guess I need to think about this some and maybe the function being a member on the signal isn't the right choice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea was first parsing the dbc file and then assigning the val object to the signal |
||
for (const auto& line : lines) { | ||
if (std::regex_search(line, match, message_re)) { | ||
uint32_t id = std::stoul(match.str(2)); | ||
|
@@ -133,6 +250,7 @@ void DbcParser::parse_dbc_messages(const std::vector<std::string>& lines) { | |
Message msg(id, name, size, node); | ||
|
||
messages.push_back(msg); | ||
continue; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we continue here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the regex matches a message is found and therefore it is not needed to check the others, because they will never match. So I can go directly to the next line |
||
} | ||
|
||
if (std::regex_search(line, match, signal_re)) { | ||
|
@@ -158,6 +276,21 @@ void DbcParser::parse_dbc_messages(const std::vector<std::string>& lines) { | |
|
||
Signal sig(name, is_multiplexed, start_bit, size, is_bigendian, is_signed, factor, offset, min, max, unit, receivers); | ||
messages.back().appendSignal(sig); | ||
continue; | ||
} | ||
|
||
if (parseVal(line, obj)) { | ||
sv.push_back(obj); | ||
continue; | ||
} | ||
} | ||
|
||
for (const auto& obj : sv) { | ||
for (auto& msg : messages) { | ||
if (msg.id() == obj.can_id) { | ||
msg.addValueDescription(obj.signal_name, obj.vd); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see now that this is done through a function on the message. I see why it is done this way now I think. |
||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be a member on the class of signal not external imo. External classes shouldn't know of these details just that they get the members after. Also not a huge fan of how long this function is. Perhaps split this up into some sub functions?
I am trying to follow what is going on and having a bit of a hard time. I will take another look again when I get a chance here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i don't think so, because this is related parsing the val object. It does the same thing like the regular expression, but in a different way because of the unknown numbers of value labels available. Therefore regex is not possible here