Exemplo n.º 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)
Exemplo n.º 2
0
def generate_result(func, i):  # export
    r = i.result  # local

    init_forms.init_forms(i)
    if i.adj:
        init_forms.init_srt_forms(i)
    # end
    _.log_table(r, 'i.result')

    common_forms.fix_stress(i)

    if i.adj and i.calc_pl:
        # `calc_pl` -- чтобы считать их только один раз, а не для каждого рода
        adj_forms.add_comparative(i)
    # end

    for key, value in r.items():
        # replace 'ё' with 'е' when unstressed
        # if _.contains_once(i.stem.unstressed, 'ё') and _.contains(value, '́ ') and _.contains(i.rest_index, 'ё'):  -- trying to bug-fix
        if _.contains_once(value, 'ё') and _.contains(value, '́ ') and _.contains(i.rest_index, 'ё'):
            if i.adj and _.contains(i.stress_type, "a'") and i.gender == 'f' and key == 'srt-sg':
                r[key] = _.replaced(value, 'ё', 'е') + ' // ' + _.replaced(value, '́', '')
            else:
                r[key] = _.replaced(value, 'ё', 'е')  # обычный случай
            # end
        # end
    # end

    if i.noun:
        noun_forms.apply_obelus(i)
    # end

    common_forms.choose_accusative_forms(i)

    common_forms.second_ins_case(i)

    if i.noun:
        noun_forms.apply_specific_3(i)
    # end

    for key, value in r.items():
#        INFO Удаляем ударение, если только один слог:
        r[key] = noun_forms.remove_stress_if_one_syllable(value)
    # end

    if i.adj:
        if i.postfix:
            # local keys
            keys = [
                'nom-sg', 'gen-sg', 'dat-sg', 'acc-sg', 'ins-sg', 'prp-sg',
                'nom-pl', 'gen-pl', 'dat-pl', 'acc-pl', 'ins-pl', 'prp-pl',
            ]  # list
            for j, key in enumerate(keys):
                r[key] = r[key] + 'ся'
            # end
        # end
    # end

    _.ends(module, func)
Exemplo n.º 3
0
def process(func, i):  # export
    _.log_info('Извлечение информации об ударении (stress_type)')
    stress.extract_stress_type(i)  # todo: move to `parse`
    _.log_value(i.stress_type, 'i.stress_type')

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

    if not i.stress_type:  # если ударение не указано
        if _.contains(i.rest_index, '0'):  # если несклоняемая схема
            i.stress_type = ''
        else:
            # INFO: Если при этом есть какой-то индекс, это явно ОШИБКА
            if _.has_value(i.rest_index):
                e.add_error(i, 'Нераспознанная часть индекса: ' + i.rest_index)
                return _.returns(module, func, i)
            # end

            # INFO: Если же индекса вообще нет, то и формы просто не известны:
            i.has_index = False
            return _.returns(module, func, i)
        # end
    # end

    _.log_info('Вычисление схемы ударения')
    stress.get_stress_schema(i)

    _.log_info('Определение типа основы (stem_type)')
    stem_type.get_stem_type(i)
    _.log_value(i.stem.type, 'i.stem.type')
    _.log_value(i.stem.base_type, 'i.stem.base_type')

    # INFO: Итак, ударение мы получили.

    # INFO: Добавление ударения для `stem.stressed` (если его не было)
    # INFO: Например, в слове только один слог, или ударение было на окончание
    if not _.contains(i.stem.stressed, '[́ ё]'):  # and not i.absent_stress ??
        if _.equals(i.stress_type, ["f", "f'"]):
            i.stem.stressed = _.replaced(i.stem.stressed,
                                         '^({consonant}*)({vowel})', '%1%2́ ')
        elif _.contains(i.rest_index, '%*'):
            pass  # *** поставим ударение позже, после чередования
        else:
            i.stem.stressed = _.replaced(i.stem.stressed,
                                         '({vowel})({consonant}*)$', '%1́ %2')
        # end
    # end

    _.log_value(i.stem.stressed, 'i.stem.stressed')

    _.log_info('Инициализируем `i.result`')
    init_result.init_result(i)

    return _.returns(module, func, i)
Exemplo n.º 4
0
def apply_specific_3(func, i):  # export
    r = i.result  # local

    # Специфика по (3)
    if _.contains(i.rest_index, '%(3%)') or _.contains(i.rest_index, '③'):
        if _.endswith(r['prp-sg'], 'и'):
            r['prp-sg'] = r['prp-sg'] + '&nbsp;//<br />' + _.replaced(r['prp-sg'], 'и$', 'е')
        # end
        if i.gender == 'f' and _.endswith(r['dat-sg'], 'и'):
            r['dat-sg'] = r['dat-sg'] + '&nbsp;//<br />' + _.replaced(r['dat-sg'], 'и$', 'е')
        # end
    # end

    _.ends(module, func)
