Пример #1
0
def loc_case(func, i):  # Местный падеж
    r = i.result  # local

    if _.contains(i.index, 'П2') or _.contains(i.index, 'П₂'):
        loc = r['dat-sg']  # local
        loc = _.replaced(loc, '́ ', '')
        loc = _.replaced(loc, 'ё', 'е')
        loc = _.replaced(loc, '({vowel})({consonant}*)$', '%1́ %2')
        loc = remove_stress_if_one_syllable(loc)  # = export.
        r['loc-sg'] = loc
        loc_prep = _.extract(i.index, 'П2%((.+)%)')  # local
        if not loc_prep:
            loc_prep = _.extract(i.index, 'П₂%((.+)%)')
        # end
        if not loc_prep:
            loc_prep = 'в, на'
        # end
        r['loc-sg'] = '(' + loc_prep + ') ' + r['loc-sg']
        if _.contains(i.index, '%[П'):
            r['loc-sg'] = r['loc-sg'] + '&nbsp;//<br />' + r['prp-sg']
        # end
    # end
    if _.has_value(i.args, 'М'):
        r['loc-sg'] = i.args['М']
    # end

    _.ends(module, func)
Пример #2
0
def get_cyrl_animacy(index, gender):
    if _.extract(index, '^' + gender + 'о//' + gender):
        return 'an//in'
    elif _.extract(index, '^' + gender + '//' + gender + 'о'):
        return 'in//an'
    elif _.extract(index, '^' + gender + 'о'):
        return 'an'
    else:
        return 'in'
Пример #3
0
def angle_brackets(func, i):  # export
    angle_index = _.extract(i.rest_index, '%<([^>]+)%>')  # local
    if angle_index:
        if not i.pt:
            i.output_gender = i.gender
            i.output_animacy = i.animacy
        # end

        i.orig_index = i.index
        i.index = angle_index

        pt_backup = i.pt  # local
        noun_parse.extract_gender_animacy(i)
        i.pt = pt_backup

        if e.has_error(i):
            return _.ends(module, func)
        # end

        _.log_value(i.adj, 'i.adj')
        if i.adj:  # fixme: Для прилагательных надо по-особенному?
            init_stem.init_stem(i)
            if e.has_error(i):
                return _.ends(module, func)
            # end
        # end
    # end

    _.ends(module, func)
Пример #4
0
def extract_stress_type(func, i):  # export
    #    OLD: Старая версия кода:
    #    # local stress_regexp = "([abcdef][′']?[′']?)"
    #    # local stress_regexp2 = '(' + stress_regexp + '.*//.*' + stress_regexp + ')'
    #    stress_regexp = '(' + stress_regexp + '(% ?.*))'
    #    i.stress_type = _.extract(i.rest_index, stress_regexp2)
    #    if not i.stress_type:
    #        i.stress_type = _.extract(i.rest_index, stress_regexp)
    #    # end
    # local stress_type, allowed_stress_types

    # INFO: Извлечение ударения из оставшейся части индекса:
    i.stress_type = _.extract(i.rest_index,
                              "([abcdef][′']?[′']?[/]?[abc]?[′']?[′']?)")

    # INFO: Замена особых апострофов в ударении на обычные:
    if i.stress_type:
        i.stress_type = _.replaced(i.stress_type, '′', "'")
    # end

    # INFO: Список допустимых схем ударений:
    allowed_stress_types = {  # todo: special variables for that?
        'a', "a'", 'b', "b'", 'c', 'd', "d'", 'e', 'f', "f'", "f''",
        'a/a', 'a/b', 'a/c', "a/a'", "a/b'", "a/c'", "a/c''",
        'b/a', 'b/b', 'b/c', "b/a'", "b/b'", "b/c'", "b/c''",
    }

    # INFO: Если ударение есть и оно не из допустимого списка -- это ошибка
    if i.stress_type and not _.equals(i.stress_type, allowed_stress_types):
        e.add_error(i, 'Ошибка: Неправильная схема ударения: ' + i.stress_type)
    # end

    _.ends(module, func)
