diff options
-rw-r--r-- | generator/CMakeLists.txt | 2 | ||||
-rw-r--r-- | generator/part.cpp | 305 | ||||
-rw-r--r-- | generator/part.h | 88 |
3 files changed, 74 insertions, 321 deletions
diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index 8c070d2..5d2f977 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt | |||
@@ -11,6 +11,6 @@ include_directories( | |||
11 | ../vendor/hkutil) | 11 | ../vendor/hkutil) |
12 | 12 | ||
13 | add_executable(generator notion.cpp word.cpp lemma.cpp form.cpp pronunciation.cpp group.cpp frame.cpp part.cpp generator.cpp main.cpp) | 13 | add_executable(generator notion.cpp word.cpp lemma.cpp form.cpp pronunciation.cpp group.cpp frame.cpp part.cpp generator.cpp main.cpp) |
14 | set_property(TARGET generator PROPERTY CXX_STANDARD 11) | 14 | set_property(TARGET generator PROPERTY CXX_STANDARD 17) |
15 | set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON) | 15 | set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON) |
16 | target_link_libraries(generator ${sqlite3_LIBRARIES} ${LIBXML2_LIBRARIES}) | 16 | target_link_libraries(generator ${sqlite3_LIBRARIES} ${LIBXML2_LIBRARIES}) |
diff --git a/generator/part.cpp b/generator/part.cpp index d3e6656..c354a07 100644 --- a/generator/part.cpp +++ b/generator/part.cpp | |||
@@ -8,13 +8,11 @@ namespace verbly { | |||
8 | 8 | ||
9 | part part::createNounPhrase(std::string role, std::set<std::string> selrestrs, std::set<std::string> synrestrs) | 9 | part part::createNounPhrase(std::string role, std::set<std::string> selrestrs, std::set<std::string> synrestrs) |
10 | { | 10 | { |
11 | part p(type::noun_phrase); | 11 | return part(type::noun_phrase, noun_phrase_type { |
12 | 12 | .role = std::move(role), | |
13 | new(&p.noun_phrase_.role) std::string(std::move(role)); | 13 | .selrestrs = std::move(selrestrs), |
14 | new(&p.noun_phrase_.selrestrs) std::set<std::string>(std::move(selrestrs)); | 14 | .synrestrs = std::move(synrestrs) |
15 | new(&p.noun_phrase_.synrestrs) std::set<std::string>(std::move(synrestrs)); | 15 | }); |
16 | |||
17 | return p; | ||
18 | } | 16 | } |
19 | 17 | ||
20 | part part::createVerb() | 18 | part part::createVerb() |
@@ -24,12 +22,10 @@ namespace verbly { | |||
24 | 22 | ||
25 | part part::createPreposition(std::set<std::string> choices, bool literal) | 23 | part part::createPreposition(std::set<std::string> choices, bool literal) |
26 | { | 24 | { |
27 | part p(type::preposition); | 25 | return part(type::preposition, preposition_type { |
28 | 26 | .choices = std::move(choices), | |
29 | new(&p.preposition_.choices) std::set<std::string>(std::move(choices)); | 27 | .literal = literal |
30 | p.preposition_.literal = literal; | 28 | }); |
31 | |||
32 | return p; | ||
33 | } | 29 | } |
34 | 30 | ||
35 | part part::createAdjective() | 31 | part part::createAdjective() |
@@ -44,286 +40,19 @@ namespace verbly { | |||
44 | 40 | ||
45 | part part::createLiteral(std::string value) | 41 | part part::createLiteral(std::string value) |
46 | { | 42 | { |
47 | part p(type::literal); | 43 | return part(type::literal, std::move(value)); |
48 | |||
49 | new(&p.literal_) std::string(std::move(value)); | ||
50 | |||
51 | return p; | ||
52 | } | 44 | } |
53 | 45 | ||
54 | part part::duplicate(const part& other) | 46 | part part::duplicate(const part& other) |
55 | { | 47 | { |
56 | part result(other.type_); | 48 | return part(other.type_, other.variant_); |
57 | |||
58 | switch (result.type_) | ||
59 | { | ||
60 | case type::noun_phrase: | ||
61 | { | ||
62 | new(&result.noun_phrase_.role) std::string(other.noun_phrase_.role); | ||
63 | new(&result.noun_phrase_.selrestrs) std::set<std::string>(other.noun_phrase_.selrestrs); | ||
64 | new(&result.noun_phrase_.synrestrs) std::set<std::string>(other.noun_phrase_.synrestrs); | ||
65 | |||
66 | break; | ||
67 | } | ||
68 | |||
69 | case type::preposition: | ||
70 | { | ||
71 | new(&result.preposition_.choices) std::set<std::string>(other.preposition_.choices); | ||
72 | result.preposition_.literal = other.preposition_.literal; | ||
73 | |||
74 | break; | ||
75 | } | ||
76 | |||
77 | case type::literal: | ||
78 | { | ||
79 | new(&result.literal_) std::string(other.literal_); | ||
80 | |||
81 | break; | ||
82 | } | ||
83 | |||
84 | case type::verb: | ||
85 | case type::adjective: | ||
86 | case type::adverb: | ||
87 | case type::invalid: | ||
88 | { | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | return result; | ||
94 | } | ||
95 | |||
96 | part::part(const part& other) | ||
97 | { | ||
98 | type_ = other.type_; | ||
99 | id_ = other.id_; | ||
100 | |||
101 | switch (type_) | ||
102 | { | ||
103 | case type::noun_phrase: | ||
104 | { | ||
105 | new(&noun_phrase_.role) std::string(other.noun_phrase_.role); | ||
106 | new(&noun_phrase_.selrestrs) std::set<std::string>(other.noun_phrase_.selrestrs); | ||
107 | new(&noun_phrase_.synrestrs) std::set<std::string>(other.noun_phrase_.synrestrs); | ||
108 | |||
109 | break; | ||
110 | } | ||
111 | |||
112 | case type::preposition: | ||
113 | { | ||
114 | new(&preposition_.choices) std::set<std::string>(other.preposition_.choices); | ||
115 | preposition_.literal = other.preposition_.literal; | ||
116 | |||
117 | break; | ||
118 | } | ||
119 | |||
120 | case type::literal: | ||
121 | { | ||
122 | new(&literal_) std::string(other.literal_); | ||
123 | |||
124 | break; | ||
125 | } | ||
126 | |||
127 | case type::verb: | ||
128 | case type::adjective: | ||
129 | case type::adverb: | ||
130 | case type::invalid: | ||
131 | { | ||
132 | break; | ||
133 | } | ||
134 | } | ||
135 | } | ||
136 | |||
137 | part::part(part&& other) : part() | ||
138 | { | ||
139 | swap(*this, other); | ||
140 | } | ||
141 | |||
142 | part& part::operator=(part other) | ||
143 | { | ||
144 | swap(*this, other); | ||
145 | |||
146 | return *this; | ||
147 | } | ||
148 | |||
149 | void swap(part& first, part& second) | ||
150 | { | ||
151 | using type = part::type; | ||
152 | |||
153 | type tempType = first.type_; | ||
154 | int tempId = first.id_; | ||
155 | std::string tempRole; | ||
156 | std::set<std::string> tempSelrestrs; | ||
157 | std::set<std::string> tempSynrestrs; | ||
158 | std::set<std::string> tempChoices; | ||
159 | bool tempPrepLiteral; | ||
160 | std::string tempLiteralValue; | ||
161 | |||
162 | switch (tempType) | ||
163 | { | ||
164 | case type::noun_phrase: | ||
165 | { | ||
166 | tempRole = std::move(first.noun_phrase_.role); | ||
167 | tempSelrestrs = std::move(first.noun_phrase_.selrestrs); | ||
168 | tempSynrestrs = std::move(first.noun_phrase_.synrestrs); | ||
169 | |||
170 | break; | ||
171 | } | ||
172 | |||
173 | case type::preposition: | ||
174 | { | ||
175 | tempChoices = std::move(first.preposition_.choices); | ||
176 | tempPrepLiteral = first.preposition_.literal; | ||
177 | |||
178 | break; | ||
179 | } | ||
180 | |||
181 | case type::literal: | ||
182 | { | ||
183 | tempLiteralValue = std::move(first.literal_); | ||
184 | |||
185 | break; | ||
186 | } | ||
187 | |||
188 | case type::verb: | ||
189 | case type::adjective: | ||
190 | case type::adverb: | ||
191 | case type::invalid: | ||
192 | { | ||
193 | break; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | first.~part(); | ||
198 | |||
199 | first.type_ = second.type_; | ||
200 | first.id_ = second.id_; | ||
201 | |||
202 | switch (first.type_) | ||
203 | { | ||
204 | case type::noun_phrase: | ||
205 | { | ||
206 | new(&first.noun_phrase_.role) std::string(std::move(second.noun_phrase_.role)); | ||
207 | new(&first.noun_phrase_.selrestrs) std::set<std::string>(std::move(second.noun_phrase_.selrestrs)); | ||
208 | new(&first.noun_phrase_.synrestrs) std::set<std::string>(std::move(second.noun_phrase_.synrestrs)); | ||
209 | |||
210 | break; | ||
211 | } | ||
212 | |||
213 | case type::preposition: | ||
214 | { | ||
215 | new(&first.preposition_.choices) std::set<std::string>(std::move(second.preposition_.choices)); | ||
216 | first.preposition_.literal = second.preposition_.literal; | ||
217 | |||
218 | break; | ||
219 | } | ||
220 | |||
221 | case type::literal: | ||
222 | { | ||
223 | new(&first.literal_) std::string(std::move(second.literal_)); | ||
224 | |||
225 | break; | ||
226 | } | ||
227 | |||
228 | case type::verb: | ||
229 | case type::adjective: | ||
230 | case type::adverb: | ||
231 | case type::invalid: | ||
232 | { | ||
233 | break; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | second.~part(); | ||
238 | |||
239 | second.type_ = tempType; | ||
240 | second.id_ = tempId; | ||
241 | |||
242 | switch (second.type_) | ||
243 | { | ||
244 | case type::noun_phrase: | ||
245 | { | ||
246 | new(&second.noun_phrase_.role) std::string(std::move(tempRole)); | ||
247 | new(&second.noun_phrase_.selrestrs) std::set<std::string>(std::move(tempSelrestrs)); | ||
248 | new(&second.noun_phrase_.synrestrs) std::set<std::string>(std::move(tempSynrestrs)); | ||
249 | |||
250 | break; | ||
251 | } | ||
252 | |||
253 | case type::preposition: | ||
254 | { | ||
255 | new(&second.preposition_.choices) std::set<std::string>(std::move(tempChoices)); | ||
256 | second.preposition_.literal = tempPrepLiteral; | ||
257 | |||
258 | break; | ||
259 | } | ||
260 | |||
261 | case type::literal: | ||
262 | { | ||
263 | new(&second.literal_) std::string(std::move(tempLiteralValue)); | ||
264 | |||
265 | break; | ||
266 | } | ||
267 | |||
268 | case type::verb: | ||
269 | case type::adjective: | ||
270 | case type::adverb: | ||
271 | case type::invalid: | ||
272 | { | ||
273 | break; | ||
274 | } | ||
275 | } | ||
276 | } | ||
277 | |||
278 | part::~part() | ||
279 | { | ||
280 | switch (type_) | ||
281 | { | ||
282 | case type::noun_phrase: | ||
283 | { | ||
284 | using string_type = std::string; | ||
285 | using set_type = std::set<std::string>; | ||
286 | |||
287 | noun_phrase_.role.~string_type(); | ||
288 | noun_phrase_.selrestrs.~set_type(); | ||
289 | noun_phrase_.synrestrs.~set_type(); | ||
290 | |||
291 | break; | ||
292 | } | ||
293 | |||
294 | case type::preposition: | ||
295 | { | ||
296 | using set_type = std::set<std::string>; | ||
297 | |||
298 | preposition_.choices.~set_type(); | ||
299 | |||
300 | break; | ||
301 | } | ||
302 | |||
303 | case type::literal: | ||
304 | { | ||
305 | using string_type = std::string; | ||
306 | |||
307 | literal_.~string_type(); | ||
308 | |||
309 | break; | ||
310 | } | ||
311 | |||
312 | case type::verb: | ||
313 | case type::adjective: | ||
314 | case type::adverb: | ||
315 | case type::invalid: | ||
316 | { | ||
317 | break; | ||
318 | } | ||
319 | } | ||
320 | } | 49 | } |
321 | 50 | ||
322 | std::string part::getNounRole() const | 51 | std::string part::getNounRole() const |
323 | { | 52 | { |
324 | if (type_ == type::noun_phrase) | 53 | if (type_ == type::noun_phrase) |
325 | { | 54 | { |
326 | return noun_phrase_.role; | 55 | return std::get<noun_phrase_type>(variant_).role; |
327 | } else { | 56 | } else { |
328 | throw std::domain_error("part::getNounRole is only valid for noun phrase parts"); | 57 | throw std::domain_error("part::getNounRole is only valid for noun phrase parts"); |
329 | } | 58 | } |
@@ -333,7 +62,7 @@ namespace verbly { | |||
333 | { | 62 | { |
334 | if (type_ == type::noun_phrase) | 63 | if (type_ == type::noun_phrase) |
335 | { | 64 | { |
336 | return noun_phrase_.selrestrs; | 65 | return std::get<noun_phrase_type>(variant_).selrestrs; |
337 | } else { | 66 | } else { |
338 | throw std::domain_error("part::getNounSelrestrs is only valid for noun phrase parts"); | 67 | throw std::domain_error("part::getNounSelrestrs is only valid for noun phrase parts"); |
339 | } | 68 | } |
@@ -343,7 +72,7 @@ namespace verbly { | |||
343 | { | 72 | { |
344 | if (type_ == type::noun_phrase) | 73 | if (type_ == type::noun_phrase) |
345 | { | 74 | { |
346 | return noun_phrase_.synrestrs; | 75 | return std::get<noun_phrase_type>(variant_).synrestrs; |
347 | } else { | 76 | } else { |
348 | throw std::domain_error("part::getNounSynrestrs is only valid for noun phrase parts"); | 77 | throw std::domain_error("part::getNounSynrestrs is only valid for noun phrase parts"); |
349 | } | 78 | } |
@@ -353,7 +82,7 @@ namespace verbly { | |||
353 | { | 82 | { |
354 | if (type_ == type::preposition) | 83 | if (type_ == type::preposition) |
355 | { | 84 | { |
356 | return preposition_.choices; | 85 | return std::get<preposition_type>(variant_).choices; |
357 | } else { | 86 | } else { |
358 | throw std::domain_error("part::getPrepositionChoices is only valid for preposition parts"); | 87 | throw std::domain_error("part::getPrepositionChoices is only valid for preposition parts"); |
359 | } | 88 | } |
@@ -363,7 +92,7 @@ namespace verbly { | |||
363 | { | 92 | { |
364 | if (type_ == type::preposition) | 93 | if (type_ == type::preposition) |
365 | { | 94 | { |
366 | return preposition_.literal; | 95 | return std::get<preposition_type>(variant_).literal; |
367 | } else { | 96 | } else { |
368 | throw std::domain_error("part::isPrepositionLiteral is only valid for preposition parts"); | 97 | throw std::domain_error("part::isPrepositionLiteral is only valid for preposition parts"); |
369 | } | 98 | } |
@@ -373,7 +102,7 @@ namespace verbly { | |||
373 | { | 102 | { |
374 | if (type_ == type::literal) | 103 | if (type_ == type::literal) |
375 | { | 104 | { |
376 | return literal_; | 105 | return std::get<literal_type>(variant_); |
377 | } else { | 106 | } else { |
378 | throw std::domain_error("part::getLiteralValue is only valid for literal parts"); | 107 | throw std::domain_error("part::getLiteralValue is only valid for literal parts"); |
379 | } | 108 | } |
diff --git a/generator/part.h b/generator/part.h index 01791f5..550f95f 100644 --- a/generator/part.h +++ b/generator/part.h | |||
@@ -3,6 +3,7 @@ | |||
3 | 3 | ||
4 | #include <string> | 4 | #include <string> |
5 | #include <set> | 5 | #include <set> |
6 | #include <variant> | ||
6 | #include "../lib/enums.h" | 7 | #include "../lib/enums.h" |
7 | 8 | ||
8 | namespace verbly { | 9 | namespace verbly { |
@@ -32,24 +33,6 @@ namespace verbly { | |||
32 | 33 | ||
33 | static part duplicate(const part& other); | 34 | static part duplicate(const part& other); |
34 | 35 | ||
35 | // Copy and move constructors | ||
36 | |||
37 | part(const part& other); | ||
38 | |||
39 | part(part&& other); | ||
40 | |||
41 | // Assignment | ||
42 | |||
43 | part& operator=(part other); | ||
44 | |||
45 | // Swap | ||
46 | |||
47 | friend void swap(part& first, part& second); | ||
48 | |||
49 | // Destructor | ||
50 | |||
51 | ~part(); | ||
52 | |||
53 | // General accessors | 36 | // General accessors |
54 | 37 | ||
55 | int getId() const | 38 | int getId() const |
@@ -82,6 +65,26 @@ namespace verbly { | |||
82 | 65 | ||
83 | private: | 66 | private: |
84 | 67 | ||
68 | struct noun_phrase_type { | ||
69 | std::string role; | ||
70 | std::set<std::string> selrestrs; | ||
71 | std::set<std::string> synrestrs; | ||
72 | }; | ||
73 | |||
74 | struct preposition_type { | ||
75 | std::set<std::string> choices; | ||
76 | bool literal; | ||
77 | }; | ||
78 | |||
79 | using literal_type = std::string; | ||
80 | |||
81 | using variant_type = | ||
82 | std::variant< | ||
83 | std::monostate, | ||
84 | noun_phrase_type, | ||
85 | preposition_type, | ||
86 | literal_type>; | ||
87 | |||
85 | static int nextId_; | 88 | static int nextId_; |
86 | 89 | ||
87 | int id_; | 90 | int id_; |
@@ -92,26 +95,47 @@ namespace verbly { | |||
92 | { | 95 | { |
93 | } | 96 | } |
94 | 97 | ||
95 | part(type t) : | 98 | part(type t, variant_type variant = {}) : |
96 | id_(nextId_++), | 99 | id_(nextId_++), |
97 | type_(t) | 100 | type_(t), |
101 | variant_(std::move(variant)) | ||
98 | { | 102 | { |
103 | bool valid_type = false; | ||
104 | switch (type_) | ||
105 | { | ||
106 | case part_type::noun_phrase: | ||
107 | { | ||
108 | valid_type = std::holds_alternative<noun_phrase_type>(variant_); | ||
109 | break; | ||
110 | } | ||
111 | case part_type::preposition: | ||
112 | { | ||
113 | valid_type = std::holds_alternative<preposition_type>(variant_); | ||
114 | break; | ||
115 | } | ||
116 | case part_type::literal: | ||
117 | { | ||
118 | valid_type = std::holds_alternative<literal_type>(variant_); | ||
119 | break; | ||
120 | } | ||
121 | case part_type::invalid: | ||
122 | case part_type::verb: | ||
123 | case part_type::adjective: | ||
124 | case part_type::adverb: | ||
125 | { | ||
126 | valid_type = std::holds_alternative<std::monostate>(variant_); | ||
127 | break; | ||
128 | } | ||
129 | } | ||
130 | if (!valid_type) | ||
131 | { | ||
132 | throw std::invalid_argument("Invalid variant provided for part"); | ||
133 | } | ||
99 | } | 134 | } |
100 | 135 | ||
101 | // Data | 136 | // Data |
102 | 137 | ||
103 | union { | 138 | variant_type variant_; |
104 | struct { | ||
105 | std::string role; | ||
106 | std::set<std::string> selrestrs; | ||
107 | std::set<std::string> synrestrs; | ||
108 | } noun_phrase_; | ||
109 | struct { | ||
110 | std::set<std::string> choices; | ||
111 | bool literal; | ||
112 | } preposition_; | ||
113 | std::string literal_; | ||
114 | }; | ||
115 | 139 | ||
116 | type type_ = type::invalid; | 140 | type type_ = type::invalid; |
117 | 141 | ||