Exemplo n.º 5
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)
Exemplo n.º 6
0
def init_stem(func, i):  # export  # todo rename to `init_stem`

    # INFO: Исходное слово без ударения:
    i.word.unstressed = _.replaced(i.word.stressed, '́ ',
                                   '')  # todo: move outside this function

    # INFO: Исходное слово вообще без ударений (в т.ч. без грависа):
    i.word.cleared = _.replaced(
        _.replaced(_.replaced(i.word.unstressed, '̀', ''), 'ѐ', 'е'), 'ѝ', 'и')

    if i.adj:
        if _.endswith(i.word.stressed, 'ся'):
            i.postfix = True
            i.stem.unstressed = _.replaced(i.word.unstressed,
                                           '{vowel}[йяе]ся$', '')
            i.stem.stressed = _.replaced(i.word.stressed, '{vowel}́ ?[йяе]ся$',
                                         '')
        else:
            i.stem.unstressed = _.replaced(i.word.unstressed, '{vowel}[йяе]$',
                                           '')
            i.stem.stressed = _.replaced(i.word.stressed, '{vowel}́ ?[йяе]$',
                                         '')
        # end
    else:
        # INFO: Удаляем окончания (-а, -е, -ё, -о, -я, -й, -ь), чтобы получить основу:
        i.stem.unstressed = _.replaced(i.word.unstressed, '[аеёийоьыя]$', '')
        i.stem.stressed = _.replaced(i.word.stressed, '[аеёийоьыя]́ ?$', '')
    # end

    _.log_value(i.word.unstressed, 'i.word.unstressed')
    _.log_value(i.stem.unstressed, 'i.stem.unstressed')
    _.log_value(i.stem.stressed, 'i.stem.stressed')

    #  INFO: Случай, когда не указано ударение у слова:
    several_vowels = _.contains_several(i.word.stressed, '{vowel+ё}')  # local
    has_stress = _.contains(i.word.stressed, '[́ ё]')  # local
    if several_vowels and not has_stress:
        _.log_info('Ошибка: Не указано ударение в слове')
        e.add_error(i, 'Ошибка: Не указано ударение в слове')
        i.result.error_category = 'Ошибка в шаблоне "сущ-ru" (не указано ударение в слове)'
    # end

    _.ends(module, func)
Exemplo n.º 7
0
def add_comparative(func, i):  # export
    # todo: move to `modify` (и сделать через основы и окончания)
    r = i.result  # local

    if _.contains(i.rest_index, '~'):
        r['comparative'] = '-'
        return _.ends(module, func)
    # end

    if i.stem.type == '3-velar':
        new_stem = i.stem.unstressed
        if _.endswith(new_stem, 'к'):
            new_stem = _.replaced(new_stem, 'к$', 'ч')
        elif _.endswith(new_stem, 'г'):
            new_stem = _.replaced(new_stem, 'г$', 'ж')
        elif _.endswith(new_stem, 'х'):
            new_stem = _.replaced(new_stem, 'х$', 'ш')
        else:
            pass  # todo: some error here
        # end

        # ударение на предпоследний слог:
        new_stem = _.replaced(new_stem, '({vowel})({consonant}*)$', '%1́ %2')

        r['comparative'] = new_stem + 'е'
    else:
        if _.contains(i.rest_index, ['%(2%)', '②']):  # todo: special variable for this
            r['comparative'] = i.parts.stems['nom-pl'] + 'ее'
            r['comparative2'] = i.parts.stems['nom-pl'] + 'ей'
        else:
            if _.equals(i.stress_type, ['a', 'a/a']):
                r['comparative'] = i.stem.stressed + 'ее'
                r['comparative2'] = i.stem.stressed + 'ей'
            else:
                r['comparative'] = i.stem.unstressed + 'е́е'
                r['comparative2'] = i.stem.unstressed + 'е́й'
            # end
        # end
    # end

    _.ends(module, func)
Exemplo n.º 8
0
def second_ins_case(func, i):  # export
    r = i.result  # local

    # Второй творительный
    if i.gender == 'f' and i.calc_sg:
        ins_sg2 = _.replaced(r['ins-sg'], 'й$', 'ю')  # local
        if ins_sg2 != r['ins-sg']:
            _.log_info(
                'Замена "й" на "ю" для второго творительного женского рода')
            r['ins-sg2'] = ins_sg2
        # end
    # end

    _.ends(module, func)
