играемся

This commit is contained in:
Alexander Yakovlev 2021-04-28 20:22:59 +07:00
commit b81f763cf1
Signed by: oreolek
GPG Key ID: 8D24103F5EE2A6C0
13 changed files with 190728 additions and 0 deletions

7
README.md Normal file
View File

@ -0,0 +1,7 @@
#ASCII арт в инстеде
Интереса ради, сделал получение размера терминала в `tinymp`.
В Linux - работает. В Windows - вряд ли.
Потом можно будет посыпать [plterm](https://github.com/philanc/plterm) и радоваться.

27
main3.lua Normal file
View File

@ -0,0 +1,27 @@
--$Name:ASCII art$
require "parser/mp-ru"
function syscols()
local retval = 0
local tmpfile = '/tmp/stmp.txt'
os.execute('tput cols > '..tmpfile)
local f = io.open(tmpfile)
for line in f:lines() do
retval = line * 1;
end
f:close()
return retval;
end
room {
nam = 'main';
title = "Комната";
dsc = function(s)
local cols = syscols()
local retval = '-';
for i = 1, (cols - 1), 1 do
retval = retval .. '-';
end
return retval;
end;
}

8
morph/COPYING Normal file
View File

@ -0,0 +1,8 @@
This code uses dictionary files from the http://aot.ru project that is
covered by the terms of the LGPL license.
Dictionary files:
https://sourceforge.net/p/seman/svn/HEAD/tree/trunk/Dicts/Morph/Russian/
License:
https://sourceforge.net/p/seman/svn/HEAD/tree/trunk/copying

131
morph/lang-en.lua Normal file
View File

@ -0,0 +1,131 @@
local type = type
local kbden = {
shifted = {
["1"] = "!",
["2"] = "@",
["3"] = "#",
["4"] = "$",
["5"] = "%",
["6"] = "^",
["7"] = "&",
["8"] = "*",
["9"] = "(",
["0"] = ")",
["-"] = "_",
["="] = "+",
["/"] = "?",
[","] = "<",
["."] = ">",
["`"] = "~",
["a"] = "A",
["b"] = "B",
["c"] = "C",
["d"] = "D",
["e"] = "E",
["f"] = "F",
["g"] = "G",
["h"] = "H",
["i"] = "I",
["j"] = "J",
["k"] = "K",
["l"] = "L",
["m"] = "M",
["n"] = "N",
["o"] = "O",
["p"] = "P",
["q"] = "Q",
["r"] = "R",
["s"] = "S",
["t"] = "T",
["u"] = "U",
["v"] = "V",
["w"] = "W",
["x"] = "X",
["y"] = "Y",
["z"] = "Z",
}
}
local function lower(str)
if type(str) ~= 'string' then
return str
end
return str:lower()
end
local function upper(str)
if type(str) ~= 'string' then
return str
end
return str:upper()
end
local function is_cap(str)
if type(str) ~= 'string' then
return false
end
local s, e
if str:find("^[A-Z]") then
s = true
end
if str:find("[A-Z]$") then
e = true
end
return s, e
end
local function cap(str)
if type(str) ~= 'string' then
return str
end
str = str:gsub("^.", function(v) return v:upper() end)
return str
end
local lang
local function norm(str)
return str
end
local vowels = {
["a"] = true,
["e"] = true,
["i"] = true,
["o"] = true,
["u"] = true,
}
local function is_vowel(l)
l = lower(l);
return vowels[l]
end
lang = { yo = false,
kbd = kbden,
norm = norm,
upper = upper,
lower = lower,
cap = cap,
is_cap = is_cap,
is_vowel = is_vowel,
flex_filter = function() return false end,
gram_compat = function() return false end,
gram_score = function() return 0 end,
gram_t = {
noun = '',
live = 'live',
nonlive = 'nonlive',
neuter = 'neutwe',
male = 'male',
female = 'female',
plural = 'plural',
proper = 'proper',
surname = 'surname',
first = 'first',
second = 'second',
third = 'third',
}
}
return lang

433
morph/lang-ru.lua Normal file
View File

@ -0,0 +1,433 @@
local type = type
local kbdru = {
["q"] = "й",
["w"] = "ц",
["e"] = "у",
["r"] = "к",
["t"] = "е",
["y"] = "н",
["u"] = "г",
["i"] = "ш",
["o"] = "щ",
["p"] = "з",
["["] = "х",
["]"] = "ъ",
["a"] = "ф",
["s"] = "ы",
["d"] = "в",
["f"] = "а",
["g"] = "п",
["h"] = "р",
["j"] = "о",
["k"] = "л",
["l"] = "д",
[";"] = "ж",
["'"] = "э",
["z"] = "я",
["x"] = "ч",
["c"] = "с",
["v"] = "м",
["b"] = "и",
["n"] = "т",
["m"] = "ь",
[","] = "б",
["."] = "ю",
["`"] = "ё",
["/"] = ".",
shifted = {
["q"] = "Й",
["w"] = "Ц",
["e"] = "У",
["r"] = "К",
["t"] = "Е",
["y"] = "Н",
["u"] = "Г",
["i"] = "Ш",
["o"] = "Щ",
["p"] = "З",
["["] = "Х",
["]"] = "Ъ",
["a"] = "Ф",
["s"] = "Ы",
["d"] = "В",
["f"] = "А",
["g"] = "П",
["h"] = "Р",
["j"] = "О",
["k"] = "Л",
["l"] = "Д",
[";"] = "Ж",
["'"] = "Э",
["z"] = "Я",
["x"] = "Ч",
["c"] = "С",
["v"] = "М",
["b"] = "И",
["n"] = "Т",
["m"] = "Ь",
[","] = "Б",
["."] = "Ю",
["`"] = "Ё",
["1"] = "!",
["2"] = "@",
["3"] = "#",
["4"] = ";",
["5"] = "%",
["6"] = ":",
["7"] = "?",
["8"] = "*",
["9"] = "(",
["0"] = ")",
["-"] = "_",
["="] = "+",
["/"] = ",",
}
}
local toupper = {
["й"] = "Й",
["ц"] = "Ц",
["у"] = "У",
["к"] = "К",
["е"] = "Е",
["н"] = "Н",
["г"] = "Г",
["ш"] = "Ш",
["щ"] = "Щ",
["з"] = "З",
["х"] = "Х",
["ъ"] = "Ъ",
["ф"] = "Ф",
["ы"] = "Ы",
["в"] = "В",
["а"] = "А",
["п"] = "П",
["р"] = "Р",
["о"] = "О",
["л"] = "Л",
["д"] = "Д",
["ж"] = "Ж",
["э"] = "Э",
["я"] = "Я",
["ч"] = "Ч",
["с"] = "С",
["м"] = "М",
["и"] = "И",
["т"] = "Т",
["ь"] = "Ь",
["б"] = "Б",
["ю"] = "Ю",
["ё"] = "Ё",
}
local function lower(str)
if type(str) ~= 'string' then
return str
end
str = str:lower()
for k, v in pairs(toupper) do
str = str:gsub(v, k)
end
return str
end
local function upper(str)
if type(str) ~= 'string' then
return str
end
str = str:upper();
for k, v in pairs(toupper) do
str = str:gsub(k, v)
end
return str
end
local function is_cap(str)
if type(str) ~= 'string' then
return false
end
local s, e
for _, v in pairs(toupper) do
if not s and str:find("^"..v) then
s = true
end
if not e and str:find(v.."$") then
e = true
end
if not s and str:find("^[A-Z]") then
s = true
end
if not e and str:find("[A-Z]$") then
e = true
end
end
return s, e
end
local function cap(str)
if type(str) ~= 'string' then
return str
end
if str:find("^[a-z]") then
str = str:gsub("^.", function(v) return v:upper() end)
return str
end
for k, v in pairs(toupper) do
local s = str:gsub("^"..k, v)
if s ~= str then
return s
end
end
return str
end
local lang
local function norm(str)
if type(str) ~= 'string' then
return str
end
if not lang.yo then
str = str:gsub("ё", "е"):gsub("Ё", "Е")
end
return str
end
local vowels = {
["у"] = true,
["е"] = true,
["ы"] = true,
["а"] = true,
["о"] = true,
["и"] = true,
["ю"] = true,
["ё"] = true,
["э"] = true,
["я"] = true,
}
local function is_vowel(l)
l = lower(l);
return vowels[l]
end
local gram_tt = {
["ИНФИНИТИВ"] = true;
["КРРИЛ"] = true;
["КРРИЧАСТИЕ"] = true;
["Г"] = true;
}
local function flex_filter(v)
local an = v.an
if an["им"] then
return true
end
if an["рд"] or an["дт"] or an["тв"] or an["пр"] or an["вн"] then
return false
end
if an["0"] then
return true
end
return gram_tt[an.t]
end
local function gram_info(a)
local t = { }
if a['мр'] then
t.gen = 'male'
elseif a['жр'] then
t.gen = 'female'
elseif a['ср'] then
t.gen = 'neuter'
else
t.gen = 'any'
end
if a['мн'] then
t.num = 'singular'
elseif a['ед'] then
t.num = 'plural'
else
t.num = 'any'
end
if a['буд'] then
t.time = 'future'
elseif a['прш'] then
t.time = 'past'
elseif a['нст'] then
t.time = 'present'
else
t.time = 'any'
end
if a[''] then
t.face = 'first'
elseif a[''] then
t.face = 'second'
elseif a[''] then
t.face = 'third'
else
t.face = 'any'
end
return t
end
local function __gram_compat(g1, g2, time)
if g1.gen ~= g2.gen and g1.gen ~= 'any' and g2.gen ~= 'any' then return false end
if not time then
if g1.num ~= g2.num and g1.num ~= 'any' and g2.num ~= 'any' then return false end
end
if g1.time ~= g2.time and g1.time ~= 'any' and g2.time ~= 'any' then return false end
if g1.face ~= g2.face and g1.face ~= 'any' and g2.face ~= 'any' then return false end
return true
end
local function gram_eq(a, b)
if not a or not b then return true end
if a == 'ИНФИНИТИВ' or b == 'ИНФИНИТИВ' then
return b == a or b == 'Г' or a == 'Г'
end
if a == 'КРРИЛ' or b == 'КРРИЛ' then
return b == a -- or b == 'П'
end
if a == 'КРРИЧАСТИЕ' or b == 'КРРИЧАСТИЕ' then
return b == a
end
if a == 'ПРИЧАСТИЕ' or b == 'ПРИЧАСТИЕ' then
return b == a
end
if a == 'Г' or b == 'Г' then return a == b end
return true
end
local function gram_compat(base, aa, bb)
if not gram_eq(base.t, aa.t) then
return false
end
-- local a, b = aa.t, bb.t
local g1, g2 = gram_info(aa), gram_info(bb)
if bb.noun then
if not base['им'] then
return false
end
local g0 = gram_info(base)
if not __gram_compat(g0, g1, true) then return false end
if not __gram_compat(g0, g2, true) then return false end
end
return __gram_compat(g1, g2)
end
local function gram_norm(an)
local a = {}
local g = {}
for _, v in ipairs(an) do
a[v] = true
table.insert(g, v)
end
if not a[''] and not a[''] and not a[''] then
table.insert(g, '')
end
return g
end
local function gram_score(an, g)
local score = 0
g = gram_norm(g)
if an["фам"] then score = score - 0.1 end
if an["арх"] then score = score - 0.1 end
for _, vv in ipairs(g or {}) do
if vv:sub(1, 1) == '~' then
vv = vv:sub(2)
if an[vv] then
score = score - 1
elseif an.t == vv then
score = score - 10
end
else
if an[vv] then
score = score + 1
elseif an.t == vv then
score = score + 10
end
end
end
return score
end
lang = { yo = false,
kbd = kbdru,
norm = norm,
upper = upper,
lower = lower,
cap = cap,
is_cap = is_cap,
is_vowel = is_vowel,
flex_filter = flex_filter,
gram_compat = gram_compat,
gram_score = gram_score,
gram_t = {
noun = 'С',
nom = 'им',
live = 'од',
nonlive = 'но',
neuter = 'ср',
male = 'мр',
female = 'жр',
plural = 'мн',
proper = 'имя',
surname = 'фам',
first = '',
second = '',
third = '',
};
dict = {
["ведро/ср,но,С"] = {
"ведро/им", "вёдра/им,мн",
"ведро/вн", "вёдра/вн,мн",
"ведра/рд", "вёдер/рд,мн",
"ведру/дт", "ведрам/дт,мн",
"ведром/тв", "вёдрами/тв,мн",
"ведре/пр", "вёдрах/пр,мн",
},
["деревья/ср,но,мн,С"] = {
"деревья/им";
"деревья/вн";
"деревьев/рд";
"деревьями/тв";
"деревьях/пр";
"деревьям/дт";
};
["дерево/ср,но,С"] = {
"дерево/им", "деревья/им,мн";
"дерево/вн", "деревья/вн,мн";
"дерева/рд", "деревьев/рд,мн";
"деревом/тв", "деревьями/тв,мн";
"дереве/пр", "деревьях/пр,мн";
"дереву/пр", "деревьям/дт,мн";
};
["огонь/мр,но,С"] = {
"огонь/им", "огни/им,мн",
"огонь/вн", "огни/вн,мн",
"огня/рд", "огней/рд,мн",
"огню/дт", "огням/дт,мн",
"огнём/тв", "огнями/тв,мн",
"огне/пр", "огнях/пр,мн",
};
["цветы/мн,мр,но,С"] = { -- цветки
"цветы/им",
"цветы/вн",
"цветов/рд",
"цветам/дт",
"цветами/тв",
"цветах/пр",
};
["хлам/пр,2"] = "хламе";
["клевер/пр"] = "клевере";
["песок/пр,2"] = "песке";
};
}
return lang

179923
morph/morphs.mrd Normal file

File diff suppressed because one or more lines are too long

928
morph/mrd.lua Normal file
View File

@ -0,0 +1,928 @@
--luacheck: no self
local curdir = std.getinfo(1).source:gsub("^(.+[\\/])[^\\/]+$", "%1"):gsub("^@", "");
local mrd = {
lang = false;
words = {};
dirs = {''};
dict_file = 'dict.mrd';
}
local msg = dprint or print
local function debug(...)
if DEBUG then
dprint(...)
end
end
local function cache_add(cache, key, val)
table.insert(cache.list, 1, key)
local len = #cache.list
if len > (cache.len or 128) then
local okey = cache.list[len]
table.remove(cache.list, len)
cache.hash[okey] = nil
end
cache.hash[key] = val
end
local function split(str, sep)
local words = {}
if not str then
return words
end
for w in str:gmatch(sep or "[^ \t]+") do
table.insert(words, w)
end
return words
end
local function empty(l)
l = l:gsub("[ \t]+", "")
return l == ""
end
function mrd:gramtab(path)
local f, e = io.open(path or 'rgramtab.tab', 'rb')
if not f then
return false, e
end
self.gram = {
an = {}; -- by ancodes
t = {}; -- by types
}
for l in f:lines() do
if not l:find("^[ \t]*//") and not empty(l) then -- not comments
local w = split(l)
if #w < 3 then
msg("Skipping gram: "..l)
else
local a = split(w[4], '[^,]+')
local an = {}
for _, v in ipairs(a) do
an[v] = true
end
an.t = w[3] -- type
self.gram.an[w[1]] = an;
self.gram.t[w[3]] = an;
end
end
end
f:close()
end
local function section(f, fn, ...)
local n = f:read("*line")
n = n and tonumber(n)
if not n then
return false
end
if n == 0 then
return true
end
for l in f:lines() do -- skip accents
if fn then fn(l, ...) end
n = n - 1
if n == 0 then
break
end
end
return true
end
local flex_filter
local function flex_fn(l, flex, an)
l = l:gsub("//.*$", "")
local fl = {}
for w in l:gmatch("[^%%]+") do
local ww = split(w, "[^%*]+")
if #ww > 3 or #ww < 1 then
msg("Skip lex: ", w, l);
else
local f = { }
if #ww == 1 then
f.an = ww[1]
f.post = ''
else
f.post = ww[1]
f.an = ww[2]
end
f.pre = ww[3] or ''
local a = an[f.an]
if not a then
msg("Gram not found. Skip lex: "..f.an)
else
f.an_name = f.an
f.an = a
if flex_filter(f) then
f.filter = true
end
table.insert(fl, f)
end
end
end
table.insert(flex, fl)
end
local function pref_fn(l, pref)
local p = split(l, "[^,]+")
table.insert(pref, p)
end
--[[
local function dump(vv)
local s = ''
if type(vv) ~= 'table' then
return string.format("%s", tostring(vv))
end
for k, v in pairs(vv) do
s = s .. string.format("%s = %s ", k, v)
end
return s
end
local function gram_dump(v)
for _, f in ipairs(v.flex) do
local tt = v.pref .. f.pre .. v.t .. f.post
print("=== ", tt)
for _, v in pairs(f.an) do
print(_, v)
end
end
end
]]--
local busy_cnt = 0
local function word_fn(l, self, dict)
local norm = mrd.lang.norm
local words = self.words
local words_list = self.words_list
local w = split(l)
if #w ~= 6 then
msg("Skipping word: "..l)
return
end
if w[1] == '#' then w[1] = '' end
local nflex = tonumber(w[2]) or false
local an = w[5]
if an == '-' then an = false end
local an_name = an
local npref = tonumber(w[6]) or false
if not nflex then
msg("Skipping word:"..l)
return
end
nflex = self.flex[nflex + 1]
if not nflex then
msg("Wrong paradigm number for word: "..l)
return
end
if an then
an = self.gram.an[an]
if not an then
msg("Wrong ancode for word: "..l)
return
end
end
if npref then
npref = self.pref[npref + 1]
if not npref then
msg("Wrong prefix for word: "..l)
return
end
end
local t = w[1]
local num = 0
local used = false
for _, v in ipairs(nflex) do
if v.filter then
for _, pref in ipairs(npref or { '' }) do
local tt = norm(pref .. v.pre .. t .. v.post)
-- if tt == 'ЗАКРЕПЛЕН' then
-- gram_dump { t = t, pref = pref, flex = nflex, an = v.an }
-- end
if not dict or dict[tt] then
local a = {}
for kk, _ in pairs(an or {}) do
a[kk] = an[kk]
end
for kk, _ in pairs(v.an) do
a[kk] = v.an[kk]
end
local wds = words[tt] or {}
table.insert(wds,
{ t = t, pref = pref, flex = nflex, an = a })
nflex.used = true
used = true
if npref then
npref.used = true
end
num = num + 1
if #wds == 1 then
words[tt] = wds
end
end
end
end
end
if used then
table.insert(words_list, { t = w[1], flex = nflex, pref = npref, an = an_name })
end
self.words_nr = self.words_nr + num
busy_cnt = busy_cnt + 1
if busy_cnt > 1000 then
if std then std.busy(true) end
busy_cnt = 0
end
return
end
function mrd:load(path, dict)
local f, e = io.open(path or 'morphs.mrd', 'rb')
if not f then
return false, e
end
local flex = {}
flex_filter = mrd.lang.flex_filter
if not section(f, flex_fn, flex, self.gram.an) then
return false, "Error in section 1"
end
self.flex = flex
if not section(f) then
return false, "Error in section 2"
end
if not section(f) then
return false, "Error in section 3"
end
local pref = {}
if not section(f, pref_fn, pref) then
return false, "Error in section 4"
end
self.pref = pref
self.words_nr = 0
self.words = {}
self.words_list = {}
-- collectgarbage("stop")
if not section(f, word_fn, self, dict) then
-- collectgarbage("restart")
return false, "Error in section 4"
end
-- collectgarbage("restart")
msg("Generated: "..tostring(self.words_nr).." word(s)");
local crc = f:read("*line")
if crc then crc = tonumber(crc) end
f:close()
if std then std.busy(false) end
return true, crc
end
function mrd:dump(path, crc)
local f, e = io.open(path or 'dict.mrd', 'wb')
if not f then
return false, e
end
local n = 0
for _, v in ipairs(self.flex) do
if v.used then
v.norm_no = n
n = n + 1
end
end
f:write(string.format("%d\n", n))
for _, v in ipairs(self.flex) do
if v.used then
local s = ''
for _, vv in ipairs(v) do
s = s .. '%'
if vv.post == '' then
s = s..vv.an_name
else
s = s..vv.post..'*'..vv.an_name
end
if vv.pre ~= '' then
s = s .. '*'..vv.pre
end
end
f:write(s.."\n")
end
end
f:write("0\n")
f:write("0\n")
n = 0
for _, v in ipairs(self.pref) do
if v.used then
v.norm_no = n
n = n + 1
end
end
f:write(string.format("%d\n", n))
for _, v in ipairs(self.pref) do
if v.used then
local s = ''
for _, vv in ipairs(v) do
if s ~= '' then s = s .. ',' end
s = s .. vv
end
f:write(s.."\n")
end
end
f:write(string.format("%d\n", #self.words_list))
for _, v in ipairs(self.words_list) do
local s
if v.t == '' then
s = '#'
else
s = v.t
end
s = s ..' '..tostring(v.flex.norm_no)
s = s..' - -'
if v.an then
s = s .. ' '..v.an
else
s = s .. ' -'
end
if v.pref then
s = s ..' '..tostring(v.pref.norm_no)
else
s = s .. ' -'
end
f:write(s..'\n')
end
if crc then
f:write(string.format("%d\n", crc))
end
f:close()
end
local function gram2an(g)
local a = {}
for _, v in ipairs(g) do
if v:sub(1, 1) == '~' then
a[v:sub(2)] = false
else
a[v] = true
end
end
a.t = nil
return a
end
local lookup_cache = {
hash = {};
list = {};
len = 512;
}
local function hint_append(hint, h)
if h == "" or not h then return hint end
if hint == "" or not hint then return h end
return hint .. ',' .. h
end
function mrd:lookup(w, g)
local key = ""
for _, v in ipairs(g or {}) do
key = hint_append(key, v)
end
key = w .. '/'..key
local cc = lookup_cache.hash[key]
if cc then
return cc.w, cc.g
end
w, g = self:__lookup(w, g)
cache_add(lookup_cache, key, { w = w, g = g })
return w, g
end
function mrd:__lookup(w, g)
local ow = w
local cap, upper = self.lang.is_cap(w)
local tt = self.lang.upper(self.lang.norm(w))
w = self.words[tt]
if not w then
return false, "No word in dictionary"
end
local res = {}
local gram_compat = self.lang.gram_compat
local gram_score = self.lang.gram_score
for _, v in ipairs(w) do
local flex = v.flex
local score = gram_score(v.an, g)
local t = v.an.t
for _, f in ipairs(flex) do
if gram_compat(v.an, f.an, gram2an(g)) then
local sc = gram_score(f.an, g)
if sc >= 0 then
if t ~= f.an.t then sc = sc - 1 end -- todo
--[[
local tt = v.pref .. f.pre .. v.t .. f.post
if tt == 'ЛЕВЫЙ' or tt == 'ЛЕВОГО' or tt == 'ШЛЕМОМ' then
print ("======looking for:", g.noun)
for _, v in pairs(g) do
print(_, v)
end
print ("======looking got:", score + sc, sc)
print(tt, v.t, score + sc)
for _, v in pairs(f.an) do
print(_, v)
end
end
]]--
table.insert(res, { score = score + sc, pos = #res, word = v, flex = f })
end
end
end
end
if #res == 0 then
return ow, gram2an(g) -- false, "No gram"
end
table.sort(res, function(a, b)
if a.score == b.score then
return a.pos < b.pos
end
return a.score > b.score
end)
--[[
for i = 1, #res do
local w = res[i]
local tt = self.lang.lower(w.word.pref .. w.flex.pre .. w.word.t .. w.flex.post)
print(i, "res: ", tt, w.score)
if tt == 'красный' or tt == 'красного' then
for _, v in pairs(w.flex.an) do
print(_, v)
end
end
-- print(tt, w.score)
end
]]--
w = res[1]
local gram = {}
for k, v in pairs(w.flex.an) do
gram[k] = v
end
for k, v in pairs(w.word.an) do
gram[k] = v
end
w = self.lang.lower(w.word.pref .. w.flex.pre .. w.word.t .. w.flex.post)
if upper then
w = self.lang.upper(w)
elseif cap then
w = self.lang.cap(w)
end
return w, gram
end
local word_match = "[^ \t,%-!/:%+&]+"
local missed_words = {}
local word_cache = { list = {}, hash = {} }
function mrd:word(w, ob)
local cache = word_cache
if ob then
if not ob.__word_cache then
std.rawset(ob, '__word_cache', {
list = {},
hash = {},
len = 32,
})
end
cache = ob.__word_cache
end
local key = w
local c = cache.hash[key]
if c then
return std.clone(c[1]), std.clone(c[2])
end
local ow = w
local s, _ = w:find("/[^/]*$")
local g = {}
local grams = {}
local hints = ''
if s then
hints = w:sub(s + 1)
w = w:sub(1, s - 1)
g = split(hints, "[^, ]+")
end
local found = true
local noun = false
local lang = self.lang
w = w:gsub(word_match,
function(t)
if noun then return t end
local ww, gg
if ob then
ww, gg = self:dict(ob.__dict, t..'/'..hints)
end
if not ww then
ww, gg = self:dict(game.__dict, t..'/'..hints)
end
if not ww then
ww, gg = self:dict(self.__dict, t..'/'..hints)
end
noun = gg and gg[lang.gram_t.noun]
if not ww then
ww, gg = self:lookup(t, g)
noun = gg and gg.t == lang.gram_t.noun
end
if gg and (gg[lang.gram_t.proper] or gg[lang.gram_t.surname]) then
noun = false
end
if not ww then
found = false
else
table.insert(grams, gg)
end
return ww or t
end)
if not found then
if DEBUG and not tonumber(w) and not missed_words[w] then
missed_words[w] = true
debug("Can not find word: '"..ow.."'")
end
end
cache_add(cache, key, { w, grams })
return w, grams
end
function mrd:file(f, dict)
dict = dict or {}
local ff, e = io.open(f, "rb")
if not ff then
return false, e
end
debug("Added file: ", f)
for l in ff:lines() do
for w in l:gmatch('%-"[^"]+"') do
w = w:gsub('^%-"', ""):gsub('"$', "")
local words = split(w, '[^|]+')
for _, word in ipairs(words) do
word = word:gsub("/[^/]*$", "")
for ww in word:gmatch(word_match) do
local t = self.lang.upper(self.lang.norm(ww))
if not dict[t] and not t:find("%*$") then
dict[t] = true;
debug("mrd: Added word: ", ww)
end
end
end
end
end
ff:close()
return dict
end
local function str_hint(str)
-- str = str:gsub("^%+", "")
local s, _ = str:find("/[^/]*$")
if not s then
return str, ""
end
if s == 1 then
return "", str:sub(2)
end
return str:sub(1, s - 1), str:sub(s + 1)
end
local function str_strip(str)
return std.strip(str)
end
local function str_split(str, delim)
local a = std.split(str, delim)
for k, _ in ipairs(a) do
a[k] = str_strip(a[k])
end
return a
end
function mrd:dict(dict, word)
if not dict then return end
local tab = {}
local w, hints = str_hint(word)
hints = str_split(hints, ",")
local tt = dict[w]
if not tt then
return
end
for _, v in ipairs(tt) do
local whints = {}
local w, h = str_hint(v)
local hh = str_split(h, ",")
for _, vv in ipairs(hh) do
whints[vv] = true
end
local t = { w, score = 0, pos = #tab, w = w }
for _, hv in ipairs(hints) do
if hv:sub(1, 1) ~= '~' then
if whints[hv] then
t.score = t.score + 1
end
else
if whints[str_strip(hv:sub(2))] then
t.score = t.score - 1
end
end
end
t.hints = str_split(hint_append(tt.hints, h), ",")
if mrd.lang.gram_t.nom and whints[mrd.lang.gram_t.nom] then
t.score = t.score + 0.5
end
table.insert(tab, t)
end
if #tab == 0 then
return
end
table.sort(tab,
function(a, b)
if a.score == b.score then
return a.pos < b.pos
end
return a.score > b.score
end)
if tab[1].score > 0 then
return tab[1].w, gram2an(tab[1].hints)
end
end
function mrd.dispof(w)
if w.raw_word ~= nil then
local d = std.call(w, 'raw_word')
return d, true
end
if w.word ~= nil then
local d = std.call(w, 'word')
return d
end
return std.titleof(w) or std.nameof(w)
end
local obj_cache = { hash = {}, list = {}, len = 128 }
function mrd:obj(w, n, nn)
local hint = ''
local hint2, disp, ob, raw
if type(w) == 'string' then
w, hint = str_hint(w)
elseif type(n) == 'string' then
hint = n
n = nn
end
if type(w) ~= 'string' then
-- w = std.object(w)
ob = w
disp, raw = self.dispof(w)
else
disp = w
end
local d = obj_cache.hash[disp]
if not d then
d = str_split(disp, '|')
if #d == 0 then
std.err("Wrong object display: ".. (disp or 'nil'), 2)
end
-- normalize
local nd = {}
for k, v in ipairs(d) do
w, hint2 = str_hint(v)
local dd = raw and { w } or str_split(w, ',')
for _, vv in ipairs(dd) do
table.insert(nd, { word = vv, hint = hint2 or '', alias = k, idx = _ })
-- for w in vv:gmatch("[^ ]+") do
-- table.insert(nd, { word = w, hint = hint2 or '', alias = k, idx = _ })
-- end
end
end
d = nd
cache_add(obj_cache, disp, d)
end
if type(n) == 'table' then
local ret = n
for _, v in ipairs(d) do
table.insert(ret, { word = v.word, hint = hint_append(hint, v.hint), alias = v.alias, idx = v.idx });
end
return ob, ret
end
n = n or (ob and ob.__word_alias) or 1
for k, v in ipairs(d) do
if v.alias == n then
n = k
break
end
end
if not d[n] then n = 1 end
w = d[n].word
hint2 = d[n].hint
return ob, w, hint_append(hint, hint2)
end
local function noun_append(rc, tab, w)
-- w = mrd.lang.norm(w)
if tab then
table.insert(tab, w)
else
if rc ~= '' then rc = rc .. '|' end
rc = rc .. w
end
return rc
end
function mrd:noun_hint(ob, n)
if not ob then
return ''
end
if not ob.__hint_cache then
std.rawset(ob, '__hint_cache', {
list = {},
hash = {},
len = 16,
})
end
local key = n or ob.__word_alias or 1
local c
if type(ob.word) == 'string' then -- do not use caching if function
c = ob.__hint_cache.hash[key]
end
if c then
return c
end
local g = ob and ob:gram('noun', n) or {}
local hint = ''
local lang = self.lang
for _, v in ipairs { lang.gram_t.male, lang.gram_t.female,
lang.gram_t.neuter, lang.gram_t.plural,
lang.gram_t.live } do
if g[v] then
hint = hint_append(hint, v)
end
end
if not g[self.lang.gram_t.live] then
hint = hint_append(hint, lang.gram_t.nonlive)
end
if ob then
hint = hint_append(hint, "noun")
end
cache_add(ob.__hint_cache, key, hint)
return hint
end
function mrd:noun(w, n, nn)
local hint, ob
local rc = ''
local tab = false
ob, w, hint = self:obj(w, n, nn)
if type(w) ~= 'table' then
local alias = nn
if type(alias) ~= 'number' then alias = n end
if type(alias) ~= 'number' then alias = nil end
w = {{ word = w, hint = hint, alias = alias }}
else
tab = {}
end
for _, v in ipairs(w) do
local hint2 = self:noun_hint(ob, v.alias)
local m = self:word(v.word .. '/'.. hint_append(v.hint, hint2), ob)
rc = noun_append(rc, tab, m)
end
return tab and tab or rc
end
local function str_hash(str)
local sum = 0
for i = 1, str:len() do
sum = sum + string.byte(str, i)
end
return sum
end
function mrd:init(l)
self.lang = l
if type(l.dict) == 'table' then
std.obj.dict(self, l.dict)
end
if self:gramtab(curdir .. "rgramtab.tab") == false then
msg("Error while opening gramtab.")
return
end
local _, crc = self:load(mrd.dict_file)
self:create(mrd.dict_file, crc) -- create or update
end
function mrd:create(fname, crc)
local dict = {}
if not std.readdir then
return
end
for _, d in ipairs(self.dirs) do
if d == '' then d = instead.gamepath() end
local list = {}
for f in std.readdir(d) do
if f:find("%.lua$") or f:find("%.LUA$") then
table.insert(list, f)
end
end
table.sort(list)
for _, f in ipairs(list) do
local path = d .. "/" .. f
mrd:file(path, dict)
end
end
local sum = 0
for w, _ in pairs(dict) do
sum = sum + str_hash(w)
sum = sum % 4294967291;
end
if crc ~= sum then
msg("Generating dict.mrd with sum: ", sum)
if mrd:load(curdir .. "morphs.mrd", dict) then
mrd:dump(fname or 'dict.mrd', sum)
else
msg("Can not find morph/morphs.mrd")
end
else
msg("Using dict.mrd")
end
end
if std then
std.obj.noun = function(self, ...)
return mrd:noun(self, ...)
end
std.obj.Noun = function(self, ...)
return mrd.lang.cap(mrd:noun(self, ...))
end
std.obj.gram = function(self, ...)
local hint, w, gram, _
_, w, hint = mrd:obj(self, ...)
_, gram = mrd:word(w .. '/'..hint)
local thint = ''
local t = mrd.lang.gram_t.noun
hint = str_split(hint, ",")
local g = gram and gram[1] or {}
for _, v in ipairs(gram or {}) do
if v.t == t or v[t] then
g = v
break
end
end
local gg = std.clone(g)
for _, v in ipairs(hint) do
gg[v] = true
end
for k, v in pairs(gg) do
if v then
thint = hint_append(thint, k)
end
end
gg.hint = thint
return gg
end
std.obj.dict = function(self, t)
local idx = std.rawget(self, '__dict') or {}
for word, v in pairs(t) do
local w, hints = str_hint(word)
if type(v) == 'table' then
idx[w] = v
v.hints = hints or ""
else
if not idx[w] then
idx[w] = { hints = "", }
end
table.insert(idx[w], v .. '/' .. hints)
end
end
std.rawset(self, '__dict', idx)
return self
end
local onew = std.obj.new
std.obj.new = function(self, v)
if type(v[1]) == 'string' or type(v[1]) == 'function' then
v.word = v[1]
table.remove(v, 1)
end
return onew(self, v)
end
end
local mt = getmetatable("")
function mt.__unm(v)
return v
end
return mrd
--mrd:gramtab()
--mrd.lang = require "lang-ru"
--mrd:load(false, { [mrd.lang.upper "подосиновики"] = true, [mrd.lang.upper "красные"] = true })
--local w = mrd:word(-"красные подосиновики/рд")
--print(w)
--mrd:file("mrd.lua")

878
morph/rgramtab.tab Normal file
View File

@ -0,0 +1,878 @@
// ====== СУЩЕСТВИТЕЛЬНЫЕ ========
// существительные мужского рода
аа A С мр,ед,им
аб A С мр,ед,рд
Эф A С мр,ед,рд,2
ав A С мр,ед,дт
аг A С мр,ед,вн
ад A С мр,ед,тв
ае A С мр,ед,пр
Эх A С мр,ед,пр,2
ас A С мр,ед,зв,
аж A С мр,мн,им
аз A С мр,мн,рд
аи A С мр,мн,дт
ай A С мр,мн,вн
ак A С мр,мн,тв
ал A С мр,мн,пр
ам B С мр,0
ан B С мр,ед,0
// ============= разговорный ================
Юо A С мр,ед,им,разг
Юп A С мр,ед,рд,разг
Юр A С мр,ед,дт,разг
Юс A С мр,ед,вн,разг
Ют A С мр,ед,тв,разг
Юф A С мр,ед,пр,разг
Юх A С мр,ед,зв,разг
Яб A С мр,мн,им,разг
Яа A С мр,мн,рд,разг
Яв A С мр,мн,дт,разг
Яг A С мр,мн,вн,разг
Яд A С мр,мн,тв,разг
Яж A С мр,мн,пр,разг
// ============= архаизм ================
го A С мр,ед,им,арх
гп A С мр,ед,рд,арх
гр A С мр,ед,дт,арх
гс A С мр,ед,вн,арх
гт A С мр,ед,тв,арх
гу A С мр,ед,пр,арх
гф A С мр,мн,им,арх
гх A С мр,мн,рд,арх
гц A С мр,мн,дт,арх
гч A С мр,мн,вн,арх
гш A С мр,мн,тв,арх
гщ A С мр,мн,пр,арх
// существительные мужского-женского рода
ва E С мр-жр,ед,им
вб E С мр-жр,ед,рд
вв E С мр-жр,ед,дт
вг E С мр-жр,ед,вн
вд E С мр-жр,ед,тв
ве E С мр-жр,ед,пр
вж E С мр-жр,мн,им
вз E С мр-жр,мн,рд
ви E С мр-жр,мн,дт
вй E С мр-жр,мн,вн
вк E С мр-жр,мн,тв
вл E С мр-жр,мн,пр
вм F С мр-жр,0
вн F С мр-жр,ед,0
// существительные мужского-женского рода (архаизм)
во E С арх,мр-жр,ед,им
вп E С арх,мр-жр,ед,рд
вр E С арх,мр-жр,ед,дт
вс E С арх,мр-жр,ед,вн
вт E С арх,мр-жр,ед,тв
ву E С арх,мр-жр,ед,пр
вф E С арх,мр-жр,мн,им
вх E С арх,мр-жр,мн,рд
вц E С арх,мр-жр,мн,дт
вч E С арх,мр-жр,мн,вн
вш E С арх,мр-жр,мн,тв
вщ E С арх,мр-жр,мн,пр
// существительные женского рода
га G С жр,ед,им
гб G С жр,ед,рд
гв G С жр,ед,дт
гг G С жр,ед,вн
гд G С жр,ед,тв
ге G С жр,ед,пр
Эч G С жр,ед,пр,2
Йш G С жр,ед,зв
гж G С жр,мн,им
гз G С жр,мн,рд
ги G С жр,мн,дт
гй G С жр,мн,вн
гк G С жр,мн,тв
гл G С жр,мн,пр
гм H С жр,0
гн H С жр,ед,0
// существительные женского (архаизм)
Йа G С арх,жр,ед,им
Йб G С арх,жр,ед,рд
Йв G С арх,жр,ед,дт
Йг G С арх,жр,ед,вн
Йд G С арх,жр,ед,тв
Йе G С арх,жр,ед,пр
Йж G С арх,жр,мн,им
Йз G С арх,жр,мн,рд
Йи G С арх,жр,мн,дт
Йй G С арх,жр,мн,вн
Йк G С арх,жр,мн,тв
Йл G С арх,жр,мн,пр
// существительные женского (разговорный)
Йм G С разг,жр,ед,им
Йн G С разг,жр,ед,рд
Йо G С разг,жр,ед,дт
Йп G С разг,жр,ед,вн
Йр G С разг,жр,ед,тв
Йс G С разг,жр,ед,пр
Йт G С разг,жр,мн,им
Йу G С разг,жр,мн,рд
Йф G С разг,жр,мн,дт
Йх G С разг,жр,мн,вн
Йц G С разг,жр,мн,тв
Йч G С разг,жр,мн,пр
// существительные среднего рода
еа K С ср,ед,им
еб K С ср,ед,рд
ев K С ср,ед,дт
ег K С ср,ед,вн
ед K С ср,ед,тв
ее K С ср,ед,пр
еж K С ср,мн,им
ез K С ср,мн,рд
еи K С ср,мн,дт
ей K С ср,мн,вн
ек K С ср,мн,тв
ел K С ср,мн,пр
ем L С ср,0
ен L С ср,ед,0
// им. Ленина
Эя K С ср,ед,рд,аббр
// существительные среднего рода (разговорный)
Яз K С разг,ср,ед,им
Яи K С разг,ср,ед,рд
Як K С разг,ср,ед,дт
Ял K С разг,ср,ед,вн
Ям K С разг,ср,ед,тв
Ян K С разг,ср,ед,пр
Яо K С разг,ср,мн,им
Яп K С разг,ср,мн,рд
Яр K С разг,ср,мн,дт
Яс K С разг,ср,мн,вн
Ят K С разг,ср,мн,тв
Яу K С разг,ср,мн,пр
// pluralia tantum
иж Q С мн,мн,им
из Q С мн,мн,рд
ии Q С мн,мн,дт
ий Q С мн,мн,вн
ик Q С мн,мн,тв
ил Q С мн,мн,пр
им R С мн,0
// аббревиатуры
ао B С мр,аббр,0,
ап B С мр,ед,аббр,0
ат H С жр,аббр,0
ау H С жр,ед,аббр,0
ац H С ср,аббр,0
ач H С ср,ед,аббр,0
аъ R С мн,аббр,0
// имена
бо C С мр,имя,ед,им
бп C С мр,имя,ед,рд
бр C С мр,имя,ед,дт
бс C С мр,имя,ед,вн
бт C С мр,имя,ед,тв
бу C С мр,имя,ед,пр
бь C С мр,имя,ед,зв,разг
бф C С мр,имя,мн,им
бх C С мр,имя,мн,рд
бц C С мр,имя,мн,дт
бч C С мр,имя,мн,вн
бш C С мр,имя,мн,тв
бщ C С мр,имя,мн,пр
бН I С мр,имя,0
вН E С мр-жр,имя,0
вО E С мр-жр,имя,ед,им
вП E С мр-жр,имя,ед,рд
вР E С мр-жр,имя,ед,дт
вС E С мр-жр,имя,ед,вн
вТ E С мр-жр,имя,ед,тв
вУ E С мр-жр,имя,ед,пр
вЬ E С мр-жр,имя,ед,зв,разг
вФ E С мр-жр,имя,мн,им
вХ E С мр-жр,имя,мн,рд
вЦ E С мр-жр,имя,мн,дт
вЧ E С мр-жр,имя,мн,вн
вШ E С мр-жр,имя,мн,тв
вЩ E С мр-жр,имя,мн,пр
до I С жр,имя,ед,им
дп I С жр,имя,ед,рд
др I С жр,имя,ед,дт
дс I С жр,имя,ед,вн
дт I С жр,имя,ед,тв
ду I С жр,имя,ед,пр
дь I С жр,имя,ед,зв,разг
дф I С жр,имя,мн,им
дх I С жр,имя,мн,рд
дц I С жр,имя,мн,дт
дч I С жр,имя,мн,вн
дш I С жр,имя,мн,тв
дщ I С жр,имя,мн,пр
дН I С жр,имя,0
// мужские отчества
Ра Q С мр,отч,ед,им,
Рб Q С мр,отч,ед,рд,
Рв Q С мр,отч,ед,дт,
Рг Q С мр,отч,ед,вн,
Рд Q С мр,отч,ед,тв,
Ре Q С мр,отч,ед,пр,
Рн Q С мр,отч,мн,им,
Ро Q С мр,отч,мн,рд,
Рп Q С мр,отч,мн,дт,
Рр Q С мр,отч,мн,вн,
Рс Q С мр,отч,мн,тв,
Рт Q С мр,отч,мн,пр,
// женские отчества
Рж Q С жр,отч,ед,им,
Рз Q С жр,отч,ед,рд,
Ри Q С жр,отч,ед,дт,
Рк Q С жр,отч,ед,вн,
Рл Q С жр,отч,ед,тв,
Рм Q С жр,отч,ед,пр,
Ру Q С жр,отч,мн,им,
Рф Q С жр,отч,мн,рд,
Рх Q С жр,отч,мн,дт,
Рц Q С жр,отч,мн,вн,
Рч Q С жр,отч,мн,тв,
Рш Q С жр,отч,мн,пр,
// мужские отчества (разг.)
Та Q С мр,отч,разг,ед,им,
Тб Q С мр,отч,разг,ед,рд,
Тв Q С мр,отч,разг,ед,дт,
Тг Q С мр,отч,разг,ед,вн,
Тд Q С мр,отч,разг,ед,тв,
Те Q С мр,отч,разг,ед,пр,
Тн Q С мр,отч,разг,мн,им,
То Q С мр,отч,разг,мн,рд,
Тп Q С мр,отч,разг,мн,дт,
Тр Q С мр,отч,разг,мн,вн,
Тс Q С мр,отч,разг,мн,тв,
Тт Q С мр,отч,разг,мн,пр,
// женские отчества (разг.)
Тж Q С жр,отч,разг,ед,им,
Тз Q С жр,отч,разг,ед,рд,
Ти Q С жр,отч,разг,ед,дт,
Тк Q С жр,отч,разг,ед,вн,
Тл Q С жр,отч,разг,ед,тв,
Тм Q С жр,отч,разг,ед,пр,
Ту Q С жр,отч,разг,мн,им,
Тф Q С жр,отч,разг,мн,рд,
Тх Q С жр,отч,разг,мн,дт,
Тц Q С жр,отч,разг,мн,вн,
Тч Q С жр,отч,разг,мн,тв,
Тш Q С жр,отч,разг,мн,пр,
// ====== ПРИЛАГАТЕЛЬНЫЕ ========
йа Y П мр,ед,им,од,но
йб Y П мр,ед,рд,од,но
йв Y П мр,ед,дт,од,но
йг Y П мр,ед,вн,од
Рщ Y П мр,ед,вн,но
йд Y П мр,ед,тв,од,но
йе Y П мр,ед,пр,од,но
йж Y П жр,ед,им,од,но
йз Y П жр,ед,рд,од,но
йи Y П жр,ед,дт,од,но
йй Y П жр,ед,вн,од,но
йк Y П жр,ед,тв,од,но
йл Y П жр,ед,пр,од,но
йм Y П ср,ед,им,од,но
йн Y П ср,ед,рд,од,но
йо Y П ср,ед,дт,од,но
йп Y П ср,ед,вн,од,но
йр Y П ср,ед,тв,од,но
йс Y П ср,ед,пр,од,но
йт Y П мн,им,од,но
йу Y П мн,рд,од,но
йф Y П мн,дт,од,но
йх Y П мн,вн,од
Рь Y П мн,вн,но
йц Y П мн,тв,од,но
йч Y П мн,пр,од,но
йш Y КРРИЛ мр,ед,од,но
йщ Y КРРИЛ жр,ед,од,но
йы Y КРРИЛ ср,ед,од,но
йэ Y КРРИЛ мн,од,но
йю Y П сравн,од,но
йъ Y П сравн,2,од,но
йь Y П сравн,од,но,разг
йя Z П 0,од,но
//== превосходная степень прилагательного
иа Y П прев,мр,ед,им,од,но
иб Y П прев,мр,ед,рд,од,но
ив Y П прев,мр,ед,дт,од,но
иг Y П прев,мр,ед,вн,од
ид Y П прев,мр,ед,вн,но
ие Y П прев,мр,ед,тв,од,но
Гб Y П прев,мр,ед,пр,од,но
Гв Y П прев,жр,ед,им,од,но
Гг Y П прев,жр,ед,рд,од,но
Гд Y П прев,жр,ед,дт,од,но
Ге Y П прев,жр,ед,вн,од,но
Гж Y П прев,жр,ед,тв,од,но
Гз Y П прев,жр,ед,пр,од,но
ин Y П прев,ср,ед,им,од,но
ио Y П прев,ср,ед,рд,од,но
ип Y П прев,ср,ед,дт,од,но
ир Y П прев,ср,ед,вн,од,но
ис Y П прев,ср,ед,тв,од,но
ит Y П прев,ср,ед,пр,од,но
иу Y П прев,мн,им,од,но
иф Y П прев,мн,рд,од,но
их Y П прев,мн,дт,од,но
иц Y П прев,мн,вн,од
ич Y П прев,мн,вн,но
иш Y П прев,мн,тв,од,но
ищ Y П прев,мн,пр,од,но
// ======== безличные глаголы ============
// подуматься,светать
нр a ИНФИНИТИВ безл
// подумается
нс a Г безл,буд
// подумалось,светало
нт a Г безл,прш
// светает
ну a Г безл,нст
ка a ИНФИНИТИВ дст
// ========================================
// ======== личные формы глагола ============
кб a Г дст,нст,1л,ед
кв a Г дст,нст,1л,мн
кг a Г дст,нст,2л,ед
кд a Г дст,нст,2л,мн
ке a Г дст,нст,3л,ед
кж a Г дст,нст,3л,мн
кз a Г дст,прш,мр,ед
ки a Г дст,прш,жр,ед
кй a Г дст,прш,ср,ед
кк a Г дст,прш,мн
кп a Г дст,буд,1л,ед
кр a Г дст,буд,1л,мн
кс a Г дст,буд,2л,ед
кт a Г дст,буд,2л,мн
ку a Г дст,буд,3л,ед
кф a Г дст,буд,3л,мн
// разговорные формы: "ложу", "ложим","дышут", "ложут", "ложат", "дождуся"
Ръ a Г дст,нст,1л,ед,разг
Ры a Г дст,нст,1л,мн,разг
Рэ a Г дст,нст,2л,ед,разг
Рю a Г дст,нст,2л,мн,разг
Ря a Г дст,нст,3л,ед,разг
кю a Г дст,нст,3л,мн,разг
кя a Г дст,прш,мн,разг
кэ a Г дст,буд,1л,ед,разг
Эа a Г дст,буд,1л,мн,разг
Эб a Г дст,буд,2л,ед,разг
Эв a Г дст,буд,2л,мн,разг
Эг a Г дст,буд,3л,ед,разг
Эд a Г дст,буд,3л,мн,разг
// архаичные формы: "указует",
Эе a Г дст,нст,1л,ед,арх
Эж a Г дст,нст,1л,мн,арх
Эз a Г дст,нст,2л,ед,арх
Эи a Г дст,нст,2л,мн,арх
Эй a Г дст,нст,3л,ед,арх
Эк a Г дст,нст,3л,мн,арх
Эл a Г дст,прш,мн,арх
Эм a Г дст,буд,1л,ед,арх
Эн a Г дст,буд,1л,мн,арх
Эо a Г дст,буд,2л,ед,арх
Эп a Г дст,буд,2л,мн,арх
Эр a Г дст,буд,3л,ед,арх
Эс a Г дст,буд,3л,мн,арх
// ===================================================
// ============== ДЕЕПРИЧАСТИЕ ====================
// ===================================================
кн a ДЕЕПРИЧАСТИЕ дст,нст
ко a ДЕЕПРИЧАСТИЕ дст,прш
// ===================================================
// ============== ДЕЕПРИЧАСТИЕ (архаизм) ==========
// ===================================================
Эт a ДЕЕПРИЧАСТИЕ дст,нст,арх
Эу a ДЕЕПРИЧАСТИЕ дст,прш,арх
//===================================================
// ============== ИМПЕРАТИВ ====================
// "не будем же забывать наших предков!"
нп a Г дст,пвл,1л,мн
къ a Г дст,пвл,1л,ед
кл a Г дст,пвл,2л,ед
км a Г дст,пвл,2л,мн
// "прощевайте"
ль a Г дст,пвл,2л,ед,разг
кь a Г дст,пвл,2л,мн,разг
// см.
Эю a Г дст,пвл,2л,ед,аббр
// "изыди", "изыдите"
фъ a Г дст,пвл,2л,ед,арх
фю a Г дст,пвл,2л,мн,арх
// действительное причастие настоящего времени
ла a ПРИЧАСТИЕ од,но,нст,дст,ед,мр,им
лб a ПРИЧАСТИЕ од,но,нст,дст,ед,мр,рд
лв a ПРИЧАСТИЕ од,но,нст,дст,ед,мр,дт
лг a ПРИЧАСТИЕ од,нст,дст,ед,мр,вн
Ла a ПРИЧАСТИЕ но,нст,дст,ед,мр,вн
лд a ПРИЧАСТИЕ од,но,нст,дст,ед,мр,тв
ле a ПРИЧАСТИЕ од,но,нст,дст,ед,мр,пр
лз a ПРИЧАСТИЕ од,но,нст,дст,ед,жр,им
ли a ПРИЧАСТИЕ од,но,нст,дст,ед,жр,рд
лй a ПРИЧАСТИЕ од,но,нст,дст,ед,жр,дт
лк a ПРИЧАСТИЕ од,но,нст,дст,ед,жр,вн
лл a ПРИЧАСТИЕ од,но,нст,дст,ед,жр,тв
лм a ПРИЧАСТИЕ од,но,нст,дст,ед,жр,пр
ло a ПРИЧАСТИЕ од,но,нст,дст,ед,ср,им
лп a ПРИЧАСТИЕ од,но,нст,дст,ед,ср,рд
лр a ПРИЧАСТИЕ од,но,нст,дст,ед,ср,дт
лс a ПРИЧАСТИЕ од,но,нст,дст,ед,ср,вн
лт a ПРИЧАСТИЕ од,но,нст,дст,ед,ср,тв
лу a ПРИЧАСТИЕ од,но,нст,дст,ед,ср,пр
лх a ПРИЧАСТИЕ од,но,нст,дст,мн,им
лц a ПРИЧАСТИЕ од,но,нст,дст,мн,рд
лч a ПРИЧАСТИЕ од,но,нст,дст,мн,дт
лш a ПРИЧАСТИЕ од,нст,дст,мн,вн
Лй a ПРИЧАСТИЕ но,нст,дст,мн,вн
лщ a ПРИЧАСТИЕ од,но,нст,дст,мн,тв
лы a ПРИЧАСТИЕ од,но,нст,дст,мн,пр
// действительное причастие прошедшего времени
ма a ПРИЧАСТИЕ од,но,прш,дст,ед,мр,им
мб a ПРИЧАСТИЕ од,но,прш,дст,ед,мр,рд
мв a ПРИЧАСТИЕ од,но,прш,дст,ед,мр,дт
мг a ПРИЧАСТИЕ од,прш,дст,ед,мр,вн
Лб a ПРИЧАСТИЕ но,прш,дст,ед,мр,вн
мд a ПРИЧАСТИЕ од,но,прш,дст,ед,мр,тв
ме a ПРИЧАСТИЕ од,но,прш,дст,ед,мр,пр
мз a ПРИЧАСТИЕ од,но,прш,дст,ед,жр,им
ми a ПРИЧАСТИЕ од,но,прш,дст,ед,жр,рд
мй a ПРИЧАСТИЕ од,но,прш,дст,ед,жр,дт
мк a ПРИЧАСТИЕ од,но,прш,дст,ед,жр,вн
мл a ПРИЧАСТИЕ од,но,прш,дст,ед,жр,тв
мм a ПРИЧАСТИЕ од,но,прш,дст,ед,жр,пр
мо a ПРИЧАСТИЕ од,но,прш,дст,ед,ср,им
мп a ПРИЧАСТИЕ од,но,прш,дст,ед,ср,рд
мр a ПРИЧАСТИЕ од,но,прш,дст,ед,ср,дт
мс a ПРИЧАСТИЕ од,но,прш,дст,ед,ср,вн
мт a ПРИЧАСТИЕ од,но,прш,дст,ед,ср,тв
му a ПРИЧАСТИЕ од,но,прш,дст,ед,ср,пр
мх a ПРИЧАСТИЕ од,но,прш,дст,мн,им
мц a ПРИЧАСТИЕ од,но,прш,дст,мн,рд
мч a ПРИЧАСТИЕ од,но,прш,дст,мн,дт
мш a ПРИЧАСТИЕ од,прш,дст,мн,вн
Лк a ПРИЧАСТИЕ но,прш,дст,мн,вн
мщ a ПРИЧАСТИЕ од,но,прш,дст,мн,тв
мы a ПРИЧАСТИЕ од,но,прш,дст,мн,пр
// страдательное причастие настоящего времени
па b ПРИЧАСТИЕ од,но,нст,стр,ед,мр,им
пб b ПРИЧАСТИЕ од,но,нст,стр,ед,мр,рд
пв b ПРИЧАСТИЕ од,но,нст,стр,ед,мр,дт
пг b ПРИЧАСТИЕ од,нст,стр,ед,мр,вн
Лг b ПРИЧАСТИЕ но,нст,стр,ед,мр,вн
пд b ПРИЧАСТИЕ од,но,нст,стр,ед,мр,тв
пе b ПРИЧАСТИЕ од,но,нст,стр,ед,мр,пр
пж b КРРИЧАСТИЕ од,но,нст,стр,ед,мр
пз b ПРИЧАСТИЕ од,но,нст,стр,ед,жр,им
пи b ПРИЧАСТИЕ од,но,нст,стр,ед,жр,рд
пй b ПРИЧАСТИЕ од,но,нст,стр,ед,жр,дт
пк b ПРИЧАСТИЕ од,но,нст,стр,ед,жр,вн
пл b ПРИЧАСТИЕ од,но,нст,стр,ед,жр,тв
пм b ПРИЧАСТИЕ од,но,нст,стр,ед,жр,пр
пн b КРРИЧАСТИЕ од,но,нст,стр,ед,жр
по b ПРИЧАСТИЕ од,но,нст,стр,ед,ср,им
пп b ПРИЧАСТИЕ од,но,нст,стр,ед,ср,рд
пр b ПРИЧАСТИЕ од,но,нст,стр,ед,ср,дт
пс b ПРИЧАСТИЕ од,но,нст,стр,ед,ср,вн
пт b ПРИЧАСТИЕ од,но,нст,стр,ед,ср,тв
пу b ПРИЧАСТИЕ од,но,нст,стр,ед,ср,пр
пф b КРРИЧАСТИЕ од,но,нст,стр,ед,ср
пх b ПРИЧАСТИЕ од,но,нст,стр,мн,им
пц b ПРИЧАСТИЕ од,но,нст,стр,мн,рд
пч b ПРИЧАСТИЕ од,но,нст,стр,мн,дт
пш b ПРИЧАСТИЕ од,нст,стр,мн,вн
Лм b ПРИЧАСТИЕ но,нст,стр,мн,вн
пщ b ПРИЧАСТИЕ од,но,нст,стр,мн,тв
пы b ПРИЧАСТИЕ од,но,нст,стр,мн,пр
пэ b КРРИЧАСТИЕ од,но,нст,стр,мн
// страдательное причастие прошедшего времени
са b ПРИЧАСТИЕ од,но,прш,стр,ед,мр,им
сб b ПРИЧАСТИЕ од,но,прш,стр,ед,мр,рд
св b ПРИЧАСТИЕ од,но,прш,стр,ед,мр,дт
сг b ПРИЧАСТИЕ од,прш,стр,ед,мр,вн
Ле b ПРИЧАСТИЕ но,прш,стр,ед,мр,вн
сд b ПРИЧАСТИЕ од,но,прш,стр,ед,мр,тв
се b ПРИЧАСТИЕ од,но,прш,стр,ед,мр,пр
сж b КРРИЧАСТИЕ од,но,прш,стр,ед,мр
сз b ПРИЧАСТИЕ од,но,прш,стр,ед,жр,им
си b ПРИЧАСТИЕ од,но,прш,стр,ед,жр,рд
сй b ПРИЧАСТИЕ од,но,прш,стр,ед,жр,дт
ск b ПРИЧАСТИЕ од,но,прш,стр,ед,жр,вн
сл b ПРИЧАСТИЕ од,но,прш,стр,ед,жр,тв
см b ПРИЧАСТИЕ од,но,прш,стр,ед,жр,пр
сн b КРРИЧАСТИЕ од,но,прш,стр,ед,жр
со b ПРИЧАСТИЕ од,но,прш,стр,ед,ср,им
сп b ПРИЧАСТИЕ од,но,прш,стр,ед,ср,рд
ср b ПРИЧАСТИЕ од,но,прш,стр,ед,ср,дт
сс b ПРИЧАСТИЕ од,но,прш,стр,ед,ср,вн
ст b ПРИЧАСТИЕ од,но,прш,стр,ед,ср,тв
су b ПРИЧАСТИЕ од,но,прш,стр,ед,ср,пр
сф b КРРИЧАСТИЕ од,но,прш,стр,ед,ср
сх b ПРИЧАСТИЕ од,но,прш,стр,мн,им
сц b ПРИЧАСТИЕ од,но,прш,стр,мн,рд
сч b ПРИЧАСТИЕ од,но,прш,стр,мн,дт
сш b ПРИЧАСТИЕ од,прш,стр,мн,вн
Ло b ПРИЧАСТИЕ но,прш,стр,мн,вн
сщ b ПРИЧАСТИЕ од,но,прш,стр,мн,тв
сы b ПРИЧАСТИЕ од,но,прш,стр,мн,пр
сэ b КРРИЧАСТИЕ од,но,прш,стр,мн
ча e МС 1л,ед,им
чб e МС 1л,ед,рд
чв e МС 1л,ед,дт
чг e МС 1л,ед,вн
чд e МС 1л,ед,тв
че e МС 1л,ед,пр
чж e МС 1л,мн,им
чз e МС 1л,мн,рд
чи e МС 1л,мн,дт
чй e МС 1л,мн,вн
чк e МС 1л,мн,тв
чл e МС 1л,мн,пр
чм e МС 2л,ед,им
чн e МС 2л,ед,рд
чо e МС 2л,ед,дт
чп e МС 2л,ед,вн
чр e МС 2л,ед,тв
чс e МС 2л,ед,пр
чт e МС 2л,мн,им
чу e МС 2л,мн,рд
чф e МС 2л,мн,дт
чх e МС 2л,мн,вн
чц e МС 2л,мн,тв
чч e МС 2л,мн,пр
ша e МС 3л,мр,ед,им
шб e МС 3л,мр,ед,рд
шв e МС 3л,мр,ед,дт
шг e МС 3л,мр,ед,вн
шд e МС 3л,мр,ед,тв
ше e МС 3л,мр,ед,пр
шж e МС 3л,жр,ед,им
шз e МС 3л,жр,ед,рд
ши e МС 3л,жр,ед,дт
шй e МС 3л,жр,ед,вн
шк e МС 3л,жр,ед,тв
шл e МС 3л,жр,ед,пр
шм e МС 3л,ср,ед,им
шн e МС 3л,ср,ед,рд
шо e МС 3л,ср,ед,дт
шп e МС 3л,ср,ед,вн
шр e МС 3л,ср,ед,тв
шс e МС 3л,ср,ед,пр
шт e МС 3л,мн,им
шу e МС 3л,мн,рд
шф e МС 3л,мн,дт
шх e МС 3л,мн,вн
шц e МС 3л,мн,тв
шч e МС 3л,мн,пр
ща e МС мр,ед,им
щб e МС мр,ед,рд
щв e МС мр,ед,дт
щг e МС мр,ед,вн
щд e МС мр,ед,тв
ще e МС мр,ед,пр
щж e МС жр,ед,им
щз e МС жр,ед,рд
щи e МС жр,ед,дт
щй e МС жр,ед,вн
щк e МС жр,ед,тв
щл e МС жр,ед,пр
щм e МС ср,ед,им
щн e МС ср,ед,рд
що e МС ср,ед,дт
щп e МС ср,ед,вн
щр e МС ср,ед,тв
щс e МС ср,ед,пр
щт e МС мн,им
щу e МС мн,рд
щф e МС мн,дт
щх e МС мн,вн
щц e МС мн,тв
щч e МС мн,пр
щщ e МС рд
щы e МС дт
щэ e МС вн
щю e МС тв
щя e МС пр
ыа f МС-П мр,ед,им,од,но
ыб f МС-П мр,ед,рд,од,но
ыв f МС-П мр,ед,дт,од,но
ыг f МС-П мр,ед,вн,но
Лф f МС-П мр,ед,вн,од
ыд f МС-П мр,ед,тв,од,но
ые f МС-П мр,ед,пр,од,но
ыж f МС-П жр,ед,им,од,но
ыз f МС-П жр,ед,рд,од,но
ыи f МС-П жр,ед,дт,од,но
ый f МС-П жр,ед,вн,од,но
ык f МС-П жр,ед,тв,од,но
ыл f МС-П жр,ед,пр,од,но
ым f МСср,ед,им,од,но
ын f МСср,ед,рд,од,но
ыо f МСср,ед,дт,од,но
ып f МСср,ед,вн,од,но
ыр f МСср,ед,тв,од,но
ыс f МСср,ед,пр,од,но
ыт f МС-П мн,им,од,но
ыу f МС-П мн,рд,од,но
ыф f МС-П мн,дт,од,но
ых f МС-П мн,вн,но
Лх f МС-П мн,вн,од
ыц f МС-П мн,тв,од,но
ыч f МС-П мн,пр,од,но
ыш f МС-П 0,од,но
ыщ g МС-ПРЕДК ед,рд
ыы g МС-ПРЕДК ед,дт
ыэ g МС-ПРЕДК ед,вн
ыю g МС-ПРЕДК ед,тв
// это анал. форма "не о ком"
ыь g МС-ПРЕДК ед,пр
ыя g МС-ПРЕДК
эа h ЧИСЛ им
эб h ЧИСЛ рд
эв h ЧИСЛ дт
эг h ЧИСЛ вн
эд h ЧИСЛ тв
эе h ЧИСЛ пр
Ца h ЧИСЛ им,арх
Цб h ЧИСЛ рд,арх
Цв h ЧИСЛ дт,арх
Цг h ЧИСЛ вн,арх
Цд h ЧИСЛ тв,арх
Це h ЧИСЛ пр,арх
эж h ЧИСЛ мр,им
эз h ЧИСЛ мр,рд
эи h ЧИСЛ мр,дт
эй h ЧИСЛ мр,вн
эк h ЧИСЛ мр,тв
эл h ЧИСЛ мр,пр
эм h ЧИСЛ жр,им
эн h ЧИСЛ жр,рд
эо h ЧИСЛ жр,дт
эп h ЧИСЛ жр,вн
эр h ЧИСЛ жр,тв
эс h ЧИСЛ жр,пр
эт h ЧИСЛ ср,им
эу h ЧИСЛ ср,рд
эф h ЧИСЛ ср,дт
эх h ЧИСЛ ср,вн
эц h ЧИСЛ ср,тв
эч h ЧИСЛ ср,пр
эш h ЧИСЛ сравн
юа i ЧИСЛ-П мр,ед,им,од,но
юб i ЧИСЛ-П мр,ед,рд,од,но
юв i ЧИСЛ-П мр,ед,дт,од,но
юг i ЧИСЛ-П мр,ед,вн,но
Лт i ЧИСЛ-П мр,ед,вн,од
юд i ЧИСЛ-П мр,ед,тв,од,но
юе i ЧИСЛ-П мр,ед,пр,од,но
юж i ЧИСЛ-П жр,ед,им,од,но
юз i ЧИСЛ-П жр,ед,рд,од,но
юи i ЧИСЛ-П жр,ед,дт,од,но
юй i ЧИСЛ-П жр,ед,вн,од,но
юк i ЧИСЛ-П жр,ед,тв,од,но
юл i ЧИСЛ-П жр,ед,пр,од,но
юм i ЧИСЛ-П ср,ед,им,од,но
юн i ЧИСЛ-П ср,ед,рд,од,но
юо i ЧИСЛ-П ср,ед,дт,од,но
юп i ЧИСЛ-П ср,ед,вн,од,но
юр i ЧИСЛ-П ср,ед,тв,од,но
юс i ЧИСЛ-П ср,ед,пр,од,но
ют i ЧИСЛ-П мн,им,од,но
юу i ЧИСЛ-П мн,рд,од,но
юф i ЧИСЛ-П мн,дт,од,но
юх i ЧИСЛ-П мн,вн,но
Лу i ЧИСЛ-П мн,вн,од
юц i ЧИСЛ-П мн,тв,од,но
юч i ЧИСЛ-П мн,пр,од,но
ющ i ЧИСЛ-П рд,од,но
// наречия
яа j Н
ян j Н вопр
яо j Н указат
яп j Н разг
// "мне интересно","мне было страшно"
яб k ПРЕДК нст
як k ПРЕДК прш
ял k ПРЕДК
// мне лучше
яр k ПРЕДК сравн,нст
// "вот", "хрусть" (нет анал. форм)
ям k ПРЕДК 0
яв l ПРЕДЛ
яг m ПОСЛ
яд n СОЮЗ
яе o МЕЖД
яё o МЕЖД разг
яж p ЧАСТ
яз q ВВОДН
яй s ФРАЗ
Пп b Г стр,буд,1л,ед
Пр b Г стр,буд,1л,мн
Пс b Г стр,буд,2л,ед
Пт b Г стр,буд,2л,мн
Пу b Г стр,буд,3л,ед
Пф b Г стр,буд,3л,мн
// общие граммемы (словообразовательные)
Уа a * лок
// Уб a *
// Ув a *
// Уг a *
// Уд a *
Уе a * кач
Уж a * дфст
Уз a * дфст,орг
Уи a * дфст,лок
//Ук a *
Ул a * св,пе
Ум a * св,нп
Ун a * нс,пе
Уо a * нс,нп
Уп a * св,нс,пе
Ур a * св,нс,нп
// для безличных глаголов
Ус a * нс
Ут a * св
Уф a * жарг
Ух a * опч
Уч a * жарг,опч
Уц a * орг,жарг
Уш a * лок,жарг
Ущ a * но,лок
Уь a * но,орг
Уы a * од,фам
Уъ a * но,дфст,лок
Уэ a * но,дфст,орг
Ую a * но,жарг
Уя a * но,опч,
Фа a * но,
Фб a * од,
Фв a * орг,жарг,но
Фг a * дфст,но
Фд a * дфст,од
Фж a * од,жарг
Фз a * имя,притяж
Фи a * притяж
Фк a * св,пе,разг
Фл a * св,нп,разг
Фн a * нс,пе,разг
Фо a * нс,нп,разг
Фп a * но,разг
Фр a * од,разг
Фс a * св,пе,жарг
Фт a * св,нп,жарг
Фу a * нс,пе,жарг
Фф a * нс,нп,жарг
Фх a * разг
Фц a * арх
Фч a * св,пе,арх
Фш a * св,нп,арх
Фщ a * нс,пе,арх
Фь a * нс,нп,арх
Фы a * но,арх
Фъ a * од,арх
Фэ a * нс,арх
Фю a * св,арх
Фя a * кач,арх
Фё a * но,од
Ха a * од,опч,
Хб a * лок,опч,
яю F С мр,жр,ср,ед,им,рд,дт,вн,тв,пр
яя F С мр,жр,ср,,ед,мн,им,рд,дт,вн,тв,пр

1235
parser/mp-en.lua Normal file

File diff suppressed because it is too large Load Diff

1192
parser/mp-ru.lua Normal file

File diff suppressed because it is too large Load Diff

2822
parser/mp.lua Normal file

File diff suppressed because it is too large Load Diff

3103
parser/mplib.lua Normal file

File diff suppressed because it is too large Load Diff

41
parser/react.lua Normal file
View File

@ -0,0 +1,41 @@
-- react_ and postreact_ event module for reactions near the object
--[[ include 'listen'
obj {
nam = 'npc';
react_Take = "Player in this room is taking something. Reject!";
}:listen();
]]--
--luacheck: globals mp
--luacheck: no self
game.react_list = std.list {}
function game:before_Any(ev, ...)
for _, v in ipairs(game.react_list) do
if v:inroom() == std.here() then
local r = mp:runmethods('react', ev, v, ...)
if r ~= false then
return
end
end
end
return false
end
function game:post_Any(ev, ...)
for _, v in ipairs(game.react_list) do
if v:inroom() == std.here() then
local r = mp:runmethods('postreact', ev, v, ...)
if r ~= false then
return
end
end
end
return false
end
function std.obj.listen(s)
game.react_list:add(s)
return s
end