src/parser.h

changeset 333
07e65a4c6611
parent 328
3ea38fd469ca
child 358
ef90ed0a5720
--- a/src/parser.h	Mon Jul 04 15:37:22 2022 +0300
+++ b/src/parser.h	Mon Jul 04 19:53:13 2022 +0300
@@ -20,15 +20,124 @@
 #include "src/basics.h"
 #include "src/model.h"
 
-class Parser : public QObject
+struct TextRange
 {
-	Q_OBJECT
-public:
-	Parser(QTextStream& stream, QObject* parent = nullptr);
-	void parseBody(Model &model);
-private:
-	QString readLine();
-	QTextStream& stream;
+	int start;
+	int length;
+};
+
+
+enum class Attribute {
+	LineType,
+	Color,
+	X1,
+	Y1,
+	Z1,
+	X2,
+	Y2,
+	Z2,
+	X3,
+	Y3,
+	Z3,
+	X4,
+	Y4,
+	Z4,
+	Name,
+	Text
+};
+
+template<typename T, Attribute... Attribs>
+struct LineType
+{
+	static constexpr Attribute attributes[] = {Attribs...};
+	QString content;
+	TextRange positions[countof(attributes)];
+	T value;
 };
 
-ModelElement parseLDrawLine(QString line);
+using LineType0 = LineType<Comment, Attribute::Text>;
+using LineType1 = LineType<Colored<SubfileReference>,
+	Attribute::LineType,
+	Attribute::Color,
+	Attribute::X1,
+	Attribute::Y1,
+	Attribute::Z1,
+	Attribute::X2,
+	Attribute::Y2,
+	Attribute::Z2,
+	Attribute::X3,
+	Attribute::Y3,
+	Attribute::Z3,
+	Attribute::X4,
+	Attribute::Y4,
+	Attribute::Z4,
+	Attribute::Name>;
+using LineType2 = LineType<Colored<LineSegment>,
+	Attribute::LineType,
+	Attribute::Color,
+	Attribute::X1,
+	Attribute::Y1,
+	Attribute::Z1,
+	Attribute::X2,
+	Attribute::Y2,
+	Attribute::Z2>;
+using LineType3 = LineType<Colored<Triangle>,
+	Attribute::LineType,
+	Attribute::Color,
+	Attribute::X1,
+	Attribute::Y1,
+	Attribute::Z1,
+	Attribute::X2,
+	Attribute::Y2,
+	Attribute::Z2,
+	Attribute::X3,
+	Attribute::Y3,
+	Attribute::Z3>;
+using LineType4 = LineType<Colored<Quadrilateral>,
+	Attribute::LineType,
+	Attribute::Color,
+	Attribute::X1,
+	Attribute::Y1,
+	Attribute::Z1,
+	Attribute::X2,
+	Attribute::Y2,
+	Attribute::Z2,
+	Attribute::X3,
+	Attribute::Y3,
+	Attribute::Z3,
+	Attribute::X4,
+	Attribute::Y4,
+	Attribute::Z4>;
+using LineType5 = LineType<Colored<ConditionalEdge>,
+	Attribute::LineType,
+	Attribute::Color,
+	Attribute::X1,
+	Attribute::Y1,
+	Attribute::Z1,
+	Attribute::X2,
+	Attribute::Y2,
+	Attribute::Z2,
+	Attribute::X3,
+	Attribute::Y3,
+	Attribute::Z3,
+	Attribute::X4,
+	Attribute::Y4,
+	Attribute::Z4>;
+
+template<typename T, Attribute Attrib>
+constexpr int findAttributeIndex()
+{
+	constexpr auto it = std::find(
+		std::begin(T::attributes),
+		std::end(T::attributes),
+		Attrib
+	);
+	static_assert(it != std::end(T::attributes), "Attribute not found");
+	return it - std::begin(T::attributes);
+}
+
+template<typename T, Attribute Attrib>
+constexpr int attribIndex = findAttributeIndex<T, Attrib>();
+static_assert(attribIndex<LineType3, Attribute::X1> == 2);
+using ParsedLine = std::variant<LineType0, LineType1, LineType2, LineType3, LineType4, LineType5>;
+opt<ParsedLine> parse(const QString& line);

mercurial