Exemplo n.º 9
0
def transform(func, i):  # export
    # local stem_stress_schema
    p = i.parts  # local

    # apply special cases (1) or (2) in index
    if i.adj:
        adj_circles.apply_adj_specific_1_2(i)
    # end

    #    *** для случая с расстановкой ударения  (см. ниже)
    #    # local orig_stem = i.stem.unstressed
    #    if _.contains(i.rest_index, ['%(2%)', '②']):
    #        orig_stem = _.replaced(p.stems['gen-pl'], '́ ', '')  -- удаляем ударение для случая "сапожок *d(2)"
    #        mw.log('> Another `orig_stem`: ' + str(orig_stem))
    #    # end

    # reducable
    i.rest_index = degree.apply_specific_degree(i)
    reducable.apply_specific_reducable(i, i.gender, i.rest_index, False)
    if not _.equals(i.stress_type, ["f", "f'"]) and _.contains(
            i.rest_index, '%*'):
        _.log_info(
            'Обработка случая на препоследний слог основы при чередовании')
        orig_stem = i.stem.unstressed
        if i.forced_stem:
            orig_stem = i.forced_stem
        # end
        for key, stem in p.stems.items():
            # mw.log(' - ' + key + ' -> ' + stem)
            # mw.log('Ударение на основу?')
            # mw.log(i.stress_schema['stem'][key])
            stem_stress_schema = i.stress_schema['stem']
            if not _.contains(stem, '[́ ё]') and _.has_key(
                    stem_stress_schema, key) and stem_stress_schema[key]:
                # *** случай с расстановкой ударения  (см. выше)
                # "Дополнительные правила об ударении", стр. 34
                old_value = p.stems[key]
                # mw.log('> ' + key + ' (old): ' + str(old_value))
                if p.stems[
                        key] != orig_stem:  # попытка обработать наличие беглой гласной (не знаю, сработает ли всегда)
                    p.stems[key] = _.replaced(
                        stem,
                        '({vowel})({consonant}*)({vowel})({consonant}*)$',
                        '%1́ %2%3%4')
                    if not _.contains(
                            p.stems[key],
                            '[́ ё]'):  # если предпоследнего слога попросту нет
                        # сделаем хоть последний ударным
                        p.stems[key] = _.replaced(stem,
                                                  '({vowel})({consonant}*)$',
                                                  '%1́ %2')
                    # end
                else:
                    p.stems[key] = _.replaced(stem, '({vowel})({consonant}*)$',
                                              '%1́ %2')
                # end
                # mw.log('> ' + key + ' (new): ' + str(p.stems[key]))
                mw.log('  - ' + key + ': "' + str(old_value) + '" -> "' +
                       str(p.stems[key]) + '"')
            # end
        # end
    # end

    if i.calc_pl:
        # Специфика по "ё"
        if _.contains(i.rest_index, 'ё') and not _.contains(
                p.endings['gen-pl'], '{vowel+ё}') and not _.contains(
                    p.stems['gen-pl'], 'ё'):
            p.stems['gen-pl'] = _.replaced(p.stems['gen-pl'], 'е́?([^е]*)$',
                                           'ё%1')
            i.rest_index = i.rest_index + 'ё'  # ???
        # end
    # end

    _.ends(module, func)
Exemplo n.º 10
0
def remove_stress_if_one_syllable(value):  # export
    if _.contains_once(value, '{vowel+ё}'):
        return _.replaced(value, '́ ', '')
    # end
    return value
Exemplo n.º 11
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)
Exemplo n.º 12
0
def get_zaliznyak(func, i):  # export
    # TODO: process <...> cases properly
    #  also e.g. "2*a + <п 1a>"
    r = i.result  # local

    if not i.has_index:
        r['зализняк1'] = '??'
        return _.ends(module, func)
    # end

    # local stem_types
    stem_types = {
        '1-hard': '1',
        '2-soft': '2',
        '3-velar': '3',
        '4-sibilant': '4',
        '5-letter-ц': '5',
        '6-vowel': '6',
        '7-letter-и': '7',
        '8-third': '8',
    }
    index = '?'  # local
    if _.contains(i.rest_index, '0'):
        index = '0'
    else:
        # index = i.stem.type[0]  -- TODO
        index = stem_types[i.stem.type]
    # end
    if _.contains(i.rest_index, '°'):
        index = index + '°'
    elif _.contains(i.rest_index, '%*'):
        index = index + '*'
    # end
    index = index + _.replaced(i.stress_type, "'", "&#39;")
    if _.contains(i.rest_index, ['⊠', '%(x%)', '%(х%)', '%(X%)', '%(Х%)']):
        index = index + '⊠'
    elif _.contains(i.rest_index, ['✕', '×', 'x', 'х', 'X', 'Х']):
        index = index + '✕'
    # end
    if _.contains(i.rest_index, ['%(1%)', '①']):
        index = index + '①'
    # end
    if _.contains(i.rest_index, ['%(2%)', '②']):
        index = index + '②'
    # end
    if _.contains(i.rest_index, ['%(3%)', '③']):
        index = index + '③'
    # end
    if _.contains(i.rest_index, '÷'):
        index = index + '÷'
    # end
    if _.contains(i.rest_index, ['%-', '—', '−']):
        index = index + '−'
    # end
    if _.contains(i.rest_index, 'ё'):
        index = index + ', ё'
    # end

    r['зализняк1'] = index
    value = r['зализняк1']  # local  # for category
    value = _.replaced(value, '①', '(1)')
    value = _.replaced(value, '②', '(2)')
    value = _.replaced(value, '③', '(3)')
    r['зализняк'] = value

    _.ends(module, func)