Exemplo n.º 1
0
def init_result(func, i):  # export
    r = i.result  # local

    r['stem_type'] = i.stem.type  # for testcases
    r['stress_type'] = i.stress_type  # for categories   -- is really used?

    r['dev'] = dev_prefix

    index.get_zaliznyak(i)

    additional_arguments(i)

    if i.noun:
        forward_gender_animacy(i)
    # end

    if i.adj:
        if _.contains(i.rest_index, ['⊠', '%(x%)', '%(х%)', '%(X%)', '%(Х%)']):
            r['краткая'] = '⊠'
        elif _.contains(i.rest_index, ['✕', '×', 'x', 'х', 'X', 'Х']):
            r['краткая'] = '✕'
        elif _.contains(i.rest_index, ['%-', '—', '−']):
            r['краткая'] = '−'
        else:
            r['краткая'] = '1'
        # end
    # end

    if not _.has_key(r, 'error_category') and i.word.cleared != i.base:
        r['error_category'] = 'Ошибка в шаблоне "сущ-ru" (слово не совпадает с заголовком статьи)'
    # end

    forward.forward_args(i)

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

    if i.calc_sg:
        if not _.endswith(p.stems['srt-sg'], 'нн'):
            # todo: log some error?
            return _.ends(module, func)
        # end
        if _.contains(i.rest_index, ['%(1%)', '①']):
            if i.gender == 'm':
                _.replace(p.stems, 'srt-sg', 'нн$', 'н')
            # end
        # end
    # end

    if _.contains(i.rest_index, ['%(2%)', '②']):
        if i.calc_sg:
            _.replace(p.stems, 'srt-sg', 'нн$', 'н')
        # end
        if i.calc_pl:
            _.replace(p.stems, 'srt-pl', 'нн$', 'н')
        # end
    # end

    _.ends(module, func)
Exemplo n.º 3
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.º 4
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.º 5
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.º 6
0
def apply_noun_specific_1_2(func, i):  # export
    p = i.parts  # local

    if _.contains(i.rest_index, ['%(1%)', '①']):
        if i.stem.base_type == '1-hard':
            if i.gender == 'm': p.endings['nom-pl'] = 'а'  # end
            if i.gender == 'n': p.endings['nom-pl'] = 'ы'  # end
        # end
        if i.stem.base_type == '2-soft':
            if i.gender == 'm': p.endings['nom-pl'] = 'я'  # end
            if i.gender == 'n': p.endings['nom-pl'] = 'и'  # end
        # end
        if _.equals(i.stem.type,
                    ['3-velar', '4-sibilant']):  # Replace "ы" to "и"
            if i.gender == 'n': p.endings['nom-pl'] = 'и'  # end
        # end
    # end

    if _.contains(i.rest_index, ['%(2%)', '②']):
        if i.stem.base_type == '1-hard':
            if i.gender == 'm': p.endings['gen-pl'] = ['', '']  # end
            if i.gender == 'n': p.endings['gen-pl'] = ['ов', 'ов']  # end
            if i.gender == 'f': p.endings['gen-pl'] = {'ей', 'ей'}  # end
        # end
        if i.stem.base_type == '2-soft':
            if i.gender == 'm': p.endings['gen-pl'] = ['ь', 'ь']  # end
            if i.gender == 'n': p.endings['gen-pl'] = ['ев', 'ёв']  # end
            if i.gender == 'f': p.endings['gen-pl'] = {'ей', 'ей'}  # end
        # end
        if _.equals(
                i.stem.type,
            ['4-sibilant', '5-letter-ц']):  # Replace unstressed "о" to "е"
            if i.gender == 'n': p.endings['gen-pl'][unstressed] = 'ев'  # end
        # end

#        # Possibly we don't need this:
#            # Replace "ов", "ев", "ёв" and null to "ей"
#            if i.stem.type = {'4-sibilant'}}
#                if i.gender == 'n': p.endings['gen-pl'] = ['ей', 'ей']
#                if i.gender == 'm': p.endings['gen-pl'][stressed] = 'ей'
#            # end
#            # Replace "ь" to "й"
#            if i.stem.type = ['6-vowel', '7-letter-и']}
#                if i.gender == 'm': p.endings['gen-pl'][stressed] = ['й', 'й']
#            # end
#            # Replace "ей" to "ев/ёв", and "ь,ей" to "й"
#            if i.stem.type = ['6-vowel', '7-letter-и']}
#                if i.gender == 'f': p.endings['gen-pl'][unstressed] = ['ев', 'ёв']
#                if i.gender == 'm': p.endings['gen-pl'][stressed] = ['й', 'й']
#            # end
#        #
# end

    _.ends(module, func)
