summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-01-23 11:49:51 -0500
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-01-23 11:49:51 -0500
commit9bd863c9002b525b7827f9158d9136143393be5c (patch)
tree6b210e9d55286c93a0f3ddd55d2b10d1efa88e99
parent9e36dbbe74fd9541f0431b7715d3f97895384d28 (diff)
downloadverbly-9bd863c9002b525b7827f9158d9136143393be5c.tar.gz
verbly-9bd863c9002b525b7827f9158d9136143393be5c.tar.bz2
verbly-9bd863c9002b525b7827f9158d9136143393be5c.zip
Added verb frame parsing
-rw-r--r--CMakeLists.txt2
-rw-r--r--lib/frame.cpp89
-rw-r--r--lib/frame.h60
-rw-r--r--lib/frame_query.cpp166
-rw-r--r--lib/frame_query.h21
-rw-r--r--lib/group.cpp44
-rw-r--r--lib/group.h60
-rw-r--r--lib/part.cpp344
-rw-r--r--lib/part.h117
9 files changed, 643 insertions, 260 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 61fcce2..8d42fdd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt
@@ -7,7 +7,7 @@ pkg_check_modules(sqlite3 sqlite3>=3.8.3 REQUIRED)
7set(CMAKE_BUILD_TYPE Debug) 7set(CMAKE_BUILD_TYPE Debug)
8 8
9include_directories(vendor/json) 9include_directories(vendor/json)
10add_library(verbly lib/filter.cpp lib/field.cpp lib/notion.cpp lib/word.cpp lib/group.cpp lib/frame.cpp lib/lemma.cpp lib/form.cpp lib/pronunciation.cpp lib/statement.cpp lib/binding.cpp lib/database.cpp) 10add_library(verbly lib/filter.cpp lib/field.cpp lib/notion.cpp lib/word.cpp lib/group.cpp lib/frame.cpp lib/lemma.cpp lib/form.cpp lib/pronunciation.cpp lib/statement.cpp lib/binding.cpp lib/database.cpp lib/selrestr.cpp lib/part.cpp)
11set_property(TARGET verbly PROPERTY CXX_STANDARD 11) 11set_property(TARGET verbly PROPERTY CXX_STANDARD 11)
12set_property(TARGET verbly PROPERTY CXX_STANDARD_REQUIRED ON) 12set_property(TARGET verbly PROPERTY CXX_STANDARD_REQUIRED ON)
13target_link_libraries(verbly ${sqlite3_LIBRARIES}) 13target_link_libraries(verbly ${sqlite3_LIBRARIES})
diff --git a/lib/frame.cpp b/lib/frame.cpp index bc3f842..3ce95ec 100644 --- a/lib/frame.cpp +++ b/lib/frame.cpp
@@ -1,21 +1,96 @@
1#include "frame.h" 1#include "frame.h"
2#include <sqlite3.h> 2#include <sqlite3.h>
3#include <json.hpp>
3 4
4namespace verbly { 5namespace verbly {
5 6
6 const object frame::objectType = object::frame; 7 const object frame::objectType = object::frame;
7 8
8 const std::list<std::string> frame::select = {"frame_id", "data"}; 9 const std::list<std::string> frame::select = {"frame_id", "data"};
9 10
10 const field frame::id = field::integerField(object::frame, "frame_id"); 11 const field frame::id = field::integerField(object::frame, "frame_id");
11 12
12 const field frame::group = field::joinThrough(object::frame, "frame_id", object::group, "groups_frames", "group_id"); 13 const field frame::group = field::joinThrough(object::frame, "frame_id", object::group, "groups_frames", "group_id");
13 14
14 frame::frame(const database& db, sqlite3_stmt* row) : db_(&db), valid_(true) 15 frame::frame(const database& db, sqlite3_stmt* row) : db_(&db), valid_(true)
15 { 16 {
16 id_ = sqlite3_column_int(row, 0); 17 id_ = sqlite3_column_int(row, 0);
17 18
18 // TODO: Initialize frame data from row. 19 // TODO: Initialize frame data from row.
20 std::string partsJsonStr(reinterpret_cast<const char*>(sqlite3_column_blob(row, 1)));
21 nlohmann::json partsJson = nlohmann::json::parse(std::move(partsJsonStr));
22
23 for (const nlohmann::json& partJson : partsJson)
24 {
25 part::type partType = static_cast<part::type>(partJson["type"].get<int>());
26
27 switch (partType)
28 {
29 case part::type::noun_phrase:
30 {
31 std::set<std::string> synrestrs;
32 for (const nlohmann::json& synrestrJson : partJson["synrestrs"])
33 {
34 synrestrs.insert(synrestrJson.get<std::string>());
35 }
36
37 parts_.push_back(part::createNounPhrase(
38 partJson["role"].get<std::string>(),
39 selrestr(partJson["selrestrs"]),
40 std::move(synrestrs)));
41
42 break;
43 }
44
45 case part::type::preposition:
46 {
47 std::vector<std::string> choices;
48 for (const nlohmann::json& choiceJson : partJson["choices"])
49 {
50 choices.push_back(choiceJson.get<std::string>());
51 }
52
53 parts_.push_back(part::createPreposition(
54 std::move(choices),
55 partJson["literal"].get<bool>()));
56
57 break;
58 }
59
60 case part::type::verb:
61 {
62 parts_.push_back(part::createVerb());
63
64 break;
65 }
66
67 case part::type::adjective:
68 {
69 parts_.push_back(part::createAdjective());
70
71 break;
72 }
73
74 case part::type::adverb:
75 {
76 parts_.push_back(part::createAdverb());
77
78 break;
79 }
80
81 case part::type::literal:
82 {
83 parts_.push_back(part::createLiteral(partJson["value"].get<std::string>()));
84
85 break;
86 }
87
88 case part::type::invalid:
89 {
90 throw std::domain_error("Invalid part data");
91 }
92 }
93 }
19 } 94 }
20 95
21}; 96};
diff --git a/lib/frame.h b/lib/frame.h index 68a4346..97473a0 100644 --- a/lib/frame.h +++ b/lib/frame.h
@@ -5,74 +5,86 @@
5#include <list> 5#include <list>
6#include "field.h" 6#include "field.h"
7#include "filter.h" 7#include "filter.h"
8#include "part.h"
8 9
9struct sqlite3_stmt; 10struct sqlite3_stmt;
10 11
11namespace verbly { 12namespace verbly {
12 13
13 class database; 14 class database;
14 15
15 class frame { 16 class frame {
16 public: 17 public:
17 18
18 // Default constructor 19 // Default constructor
19 20
20 frame() = default; 21 frame() = default;
21 22
22 // Construct from database 23 // Construct from database
23 24
24 frame(const database& db, sqlite3_stmt* row); 25 frame(const database& db, sqlite3_stmt* row);
25 26
26 // Accessors 27 // Accessors
27 28
28 operator bool() const 29 operator bool() const
29 { 30 {
30 return valid_; 31 return valid_;
31 } 32 }
32 33
33 int getId() const 34 int getId() const
34 { 35 {
35 if (!valid_) 36 if (!valid_)
36 { 37 {
37 throw std::domain_error("Bad access to uninitialized frame"); 38 throw std::domain_error("Bad access to uninitialized frame");
38 } 39 }
39 40
40 return id_; 41 return id_;
41 } 42 }
42 43
44 const std::vector<part>& getParts() const
45 {
46 if (!valid_)
47 {
48 throw std::domain_error("Bad access to uninitialized frame");
49 }
50
51 return parts_;
52 }
53
43 // Type info 54 // Type info
44 55
45 static const object objectType; 56 static const object objectType;
46 57
47 static const std::list<std::string> select; 58 static const std::list<std::string> select;
48 59
49 // Query fields 60 // Query fields
50 61
51 static const field id; 62 static const field id;
52 63
53 operator filter() const 64 operator filter() const
54 { 65 {
55 if (!valid_) 66 if (!valid_)
56 { 67 {
57 throw std::domain_error("Bad access to uninitialized frame"); 68 throw std::domain_error("Bad access to uninitialized frame");
58 } 69 }
59 70
60 return (id == id_); 71 return (id == id_);
61 } 72 }
62 73
63 // Relationships to other objects 74 // Relationships to other objects
64 75
65 static const field group; 76 static const field group;
66 77
67 private: 78 private:
68 bool valid_ = false; 79 bool valid_ = false;
69 80
70 int id_; 81 int id_;
71 82 std::vector<part> parts_;
83
72 const database* db_; 84 const database* db_;
73 85
74 }; 86 };
75 87
76}; 88};
77 89
78#endif /* end of include guard: FRAME_H_EA29065A */ 90#endif /* end of include guard: FRAME_H_EA29065A */
diff --git a/lib/frame_query.cpp b/lib/frame_query.cpp deleted file mode 100644 index 11f0432..0000000 --- a/lib/frame_query.cpp +++ /dev/null
@@ -1,166 +0,0 @@
1#include "verbly.h"
2#include <json.hpp>
3
4using json = nlohmann::json;
5
6namespace verbly {
7
8 frame_query::frame_query(const data& _data) : _data(_data)
9 {
10
11 }
12
13 frame_query& frame_query::for_verb(const verb& _v)
14 {
15 _for_verb.push_back(_v);
16
17 return *this;
18 }
19
20 frame::selrestr parse_selrestr(const json data)
21 {
22 if (data.find("children") != data.end())
23 {
24 std::list<frame::selrestr> children;
25 std::transform(std::begin(data["children"]), std::end(data["children"]), std::back_inserter(children), &parse_selrestr);
26
27 return frame::selrestr{children, data["logic"] == "or"};
28 } else if (data.find("type") != data.end())
29 {
30 return frame::selrestr{data["type"].get<std::string>(), data["pos"].get<bool>()};
31 } else {
32 return frame::selrestr{};
33 }
34 }
35
36 std::list<frame> frame_query::run() const
37 {
38 std::stringstream construct;
39 construct << "SELECT frames.data, groups.data FROM frames INNER JOIN groups ON frames.group_id = groups.group_id";
40 std::list<binding> bindings;
41
42 if (!_for_verb.empty())
43 {
44 std::list<std::string> clauses(_for_verb.size(), "verb_id = ?");
45 construct << " WHERE frames.group_id IN (SELECT group_id FROM verb_groups WHERE ";
46 construct << verbly::implode(std::begin(clauses), std::end(clauses), " OR ");
47 construct << ")";
48
49 for (auto v : _for_verb)
50 {
51 bindings.emplace_back(v._id);
52 }
53 }
54
55 sqlite3_stmt* ppstmt;
56 std::string query = construct.str();
57 if (sqlite3_prepare_v2(_data.ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK)
58 {
59 throw std::runtime_error(sqlite3_errmsg(_data.ppdb));
60 }
61
62 int i = 1;
63 for (auto& binding : bindings)
64 {
65 switch (binding.get_type())
66 {
67 case binding::type::integer:
68 {
69 sqlite3_bind_int(ppstmt, i, binding.get_integer());
70
71 break;
72 }
73
74 case binding::type::string:
75 {
76 sqlite3_bind_text(ppstmt, i, binding.get_string().c_str(), binding.get_string().length(), SQLITE_TRANSIENT);
77
78 break;
79 }
80 }
81
82 i++;
83 }
84
85 std::list<frame> output;
86 while (sqlite3_step(ppstmt) == SQLITE_ROW)
87 {
88 frame f;
89
90 std::string fdatat(reinterpret_cast<const char*>(sqlite3_column_blob(ppstmt, 0)));
91 const json fdata = json::parse(fdatat);
92 for (const auto& part : fdata)
93 {
94 frame::part p;
95
96 if (part["type"] == "np")
97 {
98 p._type = frame::part::type::noun_phrase;
99 new(&p._noun_phrase.role) std::string(part["role"].get<std::string>());
100 new(&p._noun_phrase.selrestrs) frame::selrestr(parse_selrestr(part["selrestrs"]));
101 new(&p._noun_phrase.synrestrs) std::set<std::string>();
102 for (auto synrestr : part["synrestrs"])
103 {
104 p._noun_phrase.synrestrs.insert(synrestr.get<std::string>());
105 }
106 } else if (part["type"] == "pp")
107 {
108 if (!part["values"].empty())
109 {
110 p._type = frame::part::type::literal_preposition;
111 new(&p._literal_preposition.choices) std::vector<std::string>();
112 for (auto choice : part["values"])
113 {
114 p._literal_preposition.choices.push_back(choice.get<std::string>());
115 }
116 } else if (!part["preprestrs"].empty())
117 {
118 p._type = frame::part::type::selection_preposition;
119 new(&p._selection_preposition.preprestrs) std::vector<std::string>();
120 for (auto preprestr : part["preprestrs"])
121 {
122 p._selection_preposition.preprestrs.push_back(preprestr.get<std::string>());
123 }
124 }
125 } else if (part["type"] == "v")
126 {
127 p._type = frame::part::type::verb;
128 } else if (part["type"] == "adj")
129 {
130 p._type = frame::part::type::adjective;
131 } else if (part["type"] == "adv")
132 {
133 p._type = frame::part::type::adverb;
134 } else if (part["type"] == "lex")
135 {
136 p._type = frame::part::type::literal;
137 new(&p._literal.lexval) std::string(part["value"].get<std::string>());
138 }
139
140 f._parts.push_back(p);
141 }
142
143 std::string rdatat(reinterpret_cast<const char*>(sqlite3_column_blob(ppstmt, 1)));
144 const json rdata = json::parse(rdatat);
145 for (const auto& role : rdata)
146 {
147 std::string rt = role["type"];
148 frame::selrestr rs;
149
150 if (role.find("selrestrs") != role.end())
151 {
152 rs = parse_selrestr(role["selrestrs"]);
153 }
154
155 f._roles[rt] = rs;
156 }
157
158 output.push_back(f);
159 }
160
161 sqlite3_finalize(ppstmt);
162
163 return output;
164 }
165
166};
diff --git a/lib/frame_query.h b/lib/frame_query.h deleted file mode 100644 index dd11d16..0000000 --- a/lib/frame_query.h +++ /dev/null
@@ -1,21 +0,0 @@
1#ifndef FRAME_QUERY_H_334B9D47
2#define FRAME_QUERY_H_334B9D47
3
4namespace verbly {
5
6 class frame_query {
7 public:
8 frame_query(const data& _data);
9
10 frame_query& for_verb(const verb& _v);
11
12 std::list<frame> run() const;
13
14 private:
15 const data& _data;
16 std::list<verb> _for_verb;
17 };
18
19};
20
21#endif /* end of include guard: FRAME_QUERY_H_334B9D47 */
diff --git a/lib/group.cpp b/lib/group.cpp index 8b6d985..d5790e9 100644 --- a/lib/group.cpp +++ b/lib/group.cpp
@@ -1,43 +1,61 @@
1#include "group.h" 1#include "group.h"
2#include <sqlite3.h> 2#include <sqlite3.h>
3#include "frame.h" 3#include <json.hpp>
4#include "database.h" 4#include "database.h"
5#include "query.h" 5#include "query.h"
6 6
7namespace verbly { 7namespace verbly {
8 8
9 const object group::objectType = object::group; 9 const object group::objectType = object::group;
10 10
11 const std::list<std::string> group::select = {"group_id", "data"}; 11 const std::list<std::string> group::select = {"group_id", "data"};
12 12
13 const field group::id = field::integerField(object::group, "group_id"); 13 const field group::id = field::integerField(object::group, "group_id");
14 14
15 const field group::frame = field::joinThrough(object::group, "group_id", object::frame, "groups_frames", "frame_id"); 15 const field group::frame = field::joinThrough(object::group, "group_id", object::frame, "groups_frames", "frame_id");
16 const field group::word = field::joinField(object::group, "group_id", object::word); 16 const field group::word = field::joinField(object::group, "group_id", object::word);
17 17
18 group::group(const database& db, sqlite3_stmt* row) : db_(&db), valid_(true) 18 group::group(const database& db, sqlite3_stmt* row) : db_(&db), valid_(true)
19 { 19 {
20 id_ = sqlite3_column_int(row, 0); 20 id_ = sqlite3_column_int(row, 0);
21 21
22 // TODO: Initialize role data from row. 22 std::string rolesJsonStr(reinterpret_cast<const char*>(sqlite3_column_blob(row, 1)));
23 nlohmann::json rolesJson = nlohmann::json::parse(std::move(rolesJsonStr));
24 for (const nlohmann::json& roleJson : rolesJson)
25 {
26 std::string roleName = roleJson["type"];
27 selrestr roleSelrestr;
28
29 if (roleJson.find("selrestrs") != roleJson.end())
30 {
31 roleSelrestr = selrestr(roleJson["selrestrs"]);
32 }
33
34 roles_[roleName] = role(roleName, std::move(roleSelrestr));
35 }
23 } 36 }
24 37
25 const std::vector<frame>& group::getFrames() const 38 const std::vector<frame>& group::getFrames() const
26 { 39 {
27 if (!valid_) 40 if (!valid_)
28 { 41 {
29 throw std::domain_error("Bad access to uninitialized group"); 42 throw std::domain_error("Bad access to uninitialized group");
30 } 43 }
31 44
32 if (!initializedFrames_) 45 if (!initializedFrames_)
33 { 46 {
34 frames_ = db_->frames(frame::group %= *this, false, -1).all(); 47 frames_ = db_->frames(frame::group %= *this, false, -1).all();
35 48
36 initializedFrames_ = true; 49 initializedFrames_ = true;
37 } 50 }
38 51
39 return frames_; 52 return frames_;
40 } 53 }
41 54
55 const role& group::getRole(std::string roleName) const
56 {
57 return roles_.at(roleName);
58 }
59
42}; 60};
43 61
diff --git a/lib/group.h b/lib/group.h index dd53503..fe62d39 100644 --- a/lib/group.h +++ b/lib/group.h
@@ -6,82 +6,86 @@
6#include <vector> 6#include <vector>
7#include "field.h" 7#include "field.h"
8#include "filter.h" 8#include "filter.h"
9#include "frame.h"
10#include "role.h"
9 11
10struct sqlite3_stmt; 12struct sqlite3_stmt;
11 13
12namespace verbly { 14namespace verbly {
13 15
14 class database; 16 class database;
15 class frame; 17
16
17 class group { 18 class group {
18 public: 19 public:
19 20
20 // Default constructor 21 // Default constructor
21 22
22 group() = default; 23 group() = default;
23 24
24 // Construct from database 25 // Construct from database
25 26
26 group(const database& db, sqlite3_stmt* row); 27 group(const database& db, sqlite3_stmt* row);
27 28
28 // Accessors 29 // Accessors
29 30
30 operator bool() const 31 operator bool() const
31 { 32 {
32 return valid_; 33 return valid_;
33 } 34 }
34 35
35 int getId() const 36 int getId() const
36 { 37 {
37 if (!valid_) 38 if (!valid_)
38 { 39 {
39 throw std::domain_error("Bad access to uninitialized group"); 40 throw std::domain_error("Bad access to uninitialized group");
40 } 41 }
41 42
42 return id_; 43 return id_;
43 } 44 }
44 45
45 const std::vector<frame>& getFrames() const; 46 const std::vector<frame>& getFrames() const;
46 47
48 const role& getRole(std::string roleName) const;
49
47 // Type info 50 // Type info
48 51
49 static const object objectType; 52 static const object objectType;
50 53
51 static const std::list<std::string> select; 54 static const std::list<std::string> select;
52 55
53 // Query fields 56 // Query fields
54 57
55 static const field id; 58 static const field id;
56 59
57 operator filter() const 60 operator filter() const
58 { 61 {
59 if (!valid_) 62 if (!valid_)
60 { 63 {
61 throw std::domain_error("Bad access to uninitialized group"); 64 throw std::domain_error("Bad access to uninitialized group");
62 } 65 }
63 66
64 return (id == id_); 67 return (id == id_);
65 } 68 }
66 69
67 // Relationships to other objects 70 // Relationships to other objects
68 71
69 static const field frame; 72 static const field frame;
70 73
71 static const field word; 74 static const field word;
72 75
73 private: 76 private:
74 bool valid_ = false; 77 bool valid_ = false;
75 78
76 int id_; 79 int id_;
77 80 std::map<std::string, role> roles_;
81
78 const database* db_; 82 const database* db_;
79 83
80 mutable bool initializedFrames_ = false; 84 mutable bool initializedFrames_ = false;
81 mutable std::vector<class frame> frames_; 85 mutable std::vector<class frame> frames_;
82 86
83 }; 87 };
84 88
85}; 89};
86 90
87#endif /* end of include guard: GROUP_H_BD6933C0 */ 91#endif /* end of include guard: GROUP_H_BD6933C0 */
diff --git a/lib/part.cpp b/lib/part.cpp new file mode 100644 index 0000000..e66d151 --- /dev/null +++ b/lib/part.cpp
@@ -0,0 +1,344 @@
1#include "part.h"
2#include <stdexcept>
3#include "selrestr.h"
4
5namespace verbly {
6
7 part part::createNounPhrase(std::string role, selrestr selrestrs, std::set<std::string> synrestrs)
8 {
9 part p(type::noun_phrase);
10
11 new(&p.noun_phrase_.role) std::string(std::move(role));
12 new(&p.noun_phrase_.selrestrs) selrestr(std::move(selrestrs));
13 new(&p.noun_phrase_.synrestrs) std::set<std::string>(std::move(synrestrs));
14
15 return p;
16 }
17
18 part part::createVerb()
19 {
20 return part(type::verb);
21 }
22
23 part part::createPreposition(std::vector<std::string> choices, bool literal)
24 {
25 part p(type::preposition);
26
27 new(&p.preposition_.choices) std::vector<std::string>(std::move(choices));
28 p.preposition_.literal = literal;
29
30 return p;
31 }
32
33 part part::createAdjective()
34 {
35 return part(type::adjective);
36 }
37
38 part part::createAdverb()
39 {
40 return part(type::adverb);
41 }
42
43 part part::createLiteral(std::string value)
44 {
45 part p(type::literal);
46
47 new(&p.literal_) std::string(std::move(value));
48
49 return p;
50 }
51
52 part::part(const part& other)
53 {
54 type_ = other.type_;
55
56 switch (type_)
57 {
58 case type::noun_phrase:
59 {
60 new(&noun_phrase_.role) std::string(other.noun_phrase_.role);
61 new(&noun_phrase_.selrestrs) selrestr(other.noun_phrase_.selrestrs);
62 new(&noun_phrase_.synrestrs) std::set<std::string>(other.noun_phrase_.synrestrs);
63
64 break;
65 }
66
67 case type::preposition:
68 {
69 new(&preposition_.choices) std::vector<std::string>(other.preposition_.choices);
70 preposition_.literal = other.preposition_.literal;
71
72 break;
73 }
74
75 case type::literal:
76 {
77 new(&literal_) std::string(other.literal_);
78
79 break;
80 }
81
82 case type::verb:
83 case type::adjective:
84 case type::adverb:
85 case type::invalid:
86 {
87 break;
88 }
89 }
90 }
91
92 part::part(part&& other) : part()
93 {
94 swap(*this, other);
95 }
96
97 part& part::operator=(part other)
98 {
99 swap(*this, other);
100
101 return *this;
102 }
103
104 void swap(part& first, part& second)
105 {
106 using type = part::type;
107
108 type tempType = first.type_;
109 std::string tempRole;
110 selrestr tempSelrestrs;
111 std::set<std::string> tempSynrestrs;
112 std::vector<std::string> tempChoices;
113 bool tempPrepLiteral;
114 std::string tempLiteralValue;
115
116 switch (tempType)
117 {
118 case type::noun_phrase:
119 {
120 tempRole = std::move(first.noun_phrase_.role);
121 tempSelrestrs = std::move(first.noun_phrase_.selrestrs);
122 tempSynrestrs = std::move(first.noun_phrase_.synrestrs);
123
124 break;
125 }
126
127 case type::preposition:
128 {
129 tempChoices = std::move(first.preposition_.choices);
130 tempPrepLiteral = first.preposition_.literal;
131
132 break;
133 }
134
135 case type::literal:
136 {
137 tempLiteralValue = std::move(first.literal_);
138
139 break;
140 }
141
142 case type::verb:
143 case type::adjective:
144 case type::adverb:
145 case type::invalid:
146 {
147 break;
148 }
149 }
150
151 first.~part();
152
153 first.type_ = second.type_;
154
155 switch (first.type_)
156 {
157 case type::noun_phrase:
158 {
159 new(&first.noun_phrase_.role) std::string(std::move(second.noun_phrase_.role));
160 new(&first.noun_phrase_.selrestrs) selrestr(std::move(second.noun_phrase_.selrestrs));
161 new(&first.noun_phrase_.synrestrs) std::set<std::string>(std::move(second.noun_phrase_.synrestrs));
162
163 break;
164 }
165
166 case type::preposition:
167 {
168 new(&first.preposition_.choices) std::vector<std::string>(std::move(second.preposition_.choices));
169 first.preposition_.literal = second.preposition_.literal;
170
171 break;
172 }
173
174 case type::literal:
175 {
176 new(&first.literal_) std::string(std::move(second.literal_));
177
178 break;
179 }
180
181 case type::verb:
182 case type::adjective:
183 case type::adverb:
184 case type::invalid:
185 {
186 break;
187 }
188 }
189
190 second.~part();
191
192 second.type_ = tempType;
193
194 switch (second.type_)
195 {
196 case type::noun_phrase:
197 {
198 new(&second.noun_phrase_.role) std::string(std::move(tempRole));
199 new(&second.noun_phrase_.selrestrs) selrestr(std::move(tempSelrestrs));
200 new(&second.noun_phrase_.synrestrs) std::set<std::string>(std::move(tempSynrestrs));
201
202 break;
203 }
204
205 case type::preposition:
206 {
207 new(&second.preposition_.choices) std::vector<std::string>(std::move(tempChoices));
208 second.preposition_.literal = tempPrepLiteral;
209
210 break;
211 }
212
213 case type::literal:
214 {
215 new(&second.literal_) std::string(std::move(tempLiteralValue));
216
217 break;
218 }
219
220 case type::verb:
221 case type::adjective:
222 case type::adverb:
223 case type::invalid:
224 {
225 break;
226 }
227 }
228 }
229
230 part::~part()
231 {
232 switch (type_)
233 {
234 case type::noun_phrase:
235 {
236 using string_type = std::string;
237 using set_type = std::set<std::string>;
238
239 noun_phrase_.role.~string_type();
240 noun_phrase_.selrestrs.~selrestr();
241 noun_phrase_.synrestrs.~set_type();
242
243 break;
244 }
245
246 case type::preposition:
247 {
248 using vector_type = std::vector<std::string>;
249
250 preposition_.choices.~vector_type();
251
252 break;
253 }
254
255 case type::literal:
256 {
257 using string_type = std::string;
258
259 literal_.~string_type();
260
261 break;
262 }
263
264 case type::verb:
265 case type::adjective:
266 case type::adverb:
267 case type::invalid:
268 {
269 break;
270 }
271 }
272 }
273
274 std::string part::getNounRole() const
275 {
276 if (type_ == type::noun_phrase)
277 {
278 return noun_phrase_.role;
279 } else {
280 throw std::domain_error("part::getNounRole is only valid for noun phrase parts");
281 }
282 }
283
284 selrestr part::getNounSelrestrs() const
285 {
286 if (type_ == type::noun_phrase)
287 {
288 return noun_phrase_.selrestrs;
289 } else {
290 throw std::domain_error("part::getNounSelrestrs is only valid for noun phrase parts");
291 }
292 }
293
294 std::set<std::string> part::getNounSynrestrs() const
295 {
296 if (type_ == type::noun_phrase)
297 {
298 return noun_phrase_.synrestrs;
299 } else {
300 throw std::domain_error("part::getNounSynrestrs is only valid for noun phrase parts");
301 }
302 }
303
304 bool part::nounHasSynrestr(std::string synrestr) const
305 {
306 if (type_ != type::noun_phrase)
307 {
308 throw std::domain_error("part::nounHasSynrestr is only valid for noun phrase parts");
309 }
310
311 return (noun_phrase_.synrestrs.count(synrestr) == 1);
312 }
313
314 std::vector<std::string> part::getPrepositionChoices() const
315 {
316 if (type_ == type::preposition)
317 {
318 return preposition_.choices;
319 } else {
320 throw std::domain_error("part::getPrepositionChoices is only valid for preposition parts");
321 }
322 }
323
324 bool part::isPrepositionLiteral() const
325 {
326 if (type_ == type::preposition)
327 {
328 return preposition_.literal;
329 } else {
330 throw std::domain_error("part::isPrepositionLiteral is only valid for preposition parts");
331 }
332 }
333
334 std::string part::getLiteralValue() const
335 {
336 if (type_ == type::literal)
337 {
338 return literal_;
339 } else {
340 throw std::domain_error("part::getLiteralValue is only valid for literal parts");
341 }
342 }
343
344};
diff --git a/lib/part.h b/lib/part.h new file mode 100644 index 0000000..3a15638 --- /dev/null +++ b/lib/part.h
@@ -0,0 +1,117 @@
1#ifndef PART_H_C8F0661B
2#define PART_H_C8F0661B
3
4#include <string>
5#include <vector>
6#include <set>
7#include "selrestr.h"
8
9namespace verbly {
10
11 class part {
12 public:
13 enum class type {
14 invalid = -1,
15 noun_phrase = 0,
16 verb = 1,
17 preposition = 2,
18 adjective = 3,
19 adverb = 4,
20 literal = 5
21 };
22
23 // Static factories
24
25 static part createNounPhrase(std::string role, selrestr selrestrs, std::set<std::string> synrestrs);
26
27 static part createVerb();
28
29 static part createPreposition(std::vector<std::string> choices, bool literal);
30
31 static part createAdjective();
32
33 static part createAdverb();
34
35 static part createLiteral(std::string value);
36
37 // Default constructor
38
39 part()
40 {
41 }
42
43 // Copy and move constructors
44
45 part(const part& other);
46
47 part(part&& other);
48
49 // Assignment
50
51 part& operator=(part other);
52
53 // Swap
54
55 friend void swap(part& first, part& second);
56
57 // Destructor
58
59 ~part();
60
61 // General accessors
62
63 type getType() const
64 {
65 return type_;
66 }
67
68 // Noun phrase accessors
69
70 std::string getNounRole() const;
71
72 selrestr getNounSelrestrs() const;
73
74 std::set<std::string> getNounSynrestrs() const;
75
76 bool nounHasSynrestr(std::string synrestr) const;
77
78 // Preposition accessors
79
80 std::vector<std::string> getPrepositionChoices() const;
81
82 bool isPrepositionLiteral() const;
83
84 // Literal accessors
85
86 std::string getLiteralValue() const;
87
88 private:
89
90 // Private constructors
91
92 part(type t) : type_(t)
93 {
94 }
95
96 // Data
97
98 union {
99 struct {
100 std::string role;
101 selrestr selrestrs;
102 std::set<std::string> synrestrs;
103 } noun_phrase_;
104 struct {
105 std::vector<std::string> choices;
106 bool literal;
107 } preposition_;
108 std::string literal_;
109 };
110
111 type type_ = type::invalid;
112
113 };
114
115};
116
117#endif /* end of include guard: PART_H_C8F0661B */