src/parser.cpp

changeset 35
98906a94732f
parent 33
4c41bfe2ec6e
child 77
028798a72591
equal deleted inserted replaced
34:1de2b8d64e9f 35:98906a94732f
253 if (line == "0 BFC INVERTNEXT" or line == "0 BFC CERTIFY INVERTNEXT") 253 if (line == "0 BFC INVERTNEXT" or line == "0 BFC CERTIFY INVERTNEXT")
254 { 254 {
255 invertNext = true; 255 invertNext = true;
256 continue; 256 continue;
257 } 257 }
258 std::unique_ptr<linetypes::Object> object = parseFromString(line); 258 std::unique_ptr<ldraw::Object> object = parseFromString(line);
259 auto id = editor.append(std::move(object)); 259 auto id = editor.append(std::move(object));
260 if (invertNext) 260 if (invertNext)
261 { 261 {
262 editor.invertObject(id); 262 editor.invertObject(id);
263 } 263 }
264 invertNext = false; 264 invertNext = false;
265 } 265 }
266 } 266 }
267 267
268 static Color colorFromString(const QString& colorString) 268 static ldraw::Color colorFromString(const QString& colorString)
269 { 269 {
270 bool colorSucceeded; 270 bool colorSucceeded;
271 const Color color = {colorString.toInt(&colorSucceeded)}; 271 const ldraw::Color color = {colorString.toInt(&colorSucceeded)};
272 if (colorSucceeded) 272 if (colorSucceeded)
273 { 273 {
274 return color; 274 return color;
275 } 275 }
276 else 276 else
327 } 327 }
328 } 328 }
329 return result; 329 return result;
330 } 330 }
331 331
332 static std::unique_ptr<linetypes::Object> parseType0Line( 332 static std::unique_ptr<ldraw::Object> parseType0Line(
333 const QString& line, 333 const QString& line,
334 const QStringList& tokens) 334 const QStringList& tokens)
335 { 335 {
336 Q_UNUSED(tokens) 336 Q_UNUSED(tokens)
337 if (line.startsWith("0 //")) 337 if (line.startsWith("0 //"))
338 { 338 {
339 return std::make_unique<linetypes::Comment>(line.mid(std::strlen("0 //")).simplified()); 339 return std::make_unique<ldraw::Comment>(line.mid(std::strlen("0 //")).simplified());
340 } 340 }
341 else 341 else
342 { 342 {
343 return std::make_unique<linetypes::MetaCommand>(line.mid(1).simplified()); 343 return std::make_unique<ldraw::MetaCommand>(line.mid(1).simplified());
344 } 344 }
345 } 345 }
346 346
347 static std::unique_ptr<linetypes::SubfileReference> parseType1Line( 347 static std::unique_ptr<ldraw::SubfileReference> parseType1Line(
348 const QString& line, 348 const QString& line,
349 const QStringList& tokens) 349 const QStringList& tokens)
350 { 350 {
351 Q_UNUSED(line) 351 Q_UNUSED(line)
352 constexpr int colorPosition = 1; 352 constexpr int colorPosition = 1;
355 constexpr int namePosition = 14; 355 constexpr int namePosition = 14;
356 if (tokens.size() != 15) 356 if (tokens.size() != 15)
357 { 357 {
358 throw BodyParseError{"wrong amount of tokens in a type-1 line"}; 358 throw BodyParseError{"wrong amount of tokens in a type-1 line"};
359 } 359 }
360 const Color color = colorFromString(tokens[colorPosition]); 360 const ldraw::Color color = colorFromString(tokens[colorPosition]);
361 const glm::mat4 transform = matrixFromStrings(tokens, transformPosition, positionPosition); 361 const glm::mat4 transform = matrixFromStrings(tokens, transformPosition, positionPosition);
362 const QString& name = tokens[namePosition]; 362 const QString& name = tokens[namePosition];
363 return std::make_unique<linetypes::SubfileReference>(transform, name, color); 363 return std::make_unique<ldraw::SubfileReference>(transform, name, color);
364 } 364 }
365 365
366 template<typename T, int NumVertices> 366 template<typename T, int NumVertices>
367 static std::unique_ptr<T> parsePolygon( 367 static std::unique_ptr<T> parsePolygon(
368 const QString& line, 368 const QString& line,
373 auto vertexPosition = [](int n) { return 2 + 3*n; }; 373 auto vertexPosition = [](int n) { return 2 + 3*n; };
374 if (tokens.size() != 2 + 3 * NumVertices) 374 if (tokens.size() != 2 + 3 * NumVertices)
375 { 375 {
376 throw BodyParseError{"wrong amount of tokens"}; 376 throw BodyParseError{"wrong amount of tokens"};
377 } 377 }
378 const Color color = colorFromString(tokens[colorPosition]); 378 const ldraw::Color color = colorFromString(tokens[colorPosition]);
379 QVector<glm::vec3> vertices; 379 QVector<glm::vec3> vertices;
380 vertices.reserve(NumVertices); 380 vertices.reserve(NumVertices);
381 for (int i = 0; i < NumVertices; i += 1) 381 for (int i = 0; i < NumVertices; i += 1)
382 { 382 {
383 vertices.append(vertexFromStrings(tokens, vertexPosition(i))); 383 vertices.append(vertexFromStrings(tokens, vertexPosition(i)));
384 } 384 }
385 return std::make_unique<T>(vertices, color); 385 return std::make_unique<T>(vertices, color);
386 } 386 }
387 387
388 std::unique_ptr<linetypes::Object> Parser::parseFromString(QString line) 388 std::unique_ptr<ldraw::Object> Parser::parseFromString(QString line)
389 { 389 {
390 line = line.simplified(); 390 line = line.simplified();
391 try 391 try
392 { 392 {
393 const QStringList tokens = line.split(QRegExp{R"(\s+)"}); 393 const QStringList tokens = line.split(QRegExp{R"(\s+)"});
394 if (tokens.empty() or tokens == QStringList{{""}}) 394 if (tokens.empty() or tokens == QStringList{{""}})
395 { 395 {
396 return std::make_unique<linetypes::Empty>(); 396 return std::make_unique<ldraw::Empty>();
397 } 397 }
398 bool ok_code; 398 bool ok_code;
399 const int code = tokens[0].toInt(&ok_code); 399 const int code = tokens[0].toInt(&ok_code);
400 if (not ok_code) 400 if (not ok_code)
401 { 401 {
406 case 0: 406 case 0:
407 return parseType0Line(line, tokens); 407 return parseType0Line(line, tokens);
408 case 1: 408 case 1:
409 return parseType1Line(line, tokens); 409 return parseType1Line(line, tokens);
410 case 2: 410 case 2:
411 return parsePolygon<linetypes::Edge, 2>(line, tokens); 411 return parsePolygon<ldraw::Edge, 2>(line, tokens);
412 case 3: 412 case 3:
413 return parsePolygon<linetypes::Triangle, 3>(line, tokens); 413 return parsePolygon<ldraw::Triangle, 3>(line, tokens);
414 case 4: 414 case 4:
415 return parsePolygon<linetypes::Quadrilateral, 4>(line, tokens); 415 return parsePolygon<ldraw::Quadrilateral, 4>(line, tokens);
416 case 5: 416 case 5:
417 return parsePolygon<linetypes::ConditionalEdge, 4>(line, tokens); 417 return parsePolygon<ldraw::ConditionalEdge, 4>(line, tokens);
418 default: 418 default:
419 throw BodyParseError{utility::format("bad line type '%1'", code)}; 419 throw BodyParseError{utility::format("bad line type '%1'", code)};
420 } 420 }
421 } 421 }
422 catch(const BodyParseError& error) 422 catch(const BodyParseError& error)
423 { 423 {
424 return std::make_unique<linetypes::ErrorLine>(line, error.message); 424 return std::make_unique<ldraw::ErrorLine>(line, error.message);
425 } 425 }
426 } 426 }

mercurial