src/parser.cpp

Mon, 23 Sep 2019 14:06:36 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 23 Sep 2019 14:06:36 +0300
changeset 4
68988ebc2a68
parent 3
55a55a9ec2c2
child 5
593a658cba8e
permissions
-rw-r--r--

added regular expressions for the parser

3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
1 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
2 * LDForge: LDraw parts authoring CAD
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
3 * Copyright (C) 2013 - 2018 Teemu Piippo
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
4 *
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
5 * This program is free software: you can redistribute it and/or modify
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
6 * it under the terms of the GNU General Public License as published by
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
7 * the Free Software Foundation, either version 3 of the License, or
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
8 * (at your option) any later version.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
9 *
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
10 * This program is distributed in the hope that it will be useful,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
13 * GNU General Public License for more details.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
14 *
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
17 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
18
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
19 #include "model.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
20 #include "parser.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
21 #include "objecttypes/comment.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
22 #include "objecttypes/conditionaledge.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
23 #include "objecttypes/edge.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
24 #include "objecttypes/errorline.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
25 #include "objecttypes/modelobject.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
26 #include "objecttypes/polygon.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
27 #include "objecttypes/subfilereference.h"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
28
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
29 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
30 * Constructs an LDraw parser
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
31 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
32 Parser::Parser(QIODevice& device, QObject* parent) :
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
33 QObject {parent},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
34 device {device} {}
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
35
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
36 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
37 * Reads a single line from the device.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
38 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
39 QString Parser::readLine()
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
40 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
41 return QString::fromUtf8(this->device.readLine()).trimmed();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
42 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
43
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
44 const QMap<QString, decltype(LDHeader::type)> Parser::typeStrings {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
45 {"Part", LDHeader::Part},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
46 {"Subpart", LDHeader::Subpart},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
47 {"Shortcut", LDHeader::Shortcut},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
48 {"Primitive", LDHeader::Primitive},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
49 {"8_Primitive", LDHeader::Primitive_8},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
50 {"48_Primitive", LDHeader::Primitive_48},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
51 {"Configuration", LDHeader::Configuration},
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
52 };
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
53
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
54 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
55 * Parses a single line of the header.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
56 * Possible parse results:
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
57 * · ParseSuccess: the header line was parsed successfully.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
58 * · ParseFailure: the header line was parsed incorrectly and needs to be handled otherwise.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
59 * · StopParsing: the line does not belong in the header and header parsing needs to stop.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
60 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
61 Parser::HeaderParseResult Parser::parseHeaderLine(
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
62 LDHeader& header,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
63 Winding& winding,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
64 const QString& line
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
65 ) {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
66 if (line.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
67 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
68 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
69 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
70 else if (not line.startsWith("0") or line.startsWith("0 //"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
71 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
72 return StopParsing;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
73 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
74 else if (line.startsWith("0 !LDRAW_ORG "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
75 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
76 QStringList tokens = line
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
77 .mid(strlen("0 !LDRAW_ORG "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
78 .split(" ", QString::SkipEmptyParts);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
79
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
80 if (not tokens.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
81 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
82 QString partTypeString = tokens[0];
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
83 // Anything that enters LDForge becomes unofficial in any case if saved.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
84 // Therefore we don't need to give the Unofficial type any special
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
85 // consideration.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
86 if (partTypeString.startsWith("Unofficial_"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
87 partTypeString = partTypeString.mid(strlen("Unofficial_"));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
88 header.type = Parser::typeStrings.value(partTypeString, LDHeader::Part);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
89 header.qualfiers = 0;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
90 if (tokens.contains("Alias"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
91 header.qualfiers |= LDHeader::Alias;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
92 if (tokens.contains("Physical_Color"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
93 header.qualfiers |= LDHeader::Physical_Color;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
94 if (tokens.contains("Flexible_Section"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
95 header.qualfiers |= LDHeader::Flexible_Section;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
96 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
97 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
98 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
99 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
100 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
101 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
102 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
103 else if (line == "0 BFC CERTIFY CCW")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
104 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
105 winding = CounterClockwise;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
106 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
107 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
108 else if (line == "0 BFC CERTIFY CW")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
109 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
110 winding = Clockwise;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
111 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
112 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
113 else if (line == "0 BFC NOCERTIFY")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
114 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
115 winding = NoWinding;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
116 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
117 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
118 else if (line.startsWith("0 !HISTORY "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
119 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
120 static const QRegExp historyRegexp {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
121 R"(0 !HISTORY\s+(\d{4}-\d{2}-\d{2})\s+)"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
122 R"((\{[^}]+|\[[^]]+)[\]}]\s+(.+))"
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
123 };
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
124 if (historyRegexp.exactMatch(line))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
125 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
126 QString dateString = historyRegexp.capturedTexts().value(1);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
127 QString authorWithPrefix = historyRegexp.capturedTexts().value(2);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
128 QString description = historyRegexp.capturedTexts().value(3);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
129 LDHeader::HistoryEntry historyEntry;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
130 historyEntry.date = QDate::fromString(dateString, Qt::ISODate);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
131 historyEntry.description = description;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
132
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
133 if (authorWithPrefix[0] == '{')
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
134 historyEntry.author = authorWithPrefix + "}";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
135 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
136 historyEntry.author = authorWithPrefix.mid(1);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
137
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
138 header.history.append(historyEntry);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
139 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
140 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
141 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
142 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
143 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
144 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
145 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
146 else if (line.startsWith("0 Author: "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
147 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
148 header.author = line.mid(strlen("0 Author: "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
149 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
150 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
151 else if (line.startsWith("0 Name: "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
152 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
153 header.name = line.mid(strlen("0 Name: "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
154 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
155 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
156 else if (line.startsWith("0 !HELP "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
157 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
158 if (not header.help.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
159 header.help += "\n";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
160 header.help += line.mid(strlen("0 !HELP "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
161 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
162 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
163 else if (line.startsWith("0 !KEYWORDS "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
164 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
165 if (not header.keywords.isEmpty())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
166 header.keywords += "\n";
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
167 header.keywords += line.mid(strlen("0 !KEYWORDS "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
168 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
169 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
170 else if (line.startsWith("0 !CATEGORY "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
171 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
172 header.category = line.mid(strlen("0 !CATEGORY "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
173 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
174 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
175 else if (line.startsWith("0 !CMDLINE "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
176 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
177 header.cmdline = line.mid(strlen("0 !CMDLINE "));
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
178 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
179 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
180 else if (line.startsWith("0 !LICENSE Redistributable under CCAL version 2.0"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
181 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
182 header.license = LDHeader::CaLicense;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
183 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
184 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
185 else if (line.startsWith("0 !LICENSE Not redistributable"))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
186 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
187 header.license = LDHeader::NonCaLicense;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
188 return ParseSuccess;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
189 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
190 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
191 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
192 return ParseFailure;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
193 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
194 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
195
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
196 /*
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
197 * Parses the header from the device given at construction and returns
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
198 * the resulting header structure.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
199 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
200 LDHeader Parser::parseHeader(Winding& winding)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
201 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
202 LDHeader header = {};
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
203
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
204 if (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
205 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
206 // Parse the description
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
207 QString descriptionLine = this->readLine();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
208 if (descriptionLine.startsWith("0 "))
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
209 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
210 header.description = descriptionLine.mid(strlen("0 ")).trimmed();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
211
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
212 // Parse the rest of the header
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
213 while (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
214 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
215 const QString& line = this->readLine();
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
216 auto result = parseHeaderLine(header, winding, line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
217
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
218 if (result == ParseFailure)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
219 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
220 // Failed to parse this header line, add it as a comment into the body later.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
221 this->bag.append(line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
222 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
223 else if (result == StopParsing)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
224 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
225 // Header parsing stops, add this line to the body.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
226 this->bag.append(line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
227 break;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
228 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
229 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
230 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
231 else
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
232 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
233 this->bag.append(descriptionLine);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
234 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
235 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
236
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
237 return header;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
238 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
239
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
240 /**
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
241 * @brief Parses the model body into the given model.
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
242 * @param editor Handle to model edit context
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
243 */
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
244 void Parser::parseBody(Model::EditContext& editor)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
245 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
246 bool invertNext = false;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
247 while (not this->device.atEnd())
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
248 this->bag.append(this->readLine());
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
249 for (const QString& line : this->bag)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
250 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
251 if (line == "0 BFC INVERTNEXT" or line == "0 BFC CERTIFY INVERTNEXT")
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
252 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
253 invertNext = true;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
254 continue;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
255 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
256 modelobjects::BaseObject* object = parseFromString(editor, line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
257 if (invertNext)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
258 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
259 editor.setObjectProperty(object, modelobjects::Property::IsInverted, true);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
260 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
261 invertNext = false;
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
262 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
263 }
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
264
4
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
265 namespace
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
266 {
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
267 namespace regexes
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
268 {
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
269 static const QRegExp comment {R"(^\s*0\s*\/\/\s*(.+)$)"};
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
270 static const QRegExp metacommand {R"(^\s*0\s*(.+)$)"};
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
271 static const QRegExp edgeline
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
272 {
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
273 R"(^\s*2)" // starting 2-token
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
274 R"(\s+(\d+))" // colour
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
275 R"(((?:\s+[^\s]+){3}))" // 1st vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
276 R"(((?:\s+[^\s]+){3}))" // 2nd vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
277 R"(\s*$)" // end
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
278 };
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
279 static const QRegExp triangle
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
280 {
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
281 R"(^\s*3)" // starting 3-token
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
282 R"(\s+(\d+))" // colour
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
283 R"(((?:\s+[^\s]+){3}))" // 1st vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
284 R"(((?:\s+[^\s]+){3}))" // 2nd vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
285 R"(((?:\s+[^\s]+){3}))" // 3rd vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
286 R"(\s*$)" // end
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
287 };
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
288 static const QRegExp quadrilateral
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
289 {
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
290 R"(^\s*4)" // starting 4-token
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
291 R"(\s+(\d+))" // colour
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
292 R"(((?:\s+[^\s]+){3}))" // 1st vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
293 R"(((?:\s+[^\s]+){3}))" // 2nd vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
294 R"(((?:\s+[^\s]+){3}))" // 3rd vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
295 R"(((?:\s+[^\s]+){3}))" // 4th vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
296 R"(\s*$)" // end
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
297 };
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
298 static const QRegExp conditionaledge
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
299 {
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
300 R"(^\s*5)" // starting 5-token
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
301 R"(\s+(\d+))" // colour
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
302 R"(((?:\s+[^\s]+){3}))" // 1st vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
303 R"(((?:\s+[^\s]+){3}))" // 2nd vertex
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
304 R"(((?:\s+[^\s]+){3}))" // 1st control point
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
305 R"(((?:\s+[^\s]+){3}))" // 2nd control point
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
306 R"(\s*$)" // end
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
307 };
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
308 }
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
309 }
68988ebc2a68 added regular expressions for the parser
Teemu Piippo <teemu@hecknology.net>
parents: 3
diff changeset
310
3
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
311 modelobjects::BaseObject* Parser::parseFromString(
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
312 Model::EditContext& editor,
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
313 const QString& line)
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
314 {
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
315 return editor.append<modelobjects::Comment>(line);
55a55a9ec2c2 Added lots of code
Teemu Piippo <teemu@hecknology.net>
parents:
diff changeset
316 }

mercurial