src/parser.cpp

changeset 5
593a658cba8e
parent 4
68988ebc2a68
child 8
44679e468ba9
equal deleted inserted replaced
4:68988ebc2a68 5:593a658cba8e
39 QString Parser::readLine() 39 QString Parser::readLine()
40 { 40 {
41 return QString::fromUtf8(this->device.readLine()).trimmed(); 41 return QString::fromUtf8(this->device.readLine()).trimmed();
42 } 42 }
43 43
44 const QMap<QString, decltype(LDHeader::type)> Parser::typeStrings { 44 static const QMap<QString, decltype(LDHeader::type)> typeStrings {
45 {"Part", LDHeader::Part}, 45 {"Part", LDHeader::Part},
46 {"Subpart", LDHeader::Subpart}, 46 {"Subpart", LDHeader::Subpart},
47 {"Shortcut", LDHeader::Shortcut}, 47 {"Shortcut", LDHeader::Shortcut},
48 {"Primitive", LDHeader::Primitive}, 48 {"Primitive", LDHeader::Primitive},
49 {"8_Primitive", LDHeader::Primitive_8}, 49 {"8_Primitive", LDHeader::Primitive_8},
74 else if (line.startsWith("0 !LDRAW_ORG ")) 74 else if (line.startsWith("0 !LDRAW_ORG "))
75 { 75 {
76 QStringList tokens = line 76 QStringList tokens = line
77 .mid(strlen("0 !LDRAW_ORG ")) 77 .mid(strlen("0 !LDRAW_ORG "))
78 .split(" ", QString::SkipEmptyParts); 78 .split(" ", QString::SkipEmptyParts);
79
80 if (not tokens.isEmpty()) 79 if (not tokens.isEmpty())
81 { 80 {
82 QString partTypeString = tokens[0]; 81 QString partTypeString = tokens[0];
83 // Anything that enters LDForge becomes unofficial in any case if saved. 82 // Anything that enters LDForge becomes unofficial in any case if saved.
84 // Therefore we don't need to give the Unofficial type any special 83 // Therefore we don't need to give the Unofficial type any special
85 // consideration. 84 // consideration.
86 if (partTypeString.startsWith("Unofficial_")) 85 if (partTypeString.startsWith("Unofficial_"))
87 partTypeString = partTypeString.mid(strlen("Unofficial_")); 86 partTypeString = partTypeString.mid(strlen("Unofficial_"));
88 header.type = Parser::typeStrings.value(partTypeString, LDHeader::Part); 87 header.type = typeStrings.value(partTypeString, LDHeader::Part);
89 header.qualfiers = 0; 88 header.qualfiers = 0;
90 if (tokens.contains("Alias")) 89 if (tokens.contains("Alias"))
91 header.qualfiers |= LDHeader::Alias; 90 header.qualfiers |= LDHeader::Alias;
92 if (tokens.contains("Physical_Color")) 91 if (tokens.contains("Physical_Color"))
93 header.qualfiers |= LDHeader::Physical_Color; 92 header.qualfiers |= LDHeader::Physical_Color;
198 * the resulting header structure. 197 * the resulting header structure.
199 */ 198 */
200 LDHeader Parser::parseHeader(Winding& winding) 199 LDHeader Parser::parseHeader(Winding& winding)
201 { 200 {
202 LDHeader header = {}; 201 LDHeader header = {};
203
204 if (not this->device.atEnd()) 202 if (not this->device.atEnd())
205 { 203 {
206 // Parse the description 204 // Parse the description
207 QString descriptionLine = this->readLine(); 205 QString descriptionLine = this->readLine();
208 if (descriptionLine.startsWith("0 ")) 206 if (descriptionLine.startsWith("0 "))
209 { 207 {
210 header.description = descriptionLine.mid(strlen("0 ")).trimmed(); 208 header.description = descriptionLine.mid(strlen("0 ")).trimmed();
211
212 // Parse the rest of the header 209 // Parse the rest of the header
213 while (not this->device.atEnd()) 210 while (not this->device.atEnd())
214 { 211 {
215 const QString& line = this->readLine(); 212 const QString& line = this->readLine();
216 auto result = parseHeaderLine(header, winding, line); 213 auto result = parseHeaderLine(header, winding, line);
217
218 if (result == ParseFailure) 214 if (result == ParseFailure)
219 { 215 {
220 // Failed to parse this header line, add it as a comment into the body later. 216 // Failed to parse this header line, add it as a comment into the body later.
221 this->bag.append(line); 217 this->bag.append(line);
222 } 218 }
231 else 227 else
232 { 228 {
233 this->bag.append(descriptionLine); 229 this->bag.append(descriptionLine);
234 } 230 }
235 } 231 }
236
237 return header; 232 return header;
238 } 233 }
239 234
240 /** 235 /**
241 * @brief Parses the model body into the given model. 236 * @brief Parses the model body into the given model.
306 R"(\s*$)" // end 301 R"(\s*$)" // end
307 }; 302 };
308 } 303 }
309 } 304 }
310 305
306 static Vertex vertexFromString(const QString& vertex_string)
307 {
308 static const QRegExp pattern {R"(^\s*([^\s]+)\s+([^\s]+)\s+([^\s]+)\s*$)"};
309 const bool succeeded = pattern.exactMatch(vertex_string);
310 if (succeeded)
311 {
312 const float x = pattern.cap(1).toFloat(nullptr);
313 const float y = pattern.cap(2).toFloat(nullptr);
314 const float z = pattern.cap(3).toFloat(nullptr);
315 return {x, y, z};
316 }
317 else
318 {
319 return {};
320 }
321 }
322
323 static modelobjects::Edge* parseEdgeline(
324 Model::EditContext& editor,
325 const QString& line)
326 {
327 const bool succeeded = regexes::edgeline.exactMatch(line);
328 if (succeeded)
329 {
330 const Color colour = {regexes::edgeline.cap(1).toInt(nullptr)};
331 const Vertex v_1 = vertexFromString(regexes::edgeline.cap(2));
332 const Vertex v_2 = vertexFromString(regexes::edgeline.cap(3));
333 return editor.append<modelobjects::Edge>(v_1, v_2, colour);
334 }
335 else
336 {
337 return nullptr;
338 }
339 }
340
311 modelobjects::BaseObject* Parser::parseFromString( 341 modelobjects::BaseObject* Parser::parseFromString(
312 Model::EditContext& editor, 342 Model::EditContext& editor,
313 const QString& line) 343 const QString& line)
314 { 344 {
315 return editor.append<modelobjects::Comment>(line); 345 modelobjects::Edge* edge = parseEdgeline(editor, line);
316 } 346 if (edge)
347 {
348 return edge;
349 }
350 return editor.append<modelobjects::ErrorLine>(line);
351 }

mercurial