-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpetrovich.h
157 lines (144 loc) · 5.3 KB
/
petrovich.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* Ñêëîíåíèå ïàäåæåé ðóññêèõ èì¸í ôàìèëèé è îò÷åñòâ. Âû çàäà¸òå íà÷àëüíîå èìÿ
* â èìåíèòåëüíîì ïàäåæå, à ïîëó÷àåòå â íóæíîì âàì.
*
* Èñïîëüçîâàíèå
*
* Ñêëîíåíèå â äàòåëüíîì ïàäåæå
*
* cout << Petrovich::Instance()->Firstname("Èâàí", "dative", "male"); => Èâàíó
* cout << Petrovich::Instance()->Middlename("Ñåðãååâè÷", "dative", "male"); => Ñåðãååâè÷ó
* cout << Petrovich::Instance()->Lastname("Âîðîíîâ", "dative", "male"); => Âîðîíîâó
* cout << Petrovich::Instance()->Fullname("Âîðîíîâ Èâàí Ñåðãååâè÷" "dative");
*
*
* Åñëè ïîë íå èçâåñòåí, åãî ìîæíî îïðåäåëèòü ïî îò÷åñòâó, ïðè ïîìîùè ìåòîäà DetectGender
*
* gender = Petrovich::Instance()->DetectGender("Ñåðãååâè÷") => "male"
*
* Âîçìîæíûå ïàäåæè
*
* "nominative" - èìåíèòåëüíûé
* "genitive" - ðîäèòåëüíûé
* "dative" - äàòåëüíûé
* "accusative" - âèíèòåëüíûé
* "instrumental" - òâîðèòåëüíûé
* "prepositional" - ïðåäëîæíûé
*/
#ifndef PETROVICH_H
#define PETROVICH_H
#include <vector>
#include <utility>
#include "yaml-cpp/yaml.h"
enum kCase {
NOMINATIVE, // èìåíèòåëüíûé
GENITIVE, // ðîäèòåëüíûé
DATIVE, // äàòåëüíûé
ACCUSATIVE, // âèíèòåëüíûé
INSTRUMENTAL, // òâîðèòåëüíûé
PREPOSITIONAL // ïðåäëîæíûé
};
enum kGender {
NONE,
MALE,
FEMALE,
ANDROGYNOUS
};
inline kCase StringToCase(std::string str_case) {
if (str_case == "nominative" || str_case == "èìåíèòåëüíûé")
return NOMINATIVE;
if (str_case == "genitive" || str_case == "ðîäèòåëüíûé")
return GENITIVE;
if (str_case == "dative" || str_case == "äàòåëüíûé")
return DATIVE;
if (str_case == "accusative" || str_case == "âèíèòåëüíûé")
return ACCUSATIVE;
if (str_case == "instrumental" || str_case == "òâîðèòåëüíûé")
return INSTRUMENTAL;
if (str_case == "prepositional" || str_case == "ïðåäëîæíûé")
return PREPOSITIONAL;
}
inline kGender StringToGender(std::string str_gender) {
if (str_gender == "") return NONE;
if (str_gender == "male" || str_gender == "m" || str_gender == "ì" ||
str_gender == "ìóæñêîé") return MALE;
if (str_gender == "female" || str_gender == "f" || str_gender == "æ" ||
str_gender == "æåíñêèé") return FEMALE;
if (str_gender == "androgynous") return ANDROGYNOUS;
}
inline std::string GenderToString(kGender gender) {
switch (gender) {
case NONE: return "";
case MALE: return "male";
case FEMALE: return "female";
case ANDROGYNOUS: return "androgynous";
}
}
inline std::string Downcase (std::string str) {
for (char& c:str)
if ( c >= 'A' && c <= 'Z')
c -= 'A' - 'a';
return str;
}
inline std::vector<std::string> SplitString(std::string str, char c) {
std::vector<std::string> res;
int start = 0;
for (int i = 0; i < str.length(); ++i)
if (str[i] == c) {
res.push_back(str.substr(start, i - start));
start = i + 1;
++i;
}
res.push_back(str.substr(start));
return res;
}
inline std::string JoinStrings (std::vector<std::string> strs, char c) {
std::string str = "";
for(const std::string& s: strs)
str += c + s;
return str.substr(1);
}
const YAML::Node rules = YAML::LoadFile("rules.yml");
class Petrovich {
protected:
// Íàáîð ìåòîäîâ äëÿ íàõîæäåíèÿ è ïðèìåíåíèÿ ïðàâèë ê èìåíè, ôàìèëèè è îò÷åñòâó.
class Rules {
public:
std::string Firstname(std::string, kCase, kGender, const YAML::Node&);
std::string Middlename(std::string, kCase, kGender, const YAML::Node&);
std::string Lastname(std::string, kCase, kGender, const YAML::Node&);
static Rules* Instance();
protected:
bool Match(std::string, kGender, const YAML::Node&, bool,
std::vector<std::string>);
std::string Inflect(std::string, kCase, kGender, const YAML::Node&);
void Apply(std::string&, kCase,YAML::Node*);
void FindAndApply(std::string&, kCase, kGender, const YAML::Node&,
std::vector<std::pair<std::string, bool>>* features = NULL);
YAML::Node* FindFor(std::string, kGender, const YAML::Node&,
std::vector<std::pair<std::string, bool>>* features = NULL);
YAML::Node* Find(std::string, kGender, const YAML::Node&, bool,
std::vector<std::string>);
std::string ModificatorFor(kCase, const YAML::Node*);
std::vector<std::string> ExtractTags(std::vector<std::pair<std::string,
bool>>* features = NULL);
bool TagsAllow(std::vector<std::string>, const YAML::Node& rule_tags);
Rules(){};
~Rules(){};
static Rules* self_;
};
Petrovich(){};
~Petrovich(){};
static Petrovich* self_;
public:
static Petrovich* Instance();
std::string Lastname(std::string, std::string,
std::string ggender = "androgynous");
std::string Firstname(std::string, std::string,
std::string ggender = "androgynous");
std::string Middlename(std::string, std::string,
std::string ggender = "");
std::string Fullname(std::string, std::string, std::string ggender = "");
std::string getGender();
std::string DetectGender(std::string);
};
#endif