Модуль:Lexer

Материал из Указатель частей и соединений РККА 1941-1945
Перейти к:навигация, поиск
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Для документации этого модуля может быть создана страница Модуль: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