Пример #5
0
def extract_gender_animacy(func, i):  # export
    # local convert_animacy, orig_index, rest_index

    # мо-жо - mf a
    # ж//жо - f ina//a
    # мо - m a
    # с  - n ina
    i.pt = False

    if _.startswith(i.index, 'п'):
        i.adj = True
    elif _.extract(i.index, '^м//ж') or _.extract(
            i.index,
            '^m//f'):  # todo: INFO: похоже все такие случаи либо 0, либо <...>
        i.gender = 'mf'
        i.animacy = 'in'
    elif _.extract(i.index, '^м//с') or _.extract(i.index, '^m//n'):
        i.gender = 'mn'
        i.animacy = 'in'
    elif _.extract(i.index, '^ж//м') or _.extract(i.index, '^f//m'):
        i.gender = 'fm'
        i.animacy = 'in'
    elif _.extract(i.index, '^ж//с') or _.extract(i.index, '^f//n'):
        i.gender = 'fn'
        i.animacy = 'in'
    elif _.extract(i.index, '^с//м') or _.extract(i.index, '^n//m'):
        i.gender = 'nm'
        i.animacy = 'in'
    elif _.extract(i.index, '^с//ж') or _.extract(i.index, '^n//m'):
        i.gender = 'nm'
        i.animacy = 'in'
    elif _.extract(i.index, '^мо%-жо') or _.extract(i.index, '^mf a'):
        i.gender = 'f'
        i.animacy = 'an'
        i.common_gender = True
    elif _.extract(i.index, '^мн'):
        i.gender = ''
        i.animacy = ''
        i.common_gender = False
        i.pt = True
        if _.extract(i.index, 'одуш'):
            i.animacy = 'an'
        elif _.extract(i.index, 'неод'):
            i.animacy = 'in'
        # end
        # TODO: Также удалить это ниже для rest_index, аналогично как удаляется м, мо и т.п.
        i.rest_index = i.index
    elif _.extract(i.index, '^мс'):
        i.pronoun = True
    elif _.extract(
            i.index, '^м'
    ):  # fixme: сюда частично попадает необрабатываемый пока "м//мн."
        i.gender = 'm'
        i.animacy = get_cyrl_animacy(i.index, 'м')
        i.common_gender = False
    elif _.extract(i.index, '^ж'):
        i.gender = 'f'
        i.animacy = get_cyrl_animacy(i.index, 'ж')
        i.common_gender = False
    elif _.extract(i.index, '^с'):
        i.gender = 'n'
        i.animacy = get_cyrl_animacy(i.index, 'с')
        i.common_gender = False
    else:
        i.gender = _.extract(i.index, '^([mnf])')
        i.animacy = _.extract(i.index, '^[mnf] ([a-z/]+)')
        i.common_gender = False
        if i.animacy:
            convert_animacy = {}
            convert_animacy['in'] = 'in'
            convert_animacy['an'] = 'an'
            convert_animacy['ina'] = 'in'
            convert_animacy['a'] = 'an'
            convert_animacy['a//ina'] = 'an//in'
            convert_animacy['ina//a'] = 'in//an'
            convert_animacy['anin'] = 'an//in'
            convert_animacy['inan'] = 'in//an'
            i.animacy = convert_animacy[i.animacy]
        # end
    # end

    # Удаляем теперь соответствующий кусок индекса
    if (i.gender
            or i.gender == '') and i.animacy and not i.adj and not i.pronoun:
        _.log_value(i.index, 'i.index')
        orig_index = mw.text.trim(i.index)

        #        # local test1 = _.replaced(i.index, '^mf a ?', '')
        #        mw.log('test1 = ' + mw.text.trim(test1))
        #
        #        # local test2 = _.replaced(i.index, '^mf a ', '')
        #        mw.log('test2 = ' + mw.text.trim(test2))
        #
        #        # local test3 = _.replaced(i.index, 'mf a ', '')
        #        mw.log('test3 = ' + mw.text.trim(test3))
        #
        #        # local test4 = _.replaced(i.index, 'mf a', '')
        #        mw.log('test4 = ' + mw.text.trim(test4))
        #
        #        # local test5 = mw.text.trim(_.replaced(i.index, '^mf a ?', ''))
        #        mw.log('test5 = ' + test5)
        #
        #        # local test6 = _.replaced(i.index, '^mf a ?', '')
        #        mw.log('test6 = ' + test6)
        #        # local test7 = mw.text.trim(test6)
        #        mw.log('test7 = ' + test7)

        # TODO: Simplify things a bit here (сделать циклом!):

        rest_index = _.replaced(i.index, '^mf a ?', '')
        if rest_index != orig_index:
            i.rest_index = mw.text.trim(rest_index)
            _.log_info('Удаление "mf a" из индекса')
            _.log_value(i.rest_index, 'i.rest_index')
            return _.ends(module, func)
        # end
        rest_index = _.replaced(i.index, '^[mnf]+ [a-z/]+ ?', '')
        if rest_index != orig_index:
            i.rest_index = mw.text.trim(rest_index)
            _.log_info('Удаление "[mnf] [in/an]" из индекса')
            _.log_value(i.rest_index, 'i.rest_index')
            return _.ends(module, func)
        # end
        rest_index = _.replaced(i.index, '^мн%.? неод%.? ?', '')
        if rest_index != orig_index:
            i.rest_index = mw.text.trim(rest_index)
            _.log_info('Удаление "мн. неод." из индекса')
            _.log_value(i.rest_index, 'i.rest_index')
            return _.ends(module, func)
        # end
        rest_index = _.replaced(i.index, '^мн%.? одуш%.? ?', '')
        if rest_index != orig_index:
            i.rest_index = mw.text.trim(rest_index)
            _.log_info('Удаление "мн. одуш." из индекса')
            _.log_value(i.rest_index, 'i.rest_index')
            return _.ends(module, func)
        # end
        rest_index = _.replaced(i.index, '^мн%.? ?', '')
        if rest_index != orig_index:
            i.rest_index = mw.text.trim(rest_index)
            _.log_info('Удаление "мн." из индекса')
            _.log_value(i.rest_index, 'i.rest_index')
            return _.ends(module, func)
        # end
        rest_index = _.replaced(
            i.index, '^[-мжсо/]+%,? ?',
            '')  # fixme: сюда частично попадает необрабатываемый пока "м//мн."
        if rest_index != orig_index:
            i.rest_index = mw.text.trim(rest_index)
            _.log_info('Удаление "м/ж/с/мо/жо/со/..." из индекса')
            _.log_value(i.rest_index, 'i.rest_index')
            return _.ends(module, func)
        # end
        e.add_error(i, 'TODO: process such errors')
        return _.ends(module, func)
    elif i.adj:
        _.log_value(i.index, 'i.index (п)')
        orig_index = mw.text.trim(i.index)

        rest_index = _.replaced(i.index, '^п ?', '')
        if rest_index != orig_index:
            i.rest_index = mw.text.trim(rest_index)
            _.log_info('Удаление "п" из индекса')
            _.log_value(i.rest_index, 'i.rest_index')
            return _.ends(module, func)
        # end
    elif i.pronoun:
        _.log_value(i.index, 'i.index (мс)')
        orig_index = mw.text.trim(i.index)

        rest_index = _.replaced(i.index, '^мс ?', '')
        if rest_index != orig_index:
            i.rest_index = mw.text.trim(rest_index)
            _.log_info('Удаление "мс" из индекса')
            _.log_value(i.rest_index, 'i.rest_index')
            return _.ends(module, func)
        # end
    # end

    _.ends(module, func)
