1
0
Fork 0
inform6_examination/library-glulx/RusMCE.h

995 lines
25 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

! ===========================================================================
!
! RusMCE.h:
! Системный модуль для русской грамматики
! (генератор падежей, проверка глаголов, пр.)
! Source encoding: CP1251
!
! (c) Gayev D.G. 2003
!
! ---------------------------------------------------------------------------
System_file;
Constant Tlimit = 31; ! (не больше)
Array Tbuffer --> 3+TLimit;
Array Tparse --> Tlimit;
! DL: слегка модифицированная версия для DictionaryLookup
! (из "ParserM.h")
[ DL buf len
i;
if (len == 0 || len > Tlimit) return 0;
Tbuffer-->0 = len;
for (i = 0: i ~= len: i ++) Tbuffer-->(1+i) = buf-->i;
Tbuffer-->(1+len) = 0;
VM_Tokenise(Tbuffer, Tparse);
return Tparse-->1;
];
! DLx:
! как DL, но для поиска элементов словаря на 'term'
[ DLx buf len term
i;
if (len == 0 || len >= Tlimit) return 0;
Tbuffer-->0 = len+1;
for (i = 0: i ~= len: i ++) Tbuffer-->(1+i) = buf-->i;
Tbuffer-->(1+len) = term;
Tbuffer-->(2+len) = 0;
VM_Tokenise(Tbuffer, Tparse);
return Tparse-->1;
];
[ CyrCharToUpperUni ch;
if (ch >= $0430 && ch <=$044F) {
return ch - 32;
}
if (ch == $0451) {
return $0401; ! Ё
}
return ch;
];
Attribute fem_grammar; ! (тип склонения женского рода)
Property casegen; ! (необязательный собственный генератор падежей объекта)
! # падежей (нужно парсеру)
Constant LanguageCases = 6;
! Идентификаторы падежей
Constant csOff = 0; ! Нет (отключить генератор падежей)
Constant csNom = 1; ! Именительный падеж (= номинатив)
Constant csGen = 2; ! Родительный падеж (= генитив)
Constant csDat = 3; ! Дательный падеж (= датив)
Constant csAcc = 4; ! Винительный падеж (= аккузатив)
Constant csIns = 5; ! Творительный падеж (= инструментал)
Constant csPre = 6; ! Предложный падеж (= препозитив)
! Падеж по умолчанию для вывода ShortName
Global csDflt = csNom;
! Категории объекта
Constant ocSM = 1; ! Единственное число / Мужской род
Constant ocSF = 2; ! Единственное число / Женский род
Constant ocSN = 3; ! Единственное число / Средний род
Constant ocPL = 4; ! Множественное число
! Категория объекта
! определить категорию
[ objID obj;
if (obj has pluralname) return ocPL;
else if (obj has neuter) return ocSN;
else if (obj has female) return ocSF;
else if (obj has fem_grammar) return ocSF;
else return ocSM;
];
! (Режим отладки генератора падежей)
Constant DEBUG_CASES = false;
! Основная таблица падежных суффиксов
Constant ADJ_TOP = 64;
! SM_Req: запрос к таблице падежей (#nreq)
! (ед. число, мужской род)
[ SM_Req csID nreq;
switch (nreq) {
! II склонение, на согласный:
! (дом, снег, баран, кнут, мир, парад):
! -, -а, -у, -, -ом, -е
0: switch (csID) {
csNom: return 0;
csGen: return 'а//';
csDat: return 'у//';
csAcc: return 0;
csIns: return 'ом';
csPre: return 'е//';
}
! II склонение, на -ь:
! (снегирь, апрель, пароль, кремень, фонарь, окунь, медведь):
! -ь, -я, -ю, -ь, -ем, -е
1: switch (csID) {
csNom: return 'ь//';
csGen: return 'я//';
csDat: return 'ю//';
csAcc: return 'ь//';
csIns: return 'ем';
csPre: return 'е//';
}
! II склонение, на -й:
! (иней, лакей, зной, май):
! -й, -я, -ю, -й, -ем, -е
2: switch (csID) {
csNom: return 'й//';
csGen: return 'я//';
csDat: return 'ю//';
csAcc: return 'й//';
csIns: return 'ем';
csPre: return 'е//';
}
! II склонение, на -ий:
! (литий, планетарий, крематорий, Евгений, Василий):
! -ий, -ия, -ию, -ий, -ием, -ии
3: switch (csID) {
csNom: return 'ий';
csGen: return 'ия';
csDat: return 'ию';
csAcc: return 'ий';
csIns: return 'ием';
csPre: return 'ии';
}
! Прилагательные, на -ый:
! (красный, белый, сильный, здоровый):
! -ый, -ого, -ому, -ый, -ым, -ом
64: switch (csID) {
csNom: return 'ый';
csGen: return 'ого';
csDat: return 'ому';
csAcc: return 'ый';
csIns: return 'ым';
csPre: return 'ом';
}
! Прилагательные, на -ой:
! (большой, злой, плохой, лихой, нагой):
! -ой, -ого, -ому, -ой, -ым, -ом
65: switch (csID) {
csNom: return 'ой';
csGen: return 'ого';
csDat: return 'ому';
csAcc: return 'ой';
csIns: return 'ым';
csPre: return 'ом';
}
! Прилагательные, на -ий:
! (синий, средний, хороший):
! -ий, -его, -ему, -ий, -им, -ем
66: switch (csID) {
csNom: return 'ий';
csGen: return 'его';
csDat: return 'ему';
csAcc: return 'ий';
csIns: return 'им';
csPre: return 'ем';
}
} ! switch (nreq)
return -1;
]; ! SM_Req
! SF_Req: запрос к таблице падежей (#nreq)
! (ед. число, женский род)
[ SF_Req csID nreq;
switch (nreq) {
! I склонение, на -а:
! (вода, стрела, зола, комната):
! -а, -ы, -е, -у, -ой, -е
0: switch (csID) {
csNom: return 'а//';
csGen: return 'ы//';
csDat: return 'е//';
csAcc: return 'у//';
csIns: return 'ой';
csPre: return 'е//';
}
! I склонение, на -я:
! (земля, башня):
! -я, -и, -е, -ю, -ей, -е
1: switch (csID) {
csNom: return 'я//';
csGen: return 'и//';
csDat: return 'е//';
csAcc: return 'ю//';
csIns: return 'ей';
csPre: return 'е//';
}
! III склонение, на -ь:
! (метель, ночь, медь, осень):
! -ь, -и, -и, -ь, -ью, -и
2: switch (csID) {
csNom: return 'ь//';
csGen: return 'и//';
csDat: return 'и//';
csAcc: return 'ь//';
csIns: return 'ью';
csPre: return 'и//';
}
! I склонение, на -ия:
! (сессия, лекция, пародия, агония):
! -ия, -ии, -ии, -ию, -ией, -ии
3: switch (csID) {
csNom: return 'ия';
csGen: return 'ии';
csDat: return 'ии';
csAcc: return 'ию';
csIns: return 'ией';
csPre: return 'ии';
}
! Прилагательные, на -ая:
! (красная, большая, приятная):
! -ая, -ой, -ой, -ую, -ой, -ой
64: switch (csID) {
csNom: return 'ая';
csGen: return 'ой';
csDat: return 'ой';
csAcc: return 'ую';
csIns: return 'ой';
csPre: return 'ой';
}
! Прилагательные, на -яя:
! (синяя, средняя):
! -яя, -ей, -ей, -юю, -ей, -ей
65: switch (csID) {
csNom: return 'яя';
csGen: return 'ей';
csDat: return 'ей';
csAcc: return 'юю';
csIns: return 'ей';
csPre: return 'ей';
}
} ! switch (nreq)
return -1;
]; ! SF_Req
! SN_Req: запрос к таблице падежей (#nreq)
! (ед. число, средний род)
[ SN_Req csID nreq;
switch (nreq) {
! II склонение, на -о:
! (облако, озеро, утро, ведро, зеркало):
! -о, -а, -у, -о, -ом, -е
0: switch (csID) {
csNom: return 'о//';
csGen: return 'а//';
csDat: return 'у//';
csAcc: return 'о//';
csIns: return 'ом';
csPre: return 'е//';
}
! II склонение, на -е:
! (поле, ложе):
! -е, -я, -ю, -е, -ем, -е
1: switch (csID) {
csNom: return 'е//';
csGen: return 'я//';
csDat: return 'ю//';
csAcc: return 'е//';
csIns: return 'ем';
csPre: return 'е//';
}
! II склонение, на -ие:
! (известие, занятие, приветствие, мышление):
! -ие, -ия, -ию, -ие, -ием, -ии
2: switch (csID) {
csNom: return 'ие';
csGen: return 'ия';
csDat: return 'ию';
csAcc: return 'ие';
csIns: return 'ием';
csPre: return 'ии';
}
! Разносклоняемое, на -я:
! (время, племя, имя, знамя):
! -я, -ени, -ени, -я, -енем, -ени
3: switch (csID) {
csNom: return 'я//';
csGen: return 'ени';
csDat: return 'ени';
csAcc: return 'я//';
csIns: return 'енем';
csPre: return 'ени';
}
! Прилагательные, на -ое:
! (красное, малое, мертвое):
! -ое, -ого, -ому, -ое, -ым, -ом
64: switch (csID) {
csNom: return 'ое';
csGen: return 'ого';
csDat: return 'ому';
csAcc: return 'ое';
csIns: return 'ым';
csPre: return 'ом';
}
! Прилагательные, на -ее:
! (синее, среднее):
! -ее, -его, -ему, -ее, -им, -ем
65: switch (csID) {
csNom: return 'ее';
csGen: return 'его';
csDat: return 'ему';
csAcc: return 'ее';
csIns: return 'им';
csPre: return 'ем';
}
} ! switch (nreq)
return -1;
]; ! SN_Req
! PL_Req: запрос к таблице падежей (#nreq)
! (мн. число)
[ PL_Req csID nreq;
switch (nreq) {
! TMP: нерегулярность Gen Pl
! Множественное, на -и:
! (овраги, цели, недели):
! -и, -ов/-ей/-, -ам/-ям, -и, -ами/-ями, -ах/-ях
0: switch (csID) {
csNom: return 'и//';
csGen: return 'ев'; ! TMP: не всегда! - ей,
csDat: return 'ям';
csAcc: return 'и//';
csIns: return 'ями';
csPre: return 'ях';
}
! Множественное, на -ы:
! (работы, солдаты, заботы, закаты):
! -ы, -ов/-ей/-, -ам/-ям, -и, -ами/-ями, -ах/-ях
1: switch (csID) {
csNom: return 'ы//';
csGen: return 'ов'; ! TMP: не всегда!
csDat: return 'ам';
csAcc: return 'ы//';
csIns: return 'ами';
csPre: return 'ах';
}
! Множественное, на -а:
! (облака, дома, номера):
! -а, -ов, -ам, -а, -ами, -ах
2: switch (csID) {
csNom: return 'а//';
csGen: return 'ов';
csDat: return 'ам';
csAcc: return 'а//';
csIns: return 'ами';
csPre: return 'ах';
}
! Множественное, на -я:
! (поля, моря, якоря):
! -я, -ей, -ям, -я, -ями, -ях
3: switch (csID) {
csNom: return 'я//';
csGen: return 'ей';
csDat: return 'ям';
csAcc: return 'я//';
csIns: return 'ями';
csPre: return 'ях';
}
! Множественное, на -ья:
! (листья, деревья, коренья, стулья, перья):
! -ья, -ьев, -ьям, -ья, -ьями, -ьях
4: switch (csID) {
csNom: return 'ья';
csGen: return 'ьев';
csDat: return 'ьям';
csAcc: return 'ья';
csIns: return 'ьями';
csPre: return 'ьях';
}
! Множественное, на -ия:
! (изделия, решения, стремления, понятия):
! -ия, -ий, -иям, -ия, -иями, -иях
5: switch (csID) {
csNom: return 'ия';
csGen: return 'ий';
csDat: return 'иям';
csAcc: return 'ия';
csIns: return 'иями';
csPre: return 'иях';
}
! Множественное, на -ии:
! (станции, реляции, апатии):
! -ия, -ий, -иям, -ия, -иями, -иях
6: switch (csID) {
csNom: return 'ии';
csGen: return 'ий';
csDat: return 'иям';
csAcc: return 'ии';
csIns: return 'иями';
csPre: return 'иях';
}
! Прилагательные, на -ые:
! (красные, опасные, тяжелые):
! -ые, -ых, -ым, -ые, -ыми, -ых
64: switch (csID) {
csNom: return 'ые';
csGen: return 'ых';
csDat: return 'ым';
csAcc: return 'ые';
csIns: return 'ыми';
csPre: return 'ых';
}
! Прилагательные, на -ие:
! (синие, легкие, пологие):
! -ие, -их, -им, -ие, -ими, -их
65: switch (csID) {
csNom: return 'ие';
csGen: return 'их';
csDat: return 'им';
csAcc: return 'ие';
csIns: return 'ими';
csPre: return 'их';
}
} ! switch (nreq)
return -1;
]; ! PL_Req
! Ending PostProcess (as after 'prch')
[ EndingPost u prch;
if (u) {
! Модификация после 'г'/'к'/'х'/'ж'/'ш'/'ч'/'щ':
! сапог -> сапоги, клубок -> клубки, сполох -> сполохи
if (prch == 'г' or 'к' or 'х' or 'ж' or 'ш' or 'ч' or 'щ')
switch (u) {
'ы//': return 'и//';
'ый': return 'ий';
'ые': return 'ие';
'ым': return 'им';
'ыми': return 'ими';
'ых': return 'их';
}
! TMP: больше вариантов!
! после ц: ов, ом -> ев, ем (если окончание безударное)
! после ж, ш: я -> а, ю -> у
}
return u;
];
! Ending PreProcess (as after 'prch')
[ EndingPre u prch;
if (u) {
if (prch == 'г' or 'к' or 'х' or 'ж' or 'ш' or 'ч' or 'щ')
switch (u) {
'и//': return 'ы//';
'ий': return 'ый';
'ие': return 'ые';
'им': return 'ым';
'ими': return 'ыми';
'их': return 'ых';
}
}
return u;
];
! CCaseEnd:
! перевести падежное окончание (start..end) в соответствующий падеж (csID)
! ocFN - генератор окончаний; disc - дискриминатор; prch - символ перед окончанием
[ CCaseEnd start end csID ocFN disc prch
i u v;
v = EndingPre (DL (start, (end-start)/4), prch);
! Выполнить поиск по таблицам...
for (i = 0: : ++ i) {
u = indirect (ocFN, csNom, i);
if (u == -1) {
if (i >= ADJ_TOP) ! (больше нет вариантов)
{ print "?"; return; }
else ! (прилагательные)
{ i = ADJ_TOP - 1; }
} else if (u == v) {
if (disc) { -- disc; continue; }
if (csID ~= csNom) u = EndingPost (indirect (ocFN, csID, i), prch);
else u = EndingPost (u, prch);
if (u) print (address) u;
return;
}
}
];
! Специфичная версия для 'LanguageRefers'
[ EndingLookup addr len csID
v u ocFN i;
if (csID == 0) rtrue; !! (любой падеж допустим)
if (len ~= 0) {
v = DL (addr, len);
if (v == 0) rfalse;
}
else v = 0;
ocFN = SM_Req;
for (::) {
for (i = 0: : ++ i) {
u = indirect (ocFN, csID, i);
if (u == -1) {
if (i >= ADJ_TOP) break; ! (больше нет вариантов)
else i = ADJ_TOP - 1; ! (прилагательные)
}
else if (u == v) rtrue;
}
switch (ocFN) {
SM_Req: ocFN = SF_Req;
SF_Req: ocFN = SN_Req;
SN_Req: ocFN = PL_Req;
PL_Req: rfalse; ! (больше нет вариантов)
}
}
rfalse;
];
!
! Проверить корректность глагольного суффикса
!
[ IsVerbSuffix start len;
! ("-ся|-сь": убрать)
if (len >= 2 && start-->(len-2) == 'с' && start-->(len-1) == 'я' or 'ь')
len = len - 2;
if (len == 1 && start-->0 == 'и' or 'ь') rtrue;
! "[аеиоуыюя]([ийь]|ть)"
if (start-->0 == 'а' or 'е' or 'и' or 'о' or 'у' or 'ы' or 'ю' or 'я') {
start = start + 4;
len--;
if (len == 1 && start-->0 == 'й') rtrue;
}
! "ти|ть"
if (len == 2 && start-->0 == 'т' && start-->1 == 'ь' or 'и') rtrue;
! "нь|ни|нуть"
if (start-->0 == 'н' &&
((len == 2 && start-->1 == 'и' or 'ь') ||
(len == 4 && start-->1 == 'у' && start-->2 == 'т' && start-->3 == 'ь')))
rtrue;
rfalse;
];
!
! Проверить корректность глагольного префикса
!
[ IsVerbPrefix start len
w;
w = DL (start, len);
if (w == 0) return false;
return w ==
'в//' or 'вз' or 'во' or 'вы' or
'до' or
'за' or
'из' or 'ис' or
'на' or
'о//' or 'об' or 'обо' or 'от' or 'ото' or
'по' or 'под' or 'подо' or 'пре' or 'при' or 'про' or 'пере' or
'раз' or 'рас' or
'с//' or 'со' or 'съ' or 'у//';
];
!
! Проверить корректность глагола (#wnum)
!
[ LanguageIsVerb buffer parse wnum
adr beg len end w;
adr = buffer + (parse-->(wnum*3))*4;
len = parse-->(wnum*3-1);
w = DLx (adr, len, '!');
if (w) return w;
for (end = len: end > 0: -- end) {
if (end == len || IsVerbSuffix (adr + end * 4, len - end))
for (beg = 0: beg < end: ++ beg)
if (beg == 0 || IsVerbPrefix (adr, beg)) {
w = DL (adr + beg * 4, end - beg);
if (w ~= 0 && (w->#dict_par1 & 1) ~= 0)
return w; ! (verb entry found)
}
}
return 0;
];
! Расшифровка глаголов (LanguageVerb):
! просмотреть объекты в VerbDepot
[ LanguageVerb word
obj;
objectloop (obj in VerbDepot) {
if (WordInProperty (word, obj, name))
{ print (object) obj; rtrue; }
}
rfalse;
];
! Падеж по умолчанию для вывода LanguageRefers
Global csLR = 0;
Global csLRU = 0;
! Обработчик соответствующего символа парсера
[ c_token idtok csID
retval;
csLR = csID;
csLRU = csID; ! последний падеж, который вызывался
retval = ParseToken (ELEMENTARY_TT, idtok);
csLR = 0;
return retval;
];
! LanguageRefers
! Запрос от парсера:
! может ли слово #wnum в данном контексте обращаться к объекту obj?
[ LanguageRefers obj wnum
adr len end w csID;
adr = WordAddress(wnum); len = WordLength(wnum);
! Для компасных направлений -- упрощенная обработка
if (parent (obj) == Compass) {
w = DL (adr, len);
if (w ~= 0 && WordInProperty (w, obj, name)) rtrue;
rfalse;
}
! Для мужских одушевленных предметов Acc -> Gen
csID = csLR;
if (csID == csAcc && obj has animate && obj has male && obj hasnt fem_grammar)
csID = csGen;
for (end = len: end ~= 0: -- end) {
w = DL (adr, end);
if (w ~= 0 && WordInProperty (w, obj, name) && EndingLookup (adr + end * 4, len - end, csID))
rtrue;
}
rfalse;
];
Constant ScrLen = 200;
Array Scratch --> ScrLen;
! CCase:
! перевести имя объекта (obj) в соответствующий падеж (csID)
[ CCase obj csID ucase as_obj
i dlm limit ocFN;
#iftrue DEBUG_CASES;
! (отладочный вывод)
csLabel (csID);
print " (", (object) obj, ")";
#ifnot;
if (as_obj == false && obj == player) {
if (ucase) {
switch (csID) {
csNom: print "Ты";
csGen: print "Себя";
csDat: print "Себе";
csAcc: print "Себя";
csIns: print "Собой";
csPre: print "Себе";
}
} else {
switch (csID) {
csNom: print "ты";
csGen: print "себя";
csDat: print "себе";
csAcc: print "себя";
csIns: print "собой";
csPre: print "себе";
}
}
return;
}
switch (objID (obj)) {
ocSM: ocFN = SM_Req;
ocSF: ocFN = SF_Req;
ocSN: ocFN = SN_Req;
ocPL: ocFN = PL_Req;
default: return;
}
! Для мужских одушевленных предметов Acc -> Gen
if (csID == csAcc && obj has animate &&
obj has male && obj hasnt fem_grammar)
csID = csGen;
if (csID ~= 0) {
Scratch-->0 = VM_PrintToBuffer(Scratch, ScrLen, obj);
if (ucase) {
Scratch-->1 = CyrCharToUpperUni(Scratch-->1);
}
dlm = 0;
limit = Scratch-->0;
for (i = 1: i <= limit: ++ i) {
if (Scratch-->i == '/') {
if (dlm == 0) {
dlm = Scratch + i * 4;
} else {
CCaseF (obj, ocFN, csID, dlm + 4, Scratch + i * 4);
dlm = 0;
}
} else {
if (dlm ~= 0 && Scratch-->i == ' ') {
CCaseF (obj, ocFN, csID, dlm + 4, Scratch + i * 4);
dlm = 0;
}
if (dlm == 0) print (char) (Scratch-->i);
}
}
!
if (dlm ~= 0) {
CCaseF (obj, ocFN, csID, dlm + 4, Scratch + i * 4);
}
} else {
print (object) obj;
}
#endif;
];
[ CCaseF obj ocFN csID beg end disc;
! (discriminator present?)
while (end-->(-1) == '!') { -- end; ++ disc; }
if (obj provides casegen && obj.casegen (beg, end, csID));
else CCaseEnd (beg, end, csID, ocFN, disc, beg-->(-2));
];
! Вывод краткого имени объекта (через CCase)
[ LanguagePrintShortName obj
sn;
sn = short_name;
if (obj provides sn && PrintOrRun(obj, sn, 1) ~= 0) rtrue;
CCase (obj, csDflt, false);
rtrue;
];
! Вывод списка в падеже csID
[ WriteListFromCase obj flag csID
rval csSV;
csSV = csDflt; csDflt = csID;
rval = WriteListFrom (obj, flag);
csDflt = csSV;
return rval;
];
! Подходящее местоимение для 'obj'
[ Pronoun obj;
print (string) (
IIF (obj == player, "Ты", IIF (obj has pluralname, "Они",
IIF (obj has female, "Она", IIF (obj has neuter, "Оно", "Он")))));
];
[ PronounS obj;
print (string) (
IIF (obj == player, "ты", IIF (obj has pluralname, "они",
IIF (obj has female, "она", IIF (obj has neuter, "оно", "он")))));
];
! Окончание краткой формы прилагательных/причастий, согласованных с 'obj'
! ("открыт[а|о|ы]", "пуст[а|о|ы]")
[ SAEnd obj;
switch (objID (obj)) {
ocSM: ;
ocSF: print (address) 'а//';
ocSN: print (address) 'о//';
ocPL: print (address) 'ы//';
}
];
! Окончание глаголов, согласованных с 'obj':
! (f1 ? 1-ое : 2-ое) спряжение;
! f2 ? 'ют'/'ят' : 'ут'/'ат'
[ VEnd obj f1 f2;
print (address) IIF (obj has pluralname,
IIF (f1,
IIF (f2, 'ют', 'ут'),
IIF (f2, 'ят', 'ат')),
IIF (f1, 'ет', 'ит'));
];
! Окончание глаголов: '-ет'/'-ут'
[ V1aEnd x; VEnd (x, true, false); ];
! Окончание глаголов: '-ет'/'-ют'
[ V1bEnd x; VEnd (x, true, true); ];
! Окончание глаголов: '-ит'/'-ат'
[ V2aEnd x; VEnd (x, false, false); ];
! Окончание глаголов: '-ит'/'-ят'
[ V2bEnd x; VEnd (x, false, true); ];
! Окончание глаголов в прошедшем времени
[ VPEnd noun;
if (noun has pluralname) {print "и"; rtrue;}
else if (noun has neuter) {print "о"; rtrue;}
else if (noun has female) {print "а"; rtrue;}
else {print ""; rtrue;}
];
!
! Обработчик беглых гласных
! (возвращает true если обработана)
!
[ ICVowel csID beg end ch0 ch1;
if ((beg == end && ch0 == 0) || (beg + 4 == end && beg-->0 == ch0)) {
if (csID == csNom || csID == csAcc) {
if (ch0) print (char) ch0;
}
else {
if (ch1) print (char) ch1;
}
rtrue;
}
rfalse;
];
[ AEnd noun;
if (noun has pluralname) {print "ые"; rtrue;}
else if (noun has neuter) {print "ое"; rtrue;}
else if (noun has female) {print "ая"; rtrue;}
else {print "ый"; rtrue;}
];
[ AEnd2 noun;
if (noun has pluralname) {print "ие"; rtrue;}
else if (noun has neuter) {print "ое"; rtrue;}
else if (noun has female) {print "ая"; rtrue;}
else {print "ий"; rtrue;}
];
[ AEnd3 noun;
if (noun has pluralname) {print "ие"; rtrue;}
else if (noun has neuter) {print "ое"; rtrue;}
else if (noun has female) {print "ая"; rtrue;}
else {print "ой"; rtrue;}
];
[ PEnding1 n;
if (n has pluralname) {print "ими"; rtrue;}
if (n has female) {print "ой"; rtrue;}
print "им"; rtrue;
];
[ PEnding2 n;
if (n has pluralname) {print "ыми"; rtrue;}
if (n has female) {print "ой"; rtrue;}
print "ым"; rtrue;
];
[ GenIt n;
if (n has female) {print "её"; rtrue;}
if (n has pluralname) {print "их"; rtrue;}
print "его"; rtrue;
];
[ GenIt2 n;
print "н";
if (n has female) {print "её"; rtrue;}
if (n has pluralname) {print "их"; rtrue;}
print "его"; rtrue;
];
[ DatIt n;
if (n has female) {print "ей"; rtrue;}
if (n has pluralname) {print "им"; rtrue;}
print "ему"; rtrue;
];
[ DatIt2 n;
print "н";
if (n has female) {print "ей"; rtrue;}
if (n has pluralname) {print "им"; rtrue;}
print "ему"; rtrue;
];
[ InsIt n;
if (n has female) {print "ей"; rtrue;}
if (n has pluralname) {print "ими"; rtrue;}
print "им"; rtrue;
];
[ InsIt2 n;
print "н";
if (n has female) {print "ей"; rtrue;}
if (n has pluralname) {print "ими"; rtrue;}
print "им"; rtrue;
];