Пример #1
0
def choose_endings_stress(func, i):
    p = i.parts  # local

    keys = [  # local
        'nom-sg',
        'gen-sg',
        'dat-sg',
        'acc-sg',
        'ins-sg',
        'prp-sg',  # 'srt-sg',
        'nom-pl',
        'gen-pl',
        'dat-pl',
        'acc-pl',
        'ins-pl',
        'prp-pl',  # 'srt-pl',
    ]  # list
    for j, key in enumerate(keys):
        if _.has_key(p.endings, key) and type(p.endings[key]) == list:  # type
            stress = i.stress_schema['ending'][
                key] and stressed or unstressed  # local
            p.endings[key] = p.endings[key][stress]
        # end
    # end

    if i.adj and i.gender == 'n':
        stress = i.stress_schema['ending'][
            'srt-sg-n'] and stressed or unstressed  # local
        p.endings['srt-sg'] = p.endings['srt-sg'][stress]
    # end

    _.ends(module, func)
Пример #2
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)
Пример #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 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)
Пример #5
0
def run(func, i):  # export
    # todo: move this `if` block inside `run_info` and run it recursively? :)
    if i.variations:
        _.log_info("Случай с вариациями '//'")
        i1 = i.variations[0]  # local
        i2 = i.variations[1]  # local
        run_info(i1)
        run_info(i2)
        i.result = v.join_forms(i1.result, i2.result)
        # todo: form.join_variations()
        # todo: check for errors inside variations
    elif i.plus:
        _.log_info("Случай с '+'")
        plus = []  # list  # local
        for j, sub_info in enumerate(i.plus):
            run_info(sub_info)
            plus.append(sub_info.result)
        # end
        i.result = v.plus_forms(plus)
        # todo: form.plus_out_args()
    else:
        _.log_info('Стандартный случай без вариаций')
        run_info(i)
    # end

    if i.noun:
        noun_forms.special_cases(
            i)  # todo: move to `run/result/generate_result`
    # end

    forward.forward_args(i)

    _.log_table(i.result, "i.result")
    _.ends(module, func)
Пример #6
0
def fill_other_pronoun_noun_endings(func, endings):
    mn_genders = ['m', 'n']  # local

    # INFO: Replace "ы" to "и"
    stem_type = '4-sibilant'  # local
    for j, gender in enumerate(mn_genders):
        endings[gender][stem_type]['ins-sg'] = 'им'
    # end
    for j, gender in enumerate(genders):
        endings[gender][stem_type]['nom-pl'] = 'и'
        endings[gender][stem_type]['gen-pl'] = 'их'
        endings[gender][stem_type]['dat-pl'] = 'им'
        endings[gender][stem_type]['ins-pl'] = 'ими'
        endings[gender][stem_type]['prp-pl'] = 'их'
    # end

    # INFO: Other Replace
    endings['n'][stem_type]['nom-sg'] = ['е', 'о']
    for j, gender in enumerate(mn_genders):
        endings[gender][stem_type]['gen-sg'] = ['его', 'ого']
        endings[gender][stem_type]['dat-sg'] = ['ему', 'ому']
        endings[gender][stem_type]['prp-sg'] = ['ем', 'ом']
    # end
    endings['f'][stem_type]['gen-sg'] = ['ей', 'ой']
    endings['f'][stem_type]['dat-sg'] = ['ей', 'ой']
    endings['f'][stem_type]['ins-sg'] = ['ей', 'ой']
    endings['f'][stem_type]['prp-sg'] = ['ей', 'ой']

    stem_type = '6-vowel'
    for j, gender in enumerate(mn_genders):
        endings[gender][stem_type]['gen-sg'] = 'его'
        endings[gender][stem_type]['dat-sg'] = 'ему'
    # end

    _.ends(module, func)
