# Generated by Snowball.Generator — do not edit by hand. defmodule Text.Stemmer.Stemmers.Russian do @moduledoc """ Snowball stemmer for russian. Generated from the canonical Snowball algorithm source. """ alias Snowball.Runtime alias Snowball.Grouping # Groupings @g_v Grouping.from_string("аеиоуыэюя") # Among tables @a_0 [ {"ейш", -1, 1, nil}, {"ь", -1, 3, nil}, {"ейше", -1, 1, nil}, {"н", -1, 2, nil} ] @a_1 [ {"ост", -1, 1, nil}, {"ость", -1, 1, nil} ] @a_2 [ {"у", -1, 1, nil}, {"ях", -1, 1, nil}, {"иях", 1, 1, nil}, {"ах", -1, 1, nil}, {"ы", -1, 1, nil}, {"ь", -1, 1, nil}, {"ю", -1, 1, nil}, {"ью", 6, 1, nil}, {"ию", 6, 1, nil}, {"я", -1, 1, nil}, {"ья", 9, 1, nil}, {"ия", 9, 1, nil}, {"а", -1, 1, nil}, {"ев", -1, 1, nil}, {"ов", -1, 1, nil}, {"е", -1, 1, nil}, {"ье", 15, 1, nil}, {"ие", 15, 1, nil}, {"и", -1, 1, nil}, {"еи", 18, 1, nil}, {"ии", 18, 1, nil}, {"ями", 18, 1, nil}, {"иями", 21, 1, nil}, {"ами", 18, 1, nil}, {"й", -1, 1, nil}, {"ей", 24, 1, nil}, {"ией", 25, 1, nil}, {"ий", 24, 1, nil}, {"ой", 24, 1, nil}, {"ям", -1, 1, nil}, {"иям", 29, 1, nil}, {"ам", -1, 1, nil}, {"ем", -1, 1, nil}, {"ием", 32, 1, nil}, {"ом", -1, 1, nil}, {"о", -1, 1, nil} ] @a_3 [ {"ыт", -1, 2, nil}, {"ют", -1, 1, nil}, {"уют", 1, 2, nil}, {"ят", -1, 2, nil}, {"ет", -1, 1, nil}, {"ует", 4, 2, nil}, {"ит", -1, 2, nil}, {"ны", -1, 1, nil}, {"ены", 7, 2, nil}, {"ть", -1, 1, nil}, {"ыть", 9, 2, nil}, {"ить", 9, 2, nil}, {"ешь", -1, 1, nil}, {"ишь", -1, 2, nil}, {"ю", -1, 2, nil}, {"ую", 14, 2, nil}, {"ла", -1, 1, nil}, {"ыла", 16, 2, nil}, {"ила", 16, 2, nil}, {"на", -1, 1, nil}, {"ена", 19, 2, nil}, {"ете", -1, 1, nil}, {"ите", -1, 2, nil}, {"йте", -1, 1, nil}, {"уйте", 23, 2, nil}, {"ейте", 23, 2, nil}, {"ли", -1, 1, nil}, {"ыли", 26, 2, nil}, {"или", 26, 2, nil}, {"й", -1, 1, nil}, {"уй", 29, 2, nil}, {"ей", 29, 2, nil}, {"л", -1, 1, nil}, {"ыл", 32, 2, nil}, {"ил", 32, 2, nil}, {"ым", -1, 2, nil}, {"ем", -1, 1, nil}, {"им", -1, 2, nil}, {"н", -1, 1, nil}, {"ен", 38, 2, nil}, {"ло", -1, 1, nil}, {"ыло", 40, 2, nil}, {"ило", 40, 2, nil}, {"но", -1, 1, nil}, {"ено", 43, 2, nil}, {"нно", 43, 1, nil} ] @a_4 [ {"сь", -1, 1, nil}, {"ся", -1, 1, nil} ] @a_5 [ {"вш", -1, 1, nil}, {"ывш", 0, 2, nil}, {"ивш", 0, 2, nil}, {"щ", -1, 1, nil}, {"ющ", 3, 1, nil}, {"ующ", 4, 2, nil}, {"ем", -1, 1, nil}, {"нн", -1, 1, nil} ] @a_6 [ {"ему", -1, 1, nil}, {"ому", -1, 1, nil}, {"ых", -1, 1, nil}, {"их", -1, 1, nil}, {"ую", -1, 1, nil}, {"юю", -1, 1, nil}, {"ею", -1, 1, nil}, {"ою", -1, 1, nil}, {"яя", -1, 1, nil}, {"ая", -1, 1, nil}, {"ые", -1, 1, nil}, {"ее", -1, 1, nil}, {"ие", -1, 1, nil}, {"ое", -1, 1, nil}, {"ыми", -1, 1, nil}, {"ими", -1, 1, nil}, {"ый", -1, 1, nil}, {"ей", -1, 1, nil}, {"ий", -1, 1, nil}, {"ой", -1, 1, nil}, {"ым", -1, 1, nil}, {"ем", -1, 1, nil}, {"им", -1, 1, nil}, {"ом", -1, 1, nil}, {"его", -1, 1, nil}, {"ого", -1, 1, nil} ] @a_7 [ {"вшись", -1, 1, nil}, {"ывшись", 0, 2, nil}, {"ившись", 0, 2, nil}, {"в", -1, 1, nil}, {"ыв", 3, 2, nil}, {"ив", 3, 2, nil}, {"вши", -1, 1, nil}, {"ывши", 6, 2, nil}, {"ивши", 6, 2, nil} ] @doc """ Stem a word. ### Arguments * `word` is a UTF-8 binary. ### Returns * The stemmed UTF-8 binary. """ @spec stem(binary()) :: binary() def stem(word) when is_binary(word) do state = Runtime.new(word) |> init_vars() state = run_stem(state) Runtime.assign_to(state) end defp init_vars(state), do: %{state | vars: %{p2: 0, pV: 0}} defp run_stem(%Runtime{} = state) do {_, state} = r_stem(state) state end # Snowball runtime helpers. defp snowball_do_f(state, fun) do saved_c = state.cursor {_, s} = fun.(state) %{s | cursor: saved_c} end defp snowball_do_b(state, fun) do rel = state.limit - state.cursor {_, s} = fun.(state) %{s | cursor: s.limit - rel} end defp snowball_try(state, fun) do rel = state.limit - state.cursor case fun.(state) do {:ok, s} -> s {:fail, s} -> %{s | cursor: s.limit - rel} end end defp snowball_or(state, fun1, fun2) do rel = state.limit - state.cursor case fun1.(state) do {:ok, s} -> {:ok, s} {:fail, s} -> fun2.(%{s | cursor: s.limit - rel}) end end defp lift(state, :fail), do: {:fail, state} defp lift(_state, %Runtime{} = s), do: {:ok, s} defp next_codepoint(%Runtime{cursor: c, limit: lim, current: cur} = state) do case Runtime.codepoint_at(cur, c, lim) do {_cp, size} -> {:ok, %{state | cursor: c + size}} :error -> {:fail, state} end end defp r_tidy_up(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_0) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> case (fn state -> {:ok, Runtime.slice_del(state)} end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "н")) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "н")) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end end r -> r end end end 2 -> case (fn state -> lift(state, Runtime.eq_s_b(state, "н")) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end 3 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end end end).() end defp r_derivational(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_1) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case (fn state -> r_R2(state) end).(state) do {:ok, state} -> case result do 1 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end r -> r end end end).() end defp r_noun(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_2) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end end end).() end defp r_verb(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_3) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> case (fn state -> snowball_or(state, fn state -> lift(state, Runtime.eq_s_b(state, "а")) end, fn state -> lift(state, Runtime.eq_s_b(state, "я")) end) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end 2 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end end end).() end defp r_reflexive(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_4) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end end end).() end defp r_adjectival(%Runtime{} = state) do case (fn state -> r_adjective(state) end).(state) do {:ok, state} -> {:ok, snowball_try(state, fn state -> (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_5) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> case (fn state -> snowball_or(state, fn state -> lift(state, Runtime.eq_s_b(state, "а")) end, fn state -> lift(state, Runtime.eq_s_b(state, "я")) end) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end 2 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end end end).() end)} r -> r end end defp r_adjective(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_6) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end end end).() end defp r_perfective_gerund(%Runtime{} = state) do (fn -> state = %{state | ket: state.cursor} case Runtime.find_among_b(state, @a_7) do :fail -> {:fail, state} {%Runtime{} = s, result} -> state = %{s | bra: s.cursor} case result do 1 -> case (fn state -> snowball_or(state, fn state -> lift(state, Runtime.eq_s_b(state, "а")) end, fn state -> lift(state, Runtime.eq_s_b(state, "я")) end) end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} r -> r end 2 -> {:ok, Runtime.slice_del(state)} _ -> {:ok, state} end end end).() end defp r_R2(%Runtime{} = state) do if state.vars[:p2] <= state.cursor, do: {:ok, state}, else: {:fail, state} end defp r_mark_regions(%Runtime{} = state) do case (fn state -> {:ok, put_in(state.vars[:pV], state.limit)} end).(state) do {:ok, state} -> case (fn state -> {:ok, put_in(state.vars[:p2], state.limit)} end).(state) do {:ok, state} -> {:ok, snowball_do_f(state, fn state -> case (fn state -> case Runtime.go_out_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> case (fn state -> {:ok, put_in(state.vars[:pV], state.cursor)} end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_in_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_out_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> case (fn state -> case Runtime.go_in_grouping(state, @g_v) do :fail -> {:fail, state} %Runtime{} = s -> next_codepoint(s) end end).(state) do {:ok, state} -> {:ok, put_in(state.vars[:p2], state.cursor)} r -> r end r -> r end r -> r end end r -> r end end)} end end end defp r_stem(%Runtime{} = state) do case (fn state -> {:ok, snowball_do_f(state, fn state -> (fn loop_fn -> loop_fn.(loop_fn, state) end).(fn loop_fn, state -> case (fn state -> case (fn state -> (fn loop_fn -> loop_fn.(loop_fn, state) end).(fn loop_fn, state -> v = state.cursor case (fn state -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s(state, "ё")) end).(state) do {:ok, state} -> {:ok, %{state | ket: state.cursor}} r -> r end end end).(state) do {:ok, s} -> {:ok, %{s | cursor: v}} {:fail, _} -> case next_codepoint(%{state | cursor: v}) do {:ok, s} -> loop_fn.(loop_fn, s) {:fail, _} -> {:fail, state} end end end) end).(state) do {:ok, state} -> {:ok, Runtime.slice_from(state, "е")} r -> r end end).(state) do {:ok, s} -> loop_fn.(loop_fn, s) {:fail, s} -> {:ok, %{s | cursor: state.cursor}} end end) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_f(state, fn state -> r_mark_regions(state) end)} end).(state) do {:ok, state} -> (fn state -> old_cursor = state.cursor old_lb = state.limit_backward state = %{state | cursor: state.limit, limit_backward: old_cursor} {tag, s} = (fn state -> (fn -> case (fn state -> (fn -> target = state.vars[:pV] if target < state.limit_backward or target > state.limit do {:fail, state} else {:ok, %{state | cursor: target}} end end).() end).(state) do {:fail, _} -> {:fail, state} {:ok, limit_state} -> old_lb = state.limit_backward state = %{state | limit_backward: limit_state.cursor} case (fn state -> case (fn state -> {:ok, snowball_do_b(state, fn state -> snowball_or(state, fn state -> r_perfective_gerund(state) end, fn state -> case (fn state -> {:ok, snowball_try(state, fn state -> r_reflexive(state) end)} end).(state) do {:ok, state} -> snowball_or(state, fn state -> snowball_or(state, fn state -> r_adjectival(state) end, fn state -> r_verb(state) end) end, fn state -> r_noun(state) end) end end) end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_try(state, fn state -> case (fn state -> {:ok, %{state | ket: state.cursor}} end).(state) do {:ok, state} -> case (fn state -> lift(state, Runtime.eq_s_b(state, "и")) end).(state) do {:ok, state} -> case (fn state -> {:ok, %{state | bra: state.cursor}} end).(state) do {:ok, state} -> {:ok, Runtime.slice_del(state)} end r -> r end end end)} end).(state) do {:ok, state} -> case (fn state -> {:ok, snowball_do_b(state, fn state -> r_derivational(state) end)} end).(state) do {:ok, state} -> {:ok, snowball_do_b(state, fn state -> r_tidy_up(state) end)} end end end end).(state) do {:ok, s} -> {:ok, %{s | limit_backward: old_lb}} end end end).() end).(state) {tag, %{s | cursor: old_cursor, limit_backward: old_lb}} end).(state) end end end end