Пример #6
0
def apply_specific_reducable(func, i, gender, rest_index, only_sg):  # export
    # local reduced, reduced_letter, f8_third, prev
    # local case_2_a, case_2_b, case_2_c, case_3_a, case_3_b
    # local skip_b_1, skip_b_2, skip_b_3, force_b
    # local case

    p = i.parts  # local

    if _.contains(rest_index, '%*'):

        reduced = '?'
        if i.adj:
            if gender == 'm':
                if _.contains(rest_index, ['%(1%)', '①']):
                    if gender == 'm' and i.adj and _.endswith(
                            i.word.unstressed, 'ний'
                    ) and p.endings[
                            'srt-sg'] == 'ь':  # fixme: temporary duplicated with the same code at the ending of function...
                        p.endings['srt-sg'] = ''  # вместо `ь` для `2*a`
                    # end
                    return _.ends(module, func)
                # end
                if _.contains(rest_index, ['%(2%)', '②']):
                    return _.ends(module, func)
                # end
                reduced = 'B'
            else:
                return _.ends(module, func)
            # end
        elif gender == 'm' or i.pronoun:
            reduced = 'A'
        elif gender == 'n':
            reduced = 'B'
        elif gender == 'f':
            if i.stem.type == '8-third':
                reduced = 'A'
            else:
                reduced = 'B'
            # end
        # end

        _.log_info('Случай чередования: ' + str(reduced))

        if reduced == 'A':
            reduced_letter = _.extract(i.word.unstressed,
                                       '({vowel+ё}){consonant}+$')
            f8_third = gender == 'f' and i.stem.type == '8-third'

            _.log_value(reduced_letter, 'reduced_letter')

            if reduced_letter == 'о':
                _.replace(p.stems, 'all-sg', '(.)о́ ?([^о]+)$', '%1%2')

                #                # local stem_gen_pl
                #                # У этих имён последняя гласная основы исходной формы заменяется на нуль, о или й во всех формах, не совпадающих с исходной (кроме Т. ед. на -ью).
                #                # if p.endings['gen-pl'] == '':  -- ботинок, глазок
                #                if _.contains(rest_index, ['%(2%)', '②']):
                #                    stem_gen_pl = p.stems['gen-pl']
                #                # end

                if not only_sg:
                    _.replace(p.stems, 'all-pl', '(.)о́ ?([^о]+)$', '%1%2')
                # end