Exemplo n.º 7
0
def prt_case(func, i):  # Разделительный падеж
    r = i.result  # local

    if _.contains(i.index, 'Р2') or _.contains(i.index, 'Р₂'):
        r['prt-sg'] = r['dat-sg']
    # end
    if _.has_value(i.args, 'Р'):
        r['prt-sg'] = i.args['Р']
    # end

    _.ends(module, func)
Exemplo n.º 8
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.º 9
0
def fix_stress(func, i):  # export
    r = i.result  # local

    # Add stress if there is no one
    if i.calc_sg and _.contains_several(
            r['nom-sg'], '{vowel}') and not _.contains(r['nom-sg'], '[́ ё]'):
        # perhaps this is redundant for nom-sg?
        _.replace(r, 'nom-sg', '({vowel})({consonant}*)$', '%1́ %2')
    # end
    if i.calc_pl and _.contains_several(
            r['gen-pl'], '{vowel+ё}') and not _.contains(r['gen-pl'], '[́ ё]'):
        _.replace(r, 'gen-pl', '({vowel})({consonant}*)$', '%1́ %2')
    # end

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

    if _.contains(i.rest_index, '0'):
        # todo: move to special function
        # local keys
        keys = [  # todo: depend on `calc_sg` and `calc_pl`
            '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] = i.word.stressed
        # end
        return _.ends(module, func)
    # end

    p.generate_parts(i)
    res.generate_result(i)

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

    # RU (склонение)
    if _.contains(i.rest_index, '0'):
        r['скл'] = 'не'
    elif i.adj:
        r['скл'] = 'а'
    elif i.pronoun:
        r['скл'] = 'мс'
    elif _.endswith(i.word.unstressed, '[ая]'):
        r['скл'] = '1'
    else:
        if i.gender == 'm' or i.gender == 'n':
            r['скл'] = '2'
        else:
            r['скл'] = '3'
        # end
    # end

    # RU (чередование)
    if _.contains(i.index, '%*'):
        r['чередование'] = '1'
    # end

    if i.pt:
        r['pt'] = '1'
    # end

    # RU ("-" в индексе)
    # TODO: Здесь может быть глюк, если случай глобального `//` и `rest_index` пуст (а исходный `index` не подходит, т.к. там может быть не тот дефис -- в роде)
    if i.rest_index:
        if _.contains(i.rest_index, ['%-', '—', '−']):
            r['st'] = '1'
            r['затрудн'] = '1'
        # end
    else:
        pass  # TODO
    # end

    _.ends(module, func)
Exemplo n.º 12
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.º 13
0
def voc_case(func, i):  # Звательный падеж
    r = i.result  # local

    if _.has_value(i.args, 'З'):
        r['voc-sg'] = i.args['З']
    elif _.contains(i.index, 'З'):
        if _.endswith(i.word.unstressed, ['а', 'я']):
            r['voc-sg'] = r['gen-pl']
        else:
            r['error'] = 'Ошибка: Для автоматического звательного падежа, слово должно оканчиваться на -а/-я'
        # end
    # end

    _.ends(module, func)
Exemplo n.º 14
0
def forward_args(func, i):  # export
    # INFO: Используется дважды -- при инициализации, и потом в самом конце

    # local keys, args
    r = i.result  # local

    args = i.args
    keys = [
        'nom-sg',  'gen-sg',  'dat-sg',  'acc-sg',  'ins-sg',  'prp-sg',
        'nom-sg2', 'gen-sg2', 'dat-sg2', 'acc-sg2', 'ins-sg2', 'prp-sg2',
        'nom-pl',  'gen-pl',  'dat-pl',  'acc-pl',  'ins-pl',  'prp-pl',
        'nom-pl2', 'gen-pl2', 'dat-pl2', 'acc-pl2', 'ins-pl2', 'prp-pl2',
        'voc-sg',  'loc-sg',  'prt-sg', 'srt-sg-m', 'srt-sg-f', 'srt-sg-n',
        'srt-pl', 'comparative', 'comparative2'
    ]  # list
    for j, key in enumerate(keys):
        if _.has_value(args, key):
            if args[key] == '-':
                r[key] = args[key]
            else:
                r[key] = args[key] + '<sup>△</sup>'
            # end
        # end
    # end

    keys = [
        'П', 'Пр', 'Сч',
        'hide-text', 'зачин', 'слоги', 'дореф',
        'скл', 'зализняк', 'зализняк1', 'чередование',
        'pt', 'st', 'затрудн', 'клитика',
        'коммент', 'тип', 'степень',
    ]  # list
    for j, key in enumerate(keys):
        if _.has_value(args, key):
            r[key] = args[key]
        # end
    # end

    if _.has_key(r, 'слоги'):
        if not _.contains(r['слоги'], '%<'):
            r['слоги'] = syllables.get_syllables(r['слоги'])
        # end
    else:
        r['слоги'] = i.word.unstressed  # fixme: может всё-таки stressed?
    # end

    _.ends(module, func)
Exemplo n.º 15
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.º 16
0
def get_stress_schema(func, i):  # export
    if _.contains(i.rest_index, '0'):
        _.log_info('Игнорируем схему ударения для случая "0"')
        i.stress_schema = dict()  # dict
        return _.ends(module, func)
    # end

    unit = ''  # todo: get from i.unit ?
    if i.adj:
        unit = 'adj'
    elif i.pronoun:
        unit = 'pronoun'
    else:
        unit = 'noun'
    # end
    _.log_value(unit, 'unit')
    _.log_value(i.unit, 'i.unit')

    stress_schemas = json_load(
        '../modules/dev/dev_py/ru/declension/data/stress/' + unit + '.json')
    stress_schema = stress_schemas[i.stress_type]  # local

    # ручное клонирование схемы ударения, т.к. потом через mw.clone не работает
    # ошибка: "table from mw.loadData is read-only"
    i.stress_schema = dict()  # dict
    types = ['stem', 'ending']  # local
    for j, type in enumerate(types):
        i.stress_schema[type] = dict()  # dict
        for case, value in stress_schema[type].items():
            i.stress_schema[type][case] = value
        # end
    # end

    _.log_table(i.stress_schema['stem'], "i.stress_schema['stem']")
    _.log_table(i.stress_schema['ending'], "i.stress_schema['ending']")

    _.ends(module, func)
Exemplo n.º 17
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`
Exemplo n.º 18
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.º 19
0
def parse(func, base, args, frame):  # export
    i = a.AttrDict()  # AttrDict  # local
    i.word = a.AttrDict()  # AttrDict
    i.stem = a.AttrDict()  # AttrDict
    i.parts = a.AttrDict()  # AttrDict
    i.result = a.AttrDict()  # AttrDict
    i.result.error = ''
    i.has_index = True  # изначально предполагаем, что индекс есть

    # INFO: Достаём значения из параметров:
    i.base = base
    i.args = args
    i.frame = frame
    i.lang = mw.text.trim(args['lang'])
    i.unit = mw.text.trim(args['unit'])
    i.index = mw.text.trim(args['индекс'])
    i.word.stressed = mw.text.trim(args['слово'])
    i.noun = (i.unit == 'noun')

    _.log_value(i.index, 'i.index')
    _.log_value(i.word.stressed, 'i.word.stressed')

    # mw.log('')
    # mw.log('==================================================')
    # mw.log('args: ' + str(i.index) + ' | ' + str(i.word.stressed))
    # mw.log('--------------------------------------------------')

    _.log_info('Получение информации о роде и одушевлённости')

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

        # Будем расчитывать оба числа сразу вместе
        i.calc_sg = True
        i.calc_pl = True

        _.log_value(i.gender, 'i.gender')
        _.log_value(i.animacy, 'i.animacy')
        _.log_value(i.common_gender, 'i.common_gender')
        _.log_value(i.adj, 'i.adj')
        _.log_value(i.pronoun, 'i.pronoun')
    else:
        i.gender = ''  # fixme
        i.animacy = ''  # fixme
        i.adj = True  # fixme
        i.rest_index = i.index  # fixme

        # Будем расчитывать позже по отдельности
        i.calc_sg = False
        i.calc_pl = False
    # end

    _.log_value(i.pt, 'i.pt')
    _.log_value(i.rest_index, 'i.rest_index')

    # INFO: stem, stem.stressed, etc.
    init_stem.init_stem(i)
    if e.has_error(i):
        return _.returns(module, func, i)
    # end

    if i.noun:
        # INFO: Случай, если род или одушевлённость не указаны:
        if (not i.gender or not i.animacy) and not i.pt:
            # INFO: Не показываем ошибку, просто считаем, что род или одушевлённость *ещё* не указаны
            return _.returns(module, func, i)
        # end
    # end

    # INFO: Проверяем случай с вариациями:
    variations = mw.text.split(i.rest_index, '//')  # local
    n_variations = a.table_len(variations)  # local

    if n_variations == 1:  # INFO: Дополнительных вариаций нет
        if _.contains(i.animacy, '//'):  # INFO: Случаи 'in//an' и 'an//in'
            v.process_animacy_variations(i)
            return _.returns(module, func, i)
            # TODO: А что если in//an одновременно со следующими случаями "[]" или "+"
        # end

        # _.log_info('Случай с "+" (несколько составных частей слова через дефис)')

        plus_index = mw.text.split(i.rest_index, '%+')  # local
        plus_words = mw.text.split(i.word.stressed, '-')  # local
        n_plus = a.table_len(plus_index)  # local
        if n_plus > 1:
            v.process_plus(i, plus_words, plus_index)
            return _.returns(module, func, i)
        # end

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

        if _.contains(i.rest_index, '%[%([12]%)%]') or _.contains(
                i.rest_index, '%[[①②]%]'):
            v.process_brackets_variations(i)
            return _.returns(module, func, i)
        # end

    elif n_variations == 2:  # INFO: Вариации "//" для ударения (и прочего индекса)
        _.log_info('> Случай с вариациями //')

        if _.contains(i.animacy, '//'):
            # INFO: Если используются вариации одновременно и отдельно для одушевлённости и ударения
            e.add_error(
                i,
                'Ошибка: Случай с несколькими "//" пока не реализован. Нужно реализовать?'
            )
            return _.returns(module, func, i)
        # end

        v.process_full_variations(i, variations)

        return _.returns(module, func, i)

    else:  # INFO: Какая-то ошибка, слишком много "//" в индексе
        e.add_error(i, 'Ошибка: Слишком много частей для "//"')
        return _.returns(module, func, i)
    # end

    _.ends(module, func)
    return p.process(i)
Exemplo n.º 20
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)
Exemplo n.º 21
0
def apply_specific_degree(func, i):  # export
    # If degree sign °
    p = i.parts  # local
    word = i.word.unstressed  # local

    if _.contains(i.rest_index, '°') and _.endswith(word, '[ая]нин'):
        _.replace(p.stems, 'all-pl', '([ая])ни́ н$', '%1́ н')
        _.replace(p.stems, 'all-pl', '([ая]́ ?н)ин$', '%1')
        p.endings['nom-pl'] = 'е'
        p.endings['gen-pl'] = ''
        return _.returns(module, func, i.rest_index)
    # end

    if _.contains(i.rest_index, '°') and _.endswith(word, 'ин'):
        _.replace(p.stems, 'all-pl', 'и́ ?н$', '')
        if not _.contains(i.rest_index, ['%(1%)', '①']):
            p.endings['nom-pl'] = 'е'
        # end
        p.endings['gen-pl'] = ''
    # end

    if _.contains(i.rest_index, '°') and _.endswith(word, ['ёнок', 'онок']):
        _.replace(p.stems, 'all-pl', 'ёнок$', 'я́т')
        _.replace(p.stems, 'all-pl', 'о́нок$', 'а́т')

        # INFO: Эмуляция среднего рода `1a` для форм мн. числа
        p.endings['nom-pl'] = 'а'
        p.endings['gen-pl'] = ''

        reducable.apply_specific_reducable(i, i.gender, i.rest_index + '*',
                                           True)
        return _.returns(module, func, i.rest_index)
    # end

    if _.contains(i.rest_index, '°') and _.endswith(word,
                                                    ['ёночек', 'оночек']):

        _.replace(p.stems, 'all-pl', 'ёночек$', 'я́тк')
        _.replace(p.stems, 'all-pl', 'о́ночек$', 'а́тк')

        # INFO: Черездование для единичной формы (возможно применится также и для множественной, но это не страшно, потом заменится по идее)
        reducable.apply_specific_reducable(i, i.gender, i.rest_index + '*',
                                           False)

        # INFO: По сути должно примениться только к мн. формам (случай `B`)
        reducable.apply_specific_reducable(i, 'f', i.rest_index + '*', False)

        p.endings['gen-pl'] = ''  # INFO: Странный фикс, но он нужен.. <_<

        return _.returns(module, func, i.rest_index)
    # end

    if _.contains(i.rest_index, '°') and i.gender == 'n' and _.endswith(
            word, 'мя'):
        _.replace(p.stems, 'all-sg', 'м$', 'мен')
        _.replace(p.stems, 'ins-sg', 'м$', 'мен')
        _.replace(p.stems, 'all-pl', 'м$', 'мен')

        p.endings['nom-sg'] = 'я'
        p.endings['gen-sg'] = 'и'
        p.endings['dat-sg'] = 'и'
        p.endings['ins-sg'] = 'ем'
        p.endings['prp-sg'] = 'и'
    # end

    return _.returns(module, func, i.rest_index)
Exemplo n.º 22
0
def get_stem_type(func, i):  # export  # INFO: Определение типа основы
    word = i.word.unstressed  # local
    stem = i.stem.unstressed  # local

    i.stem.type = ''

    if _.endswith(stem, '[гкх]'):
        i.stem.type = '3-velar'
    elif _.endswith(stem, '[жчшщ]'):
        i.stem.type = '4-sibilant'
    elif _.endswith(stem, 'ц'):
        i.stem.type = '5-letter-ц'
    elif _.endswith(stem, ['[йь]', '[аоеёуыэюя]']):
        i.stem.type = '6-vowel'
    elif _.endswith(stem, 'и'):
        i.stem.type = '7-letter-и'
    else:
        if i.adj:
            if _.endswith(word, ['ый', 'ой', 'ая', 'ое', 'ые']):
                i.stem.type = '1-hard'
            elif _.endswith(word, ['ий', 'яя', 'ее', 'ие']):
                i.stem.type = '2-soft'
            # end
        elif i.gender == 'm':
            if stem == word or _.endswith(word, 'ы'):
                i.stem.type = '1-hard'
            elif _.endswith(word, 'путь'):
                i.stem.type = '8-third'
            elif _.endswith(word, 'ь') or _.endswith(word, 'и'):
                i.stem.type = '2-soft'
            elif _.endswith(word, 'а'):
                i.stem.type = '1-hard'
                # i.gender = 'f' ??
            elif _.endswith(word, 'я'):
                i.stem.type = '2-soft'
                # i.gender = 'f' ??
            # end
        elif i.gender == 'f':
            if _.endswith(word, 'а') or _.endswith(word, 'ы'):
                i.stem.type = '1-hard'
            elif _.endswith(word, 'я'):
                i.stem.type = '2-soft'
            elif _.endswith(word, 'и') and _.contains(
                    i.rest_index, '2'):  # todo: а что если нет индекса??
                i.stem.type = '2-soft'
            elif _.endswith(word, 'и') and _.contains(i.rest_index, '8'):
                i.stem.type = '8-third'
            elif _.endswith(word, 'ь'):  # conflict in pl
                i.stem.type = '8-third'
            # end
        elif i.gender == 'n':
            if _.endswith(word, 'о') or _.endswith(word, 'а'):
                i.stem.type = '1-hard'
            elif _.endswith(word, 'мя') or _.endswith(word, 'мена'):
                i.stem.type = '8-third'
            elif _.endswith(word, 'е') or _.endswith(word, 'я'):
                i.stem.type = '2-soft'
            # end
        # end
    # end

#    if gender == 'm':
#        if _.endswith(word, ['а', 'я']):
#            i.gender = 'f'
#        # end
#    # end

    if i.gender == 'f' and i.stem.type == '4-sibilant' and _.endswith(
            word, 'ь'):
        i.stem.type = '8-third'
    # end
    if i.stem.type == '':
        i.stem.type = '1-hard'
        # e.add_error(i, 'Неизвестный тип основы')  -- fixme ?
        # return _.ends(module, func)
    # end

    # INFO: Выбор подходящего `stem_type` из двух базовых типов: '1-hard' и '2-soft'
    i.stem.base_type = get_stem_base_type(i)

    _.ends(module, func)
Exemplo n.º 23
0
def apply_obelus(func, i):  # export
    if _.contains(i.rest_index, '÷'):
        i.result['obelus'] = '1'
    # end
    _.ends(module, func)