Модуль: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