#                if stem_gen_pl:  # ботинок, глазок
#                    p.stems['gen-pl'] = stem_gen_pl
#                # end

                if not f8_third:
                    _.replace(p.stems, 'ins-sg', '(.)о́ ?([^о]+)$', '%1%2')
                # end

            elif reduced_letter == 'и':  # бывает только в подтипе мс 6*
                _.replace(p.stems, 'all-sg', '(.)и́ ?([^и]+)$', '%1ь%2')
                if not only_sg:
                    _.replace(p.stems, 'all-pl', '(.)и́ ?([^и]+)$', '%1ь%2')
                # end

            elif _.In(reduced_letter, ['е', 'ё']):
                prev = _.extract(i.word.unstressed, '(.)[её][^её]+$')

                case_2_a = i.stem.type == '6-vowel'  # 2) а).
                case_2_b = i.stem.type == '3-velar' and _.contains(
                    prev, '[^аеёиоуыэюяшжчщц]')  # 2) б).
                case_2_c = not _.equals(
                    i.stem.type,
                    ['6-vowel', '3-velar']) and prev == 'л'  # 2) в).

                if _.contains(prev, '{vowel+ё}'):  # 1).
                    _.log_info('Подслучай A.1).')
                    _.replace(p.stems, 'all-sg', '[её]́ ?([^её]+)$', 'й%1')
                    if not f8_third:
                        _.replace(p.stems, 'ins-sg', '[её]́ ?([^её]+)$', 'й%1')
                    # end
                    if not only_sg:
                        _.replace(p.stems, 'all-pl', '[её]́ ?([^её]+)$', 'й%1')
                    # end

                elif case_2_a or case_2_b or case_2_c:  # 2).

                    _.log_info('Подслучай A.2).')
                    _.replace(p.stems, 'all-sg', '[её]́ ?([^её]*)$', 'ь%1')
                    if not f8_third:
                        _.replace(p.stems, 'ins-sg', '[её]́ ?([^её]*)$', 'ь%1')
                    # end
                    if not only_sg:
                        _.replace(p.stems, 'all-pl', '[её]́ ?([^её]*)$', 'ь%1')
                    # end

                else:  # 3).
                    _.log_info('Подслучай A.3).')
                    _.replace(p.stems, 'all-sg', '[её]́ ?([^её]*)$', '%1')
                    if not f8_third:
                        _.replace(p.stems, 'ins-sg', '[её]́ ?([^её]*)$', '%1')
                    # end
                    if not only_sg:
                        _.replace(p.stems, 'all-pl', '[её]́ ?([^её]*)$', '%1')
                    # end
                # end
            # end
        # end  # reduced A

        if only_sg:
            return _.ends(
                module, func
            )  # ниже всё равно обрабатывается только множественное число уже
        # end

        # we should ignore asterix for 2*b and 2*f (so to process it just like 2b or 2f)
        skip_b_1 = i.stem.type == '2-soft' and _.In(i.stress_type, ['b', 'f'])

        # and also the same for (2)-specific and 3,5,6 stem-types
        skip_b_2 = _.contains(rest_index, ['%(2%)', '②']) and (
            _.In(i.stem.type, {'2-soft'})  # '2-soft' из сходня 2*a(2)

            # TODO: Разобраться, почему это нужно было на самом деле?
            #            _.In(i.stem.type, ['3-velar', '5-letter-ц', '6-vowel'])  # так было раньше, без прочих skip
        )

        # TODO: Разобраться, почему это нужно на самом деле?
        skip_b_3 = _.contains(rest_index,
                              ['%(2%)', '②']) and gender == 'n'  # temp fix

        stem = i.stem.unstressed  # local

        force_b = False
        if _.contains(rest_index, ['%(2%)', '②']):
            gender = 'n'  # fixme: ????
            i.forced_stem = p.stems['gen-pl']
            stem = p.stems['gen-pl']
            _.log_info('New force stem (gen-pl): ' + str(stem))
            force_b = True
        # end

        # TODO: б) в словах прочих схем ударения — на последний слог основы, если основа не содержит беглой гласной, и на предпоследний слог основы, если основа содержит беглую гласную, на¬пример: величина, тюрьма, полотно (схема d) — И.мн. величины, тюрьмы, полотна, Р.мн. ве¬личин, тюрем, полотен.
        # это для глАзок

        if (reduced == 'B'
                or force_b) and not skip_b_1 and not skip_b_2 and not skip_b_3:
            if i.adj:
                case = 'srt-sg'
            else:
                case = 'gen-pl'
            # end

            _.log_info('Зашли в случай чередования B')
            if i.stem.type == '6-vowel':  # 1).
                _.log_info('Подслучай B.1).')
                if _.In(i.stress_type, {
                        'b', 'c', 'e', 'f', "f'", "b'"
                }):  # gen-pl ending stressed  -- TODO: special vars for that
                    _.replace(p.stems, case, 'ь$', 'е́')
                else:
                    _.replace(p.stems, case, 'ь$', 'и')
                # end
            elif _.contains(stem, '[ьй]{consonant}$'):  # 2).
                _.log_info('Подслучай B.2).')
                if i.adj:
                    e = i.stem.type == '5-letter-ц' or not _.contains(
                        i.stress_type, 'b') or _.endswith(
                            i.stress_type,
                            ['/b', "/b'"])  # todo: fix only "b" for srt...
                else:
                    e = i.stem.type == '5-letter-ц' or _.equals(
                        i.stress_type, ['a', 'd', "d'"]
                    )  # gen_pl ending unstressed  -- TODO: special vars for that
                # end
                if e:
                    _.replace(p.stems, case, '[ьй]({consonant})$', 'е%1')
                else:
                    _.replace(p.stems, case, '[ьй]({consonant})$', 'ё%1')
                # end
            else:  # 3).
                prev = _.extract(stem, '(.){consonant}$')
                case_3_a = i.stem.type == '3-velar' and _.contains(
                    prev, '[^жшчщц]')  # 3). а).
                case_3_b = _.contains(prev, '[кгх]')  # 3). б).
                if case_3_a or case_3_b:
                    _.log_info('Подслучай B.3). а,б).')
                    _.replace(p.stems, case, '(.)({consonant})$', '%1о%2')
                else:  # 3). в).
                    _.log_info('Подслучай B.3). в).')
                    if i.stem.type == '5-letter-ц':
                        _.log_info('i.stem.type == "letter-ц"')
                        _.replace(p.stems, case, '(.)({consonant})$', '%1е%2')
                    else:
                        if i.adj:
                            e = _.equals(i.stress_type, 'b') or _.endswith(
                                i.stress_type,
                                ['/b', "/b'"])  # TODO: special vars for that
                        else:
                            e = _.In(
                                i.stress_type,
                                {'b', 'c', 'e', 'f', "f'", "b'"}
                            )  # gen_pl ending stressed  -- TODO: special vars for that
                        # end
                        if e:
                            _.log_info('в `' + case +
                                       '` ударение на окончание')
                            p.stems[case] = stem
                            if _.contains(prev, '[жшчщ]'):
                                _.log_info('предыдущая [жшчщ]')
                                _.replace(p.stems, case, '(.)({consonant})$',
                                          '%1о́%2')
                            else:
                                _.log_info('предыдущая не [жшчщ]')
                                _.replace(p.stems, case, '(.)({consonant})$',
                                          '%1ё%2')
                            # end
                        else:
                            _.log_info('ударение на основу в ["' + case +
                                       '"] ')
                            _.replace(p.stems, case, '(.)({consonant})$',
                                      '%1е%2')
                        # end
                    # end
                # end
            # end
            if i.stem.type == '2-soft' and _.endswith(
                    i.word.unstressed, 'ня'
            ) and i.stress_type == 'a' and p.endings['gen-pl'] == 'ь':
                p.endings['gen-pl'] = ''  # вместо `ь` для `2*a`
            # end
            if gender == 'm' and i.adj and _.endswith(
                    i.word.unstressed, 'ний') and p.endings['srt-sg'] == 'ь':
                p.endings['srt-sg'] = ''  # вместо `ь` для `2*a`