Модуль:Lexer
Материал из Указатель частей и соединений РККА 1941-1945
Для документации этого модуля может быть создана страница Модуль:Lexer/doc
local lexer = {} local cargo = mw.ext.cargo local global = mw.ext.luaglobal local ending = { -- и = р,д,в,т,п,мн ['Гв.'] = { 'Гв.', 'Гв.', 'Гв.', 'Гв.', 'Гв.', 'Гв.', }, ['гв.'] = { 'гв.', 'гв.', 'гв.', 'гв.', 'гв.', 'гв.', }, ['и'] = { 'и', 'и', 'и', 'и', 'и', 'и', }, ['тд.'] = { 'тд.', 'тд.', 'тд.', 'тд.', 'тд.', 'тд.', }, ['ада'] = { 'ады', 'аде', 'аду', 'адой', 'аде', 'ады', stop = 'ж', }, -- бригада ['аза'] = { 'азы', 'азе', 'азу', 'азой', 'азе', 'азы', stop = 'ж', }, -- база ['аль'] = { 'аля', 'алю', 'аль', 'алем', 'але', 'али', stop = 'м', }, -- госпиталь ['арк'] = { 'арка', 'арку', 'арк', 'арком', 'арке', 'арки', stop = 'м', }, -- парк ['вод'] = { 'вода', 'воду', 'вод', 'водом', 'воде', 'воды', stop = 'м', }, -- взвод ['езд'] = { 'езда', 'езду', 'езд', 'ездом', 'езде', 'езда', stop = 'м', }, -- бронепоезд ['ено'] = { 'ена', 'ену', 'ено', 'еном', 'ене', 'енья', stop = 'с', }, -- звено ['ерв'] = { 'ерва', 'ерву', 'ерв', 'ервом', 'ерве', 'ервы', stop = 'м', }, -- резерв ['зия'] = { 'зии', 'зии', 'зию', 'зией', 'зии', 'зии', stop = 'ж', }, -- дивизия ['илы'] = { 'ил', 'илам', 'илы', 'илами', 'илах', 'илы', stop = 'х', }, -- силы ['ион'] = { 'иона', 'иону', 'ион', 'ионом', 'ионе', 'ионы', stop = 'м', }, -- дивизион ['йон'] = { 'йона', 'йону', 'йон', 'йоном', 'йоне', 'йоны', stop = 'м', }, -- район ['ище'] = { 'ища', 'ищу', 'ище', 'ищем', 'ище', 'ища', stop = 'с', }, -- училище ['лад'] = { 'лада', 'ладу', 'лад', 'ладом', 'ладе', 'лады', stop = 'м', }, -- склад ['лия'] = { 'лии', 'лии', 'лию', 'лией', 'лии', 'лии', stop = 'ж', }, -- флотилия ['лот'] = { 'лота', 'лоту', 'лот', 'лотом', 'лоте', 'лоты', stop = 'м', }, -- флот ['лья'] = { 'льи', 'лье', 'лью', 'льей', 'лье', 'льи', stop = 'ж', }, -- эскадрилья ['мия'] = { 'мии', 'мии', 'мию', 'мией', 'мии', 'мии', stop = 'ж', }, -- армия ['нда'] = { 'нды', 'нде', 'нду', 'ндой', 'нде', 'нды', stop = 'ж', }, -- команда ['ние'] = { 'ния', 'нию', 'ние', 'нием', 'нии', 'ния', stop = 'с', }, -- управление ['нкт'] = { 'нкта', 'нкту', 'нкт', 'нктом', 'нкте', 'нкты', stop = 'м', }, -- пункт ['олк'] = { 'олка', 'олку', 'олк', 'олком', 'олке', 'олки', stop = 'м', }, -- полк ['она'] = { 'оны', 'оне', 'ону', 'оной', 'оне', 'оны', stop = 'ж', }, -- зона ['онт'] = { 'онта', 'онту', 'онт', 'онтом', 'онте', 'онты', stop = 'м', }, -- фронт ['орт'] = { 'орта', 'орту', 'орт', 'ортом', 'орте', 'орты', stop = 'м', }, -- транспорт ['ота'] = { 'оты', 'оте', 'оту', 'отой', 'оте', 'оты', stop = 'ж', }, -- рота ['ппа'] = { 'ппы', 'ппе', 'ппу', 'ппой', 'ппе', 'ппы', stop = 'ж', }, -- группа ['пус'] = { 'пуса', 'пусу', 'пус', 'пусом', 'пусе', 'пуса', stop = 'м', }, -- корпус ['рет'] = { 'рета', 'рету', 'рет', 'ретом', 'рете', 'реты', stop = 'м', }, -- лазарет ['рея'] = { 'реи', 'рее', 'рею', 'реей', 'рее', 'реи', stop = 'ж', }, -- батарея ['рня'] = { 'рни', 'рне', 'рню', 'рней', 'рне', 'рни', stop = 'ж', }, -- пекарня ['рон'] = { 'рона', 'рону', 'рон', 'роном', 'роне', 'роны', stop = 'м', }, -- эскадрон ['рсы'] = { 'рсов', 'рсам', 'рсы', 'рсами', 'рсах', 'рсы', stop = 'х', }, -- курсы ['руг'] = { 'руга', 'ругу', 'руг', 'ругом', 'руге', 'руга', stop = 'м', }, -- округ ['ряд'] = { 'ряда', 'ряду', 'ряд', 'рядом', 'ряде', 'ряды', stop = 'м', }, -- отряд ['ска'] = { 'ск', 'скам', 'ска', 'сками', 'сках', 'ска', stop = 'х', }, -- войска ['сса'] = { 'ссы', 'ссе', 'ссу', 'ссой', 'ссе', 'ссы', stop = 'ж', }, -- касса ['таб'] = { 'таба', 'табу', 'таб', 'табом', 'табе', 'табы', stop = 'м', }, -- штаб ['ток'] = { 'тка', 'тку', 'ток', 'тком', 'тке', 'тки', stop = 'м', }, -- участок ['тор'] = { 'тора', 'тору', 'тор', 'тором', 'торе', 'тора', stop = 'м', }, -- сектор ['урт'] = { 'урта', 'урту', 'урт', 'уртом', 'урте', 'урты', stop = 'м', }, -- гурт ['ция'] = { 'ции', 'ции', 'цию', 'цией', 'ции', 'ции', stop = 'ж', }, -- Авиация ['ьон'] = { 'ьона', 'ьону', 'ьон', 'ьоном', 'ьоне', 'ьоны', stop = 'м', }, -- батальон ['бая'] = { 'бой', 'бой', 'бую', 'бой', 'бой', 'бые', }, ['бый'] = { 'бого', 'бому', 'бый', 'бым', 'бом', 'бые', }, ['вая'] = { 'вой', 'вой', 'вую', 'вой', 'вой', 'вые', }, ['вое'] = { 'вого', 'вому', 'вое', 'вым', 'вом', 'вые', }, ['вой'] = { 'вого', 'вому', 'вой', 'вым', 'вом', 'вые', }, ['вый'] = { 'вого', 'вому', 'вый', 'вым', 'вом', 'вые', }, ['кая'] = { 'кой', 'кой', 'кую', 'кой', 'кой', 'кие', stop = '?', }, -- мастерская ['кий'] = { 'кого', 'кому', 'кий', 'ким', 'ком', 'кие', }, ['кое'] = { 'кого', 'кому', 'кое', 'ким', 'ком', 'кие', }, ['кой'] = { 'кого', 'кому', 'кой', 'ким', 'ком', 'кие', }, ['лая'] = { 'лой', 'лой', 'лую', 'лой', 'лой', 'лые', }, ['лый'] = { 'лого', 'лому', 'лый', 'лым', 'лом', 'лые', }, ['ная'] = { 'ной', 'ной', 'ную', 'ной', 'ной', 'ные', }, ['ний'] = { 'него', 'нему', 'ний', 'ним', 'ном', 'ние', }, ['ное'] = { 'ного', 'ному', 'ное', 'ным', 'ном', 'ные', }, ['ной'] = { 'ного', 'ному', 'ной', 'ным', 'ном', 'ные', }, ['ные'] = { 'ных', 'ным', 'ные', 'ными', 'ных', 'ные', }, ['ный'] = { 'ного', 'ному', 'ный', 'ным', 'ном', 'ные', }, ['чая'] = { 'чей', 'чей', 'чую', 'чей', 'чей', 'чие', }, ['чья'] = { 'чьей', 'чьей', 'чью', 'чьей', 'чьей', 'чьи', }, } local adjnoon = { ['мастерская'] = 'ж', } local endingGv = { -- и,р,д,в,т,п ['м'] = { 'гвардейский', 'гвардейского', 'гвардейскому', 'гвардейский', 'гвардейским', 'гвардейском', }, ['ж'] = { 'гвардейская', 'гвардейской', 'гвардейской', 'гвардейскую', 'гвардейской', 'гвардейской', }, ['с'] = { 'гвардейское', 'гвардейского', 'гвардейскому', 'гвардейское', 'гвардейским', 'гвардейском', }, ['х'] = { 'гвардейские', 'гвардейских', 'гвардейским', 'гвардейские', 'гвардейскими', 'гвардейских', }, } local endingOtd = { ['м'] = { 'отдельный', 'отдельного', 'отдельному', 'отдельный', 'отдельным', 'отдельном', }, ['ж'] = { 'отдельная', 'отдельной', 'отдельной', 'отдельную', 'отдельной', 'отдельной', }, ['с'] = { 'отдельное', 'отдельного', 'отдельному', 'отдельное', 'отдельным', 'отдельном', }, ['х'] = { 'отдельные', 'отдельных', 'отдельным', 'отдельные', 'отдельными', 'отдельных', }, } function lexer.declension( str, form, skip_err ) local words = mw.text.split( str, ' ' ) -- local err = {} local key, gender for i, word in ipairs( words ) do local x = mw.ustring.sub( word, -3, -1 ) local u = ending[x] if u then if form ~= 0 then words[i] = mw.ustring.sub( word, 1, -4 ) .. u[form] end if u.stop then if u.stop == '?' then if adjnoon[word] then gender = adjnoon[word] key = words[i] break end else key = words[i] gender = u.stop break end end elseif not tonumber( word ) then if skip_err then return str else return nil, word end -- elseif not skip_err and not tonumber( word ) then -- if not tonumber( mw.ustring.sub( word, 1, 1 ) ) then -- return nil, word -- end -- elseif skip_err then -- return str end end if key or skip_err then return table.concat( words, ' ' ), key, gender end return nil, str end function lexer._declension( str, form, text, abbr ) local report = require( 'Module:Report' ) local unit = report.bigfuller( str ) if text then if text == '!' then return unit end elseif abbr then text = report.shorter( unit ) elseif form == 0 then text = unit else text = lexer.declension( unit, form ) end global.add( 'UNIT-IN-TEXT', unit ) return '<span class=unit-in-text data-unit="' .. unit .. '">[[' .. unit .. '|' .. ( text or '<span class=error>(Ошибка! Не удалось просклонять)</span>' ) .. ']]</span>' end function lexer.Declension( frame ) local args = require( 'Module:Tools' ).checkargs( frame:getParent().args, { true, true -- form = 0 -- форма (падеж) задается в шаблоне, а не в вызове } ) -- падеж задается в шаблоне -- в вызове задаются -- первый параметр — юнит (к нему мы применяем fuller) -- второй параметр — либо точка (тогда мы к юниту применим shorter), либо "!" (тогда мы вернем юнит без склонения и ссылки) local form = tonumber( frame.args.form or 0 ) local text = args[2] local abbr = text == '.' if abbr then text = nil end return lexer._declension( args[1], form, text, abbr ) end function lexer.Check( frame ) local cq local out = {} local offset = 0 repeat cq = cargo.query( 'unitpages', '_pageName, unit,special', { offset = offset, limit = 5000, orderBy = 'unit,special' } ) for _, u in ipairs( cq ) do local unit = u.unit local v, err = lexer.declension( unit, 1 ) if v then table.insert( out, unit .. ' / ' .. v ) else table.insert( out, unit .. ': <span class=error>' .. err .. '</span>' ) end --[[ local ctg = lexer.category( unit ) or '—' local ctgGood = categories.names[ctg] or { group = '—' } local abbr = lexer.shorter( unit ) or '—' if abbr == unit then local unitLow = mw.ustring.lower( mw.ustring.sub( unit, 1, 1 ) ) .. mw.ustring.sub( unit, 2, -1 ) abbr = lexer.shorter( unitLow ) end table.insert( out, unit .. '/' .. ctg .. '/' .. ctgGood.group .. '/' .. abbr ) lexer.gene = nil --]] end offset = offset + #cq until #cq == 0 return table.concat( out, '<br>' ) end return lexer