Пример #7
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)
Пример #8
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)
Пример #9
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)
Пример #10
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)
Пример #11
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)
Пример #12
0
def init_srt_forms(func, i):  # export  # todo move to `init_forms` (with if i.adj) ?
    p = i.parts  # local
    r = i.result  # local

    if i.calc_sg:
        r['srt-sg'] = p.stems['srt-sg'] + p.endings['srt-sg']
    # end
    if i.calc_pl:
        r['srt-pl'] = p.stems['srt-pl'] + p.endings['srt-pl']
    # end
    _.ends(module, func)
Пример #13
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)
Пример #14
0
def prepare(func, i):  # export
    # INFO: Generates `.endings` and `.stems`

    # todo: logging information
    endings.get_endings(i)

    # todo: logging information
    i.parts.stems = dict()  # dict
    stress_apply.apply_stress_type(i)
    _.log_table(i.parts.stems, 'i.parts.stems')
    _.log_table(i.parts.endings, 'i.parts.endings')

    _.ends(module, func)
Пример #15
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)
Пример #16
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)
Пример #17
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)
Пример #18
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)
Пример #19
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)
Пример #20
0
def choose_accusative_forms(func, i):  # export
    p = i.parts  # local
    r = i.result  # local

    if i.calc_sg:
        r['acc-sg-in'] = ''  # todo: remove this?
        r['acc-sg-an'] = ''

        if i.gender == 'm' or (i.gender == 'n' and i.output_gender == 'm'):
            if i.animacy == 'in':
                r['acc-sg'] = r['nom-sg']
            elif i.animacy == 'an':
                r['acc-sg'] = r['gen-sg']
            else:
                r['acc-sg-in'] = r['nom-sg']
                r['acc-sg-an'] = r['gen-sg']
            # end
        elif i.gender == 'f':
            if i.stem.type == '8-third':
                r['acc-sg'] = r['nom-sg']
            else:
                r['acc-sg'] = p.stems['acc-sg'] + p.endings[
                    'acc-sg']  # todo: don't use `parts` here?
            # end
        elif i.gender == 'n':
            r['acc-sg'] = r['nom-sg']
        # end
    # end

    if i.calc_pl:
        r['acc-pl-in'] = ''  # todo: remove this?
        r['acc-pl-an'] = ''

        if i.animacy == 'in':
            r['acc-pl'] = r['nom-pl']
        elif i.animacy == 'an':
            r['acc-pl'] = r['gen-pl']
        else:
            r['acc-pl-in'] = r['nom-pl']
            r['acc-pl-an'] = r['gen-pl']
        # end
    # end

    _.ends(module, func)
Пример #21
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)
Пример #22
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)
Пример #23
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)
Пример #24
0
def forward_gender_animacy(func, i):
    r = i.result  # local

    # Род:
    genders = dict(m='муж',
                   f='жен',
                   n='ср',
                   mf='мж',
                   mn='мс',
                   fm='жм',
                   fn='жс',
                   nm='см',
                   nf='сж')  # dict  # local

    if i.common_gender:
        r['род'] = 'общ'
    elif i.output_gender:
        r['род'] = genders[i.output_gender]
    elif i.gender:
        r['род'] = genders[i.gender]
    else:
        pass
    # end

    # Одушевлённость:
    animacies = dict()  # dict  # local
    animacies['in'] = 'неодуш'
    animacies['an'] = 'одуш'
    animacies['in//an'] = 'неодуш-одуш'
    animacies['an//in'] = 'одуш-неодуш'

    if i.output_animacy:
        r['кат'] = animacies[i.output_animacy]
    else:
        r['кат'] = animacies[i.animacy]
    # end

    _.ends(module, func)
Пример #25
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)
Пример #26
0
def special_cases(func, i):  # export
    prt_case(i)
    loc_case(i)
    voc_case(i)

    _.ends(module, func)
Пример #27
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)
Пример #28
0
def apply_obelus(func, i):  # export
    if _.contains(i.rest_index, '÷'):
        i.result['obelus'] = '1'
    # end
    _.ends(module, func)
Пример #29
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)
Пример #30
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)