@@ -10,6 +10,7 @@ using namespace DBCParser;
1010std::shared_ptr<CANSignal> parseSignal (Tokenizer& tokenizer);
1111std::shared_ptr<CANFrame> parseFrame (Tokenizer& tokenizer);
1212std::set<std::string> parseECUs (Tokenizer& tokenizer);
13+ void parseNewSymbols (Tokenizer& tokenizer);
1314void addBADirective (Tokenizer& tokenizer,
1415 CANDatabase& db);
1516void addComment (Tokenizer& tokenizer, CANDatabase& db);
@@ -23,11 +24,20 @@ void addComment(Tokenizer& tokenizer, CANDatabase& db) {
2324 Token targetSignal;
2425
2526 assertToken (tokenizer, " CM_" );
26- commentType = checkTokenType (tokenizer, Token::Identifier);
27+
28+ // Handle global comment
29+ Token currentToken = tokenizer.getNextToken ();
30+ if (currentToken.type () == Token::Literal) {
31+ skipIf (tokenizer, " ;" );
32+ return ;
33+ }
34+
35+ commentType = checkCurrentTokenType (currentToken, Token::Identifier, tokenizer.lineCount ());
2736
2837 auto wWrongFrameId = [](const std::string& fId , unsigned long long line) {
2938 warning (" Frame " + fId + " does not exist" , line);
3039 };
40+
3141 if (commentType.image () == " SG_" ) {
3242 targetFrame = checkTokenType (tokenizer, Token::Number);
3343 targetSignal = checkTokenType (tokenizer, Token::Identifier);
@@ -75,7 +85,7 @@ void addBADirective(Tokenizer& tokenizer, CANDatabase& db) {
7585 assertToken (tokenizer, " BA_" );
7686
7787 infoType = checkTokenType (tokenizer, Token::Literal);
78- if (infoType.image () == " GenMsgCycleTime" ) {
88+ if (infoType.image () == " GenMsgCycleTime" || infoType. image () == " CycleTime " ) {
7989 skipIf (tokenizer, " BO_" );
8090 Token frameId = checkTokenType (tokenizer, Token::Number);
8191 Token period = checkTokenType (tokenizer, Token::Number);
@@ -92,16 +102,18 @@ void addBADirective(Tokenizer& tokenizer, CANDatabase& db) {
92102 return ;
93103 }
94104
95- unsigned int iFrameId = std::stoul ( frameId.image () );
96- unsigned int iPeriod = std::stoul ( period.image () );
105+ unsigned int iFrameId = frameId.toUInt ( );
106+ unsigned int iPeriod = period.toUInt ( );
97107
98- auto frame = db.at (iFrameId);
99- if (!frame) {
100- std::cout << " WARNING: frame " << iPeriod << " does not exist "
101- << " at line " << tokenizer.lineCount ()
102- << std::endl;
103- return ;
108+ std::shared_ptr<CANFrame> frame;
109+ try {
110+ frame = db.at (iFrameId);
104111 }
112+ catch (const std::out_of_range& e) {
113+ std::string tempStr = std::to_string (iFrameId) + " does not exist at line " + std::to_string (tokenizer.lineCount ());
114+ throw CANDatabaseException (tempStr);
115+ }
116+
105117 frame->setPeriod (iPeriod);
106118 }
107119 else {
@@ -116,6 +128,23 @@ CANDatabase DBCParser::fromTokenizer(Tokenizer& tokenizer) {
116128 return fromTokenizer (" " , tokenizer);
117129}
118130
131+ void parseNewSymbols (Tokenizer& tokenizer) {
132+ static std::set<std::string> ns_choices = {
133+ " CM_" , " BA_DEF_" , " BA_" , " VAL_" , " CAT_DEF_" , " CAT_" , " FILTER" , " BA_DEF_DEF_" ,
134+ " EV_DATA_" , " ENVVAR_DATA" , " SGTYPE_" , " SGTYPE_VAL_" , " BA_DEF_SGTYPE_" , " BA_SGTYPE_" ,
135+ " SIG_TYPE_DEF_"
136+ };
137+
138+ assertToken (tokenizer, " NS_" );
139+ skipIf (tokenizer, " :" );
140+
141+ Token token = tokenizer.getNextToken ();
142+ while (ns_choices.find (token.image ()) != ns_choices.end ()) {
143+ token = tokenizer.getNextToken ();
144+ }
145+ tokenizer.saveToken (token);
146+ }
147+
119148CANDatabase DBCParser::fromTokenizer (const std::string& name, Tokenizer& tokenizer) {
120149 std::cout << " Parsing: " << std::endl;
121150 Token currentToken = tokenizer.getNextToken ();
@@ -124,37 +153,59 @@ CANDatabase DBCParser::fromTokenizer(const std::string& name, Tokenizer& tokeniz
124153
125154 while (currentToken.type () != Token::Eof) {
126155 // std::cout << currentToken.image() << std::endl;
127- if (currentToken.image () == " VERSION" ) {
156+ if (currentToken.image () == " VERSION" ) {
128157 currentToken = checkTokenType (tokenizer, Token::Literal);
129158 std::cout << " DBC version: " << currentToken.image () << std::endl;
130159 }
131- else if (currentToken.image () == " BU_" ) {
160+ else if (currentToken.image () == " BU_" ) {
132161 std::set<std::string> ecus = parseECUs (tokenizer);
133162 std::cout << " The following ECUs have been defined:" << std::endl;
134- for (const auto & ecu : ecus) {
163+ for (const auto & ecu : ecus) {
135164 std::cout << ecu << " , " ;
136165 }
137166 std::cout << std::endl;
138167 }
139- else if (currentToken.image () == " BO_" ) {
168+ else if (currentToken.image () == " BO_" ) {
140169 std::shared_ptr<CANFrame> frame = parseFrame (tokenizer);
141170 result.addFrame (frame);
142171 }
143- else if (currentToken.image () == " SG_" ) {
172+ else if (currentToken.image () == " SG_" ) {
144173 parseSignal (tokenizer);
145- std::cout << " Identified signal outside frame -> WARNING !!!"
146- << std::endl;
174+ std::cout << " Identified signal outside frame -> WARNING !!! (line "
175+ << tokenizer. lineCount () << " ) " << std::endl;
147176 }
148- else if (currentToken.image () == " CM_" ) {
177+ else if (currentToken.image () == " CM_" ) {
149178 addComment (tokenizer, result);
150179 // TODO: Handle comments
151180 }
152- else if (currentToken.image () == " BA_" ) {
181+ else if (currentToken.image () == " BA_" ) {
153182 addBADirective (tokenizer, result);
154183 }
155- else if (currentToken.image () == " VAL_" ) {
184+ else if (currentToken.image () == " VAL_" ) {
156185 parseSignalChoices (tokenizer, result);
157186 }
187+ else if (currentToken.image () == " NS_" ) {
188+ parseNewSymbols (tokenizer);
189+ }
190+ else if (currentToken.image () == " BS_" ) {
191+ skipIf (tokenizer, " :" );
192+
193+ currentToken = tokenizer.getNextToken ();
194+ if (currentToken.type () != Token::Number)
195+ continue ;
196+
197+ Token baudrate = checkCurrentTokenType (currentToken, Token::Number, tokenizer.lineCount ());
198+ skipIf (tokenizer, " :" );
199+ Token btr1 = checkTokenType (tokenizer, Token::Number);
200+ skipIf (tokenizer, " ," );
201+ Token btr2 = checkTokenType (tokenizer, Token::Number);
202+
203+ // TODO: handle the statement
204+ }
205+ else {
206+ std::cerr << currentToken.image () << " is not a valid statement (yet). The statement is skipped." << std::endl;
207+ tokenizer.skipUntil (" ;" );
208+ }
158209 currentToken = tokenizer.getNextToken ();
159210 }
160211
@@ -187,7 +238,16 @@ std::shared_ptr<CANSignal> parseSignal(Tokenizer& tokenizer) {
187238 max = checkTokenType (tokenizer, Token::Number);
188239 skipIf (tokenizer, " ]" );
189240 unit = checkTokenType (tokenizer, Token::Literal);
241+
190242 targetECU = checkTokenType (tokenizer, Token::Identifier); // Ignored for now
243+ Token currentToken = tokenizer.getNextToken ();
244+ while (currentToken.image () == " ," ) {
245+ targetECU = checkTokenType (tokenizer, Token::Identifier);
246+ currentToken = tokenizer.getNextToken ();
247+ }
248+
249+ if (currentToken.type () != Token::Eof)
250+ tokenizer.saveToken (currentToken);
191251
192252 return std::make_shared<CANSignal>(
193253 signalName.image (),
@@ -219,8 +279,8 @@ std::shared_ptr<CANFrame> parseFrame(Tokenizer& tokenizer) {
219279
220280 std::shared_ptr<CANFrame> result = std::make_shared<CANFrame>(
221281 name.image (),
222- std::stoul ( id.image () ),
223- std::stoul ( dlc.image () )
282+ id.toUInt ( ),
283+ dlc.toUInt ( )
224284 );
225285
226286 Token currentToken = tokenizer.getNextToken ();
0 commit comments