summary refs log tree commit diff stats
path: root/generator/group.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'generator/group.cpp')
-rw-r--r--generator/group.cpp166
1 files changed, 98 insertions, 68 deletions
diff --git a/generator/group.cpp b/generator/group.cpp index cebe2b9..aa28d42 100644 --- a/generator/group.cpp +++ b/generator/group.cpp
@@ -15,12 +15,15 @@ namespace verbly {
15 { 15 {
16 } 16 }
17 17
18 void group::setParent(const group& parent) 18 group::group(const group& parent) :
19 id_(nextId_++),
20 roles_(parent.roles_),
21 roleNames_(parent.roleNames_)
19 { 22 {
20 // Adding a group to itself is nonsensical. 23 for (const frame& f : parent.frames_)
21 assert(&parent != this); 24 {
22 25 frames_.push_back(frame::duplicate(f));
23 parent_ = &parent; 26 }
24 } 27 }
25 28
26 void group::addRole(role r) 29 void group::addRole(role r)
@@ -30,87 +33,114 @@ namespace verbly {
30 roleNames_.insert(std::move(name)); 33 roleNames_.insert(std::move(name));
31 } 34 }
32 35
33 void group::addFrame(const frame& f) 36 void group::addFrame(frame f)
34 { 37 {
35 frames_.insert(&f); 38 frames_.push_back(std::move(f));
36 } 39 }
37 40
38 std::set<std::string> group::getRoles() const 41 bool group::hasRole(std::string name) const
39 { 42 {
40 std::set<std::string> fullRoles = roleNames_; 43 // Rarely, a noun phrase part may use a role that is not defined in the
41 44 // group. See confess-37.10 "NP V NP ADJ".
42 if (hasParent()) 45 return (roles_.count(name) == 1);
43 {
44 for (std::string name : getParent().getRoles())
45 {
46 fullRoles.insert(name);
47 }
48 }
49
50 return fullRoles;
51 } 46 }
52 47
53 const role& group::getRole(std::string name) const 48 const role& group::getRole(std::string name) const
54 { 49 {
55 if (roles_.count(name)) 50 return roles_.at(name);
56 {
57 return roles_.at(name);
58 } else if (hasParent())
59 {
60 return getParent().getRole(name);
61 } else {
62 throw std::invalid_argument("Specified role not found in verb group");
63 }
64 }
65
66 std::set<const frame*> group::getFrames() const
67 {
68 std::set<const frame*> fullFrames = frames_;
69
70 if (hasParent())
71 {
72 for (const frame* f : getParent().getFrames())
73 {
74 fullFrames.insert(f);
75 }
76 }
77
78 return fullFrames;
79 } 51 }
80 52
81 database& operator<<(database& db, const group& arg) 53 database& operator<<(database& db, const group& arg)
82 { 54 {
83 // Serialize the group first 55 // Serialize each frame
56 for (const frame& f : arg.getFrames())
84 { 57 {
85 std::list<field> fields; 58 // First, serialize the group/frame relationship
86 fields.emplace_back("group_id", arg.getId());
87
88 nlohmann::json jsonRoles;
89 for (std::string name : arg.getRoles())
90 { 59 {
91 const role& r = arg.getRole(name); 60 std::list<field> fields;
92 61
93 nlohmann::json jsonRole; 62 fields.emplace_back("frame_id", f.getId());
94 jsonRole["type"] = name; 63 fields.emplace_back("group_id", arg.getId());
95 jsonRole["selrestrs"] = r.getSelrestrs().toJson(); 64 fields.emplace_back("length", f.getLength());
96 65
97 jsonRoles.emplace_back(std::move(jsonRole)); 66 db.insertIntoTable("frames", std::move(fields));
98 } 67 }
99 68
100 fields.emplace_back("data", jsonRoles.dump()); 69 // Then, serialize the frame parts in the context of the group
101 70 for (int partIndex = 0; partIndex < f.getLength(); partIndex++)
102 db.insertIntoTable("groups", std::move(fields)); 71 {
103 } 72 const part& p = f[partIndex];
104 73
105 // Then, serialize the group/frame relationship 74 std::list<field> fields;
106 for (const frame* f : arg.getFrames()) 75 fields.emplace_back("part_id", p.getId());
107 { 76 fields.emplace_back("frame_id", f.getId());
108 std::list<field> fields; 77 fields.emplace_back("part_index", partIndex);
109 78 fields.emplace_back("type", static_cast<int>(p.getType()));
110 fields.emplace_back("group_id", arg.getId()); 79
111 fields.emplace_back("frame_id", f->getId()); 80 switch (p.getType())
112 81 {
113 db.insertIntoTable("groups_frames", std::move(fields)); 82 case part::type::noun_phrase:
83 {
84 fields.emplace_back("role", p.getNounRole());
85
86 selrestr partSelrestr;
87 if (p.getNounSelrestrs().getType() != selrestr::type::empty)
88 {
89 partSelrestr = p.getNounSelrestrs();
90 } else if (arg.hasRole(p.getNounRole()))
91 {
92 partSelrestr = arg.getRole(p.getNounRole()).getSelrestrs();
93 }
94
95 fields.emplace_back("selrestrs", partSelrestr.toJson().dump());
96
97 // Short interlude to serialize the synrestrs
98 for (const std::string& s : p.getNounSynrestrs())
99 {
100 std::list<field> synrestrFields;
101
102 synrestrFields.emplace_back("part_id", p.getId());
103 synrestrFields.emplace_back("synrestr", s);
104
105 db.insertIntoTable("synrestrs", std::move(synrestrFields));
106 }
107
108 break;
109 }
110
111 case part::type::preposition:
112 {
113 fields.emplace_back("prepositions", nlohmann::json(p.getPrepositionChoices()).dump());
114 fields.emplace_back("preposition_literality", p.isPrepositionLiteral() ? 1 : 0);
115
116 break;
117 }
118
119 case part::type::literal:
120 {
121 fields.emplace_back("literal_value", p.getLiteralValue());
122
123 break;
124 }
125
126 case part::type::verb:
127 case part::type::adjective:
128 case part::type::adverb:
129 {
130 break;
131 }
132
133 case part::type::invalid:
134 {
135 // Invalid parts should not be serialized.
136 assert(false);
137
138 break;
139 }
140 }
141
142 db.insertIntoTable("parts", std::move(fields));
143 }
114 } 144 }
115 145
116 return db; 146 return db;