Blame voikko/voikko-fi_FI.mor

Packit 1f3717
# Suomi-malaga, suomen kielen muoto-opin kuvaus.
Packit 1f3717
#
Packit 1f3717
# Tekijänoikeus © 2006 Hannu Väisänen (Etunimi.Sukunimi@joensuu.fi)
Packit 1f3717
#                 2006 - 2010 Harri Pitkänen (hatapitk@iki.fi)
Packit 1f3717
#
Packit 1f3717
# Tämä ohjelma on vapaa; tätä ohjelmaa on sallittu levittää
Packit 1f3717
# edelleen ja muuttaa GNU yleisen lisenssin (GPL lisenssin)
Packit 1f3717
# ehtojen mukaan sellaisina kuin Free Software Foundation
Packit 1f3717
# on ne julkaissut; joko Lisenssin version 2, tai (valinnan
Packit 1f3717
# mukaan) minkä tahansa myöhemmän version mukaisesti.
Packit 1f3717
#
Packit 1f3717
# Tätä ohjelmaa levitetään siinä toivossa, että se olisi
Packit 1f3717
# hyödyllinen, mutta ilman mitään takuuta; ilman edes
Packit 1f3717
# hiljaista takuuta kaupallisesti hyväksyttävästä laadusta tai
Packit 1f3717
# soveltuvuudesta tiettyyn tarkoitukseen. Katso GPL
Packit 1f3717
# lisenssistä lisää yksityiskohtia.
Packit 1f3717
#
Packit 1f3717
# Tämän ohjelman mukana pitäisi tulla kopio GPL
Packit 1f3717
# lisenssistä; jos näin ei ole, kirjoita osoitteeseen Free
Packit 1f3717
# Software Foundation Inc., 51 Franklin Street, Fifth Floor,
Packit 1f3717
# Boston, MA 02110-1301, USA.
Packit 1f3717
#
Packit 1f3717
# Tämän ohjeman linkittäminen staattisesti tai dynaamisesti
Packit 1f3717
# muihin moduuleihin on ohjelmaan perustuvan teoksen
Packit 1f3717
# tekemistä, joka on siis GPL lisenssin ehtojen alainen.
Packit 1f3717
#
Packit 1f3717
#
Packit 1f3717
# This program is free software; you can redistribute it and/or modify
Packit 1f3717
# it under the terms of the GNU General Public License as published by
Packit 1f3717
# the Free Software Foundation; either version 2, or (at your option)
Packit 1f3717
# any later version.
Packit 1f3717
#
Packit 1f3717
# This program is distributed in the hope that it will be useful, but
Packit 1f3717
# WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 1f3717
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 1f3717
# General Public License for more details.
Packit 1f3717
#
Packit 1f3717
# You should have received a copy of the GNU General Public License
Packit 1f3717
# along with this program; see the file COPYING.  If not, write to the
Packit 1f3717
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
Packit 1f3717
# 02110-1301, USA.
Packit 1f3717
#
Packit 1f3717
# Linking this program statically or dynamically with other modules is
Packit 1f3717
# making a combined work based on this program.  Thus, the terms and
Packit 1f3717
# conditions of the GNU General Public License cover the whole
Packit 1f3717
# combination.
Packit 1f3717
Packit 1f3717
Packit 1f3717
initial <>, rules erisnimi, laatusana,
Packit 1f3717
                  lukusana, sanan_alku, teonsana,
Packit 1f3717
                  laatusana_laatusanasta, paikannimen_lainen_johdos;
Packit 1f3717
Packit 1f3717
include "config.inc";
Packit 1f3717
include "suomi.inc";
Packit 1f3717
include "mor.inc";
Packit 1f3717
Packit 1f3717
# Palauttaa yes, jos $sana voi liittyä listaan $vasen yhdyssanassa,
Packit 1f3717
# jossa yhdysviiva käyttö on sallittua ja pakollista täsmälleen silloin,
Packit 1f3717
# kun alkuosa päättyy samaan vokaaliin jolla loppuosa alkaa.
Packit 1f3717
# Listan $vasen on sisällettävä vähintään yksi elementti.
Packit 1f3717
subrule vokaaliehdollinen_yhdysviiva_ok($vasen, $sana):
Packit 1f3717
  define $i := length($vasen);
Packit 1f3717
  if ($vasen.$i.luokka = tavuviiva) then
Packit 1f3717
    if ($i = 1) then
Packit 1f3717
      return yes;
Packit 1f3717
    end;
Packit 1f3717
    if $vasen.$i.vokaaliehto = no then
Packit 1f3717
      return yes;
Packit 1f3717
    end;
Packit 1f3717
    define $edellinen := $vasen.($i - 1);
Packit 1f3717
    if (vokaali(first($sana)) and first($sana) = last($edellinen.alku)) then
Packit 1f3717
      return yes;
Packit 1f3717
    # is- ("teknillis-tieteellinen", "Kaakkois-Suomi")
Packit 1f3717
    # FIXME: tämä ei ole tarkalleen ottaen oikein, mutta toistaiseksi riittävän hyvä
Packit 1f3717
    elseif ($edellinen.alku matches ".*is") then
Packit 1f3717
      return yes;
Packit 1f3717
    elseif $edellinen.tiedot /= nil and sitlaina in $edellinen.tiedot then
Packit 1f3717
      return yes;
Packit 1f3717
    else
Packit 1f3717
      return no;
Packit 1f3717
    end;
Packit 1f3717
  else
Packit 1f3717
    if (vokaali(first($sana)) and first($sana) = last($vasen.$i.alku)) then
Packit 1f3717
      return no;
Packit 1f3717
    else
Packit 1f3717
      return yes;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
define @ehtotapa := <ehtotapa, ehtotapa_ttA, ehtotapa_tA>;
Packit 1f3717
Packit 1f3717
define @mahtotapa := 
Packit 1f3717
                      mahtotapa_ttA, mahtotapa_tA>;
Packit 1f3717
Packit 1f3717
define @käskytapa := 
Packit 1f3717
                      käskytapa_tA>;
Packit 1f3717
Packit 1f3717
define @nimitapa_1 := 
Packit 1f3717
                       nimitapa_1_nA, nimitapa_1_rA, nimitapa_1_tA>;
Packit 1f3717
define @nimitapa_2 := <nimitapa_2, nimitapa_2_ttA, nimitapa_2_tA>;
Packit 1f3717
define @nimitapa_3 := <nimitapa_3, nimitapa_3_ttA, nimitapa_3_tA>;
Packit 1f3717
Packit 1f3717
# Johtimet teonsanoista
Packit 1f3717
Packit 1f3717
define @johdin_tU := <johdin_dU, johdin_lU, johdin_nU, johdin_rU, johdin_tU, johdin_tU_lU_oltu>;
Packit 1f3717
Packit 1f3717
define @johtimet_nimisana_teonsanasta :=
Packit 1f3717
       <johdin_mA, johdin_UUs, johdin_Us, johdin_ntA, johdin_nti, johdin_Us_ksen>
Packit 1f3717
       + @johdin_jA;
Packit 1f3717
Packit 1f3717
define @johtimet_laatusana_teonsanasta :=
Packit 1f3717
       
Packit 1f3717
        johdin_ttU> + @johdin_nUt + @johdin_tU;
Packit 1f3717
Packit 1f3717
define @johtimet_seikkasana_teonsanasta := <johdin_ittAin>; # esim. "pamahduksittain"
Packit 1f3717
Packit 1f3717
define @johdin_teonsanasta := @johtimet_nimisana_teonsanasta
Packit 1f3717
                            + @johtimet_laatusana_teonsanasta
Packit 1f3717
                            + @johtimet_seikkasana_teonsanasta;
Packit 1f3717
Packit 1f3717
Packit 1f3717
# Johtimet nimisanoista
Packit 1f3717
Packit 1f3717
define @johtimet_nimisana_nimisanasta := <johdin_tAr, johdin_lAinen>;
Packit 1f3717
Packit 1f3717
define @johtimet_laatusana_nimisanasta := <johdin_inen, johdin_tOn, johdin_mAinen>;
Packit 1f3717
Packit 1f3717
define @johdin_nimisanasta := @johtimet_nimisana_nimisanasta
Packit 1f3717
                            + @johtimet_laatusana_nimisanasta
Packit 1f3717
                            + <johdin_ittAin>
Packit 1f3717
                            + @johdin_jA; #FIXME: onko tämä oikein?
Packit 1f3717
Packit 1f3717
Packit 1f3717
# Johtimet laatusanoista
Packit 1f3717
define @johtimet_nimisana_laatusanasta := <johdin_Us, johdin_UUs>;
Packit 1f3717
define @johtimet_laatusana_laatusanasta := <johdin_nlainen>;
Packit 1f3717
define @johtimet_laatusanasta := @johtimet_nimisana_laatusanasta
Packit 1f3717
                               + @johtimet_laatusana_laatusanasta;
Packit 1f3717
Packit 1f3717
combi_rule sanan_alku ($vasen, $oikea, $sana):
Packit 1f3717
  if $oikea.luokka = lyhenne then
Packit 1f3717
    if (kaksoispiste in $oikea.jatko) then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules kaksoispiste;
Packit 1f3717
    end;
Packit 1f3717
    if (tavuviiva in $oikea.jatko) then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules yhdysmerkki_lyhenteen_jälkeen;
Packit 1f3717
    end;
Packit 1f3717
    if (loppu in $oikea.jatko) then
Packit 1f3717
      result <[alku: $sana] + $oikea>, accept;
Packit 1f3717
    end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
  elseif $oikea.luokka in <sidesana, huudahdussana> then
Packit 1f3717
    result <[alku: $sana] + $oikea>, accept;
Packit 1f3717
Packit 1f3717
  elseif $oikea.luokka = etuliite then
Packit 1f3717
    if nimisana in $oikea.jatko and laatusana in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules
Packit 1f3717
        inen_johdos_nimisanasta, laatusana, paikannimen_lainen_johdos;
Packit 1f3717
    elseif nimisana in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules inen_johdos_nimisanasta, paikannimen_lainen_johdos;
Packit 1f3717
    elseif laatusana in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules laatusana, paikannimen_lainen_johdos, inen_johdos_nimisanasta;
Packit 1f3717
    end;
Packit 1f3717
    if tavuviiva in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules yhdysmerkki_etuliitteen_jälkeen;
Packit 1f3717
    else
Packit 1f3717
      result <[alku: $sana] + $oikea>, accept;
Packit 1f3717
    end;
Packit 1f3717
    if teonsana in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules teonsana;
Packit 1f3717
    elseif nimisana in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules nimisana_teonsanasta;
Packit 1f3717
    end;
Packit 1f3717
    if teonsanan_johdoksen_etuliite in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules nimisana_teonsanasta;
Packit 1f3717
    end;
Packit 1f3717
    result <[alku: $sana] + $oikea>, rules etuliite, nimisana;
Packit 1f3717
Packit 1f3717
  elseif $oikea.luokka = kieltosana then
Packit 1f3717
    if kieltosanan_liitesana in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules kieltosanan_liitesana;
Packit 1f3717
    end;
Packit 1f3717
    result <[alku: $sana] + $oikea>, accept;
Packit 1f3717
Packit 1f3717
  elseif $oikea.luokka in <seikkasana, suhdesana> then
Packit 1f3717
    if (loppu in $oikea.jatko) then
Packit 1f3717
      result <[alku: $sana] + $oikea>, accept;
Packit 1f3717
    end;
Packit 1f3717
    if (liitesana in $oikea.jatko) then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    if (omistusliite in $oikea.jatko) then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    result <[alku: $sana] + $oikea>, rules ei_ys_sijapääte; # FIXME: esiehto testaamatta
Packit 1f3717
Packit 1f3717
  elseif $oikea.luokka = asemosana then
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    result <[alku: $sana] + $oikea>,
Packit 1f3717
           rules asemosanan_sijapääte;
Packit 1f3717
Packit 1f3717
  elseif $oikea.luokka = kieltosanan_etuliite then
Packit 1f3717
    result <[alku: $sana] + $oikea>, rules kieltosana;
Packit 1f3717
Packit 1f3717
  elseif $oikea.luokka = tavuviiva then
Packit 1f3717
    result <[vokaaliehto: no, alku: "-"] + $oikea>,
Packit 1f3717
           rules nimisana, erisnimi, laatusana, lyhennesääntö,
Packit 1f3717
                 etuliite, nimisana_teonsanasta, lukusanan_jälkiliite, inen_johdos_nimisanasta_ehdollinen,
Packit 1f3717
                 lukusana;
Packit 1f3717
Packit 1f3717
  elseif $oikea.luokka in <nimisana, nimi_laatusana> then
Packit 1f3717
    ? $oikea.tiedot = nil or not ysj in $oikea.tiedot;
Packit 1f3717
Packit 1f3717
    if ($oikea.luokka = nimisana and voittoaste in $oikea.jatko) then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules voittoaste;
Packit 1f3717
    end;
Packit 1f3717
    if (tavuviiva in $oikea.jatko and ($oikea.tiedot = nil or
Packit 1f3717
        (not ei_ysa in $oikea.tiedot and not ei_ys in $oikea.tiedot))) then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules nimisana, nimisana_laatusanasta,
Packit 1f3717
             nimisana_teonsanasta, nimi_laatusanan_etuliite, paikannimen_lainen_johdos,
Packit 1f3717
             inen_johdos_nimisanasta,
Packit 1f3717
             inen_päätteinen_laatusana_ei_nimisanajohdosta; # Kieli=poliittinen
Packit 1f3717
      if ($oikea.luokka = nimisana or $oikea.aluetta_tarkentava_etuliite = nil) then
Packit 1f3717
        result <[alku: $sana] + $oikea>, rules yhdysmerkki_yleisnimen_jälkeen;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      if $oikea.etuliite = yes then
Packit 1f3717
        result <[alku: $sana] + $oikea + [luokka: etuliite]>, accept;
Packit 1f3717
      else
Packit 1f3717
        result <[alku: $sana] + $oikea>, accept;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    if $oikea.luokka = nimisana then
Packit 1f3717
      result <[alku: $sana] + $oikea>, rules nimisanan_sijapääte, nimisanan_johdos;
Packit 1f3717
    else
Packit 1f3717
      result <$oikea + [alku: $sana, luokka: nimisana, jatko: $oikea.jatko - <johdin_UUs>]>,
Packit 1f3717
             rules nimisanan_sijapääte, nimisanan_johdos;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule etuliite ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = etuliite;
Packit 1f3717
Packit 1f3717
  ? $oikea.tiedot = nil or not ei_ysj in $oikea.tiedot;
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if nimisana in $oikea.jatko and laatusana in $oikea.jatko then
Packit 1f3717
    result $res, rules
Packit 1f3717
      inen_johdos_nimisanasta, laatusana, paikannimen_lainen_johdos, nimisana_teonsanasta;
Packit 1f3717
  elseif nimisana in $oikea.jatko then
Packit 1f3717
    result $res, rules inen_johdos_nimisanasta, paikannimen_lainen_johdos, nimisana_teonsanasta;
Packit 1f3717
  elseif laatusana in $oikea.jatko then
Packit 1f3717
    result $res, rules laatusana, paikannimen_lainen_johdos, inen_johdos_nimisanasta;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if (teonsana in $oikea.jatko) then
Packit 1f3717
    result $res, rules teonsana;
Packit 1f3717
  end;
Packit 1f3717
  if teonsanan_johdoksen_etuliite in $oikea.jatko then
Packit 1f3717
      result $res, rules nimisana_teonsanasta;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if (kieltosana in $oikea.jatko) then
Packit 1f3717
    result $res, rules kieltosana;
Packit 1f3717
  else
Packit 1f3717
    if tavuviiva in $oikea.jatko then
Packit 1f3717
      result $res, rules yhdysmerkki_etuliitteen_jälkeen;
Packit 1f3717
    else
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    result $res, rules etuliite, nimisana;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### ETULIITESÄÄNNÖT ALKAVAT
Packit 1f3717
Packit 1f3717
combi_rule nimisanan_etuliite ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = etuliite;
Packit 1f3717
Packit 1f3717
  ? $oikea.tiedot = nil or not ei_ysj in $oikea.tiedot;
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if nimisana in $oikea.jatko then
Packit 1f3717
    result $res, rules inen_johdos_nimisanasta, nimisana_laatusanasta;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  ? not kieltosana in $oikea.jatko;
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
    result $res, rules yhdysmerkki_etuliitteen_jälkeen;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules etuliite, nimisana, nimisana_teonsanasta;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule nimi_laatusanan_etuliite ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = etuliite;
Packit 1f3717
Packit 1f3717
  ? $oikea.tiedot = nil or not ei_ysj in $oikea.tiedot;
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if nimisana in $oikea.jatko and laatusana in $oikea.jatko then
Packit 1f3717
    result $res, rules
Packit 1f3717
      inen_johdos_nimisanasta, laatusana, paikannimen_lainen_johdos;
Packit 1f3717
  elseif nimisana in $oikea.jatko then
Packit 1f3717
    result $res, rules inen_johdos_nimisanasta, paikannimen_lainen_johdos;
Packit 1f3717
  elseif laatusana in $oikea.jatko then
Packit 1f3717
    result $res, rules laatusana, paikannimen_lainen_johdos, inen_johdos_nimisanasta;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if (kieltosana in $oikea.jatko) then
Packit 1f3717
    result $res, rules kieltosana;
Packit 1f3717
  else
Packit 1f3717
    if tavuviiva in $oikea.jatko then
Packit 1f3717
      result $res, rules yhdysmerkki_etuliitteen_jälkeen;
Packit 1f3717
    else
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    result $res, rules etuliite, nimisana, nimisana_teonsanasta;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### ETULIITESÄÄNNÖT PÄÄTTYVÄT
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule erisnimi ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @erisnimi;
Packit 1f3717
  ? ($oikea.tiedot = nil) or ($index = 1) or
Packit 1f3717
    (not ei_ysj in $oikea.tiedot and not ei_ys in $oikea.tiedot);
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  if tavuviiva in $oikea.jatko or loppu in $oikea.jatko then
Packit 1f3717
    result $res, rules yhdysmerkki_erisnimen_jälkeen;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules erisnimen_sijapääte;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
# Esiehto: ei sanan alussa
Packit 1f3717
combi_rule nimisana ($vasen, $oikea, $sana, $index):
Packit 1f3717
  if ($oikea.luokka = seikkasana and $oikea.tiedot /= nil and
Packit 1f3717
      ys_perusosa in $oikea.tiedot) then
Packit 1f3717
    if (loppu in $oikea.jatko) then
Packit 1f3717
      result $vasen + <[alku: $sana] + $oikea>, accept;
Packit 1f3717
    end;
Packit 1f3717
    if (liitesana in $oikea.jatko) then
Packit 1f3717
      result $vasen + <[alku: $sana] + $oikea>, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    if (omistusliite in $oikea.jatko) then
Packit 1f3717
      result $vasen + <[alku: $sana] + $oikea>, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    result $vasen + <[alku: $sana] + $oikea>, rules ei_ys_sijapääte; # FIXME: esiehto testaamatta
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  ? $oikea.luokka in <nimisana, nimi_laatusana>;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? ((nimisana in $edellinen.jatko)    or
Packit 1f3717
     (tavuviiva in $edellinen.jatko and $edellinen.luokka in @nimisana + <laatusana>) or
Packit 1f3717
     ($edellinen.luokka = lukusana)    or
Packit 1f3717
     ($oikea.lähtöluokka = teonsana and
Packit 1f3717
      (teonsana in $edellinen.jatko or teonsanan_johdoksen_etuliite in $edellinen.jatko)));
Packit 1f3717
Packit 1f3717
  ? ($oikea.tiedot = nil) or
Packit 1f3717
    (not ei_ysj in $oikea.tiedot and not ei_ys in $oikea.tiedot);
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana) or ($oikea.tiedot /= nil and sitlaina in $oikea.tiedot and $edellinen.luokka = tavuviiva);
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  
Packit 1f3717
  if $edellinen.luokka in <laatusana, nimi_laatusana> then
Packit 1f3717
    if $edellinen.luokka = laatusana then
Packit 1f3717
      result $res, rules johdin_laatusana_nimisanasta;
Packit 1f3717
      stop;
Packit 1f3717
    end;
Packit 1f3717
  elseif $edellinen.lukutyyppi /= nil then
Packit 1f3717
    if tavuviiva in $oikea.jatko then
Packit 1f3717
      result $res, rules etuliite, tavuviiva, nimisana, nimisana_laatusanasta, nimisana_teonsanasta;
Packit 1f3717
    end;
Packit 1f3717
    stop;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if ($oikea.luokka = nimisana and voittoaste in $oikea.jatko) then
Packit 1f3717
    result $res, rules voittoaste;
Packit 1f3717
  end;
Packit 1f3717
  if (tavuviiva in $oikea.jatko and ($oikea.tiedot = nil or
Packit 1f3717
      (not ei_ysa in $oikea.tiedot and not ei_ys in $oikea.tiedot))) then
Packit 1f3717
    result $res, rules nimisana, nimisana_laatusanasta, nimisana_teonsanasta,
Packit 1f3717
                       etuliite, paikannimen_lainen_johdos, yhdysmerkki_yleisnimen_jälkeen,
Packit 1f3717
                       inen_johdos_nimisanasta, inen_päätteinen_laatusana_ei_nimisanajohdosta; # Kieli=poliittinen
Packit 1f3717
  end;
Packit 1f3717
  
Packit 1f3717
  $res := $vasen + <$oikea + [alku: $sana, luokka: nimisana, lähtöluokka: $oikea.luokka]>;
Packit 1f3717
  
Packit 1f3717
  if (loppu in $oikea.jatko) then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules nimisanan_sijapääte, nimisanan_johdos;
Packit 1f3717
  
Packit 1f3717
  if $oikea.erisnimen_pääte = yes and $vasen.(1).luokka /= tavuviiva then
Packit 1f3717
    $res := $vasen + <$oikea + [alku: $sana, luokka: nimi]>;
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    result $res, rules erisnimen_sijapääte;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### JOHDETTUJEN SANOJEN ALOITUSSÄÄNNÖT ALKAVAT
Packit 1f3717
Packit 1f3717
# Teonsanasta johdettu nimisana, esim. sanoma <- sanoa.
Packit 1f3717
combi_rule nimisana_teonsanasta ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = teonsana;
Packit 1f3717
  if ($index greater 1) then
Packit 1f3717
    ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  end;
Packit 1f3717
  ? $oikea.tiedot = nil or not ei_ysj in $oikea.tiedot;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if nimitapa_45 in $oikea.jatko then
Packit 1f3717
    result $res, rules nimitapa_4;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules teonsanan_johdos; # FIXME: johdetun muodon on oltava nimisana
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# Teonsanasta johdettu laatusana, esim. kasvattava <- kasvattaa.
Packit 1f3717
combi_rule laatusana_teonsanasta ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = teonsana;
Packit 1f3717
  if ($index greater 1) then
Packit 1f3717
    ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  end;
Packit 1f3717
  ? $oikea.tiedot = nil or not ei_ysj in $oikea.tiedot;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  result $res, rules johdin_laatusana_teonsanasta;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# Laatusanasta johdettu nimisana, esim. vapaus <- vapaa.
Packit 1f3717
combi_rule nimisana_laatusanasta ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @laatusana;
Packit 1f3717
  ? $oikea.tiedot = nil or (not ei_ys in $oikea.tiedot and not ei_ysj in $oikea.tiedot);
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  result $vasen + <[alku: $sana] + $oikea>,
Packit 1f3717
         rules johdin_nimisana_laatusanasta;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# Laatusanasta johdettu laatusana, esim. paha+nlai+nen <- paha.
Packit 1f3717
combi_rule laatusana_laatusanasta ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka in @laatusana;
Packit 1f3717
  if (omanto_n in $oikea.jatko) then
Packit 1f3717
    result $vasen + <[alku: $sana] + $oikea>, rules johdin_nlainen;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# inen-johdinta edeltävä nimisana
Packit 1f3717
# sääntö ei voi olla sanan alussa
Packit 1f3717
combi_rule inen_johdos_nimisanasta ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in <nimisana, nimi_laatusana>;
Packit 1f3717
  ? johdin_inen in $oikea.jatko;
Packit 1f3717
  ? $oikea.tiedot = nil or (not ei_ys in $oikea.tiedot and not ei_ysj in $oikea.tiedot);
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  if tavuviiva in $oikea.jatko and $edellinen.luokka /= etuliite then
Packit 1f3717
    result $res, rules johdin_inen, inen_johdos_nimisanasta;
Packit 1f3717
  else
Packit 1f3717
    result $res, rules johdin_inen;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# inen-johdinta edeltävä nimisana
Packit 1f3717
# sääntö ei voi olla sanan alussa eikä koske sanoja, joille inen-johdin on aina sallittu
Packit 1f3717
combi_rule inen_johdos_nimisanasta_ehdollinen ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in <nimisana, nimi_laatusana>;
Packit 1f3717
  ? johdin_inen in $oikea.jatko;
Packit 1f3717
  ? $oikea.tiedot = nil or (not ei_ys in $oikea.tiedot and not ei_ysj in $oikea.tiedot and not inen in $oikea.tiedot);
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  if tavuviiva in $oikea.jatko and $edellinen.luokka /= etuliite then
Packit 1f3717
    result $res, rules johdin_inen, inen_johdos_nimisanasta;
Packit 1f3717
  else
Packit 1f3717
    result $res, rules johdin_inen;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# Paikannimestä johdettu kansallisuuden nimi
Packit 1f3717
combi_rule paikannimen_lainen_johdos ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = paikannimi;
Packit 1f3717
  ? johdin_lAinen in $oikea.jatko;
Packit 1f3717
  if ($index greater 1) then
Packit 1f3717
    ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  end;
Packit 1f3717
  result $vasen + <[alku: $sana] + $oikea>, rules paikannimen_lainen_johdin;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### JOHDETTUJEN SANOJEN ALOITUSSÄÄNNÖT PÄÄTTYVÄT
Packit 1f3717
Packit 1f3717
###### JOHDINSÄÄNNÖT ALKAVAT
Packit 1f3717
Packit 1f3717
combi_rule johdin_nlainen ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = johdin_nlainen;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
    result $res, rules nimisana, laatusana,
Packit 1f3717
           tavuviiva, etuliite;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res,
Packit 1f3717
         rules laatusanan_sijapääte,
Packit 1f3717
               johdin_nimisana_laatusanasta,
Packit 1f3717
               voitto_yliaste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule johdin_inen ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = johdin_inen;
Packit 1f3717
Packit 1f3717
  $oikea.äs := $vasen.($index - 1).äs;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
    result $res, rules nimisana, laatusana,
Packit 1f3717
           tavuviiva, etuliite, nimisana_teonsanasta;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
    result $res, rules laatusanan_sijapääte,
Packit 1f3717
                 johdin_nimisana_laatusanasta,
Packit 1f3717
                 voitto_yliaste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule johdettu_paikannimi ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.paikannimen_jälkiliite = yes;
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
    result $res, rules yhdysmerkki_erisnimen_jälkeen, johdettu_paikannimi;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules erisnimen_sijapääte;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule paikannimen_lainen_johdin ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = johdin_lAinen;
Packit 1f3717
  ? vokaalisointu_oikein_ei_aä($vasen.($index - 1), $oikea);
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
    result $res, rules nimisana, inen_johdos_nimisanasta_ehdollinen, yhdysmerkki_lainen_johdoksen_jälkeen,
Packit 1f3717
                 nimisana_teonsanasta, paikannimen_lainen_johdos, inen_päätteinen_laatusana_ei_nimisanajohdosta, nimisana_laatusanasta;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then result $res, rules omistusliite; end;
Packit 1f3717
  if liitesana in $oikea.jatko then result $res, rules liitesana; end;
Packit 1f3717
  if loppu in $oikea.jatko then result $res, accept; end;
Packit 1f3717
  if johdin_ittAin in $oikea.jatko then result $res, rules johdin_seikkasana_ittain; end;
Packit 1f3717
  if voittoaste in $oikea.jatko or yliaste in $oikea.jatko then result $res, rules voitto_yliaste; end;
Packit 1f3717
  result $res, rules laatusanan_sijapääte_omistusliitteellä, johdin_nimisana_laatusanasta;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### JOHDINSÄÄNNÖT PÄÄTTYVÄT
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule laatusana ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @laatusana;
Packit 1f3717
Packit 1f3717
  if ($index greater 1) then
Packit 1f3717
    ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
    ? $oikea.tiedot = nil or (not ei_ys in $oikea.tiedot and not ei_ysj in $oikea.tiedot);
Packit 1f3717
  else
Packit 1f3717
    ? $oikea.tiedot = nil or not ysj in $oikea.tiedot;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  define $lähtöluokka := $oikea.luokka;
Packit 1f3717
  define $res := $vasen + <$oikea + [alku: $sana, luokka: laatusana, lähtöluokka: $lähtöluokka]>;
Packit 1f3717
  
Packit 1f3717
  if $oikea.luokka = laatusana or ($index greater 1 and $vasen.($index - 1).luokka /= nimitapa_45) then
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  
Packit 1f3717
  if tavuviiva in $oikea.jatko and
Packit 1f3717
    ($oikea.tiedot = nil or not (ei_ys in $oikea.tiedot or ei_ysa in $oikea.tiedot)) then
Packit 1f3717
    if $oikea.luokka /= laatusana or $oikea.inen_loppu = yes then
Packit 1f3717
      result $res, rules laatusana;
Packit 1f3717
    else
Packit 1f3717
      result $res, rules inen_päätteinen_laatusana;
Packit 1f3717
    end;
Packit 1f3717
    if ($oikea.luokka = laatusana or $index greater 1) then
Packit 1f3717
      result $res, rules etuliite, nimisana, inen_johdos_nimisanasta;
Packit 1f3717
    end;
Packit 1f3717
    if $oikea.aluetta_tarkentava_etuliite = yes then
Packit 1f3717
      result $res, rules yhdysmerkki_laatusanan_jälkeen_ei_kansallisuutta;
Packit 1f3717
    else
Packit 1f3717
      result $res, rules yhdysmerkki_laatusanan_jälkeen;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  result $res,
Packit 1f3717
         rules laatusanan_sijapääte,
Packit 1f3717
               johdin_nimisana_laatusanasta,
Packit 1f3717
               voitto_yliaste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule inen_päätteinen_laatusana ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.inen_loppu = yes;
Packit 1f3717
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  ? $oikea.tiedot = nil or (not ei_ys in $oikea.tiedot and not ei_ysj in $oikea.tiedot);
Packit 1f3717
Packit 1f3717
  # nimisana, laatusana ja etuliite jätetty pois, koska todennäköinen käyttö vähäistä
Packit 1f3717
  # (teoriassa voi olla OK)
Packit 1f3717
  define $res := $vasen + <$oikea + [alku: $sana, luokka: laatusana]>;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
      result $res, rules tavuviiva, paikannimen_lainen_johdos;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules laatusanan_sijapääte, johdin_nimisana_laatusanasta, voitto_yliaste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule inen_päätteinen_laatusana_ei_nimisanajohdosta ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.inen_loppu = yes;
Packit 1f3717
Packit 1f3717
  ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
  ? $oikea.tiedot = nil or (not ei_ys in $oikea.tiedot and not ei_ysj in $oikea.tiedot);
Packit 1f3717
Packit 1f3717
  # nimisana, laatusana ja etuliite jätetty pois, koska todennäköinen käyttö vähäistä
Packit 1f3717
  # (teoriassa voi olla OK)
Packit 1f3717
  define $res := $vasen + <$oikea + [alku: $sana, luokka: laatusana]>;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
      result $res, rules tavuviiva, paikannimen_lainen_johdos;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules laatusanan_sijapääte, voitto_yliaste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule lyhennesääntö ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = lyhenne;
Packit 1f3717
  ? $oikea.alaluokka /= roomalainen;
Packit 1f3717
  ? $index less 2 or $oikea.tiedot = nil or (not ei_ys in $oikea.tiedot and not ei_ysj in $oikea.tiedot);
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if (kaksoispiste in $oikea.jatko) then result $res, rules kaksoispiste; end;
Packit 1f3717
  if (tavuviiva in $oikea.jatko) then result $res, rules yhdysmerkki_lyhenteen_jälkeen; end;
Packit 1f3717
  if (loppu in $oikea.jatko) then result $res, accept; end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule kaksoispiste ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = kaksoispiste;
Packit 1f3717
Packit 1f3717
  result $vasen + <[alku: $sana] + $oikea + [äs: $vasen.($index - 1).äs]>,
Packit 1f3717
         rules kaksoispisteen_sijapääte, omistusliite, liitesana;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule tavuviiva ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: yes, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  result $res,
Packit 1f3717
         rules nimisana, erisnimi, laatusana, lyhennesääntö,
Packit 1f3717
               etuliite, nimisana_teonsanasta;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
###### YHDYSMERKKISÄÄNNÖT ALKAVAT
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_yleisnimen_jälkeen ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: yes, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  result $res,
Packit 1f3717
         rules nimisana, erisnimi, laatusana, lyhennesääntö, etuliite,
Packit 1f3717
	       nimisana_teonsanasta, inen_johdos_nimisanasta_ehdollinen;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_erisnimen_jälkeen ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: no, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  result $res, rules erisnimi;
Packit 1f3717
  if ($edellinen.sijamuoto in <nimentö, omanto> or
Packit 1f3717
      ($edellinen.luokka /= sijapääte and ($edellinen.luokka /= nimi or tavuviiva in $edellinen.jatko or liitesana in $edellinen.jatko))) then
Packit 1f3717
    result $res, rules
Packit 1f3717
           nimisana, nimisana_laatusanasta,
Packit 1f3717
           etuliite, nimisana_teonsanasta, inen_päätteinen_laatusana_ei_nimisanajohdosta, inen_johdos_nimisanasta_ehdollinen;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_teonsanan_jälkeen ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: yes, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  result $res, rules nimisana, erisnimi, lyhennesääntö, etuliite;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_lyhenteen_jälkeen ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: no, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  result $res, rules
Packit 1f3717
         nimisana, erisnimi, laatusana,
Packit 1f3717
         etuliite, nimisana_teonsanasta;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_laatusanan_jälkeen ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: yes, alku: "-"] + $oikea>;
Packit 1f3717
  if $index /= 2 or $vasen.($index - 1).lähtöluokka /= nimi_laatusana then
Packit 1f3717
    result $res, accept;
Packit 1f3717
    result $res, rules nimisana, erisnimi;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules
Packit 1f3717
         laatusana, lyhennesääntö,
Packit 1f3717
         etuliite, nimisana_teonsanasta, inen_johdos_nimisanasta,
Packit 1f3717
         paikannimen_lainen_johdos;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_inen_johdoksen_jälkeen ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: yes, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  result $res, rules
Packit 1f3717
         nimisana, laatusana,
Packit 1f3717
         etuliite, nimisana_teonsanasta, inen_johdos_nimisanasta,
Packit 1f3717
         paikannimen_lainen_johdos;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_laatusanan_jälkeen_ei_kansallisuutta($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: yes, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  result $res, rules
Packit 1f3717
         nimisana, erisnimi, laatusana, lyhennesääntö,
Packit 1f3717
         etuliite, nimisana_teonsanasta, inen_johdos_nimisanasta;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_sanan_lopussa ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
  result $vasen + <[vokaaliehto: no, alku: "-"] + $oikea>, accept;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_lainen_johdoksen_jälkeen ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: no, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  result $res,
Packit 1f3717
         rules erisnimi, paikannimen_lainen_johdos,
Packit 1f3717
               inen_päätteinen_laatusana, inen_johdos_nimisanasta;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule merkki_numeron_jälkeen ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka in <tavuviiva, kaksoispiste>;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: no, alku: "-"] + $oikea>;
Packit 1f3717
  if $oikea.luokka = tavuviiva then
Packit 1f3717
    result $res, accept;
Packit 1f3717
    result $res, rules lukusanan_jälkiliite, inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
  else
Packit 1f3717
    result $res, rules lukusana_numero, kaksoispisteen_sijapääte;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_etuliitteen_jälkeen ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: yes, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  define $jatko := $vasen.($index - 1).jatko;
Packit 1f3717
  if teonsana in $jatko then
Packit 1f3717
    if nimisana in $jatko or laatusana in $jatko then
Packit 1f3717
      result $res, rules nimisana, laatusana, erisnimi;
Packit 1f3717
    end;
Packit 1f3717
    result $res, rules etuliite, teonsana;
Packit 1f3717
  else
Packit 1f3717
    result $res, rules nimisana, laatusana, etuliite, erisnimi, nimisana_teonsanasta;
Packit 1f3717
  end;
Packit 1f3717
  if nimisana in $jatko then
Packit 1f3717
    result $res, rules lyhennesääntö;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdysmerkki_ennen_paikannimea ($vasen, $oikea, $sana):
Packit 1f3717
  ? $oikea.luokka = tavuviiva;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[vokaaliehto: yes, alku: "-"] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  result $res, rules erisnimi;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### YHDYSMERKKISÄÄNNÖT PÄÄTTYVÄT
Packit 1f3717
Packit 1f3717
Packit 1f3717
define @sti_edeltäjä := 
Packit 1f3717
                         johdin_tAvA, johdin_ttAvA, johdin_ttU,
Packit 1f3717
                         johdin_vA, johdin_vE, johdin_lAinen>
Packit 1f3717
                        + @johdin_nUt + @johdin_tU
Packit 1f3717
                        + @johtimet_laatusana_nimisanasta
Packit 1f3717
                        + @johtimet_laatusana_laatusanasta;
Packit 1f3717
Packit 1f3717
###### SIJAPÄÄTESÄÄNNÖT ALKAVAT
Packit 1f3717
Packit 1f3717
combi_rule erisnimen_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  
Packit 1f3717
  if $oikea.sija = sisätulento_Vn then
Packit 1f3717
    ? sisätulento_Vn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  elseif $oikea.sija = sisätulento_hVn then
Packit 1f3717
    ? sisätulento_hVn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  else
Packit 1f3717
    ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if ($oikea.sija = kerronto_sti) then
Packit 1f3717
    ? $edellinen.luokka in @sti_edeltäjä;
Packit 1f3717
  elseif ($oikea.sijamuoto = omanto and
Packit 1f3717
          $oikea.luku = yksikkö) then
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if $edellinen.luokka = paikannimi then
Packit 1f3717
      result $res, rules paikannimen_lainen_johdos, inen_päätteinen_laatusana;
Packit 1f3717
    end;
Packit 1f3717
    result $res, rules yhdysmerkki_erisnimen_jälkeen, johdettu_paikannimi;
Packit 1f3717
  else
Packit 1f3717
    if omistusliite in $oikea.jatko and ($oikea.sija /= omanto_n or $edellinen.ei_yks = nil) then
Packit 1f3717
       result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if tavuviiva in $oikea.jatko and $oikea.sijamuoto in <nimentö, omanto> then
Packit 1f3717
      result $res, rules yhdysmerkki_erisnimen_jälkeen;
Packit 1f3717
    end;
Packit 1f3717
    if $oikea.sijamuoto = omanto and $edellinen.luokka = sukunimi and tavuviiva in $oikea.jatko then
Packit 1f3717
      result $res, rules johdettu_paikannimi;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  if $oikea.sija /= omanto_n or $edellinen.ei_yks = nil then
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule voitto_yliasteen_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  ? $oikea.sija /= kerronto_sti or $edellinen.luokka in @sti_edeltäjä;
Packit 1f3717
  
Packit 1f3717
  if $oikea.sija = sisätulento_Vn then
Packit 1f3717
    ? sisätulento_Vn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  elseif $oikea.sija = sisätulento_hVn then
Packit 1f3717
    ? sisätulento_hVn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  else
Packit 1f3717
    ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.sija = kerronto_sti) then
Packit 1f3717
    result $res, accept;
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  else
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    define $kantasana := $vasen.(length($vasen)-1);
Packit 1f3717
    if ($oikea.sijamuoto = omanto and
Packit 1f3717
        ($kantasana.tiedot = nil or
Packit 1f3717
         not (ei_ysa in $kantasana.tiedot and ei_ys in $kantasana.tiedot))) then
Packit 1f3717
      result $res, rules inen_johdos_nimisanasta;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if $vasen.($index - 2).luokka in <nimisana, nimi_laatusana> and
Packit 1f3717
     $oikea.sijamuoto = omanto then
Packit 1f3717
    result $res, rules nimisana, nimisana_teonsanasta, nimisana_laatusanasta,
Packit 1f3717
                 yhdysmerkki_yleisnimen_jälkeen, nimisanan_etuliite;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule nimisanan_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
  ? $oikea.sija /= kerronto_sti;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  
Packit 1f3717
  if $oikea.sija = sisätulento_Vn then
Packit 1f3717
    ? sisätulento_Vn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  elseif $oikea.sija = sisätulento_hVn then
Packit 1f3717
    ? sisätulento_hVn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  else
Packit 1f3717
    ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.sija = kerronto_sti) then
Packit 1f3717
    ? $edellinen.luokka in @sti_edeltäjä;
Packit 1f3717
    result $res, accept;
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  else
Packit 1f3717
    if $oikea.sija /= omanto_n or $edellinen.ei_yks = nil then
Packit 1f3717
      if omistusliite in $oikea.jatko then
Packit 1f3717
        result $res, rules omistusliite;
Packit 1f3717
      end;
Packit 1f3717
      if loppu in $oikea.jatko then
Packit 1f3717
        result $res, accept;
Packit 1f3717
      end;
Packit 1f3717
      if liitesana in $oikea.jatko then
Packit 1f3717
        result $res, rules liitesana;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
    if (tavuviiva in $oikea.jatko and ($edellinen.tiedot = nil or
Packit 1f3717
        (not ei_ysa in $edellinen.tiedot and not ei_ys in $edellinen.tiedot))) then
Packit 1f3717
      # "kissan+karva", "työhön+otto"
Packit 1f3717
      if $oikea.sijamuoto = omanto then
Packit 1f3717
        result $res,
Packit 1f3717
               rules nimisana, nimisana_teonsanasta, yhdysmerkki_yleisnimen_jälkeen,
Packit 1f3717
                     nimisanan_etuliite;
Packit 1f3717
      end;
Packit 1f3717
      if $oikea.sijamuoto = nimentö and $oikea.luku = yksikkö then
Packit 1f3717
        result $res, rules nimisana_teonsanasta;
Packit 1f3717
      end;
Packit 1f3717
      if $edellinen.luokka in <laatusana, nimi_laatusana> then
Packit 1f3717
        result $res, rules yhdysmerkki_laatusanan_jälkeen;
Packit 1f3717
      end;
Packit 1f3717
      if $oikea.sijamuoto = omanto then
Packit 1f3717
        if $oikea.luku = yksikkö then
Packit 1f3717
          result $res, rules laatusana, inen_johdos_nimisanasta;
Packit 1f3717
        else
Packit 1f3717
          result $res, rules nimisana_laatusanasta;
Packit 1f3717
        end;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule laatusanan_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  
Packit 1f3717
  if $oikea.sija = sisätulento_Vn then
Packit 1f3717
    ? sisätulento_Vn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  elseif $oikea.sija = sisätulento_hVn then
Packit 1f3717
    ? sisätulento_hVn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  else
Packit 1f3717
    ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.sija = kerronto_sti) then
Packit 1f3717
    ? $edellinen.luokka in @sti_edeltäjä;
Packit 1f3717
    result $res, accept;
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  else
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    if (tavuviiva in $oikea.jatko and ($edellinen.tiedot = nil or
Packit 1f3717
        (not ei_ysa in $edellinen.tiedot and not ei_ys in $edellinen.tiedot))) then
Packit 1f3717
      if $edellinen.aluetta_tarkentava_etuliite = yes then
Packit 1f3717
        result $res, rules yhdysmerkki_ennen_paikannimea;
Packit 1f3717
      end;
Packit 1f3717
      if $oikea.sijamuoto = omanto and $edellinen.lähtöluokka /= nimi_laatusana then
Packit 1f3717
          result $res,
Packit 1f3717
                 rules laatusana, laatusana_teonsanasta, tavuviiva;
Packit 1f3717
        if $oikea.luku = yksikkö then
Packit 1f3717
          result $res, rules inen_johdos_nimisanasta;
Packit 1f3717
        end;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule laatusanan_sijapääte_omistusliitteellä ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  
Packit 1f3717
  if $oikea.sija = sisätulento_Vn then
Packit 1f3717
    ? sisätulento_Vn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  elseif $oikea.sija = sisätulento_hVn then
Packit 1f3717
    ? sisätulento_hVn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  else
Packit 1f3717
    ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.sija = kerronto_sti) then
Packit 1f3717
    ? $edellinen.luokka in @sti_edeltäjä;
Packit 1f3717
    result $res, accept;
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  else
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    if (tavuviiva in $oikea.jatko and ($edellinen.tiedot = nil or
Packit 1f3717
        (not ei_ysa in $edellinen.tiedot and not ei_ys in $edellinen.tiedot))) then
Packit 1f3717
      if $oikea.sijamuoto = omanto then
Packit 1f3717
        result $res,
Packit 1f3717
               rules laatusana, nimisana_teonsanasta, tavuviiva;
Packit 1f3717
        if $oikea.luku = yksikkö then
Packit 1f3717
          result $res, rules inen_johdos_nimisanasta;
Packit 1f3717
        end;
Packit 1f3717
      end;
Packit 1f3717
      if $edellinen.luokka in <laatusana, nimi_laatusana> then
Packit 1f3717
        result $res, rules yhdysmerkki_laatusanan_jälkeen;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule ttU_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  
Packit 1f3717
  if $oikea.sija = sisätulento_Vn then
Packit 1f3717
    ? sisätulento_Vn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  elseif $oikea.sija = sisätulento_hVn then
Packit 1f3717
    ? sisätulento_hVn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  else
Packit 1f3717
    ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.sija = kerronto_sti) then
Packit 1f3717
    ? $edellinen.luokka in @sti_edeltäjä;
Packit 1f3717
    result $res, accept;
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  else
Packit 1f3717
    if $oikea.sija = osanto_A and omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    if (tavuviiva in $oikea.jatko and ($edellinen.tiedot = nil or
Packit 1f3717
        (not ei_ysa in $edellinen.tiedot and not ei_ys in $edellinen.tiedot))) then
Packit 1f3717
      if $oikea.sijamuoto = omanto then
Packit 1f3717
        result $res,
Packit 1f3717
               rules laatusana, nimisana_teonsanasta, tavuviiva;
Packit 1f3717
        if $oikea.luku = yksikkö then
Packit 1f3717
          result $res, rules inen_johdos_nimisanasta;
Packit 1f3717
        end;
Packit 1f3717
      end;
Packit 1f3717
      if $edellinen.luokka in <laatusana, nimi_laatusana> then
Packit 1f3717
        result $res, rules yhdysmerkki_laatusanan_jälkeen;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule asemosanan_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  
Packit 1f3717
  if $oikea.sija = sisätulento_Vn then
Packit 1f3717
    ? sisätulento_Vn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  elseif $oikea.sija = sisätulento_hVn then
Packit 1f3717
    ? sisätulento_hVn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  else
Packit 1f3717
    ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.sija = kerronto_sti) then
Packit 1f3717
    ? $edellinen.luokka in @sti_edeltäjä;
Packit 1f3717
    result $res, accept;
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  else
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko and $oikea.sija /= omanto_nkA and $oikea.sija /= nimentö_tkA then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    if $oikea.sijamuoto = omanto then
Packit 1f3717
      result $res, rules inen_johdos_nimisanasta;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# Sijapääte, jota ei voi käyttää yhdyssanan sisällä
Packit 1f3717
combi_rule ei_ys_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  
Packit 1f3717
  if $oikea.sija = sisätulento_Vn then
Packit 1f3717
    ? sisätulento_Vn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  elseif $oikea.sija = sisätulento_hVn then
Packit 1f3717
    ? sisätulento_hVn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  else
Packit 1f3717
    ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.sija = kerronto_sti) then
Packit 1f3717
    ? $edellinen.luokka in @sti_edeltäjä;
Packit 1f3717
    result $res, accept;
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  else
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule kaksoispisteen_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
  # sisätulento_Vn kielletty, koska kaksoispisteellä taivutettaessa pitkä vokaali
Packit 1f3717
  # laitetaan aina näkyviin.
Packit 1f3717
  ? not $oikea.sija in <keinonto_n, tulento_s, omanto_nkA, sisätulento_Vn, kohdanto_t>;
Packit 1f3717
  ? not ei_kaksoispisteen_jälkeen in $oikea;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### SIJAPÄÄTESÄÄNNÖT PÄÄTTYVÄT
Packit 1f3717
Packit 1f3717
Packit 1f3717
###### LUKUSANASÄÄNNÖT ALKAVAT
Packit 1f3717
Packit 1f3717
combi_rule lukusana ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = lukusana;
Packit 1f3717
  define $sijamuoto := nil;
Packit 1f3717
  define $luku := nil;
Packit 1f3717
Packit 1f3717
  if ($oikea.alaluokka = erikoisluku) then
Packit 1f3717
    define $erikoisres := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
    if (loppu in $oikea.jatko) then
Packit 1f3717
      result $erikoisres, accept;
Packit 1f3717
    end;
Packit 1f3717
    if (liitesana in $oikea.jatko) then
Packit 1f3717
      result $erikoisres, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    if (lukusanan_jälkiliite in $oikea.jatko) then
Packit 1f3717
      result $erikoisres, rules lukusanan_jälkiliite;
Packit 1f3717
    end;
Packit 1f3717
    stop;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if ($index greater 1) then
Packit 1f3717
    define $edellinen := $vasen.($index - 1);
Packit 1f3717
    ? $edellinen.lukutyyppi = nil or $edellinen.lukutyyppi = $oikea.lukutyyppi;
Packit 1f3717
    $sijamuoto := $edellinen.sijamuoto;
Packit 1f3717
    $luku := $edellinen.luku;
Packit 1f3717
    # Estetään peräkkäiset "satasata", "tuhattuhat" jne.
Packit 1f3717
    if ($edellinen.luokka = lukusana) then
Packit 1f3717
      ? not ($oikea.alaluokka = $edellinen.alaluokka);
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana, sijamuoto: $sijamuoto, luku: $luku] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.alaluokka = yksiyhdeksän) then
Packit 1f3717
    if (nimentö in $oikea.jatko) then
Packit 1f3717
      if loppu in $oikea.jatko then
Packit 1f3717
        result $res, accept;
Packit 1f3717
      end;
Packit 1f3717
      if liitesana in $oikea.jatko then
Packit 1f3717
        result $res, rules liitesana;
Packit 1f3717
      end;
Packit 1f3717
      if tavuviiva in $oikea.jatko then
Packit 1f3717
        result $res, rules lukusana_toista, lukusana_sisäkerroin,
Packit 1f3717
                     lukusanan_jälkiliite,
Packit 1f3717
                     nimisana, inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
    if ($oikea.lukutyyppi = järjestysluku and omistusliite in $oikea.jatko) then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
  elseif ($oikea.alaluokka in <kymmenen, sata>) then
Packit 1f3717
    if (nimentö in $oikea.jatko) then
Packit 1f3717
      if loppu in $oikea.jatko then
Packit 1f3717
        result $res, accept;
Packit 1f3717
      end;
Packit 1f3717
      if liitesana in $oikea.jatko then
Packit 1f3717
        result $res, rules liitesana;
Packit 1f3717
      end;
Packit 1f3717
      result $res, rules lukusana_sisäkerroin,
Packit 1f3717
                   lukusanan_jälkiliite,
Packit 1f3717
                   nimisana, inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
    end;
Packit 1f3717
  elseif ($oikea.alaluokka in <tuhat, miljoona> and nimentö in $oikea.jatko) then
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    result $res, rules lukusanan_jälkiliite,
Packit 1f3717
                 nimisana, inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
   elseif ($oikea.alaluokka = numeromerkki) then
Packit 1f3717
     $res := $vasen + <[alku: $sana, pilkku: no, rakenne: "q"] + $oikea>;
Packit 1f3717
     result $res, rules lukusana_numero, merkki_numeron_jälkeen;
Packit 1f3717
     result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if ($oikea.alaluokka in <sata, tuhat>) then
Packit 1f3717
    if (nimentö in $oikea.jatko) then
Packit 1f3717
      result $res, rules lukusana;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules lukusana_sijapääte;
Packit 1f3717
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule lukusana_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  ? $edellinen.sijamuoto = nil or $edellinen.sijamuoto = $oikea.sijamuoto;
Packit 1f3717
  ? $edellinen.luku = nil or $edellinen.luku = $oikea.luku;
Packit 1f3717
  ? $oikea.sija /= sisätulento_Vn or sisätulento_Vn_oikein(last($edellinen.alku), $sana);
Packit 1f3717
  ? $edellinen.lukutyyppi /= järjestysluku or $oikea.sija /= kerronto_sti;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana, lukutyyppi: $edellinen.lukutyyppi] + $oikea>;
Packit 1f3717
  if ($edellinen.alaluokka = yksiyhdeksän) then
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    result $res, rules lukusana_toista, lukusana_sisäkerroin,
Packit 1f3717
                 lukusanan_jälkiliite,
Packit 1f3717
                 nimisana, inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
  elseif ($edellinen.alaluokka = kymmenen) then
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    result $res, rules lukusana_sisäkerroin, lukusanan_jälkiliite;
Packit 1f3717
  else
Packit 1f3717
    result $res, rules nimisana, lukusanan_jälkiliite, inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if ($edellinen.alaluokka in <sata, tuhat>) then
Packit 1f3717
    result $res, rules lukusana;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule lukusana_sisäkerroin ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = lukusana;
Packit 1f3717
  ? $oikea.alaluokka in <kymmenen, sata, tuhat, miljoona>;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $edellinen.lukutyyppi = $oikea.lukutyyppi;
Packit 1f3717
  define $res := $vasen + <[alku: $sana, sijamuoto: $edellinen.sijamuoto, luku: $edellinen.luku] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($edellinen.sijamuoto in <nil, nimentö>) then
Packit 1f3717
    result $res, rules lukusana_sisäkerroin_osanto;
Packit 1f3717
  else
Packit 1f3717
    result $res, rules lukusana_sisäkerroin_sijapääte;
Packit 1f3717
  end;
Packit 1f3717
  
Packit 1f3717
  if ($oikea.lukutyyppi = järjestysluku) then
Packit 1f3717
    result $res, rules lukusana;
Packit 1f3717
  end;
Packit 1f3717
  
Packit 1f3717
  if ($oikea.lukutyyppi = järjestysluku and loppu in $oikea.jatko) then
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule lukusana_sisäkerroin_sijapääte ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  ? $edellinen.sijamuoto = nil or $edellinen.sijamuoto = $oikea.sijamuoto;
Packit 1f3717
  ? $edellinen.luku = nil or $edellinen.luku = $oikea.luku;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana, lukutyyppi: $edellinen.lukutyyppi] + $oikea>;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules lukusana,
Packit 1f3717
               lukusanan_jälkiliite,
Packit 1f3717
               nimisana, inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule lukusana_sisäkerroin_osanto ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = sijapääte;
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.sija in $edellinen.jatko;
Packit 1f3717
  ? $oikea.sijamuoto = osanto;
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <$oikea + [alku: $sana, lukutyyppi: $edellinen.lukutyyppi, sijamuoto: nil]>;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules lukusana, lukusanan_jälkiliite,
Packit 1f3717
               nimisana, inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule lukusana_toista ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = lukusana;
Packit 1f3717
  ? $oikea.alaluokka = toista;
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  define $res := $vasen + <[alku: $sana, sijamuoto: $edellinen.sijamuoto,
Packit 1f3717
                            luku: $edellinen.luku, lukutyyppi: $edellinen.lukutyyppi] + $oikea>;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules lukusana_sisäkerroin,
Packit 1f3717
                     lukusanan_jälkiliite,
Packit 1f3717
                     nimisana, inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule lukusanan_jälkiliite ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in <lukusanan_jälkiliite, tavuviiva>;
Packit 1f3717
  # FIXME: yhdysviivan käyttöä ei vielä tueta lukusanan ja sen jälkiliitteen välissä
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  if $oikea.luokka = tavuviiva then
Packit 1f3717
    if $edellinen.luokka /= tavuviiva then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
  else
Packit 1f3717
    ? $edellinen.lukutyyppi = nil or $edellinen.lukutyyppi = $oikea.lukutyyppi;
Packit 1f3717
    if omistusliite in $oikea.jatko then
Packit 1f3717
      result $res, rules omistusliite;
Packit 1f3717
    end;
Packit 1f3717
    if tavuviiva in $oikea.jatko then
Packit 1f3717
      result $res, rules yhdysmerkki_yleisnimen_jälkeen;
Packit 1f3717
    end;
Packit 1f3717
    if loppu in $oikea.jatko then
Packit 1f3717
      result $res, accept;
Packit 1f3717
    end;
Packit 1f3717
    if liitesana in $oikea.jatko then
Packit 1f3717
      result $res, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
    result $res,
Packit 1f3717
           rules ei_ys_sijapääte,
Packit 1f3717
                 nimisana, etuliite,
Packit 1f3717
                 nimisanan_johdos,
Packit 1f3717
                 nimisana_laatusanasta, nimisana_teonsanasta;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule lukusana_numero ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = lukusana;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  $oikea :=+ [pilkku: $edellinen.pilkku];
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if $oikea.alaluokka = numeromerkki then
Packit 1f3717
    result $res, rules lukusana_numero, merkki_numeron_jälkeen;
Packit 1f3717
    result $res, accept;
Packit 1f3717
  elseif $oikea.alaluokka = pilkku and $oikea.pilkku /= yes then
Packit 1f3717
    $oikea :=+ [pilkku: yes];
Packit 1f3717
    result $vasen + <[alku: $sana] + $oikea>, rules lukusana_numero;
Packit 1f3717
  elseif $oikea.alaluokka = piste and $oikea.pilkku /= yes then
Packit 1f3717
    result $res, rules lukusana_pvm_kk;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule lukusana_pvm_kk($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = lukusana;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if $oikea.alaluokka = numeromerkki then
Packit 1f3717
    result $res, rules lukusana_pvm_kk;
Packit 1f3717
  elseif $oikea.alaluokka = piste then
Packit 1f3717
    # sallitaan enemmänkin pisteitä, esim. IP-osoitteet
Packit 1f3717
    result $res, rules lukusana_numero_tai_piste;
Packit 1f3717
    # sallitaan päivämäärä ilman vuotta (12.4.)
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule lukusana_numero_tai_piste($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = lukusana;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if $oikea.alaluokka = numeromerkki then
Packit 1f3717
    result $res, rules lukusana_numero_tai_piste;
Packit 1f3717
    result $res, accept;
Packit 1f3717
  elseif $oikea.alaluokka = piste then
Packit 1f3717
    result $res, rules lukusana_numero_tai_piste;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### LUKUSANASÄÄNNÖT PÄÄTTYVÄT
Packit 1f3717
Packit 1f3717
combi_rule teonsana ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = teonsana;
Packit 1f3717
Packit 1f3717
  if ($index greater 1) then
Packit 1f3717
    ? tavuviiva in $vasen.($index - 1).jatko;
Packit 1f3717
    ? vokaaliehdollinen_yhdysviiva_ok($vasen, $sana);
Packit 1f3717
    ? $oikea.tiedot = nil or (not ei_ysj in $oikea.tiedot and not ei_ys in $oikea.tiedot);
Packit 1f3717
  else
Packit 1f3717
    ? $oikea.tiedot = nil or (not ysj in $oikea.tiedot);
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
    result $res, rules yhdysmerkki_teonsanan_jälkeen;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana_pi in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana_pi;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules tekijämuodot, nimitavat, teonsanan_johdos;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule tekijämuodot ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @kestämän_tekijäpääte + @tositavan_tekijäpääte_4
Packit 1f3717
                     + @kertoman_tekijäpääte
Packit 1f3717
                     + @ehtotapa + @mahtotapa + @käskytapa;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.luokka in $edellinen.jatko;
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  ? $oikea.luokka /= kestämän_tekijäpääte_y3 or
Packit 1f3717
    taivutusvokaali(last($edellinen.alku)) = $sana;
Packit 1f3717
  ? $oikea.tekijä = nil or $edellinen.tiedot = nil or (
Packit 1f3717
      ((not yt in $edellinen.tiedot) or (not $oikea.tekijä in <tekijä_1, tekijä_2, tekijä_4> and not $oikea.luku = monikko))
Packit 1f3717
     and
Packit 1f3717
      ((not ym3 in $edellinen.tiedot) or (not $oikea.tekijä in <tekijä_1, tekijä_2, tekijä_4>))
Packit 1f3717
    );
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  if $edellinen.tapaluokka = mahtotapa and $oikea.luokka in @kestämän_tekijäpääte then $oikea.tapaluokka := mahtotapa; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  result $res, accept;
Packit 1f3717
  if (liitesana in $oikea.jatko) then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  if (liitesana_pi in $oikea.jatko) then
Packit 1f3717
    result $res, rules liitesana_pi;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### NIMITAPASÄÄNNÖT ALKAVAT
Packit 1f3717
Packit 1f3717
combi_rule nimitapa_4 ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = nimitapa_45 and $oikea.tapaluokka = nimitapa_4;
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then
Packit 1f3717
    $oikea.äs := $vasen.($index - 1).äs;
Packit 1f3717
  end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if (tavuviiva in $oikea.jatko) then
Packit 1f3717
    result $res, rules nimisana, nimisana_laatusanasta, yhdysmerkki_sanan_lopussa;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules nimisanan_sijapääte;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### NIMITAPASÄÄNNÖT PÄÄTTYVÄT
Packit 1f3717
Packit 1f3717
combi_rule nimitavat ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @nimitapa_1 + @nimitapa_2 + @nimitapa_3 + <nimitapa_45>;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.luokka in $edellinen.jatko;
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if (tavuviiva in $oikea.jatko) then
Packit 1f3717
    result $res, rules yhdysmerkki_sanan_lopussa, nimisana, laatusana, nimisana_teonsanasta, inen_johdos_nimisanasta_ehdollinen;
Packit 1f3717
  end;
Packit 1f3717
  if (nimitapa_1_pitkä in $oikea.jatko) then
Packit 1f3717
    result $res, rules nimitapa_1_pitkä;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules nimisanan_sijapääte;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule nimitapa_1_pitkä ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = nimitapa_1_pitkä;
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $vasen.($index - 1).äs; end;
Packit 1f3717
  result $vasen + <[alku: $sana] + $oikea>, rules omistusliite;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule kieltosana ($vasen, $oikea, $sana):
Packit 1f3717
  # Esiehto: tämä sääntö on aina järjestyksessä toisen allomorfin sääntö,
Packit 1f3717
  # ensimmäinen allomorfi on kieltosanan_etuliite.
Packit 1f3717
  ? $oikea.luokka = kieltosana;
Packit 1f3717
  ? $oikea.tapaluokka = tositapa;
Packit 1f3717
Packit 1f3717
  define $äs := ä;
Packit 1f3717
  if $oikea.äs /= nil then
Packit 1f3717
    $äs := $oikea.äs;
Packit 1f3717
  elseif ($vasen.1).äs /= nil then
Packit 1f3717
    $äs := ($vasen.1).äs;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea + [äs: $äs]>;
Packit 1f3717
  if kieltosanan_liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules yhdyskieltosanan_liitesana;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### LIITESANASÄÄNNÖT ALKAVAT
Packit 1f3717
Packit 1f3717
combi_rule liitesana ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = liitesana;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
Packit 1f3717
  if ($edellinen.tapaluokka = käskytapa) then
Packit 1f3717
    ? not ($sana in <"ko", "kö">);
Packit 1f3717
    if (($edellinen.tekijä /= tekijä_2) or ($edellinen.luku /= yksikkö)) then
Packit 1f3717
      ? not ($sana in <"kaan", "kään">);
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if ($edellinen.kielto /= nil and $oikea.kielto /= no) then
Packit 1f3717
    result $vasen + <$oikea + [alku: $sana, kielto: $edellinen.kielto]>, accept;
Packit 1f3717
  else
Packit 1f3717
    result $vasen + <$oikea + [alku: $sana]>, accept;
Packit 1f3717
  end;
Packit 1f3717
    
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
cimbi_rule liitesana_pi ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = liitesana_pi;
Packit 1f3717
Packit 1f3717
  result $vasen + <[alku: $sana] + $oikea>, accept;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
###### LIITESANASÄÄNNÖT PÄÄTTYVÄT
Packit 1f3717
Packit 1f3717
combi_rule kieltosanan_liitesana ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = kieltosanan_liitesana;
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? ($edellinen.äs = $oikea.äs) or ($oikea.äs = ä and $edellinen.äs /= a);
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $vasen + <[alku: $sana] + $oikea>, accept;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule yhdyskieltosanan_liitesana ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = liitesana;
Packit 1f3717
  ? vokaalisointu_oikein($vasen.($index - 1), $oikea);
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $vasen + <[alku: $sana] + $oikea>, accept;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule omistusliite ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = omistusliite;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $result := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($sana in <"ni", "si", "nsa", "nsä", "mme", "nne">) then
Packit 1f3717
    result $result, accept;
Packit 1f3717
    result $result, rules liitesana;
Packit 1f3717
Packit 1f3717
  elseif (omistusliite3_oikein(last($edellinen.alku), $sana)) then
Packit 1f3717
    if ($edellinen.luokka in <seikkasana, suhdesana>) or
Packit 1f3717
       ($edellinen.luokka = nimisana and $edellinen.sijamuoto /= nil) then
Packit 1f3717
      if (not ($edellinen.alku matches ".*(aa|ee|ii|oo|uu|yy|ää|öö)")) then
Packit 1f3717
        result $result, accept;
Packit 1f3717
        result $result, rules liitesana;
Packit 1f3717
      end;
Packit 1f3717
    elseif ($edellinen.luokka = sijapääte) then
Packit 1f3717
      if (($edellinen.sija in 
Packit 1f3717
                              osanto_tA, osanto_ttA, osanto_itA,
Packit 1f3717
                              osanto_jA,
Packit 1f3717
                              olento_nA, olento_inA,
Packit 1f3717
                              tulento_ksi,
Packit 1f3717
                              sisäolento_ssA, sija_monikko_1,
Packit 1f3717
                              ulkopaikallissija_llA,
Packit 1f3717
                              ulkopaikallissija_illA,
Packit 1f3717
                              vajanto_ttA, vajanto_ittA,
Packit 1f3717
                              seuranto_ine>)) or
Packit 1f3717
          ($edellinen.sija = osanto_A and not last($vasen.($index - 2).alku) in <"a", "ä">) then
Packit 1f3717
        result $result, accept;
Packit 1f3717
        result $result, rules liitesana;
Packit 1f3717
      end;
Packit 1f3717
    elseif ($edellinen.luokka in <nimitapa_1_pitkä, nimitapa_2> or $edellinen.tapaluokka = nimitapa_5) then
Packit 1f3717
      result $result, accept; # "puhuakseen"
Packit 1f3717
      result $result, rules liitesana;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule voittoaste ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = voittoaste;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules
Packit 1f3717
         voitto_yliasteen_sijapääte, inen_johdos_nimisanasta;
Packit 1f3717
end;
Packit 1f3717
  
Packit 1f3717
Packit 1f3717
combi_rule voitto_yliaste ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in <voittoaste, yliaste>;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
Packit 1f3717
  ? $oikea.luokka in $edellinen.jatko;
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules voitto_yliasteen_sijapääte;
Packit 1f3717
  if ($oikea.luokka = voittoaste) then
Packit 1f3717
    result $res, rules inen_johdos_nimisanasta, inen_päätteinen_laatusana;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if johdin_UUs in $oikea.jatko then
Packit 1f3717
    result $res, rules johdin_nimisana_laatusanasta;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule johdin_seikkasana_ittain($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka = johdin_ittAin;
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  result $res, rules liitesana;
Packit 1f3717
  result $res, accept;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule teonsanan_johdos ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @johdin_teonsanasta + <johdin_inen>;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.luokka in $edellinen.jatko;
Packit 1f3717
  ? $oikea.luokka /= johdin_inen or not $edellinen.luokka in <johdin_ntA, johdin_nti, johdin_Us_ksen> or $index greater 3;
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  if ($edellinen.luokka = teonsana) then
Packit 1f3717
    $vasen.($index - 1) :=+ [lähtöluokka: teonsana];
Packit 1f3717
    if $oikea.luokka in @johtimet_laatusana_teonsanasta then
Packit 1f3717
      $vasen.($index - 1).luokka := laatusana;
Packit 1f3717
    else
Packit 1f3717
      $vasen.($index - 1).luokka := nimisana;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.luokka in 
Packit 1f3717
                        johdin_mA> + @johdin_jA) or $oikea.jluokka = nimisana then
Packit 1f3717
    result $res, rules nimisanan_sijapääte;
Packit 1f3717
  elseif $oikea.luokka = johdin_lUt then
Packit 1f3717
    result $res, rules laatusanan_sijapääte;
Packit 1f3717
  elseif $oikea.laatutapa = johdin_ttU then
Packit 1f3717
    result $res, rules ttU_sijapääte;
Packit 1f3717
  else
Packit 1f3717
    result $res, rules laatusanan_sijapääte_omistusliitteellä;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
    if ($oikea.luokka in <johdin_UUs, johdin_Us, johdin_ntA, johdin_nti, johdin_Us_ksen>
Packit 1f3717
        + @johdin_jA) or $oikea.jluokka in <nimisana, nimi_laatusana> then
Packit 1f3717
      result $res, rules nimisana, nimisana_teonsanasta, inen_päätteinen_laatusana_ei_nimisanajohdosta,
Packit 1f3717
                         nimisana_laatusanasta, inen_johdos_nimisanasta_ehdollinen,
Packit 1f3717
                         nimisanan_etuliite, yhdysmerkki_yleisnimen_jälkeen;
Packit 1f3717
    else
Packit 1f3717
      result $res, rules inen_johdos_nimisanasta, yhdysmerkki_laatusanan_jälkeen,
Packit 1f3717
                         inen_päätteinen_laatusana;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules teonsanan_johdos, voitto_yliaste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule nimisanan_johdos ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @johdin_nimisanasta + <johdin_UUs>;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.luokka in $edellinen.jatko;
Packit 1f3717
  ? $oikea.luokka /= johdin_UUs or (not $edellinen.luokka in <johdin_jA_kantaja, johdin_jA_kulkija, johdin_jA_myyjä> and $edellinen.lähtöluokka /= nimi_laatusana);
Packit 1f3717
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.luokka = johdin_inen) then
Packit 1f3717
    if ($edellinen.tiedot /= nil and inen in $edellinen.tiedot) and
Packit 1f3717
        (($index = 2) or
Packit 1f3717
         (not ($vasen.($index - 2).luokka in <nimisana, laatusana, nimi_laatusana, etuliite>) and
Packit 1f3717
          ($vasen.($index - 2).sijamuoto /= omanto or $vasen.($index - 2).luku /= yksikkö)) or
Packit 1f3717
          ($index greater 3 and $vasen.($index - 3).lukutyyppi /= nil)) then
Packit 1f3717
      if omistusliite in $oikea.jatko then
Packit 1f3717
        result $res, rules omistusliite;
Packit 1f3717
      end;
Packit 1f3717
      if tavuviiva in $oikea.jatko then
Packit 1f3717
        result $res, rules yhdysmerkki_inen_johdoksen_jälkeen;
Packit 1f3717
      end;
Packit 1f3717
      if loppu in $oikea.jatko then
Packit 1f3717
        result $res, accept;
Packit 1f3717
      end;
Packit 1f3717
      if liitesana in $oikea.jatko then
Packit 1f3717
        result $res, rules liitesana;
Packit 1f3717
      end;
Packit 1f3717
      result $res,
Packit 1f3717
             rules laatusanan_sijapääte_omistusliitteellä, inen_johdos_nimisanasta,
Packit 1f3717
                   voitto_yliaste, johdin_nimisana_laatusanasta;
Packit 1f3717
    end;
Packit 1f3717
    stop;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
    result $res, rules nimisana, nimisana_teonsanasta,
Packit 1f3717
           etuliite, tavuviiva, inen_johdos_nimisanasta;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko and not $oikea.luokka in @johtimet_laatusana_nimisanasta then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  if $oikea.luokka in @johtimet_nimisana_nimisanasta + <johdin_UUs> then
Packit 1f3717
    result $res, rules nimisanan_sijapääte, nimisanan_johdos;
Packit 1f3717
  elseif $oikea.luokka in @johtimet_laatusana_nimisanasta then
Packit 1f3717
    result $res, rules laatusana, laatusanan_sijapääte, voitto_yliaste, johdin_nimisana_laatusanasta;
Packit 1f3717
  elseif $oikea.luokka in @johdin_jA then
Packit 1f3717
    result $res, rules nimisanan_sijapääte, johdin_nimisana_laatusanasta, nimisanan_johdos;
Packit 1f3717
    if tavuviiva in $oikea.jatko then
Packit 1f3717
      result $res, rules inen_päätteinen_laatusana_ei_nimisanajohdosta, nimisana_laatusanasta;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
combi_rule johdin_laatusana_teonsanasta ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @johtimet_laatusana_teonsanasta + <johdin_inen>;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.luokka in $edellinen.jatko;
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  if ($edellinen.luokka = teonsana) then
Packit 1f3717
    $vasen.($index - 1) :=+ [lähtöluokka: teonsana];
Packit 1f3717
    if $oikea.luokka in @johtimet_laatusana_teonsanasta then
Packit 1f3717
      $vasen.($index - 1).luokka := laatusana;
Packit 1f3717
    else
Packit 1f3717
      $vasen.($index - 1).luokka := nimisana;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if $oikea.luokka = johdin_lUt then
Packit 1f3717
    result $res, rules laatusanan_sijapääte;
Packit 1f3717
  else
Packit 1f3717
    result $res, rules laatusanan_sijapääte_omistusliitteellä;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
     result $res, rules inen_johdos_nimisanasta, yhdysmerkki_laatusanan_jälkeen,
Packit 1f3717
                        inen_päätteinen_laatusana;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules teonsanan_johdos, voitto_yliaste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule johdin_laatusana_nimisanasta ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @johtimet_laatusana_nimisanasta;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.luokka in $edellinen.jatko;
Packit 1f3717
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
Packit 1f3717
  if ($oikea.luokka = johdin_inen) then
Packit 1f3717
    if ($edellinen.tiedot /= nil and inen in $edellinen.tiedot) and
Packit 1f3717
        (($index = 2) or
Packit 1f3717
         (not ($vasen.($index - 2).luokka in <nimisana, laatusana, nimi_laatusana, etuliite>) and
Packit 1f3717
          ($vasen.($index - 2).sijamuoto /= omanto or $vasen.($index - 2).luku /= yksikkö)) or
Packit 1f3717
          ($index greater 3 and $vasen.($index - 3).lukutyyppi /= nil)) then
Packit 1f3717
      if omistusliite in $oikea.jatko then
Packit 1f3717
        result $res, rules omistusliite;
Packit 1f3717
      end;
Packit 1f3717
      if tavuviiva in $oikea.jatko then
Packit 1f3717
        result $res, rules yhdysmerkki_yleisnimen_jälkeen;
Packit 1f3717
      end;
Packit 1f3717
      if loppu in $oikea.jatko then
Packit 1f3717
        result $res, accept;
Packit 1f3717
      end;
Packit 1f3717
      if liitesana in $oikea.jatko then
Packit 1f3717
        result $res, rules liitesana;
Packit 1f3717
      end;
Packit 1f3717
      result $res,
Packit 1f3717
             rules laatusanan_sijapääte_omistusliitteellä, inen_johdos_nimisanasta,
Packit 1f3717
                   voitto_yliaste, johdin_nimisana_laatusanasta;
Packit 1f3717
    end;
Packit 1f3717
    stop;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if tavuviiva in $oikea.jatko then
Packit 1f3717
    result $res, rules nimisana, laatusana, nimisana_teonsanasta,
Packit 1f3717
           etuliite, tavuviiva, inen_johdos_nimisanasta;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res, rules laatusanan_sijapääte, voitto_yliaste, johdin_nimisana_laatusanasta;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
combi_rule johdin_nimisana_laatusanasta ($vasen, $oikea, $sana, $index):
Packit 1f3717
  ? $oikea.luokka in @johtimet_nimisana_laatusanasta;
Packit 1f3717
Packit 1f3717
  define $edellinen := $vasen.($index - 1);
Packit 1f3717
  ? $oikea.luokka in $edellinen.jatko;
Packit 1f3717
Packit 1f3717
  ? vokaalisointu_oikein($edellinen, $oikea);
Packit 1f3717
  if $oikea.äs = aä then $oikea.äs := $edellinen.äs; end;
Packit 1f3717
Packit 1f3717
  define $res := $vasen + <[alku: $sana] + $oikea>;
Packit 1f3717
  if tavuviiva in $oikea.jatko and ($edellinen.tiedot = nil or
Packit 1f3717
        (not ei_ysa in $edellinen.tiedot and not ei_ys in $edellinen.tiedot)) then
Packit 1f3717
    result $res, rules nimisana, laatusana, nimisana_teonsanasta,
Packit 1f3717
           etuliite, tavuviiva, inen_johdos_nimisanasta;
Packit 1f3717
  end;
Packit 1f3717
  if $index greater 2 and johdin_inen in $oikea.jatko then
Packit 1f3717
    result $res, rules johdin_inen;
Packit 1f3717
  end;
Packit 1f3717
  if omistusliite in $oikea.jatko then
Packit 1f3717
    result $res, rules omistusliite;
Packit 1f3717
  end;
Packit 1f3717
  if loppu in $oikea.jatko then
Packit 1f3717
    result $res, accept;
Packit 1f3717
  end;
Packit 1f3717
  if liitesana in $oikea.jatko then
Packit 1f3717
    result $res, rules liitesana;
Packit 1f3717
  end;
Packit 1f3717
  result $res,
Packit 1f3717
          rules nimisanan_sijapääte,
Packit 1f3717
                nimisanan_johdos;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
subrule sisätulento_Vn_oikein ($ed_kirjain, $sana):
Packit 1f3717
  return ((($ed_kirjain matches @a) and ($sana matches "an?")) or
Packit 1f3717
          (($ed_kirjain matches @e) and ($sana matches "en?")) or
Packit 1f3717
          (($ed_kirjain matches @i) and ($sana matches "in?")) or
Packit 1f3717
          (($ed_kirjain matches @o) and ($sana matches "on?")) or
Packit 1f3717
          (($ed_kirjain matches @u) and ($sana matches "un?")) or
Packit 1f3717
          (($ed_kirjain matches @y) and ($sana matches "yn?")) or
Packit 1f3717
          (($ed_kirjain matches @ä) and ($sana matches "än?")) or
Packit 1f3717
          (($ed_kirjain matches @ö) and ($sana matches "ön?")));
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
subrule sisätulento_hVn_oikein ($ed_kirjain, $sana):
Packit 1f3717
  return ((($ed_kirjain matches @a) and ($sana matches "han?")) or
Packit 1f3717
          (($ed_kirjain matches @e) and ($sana matches "hen?")) or
Packit 1f3717
          (($ed_kirjain matches @i) and ($sana matches "hin?")) or
Packit 1f3717
          (($ed_kirjain matches @o) and ($sana matches "hon?")) or
Packit 1f3717
          (($ed_kirjain matches @u) and ($sana matches "hun?")) or
Packit 1f3717
          (($ed_kirjain matches @y) and ($sana matches "hyn?")) or
Packit 1f3717
          (($ed_kirjain matches @ä) and ($sana matches "hän?")) or
Packit 1f3717
          (($ed_kirjain matches @ö) and ($sana matches "hön?")) or
Packit 1f3717
          (($ed_kirjain = "'"))); # Parfait'hen yms.
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
# Onko vokaalisointu oikein silloin, kun tiedetään, että $oikea.äs ei ole aä
Packit 1f3717
subrule vokaalisointu_oikein_ei_aä($edellinen, $oikea):
Packit 1f3717
  return ($edellinen.äs = aä or $oikea.äs = $edellinen.äs);
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# Onko vokaalisointu oikein silloin, kun $oikea.äs voi olla aä
Packit 1f3717
subrule vokaalisointu_oikein($edellinen, $oikea):
Packit 1f3717
  return ($oikea.äs = aä or $edellinen.äs = aä or $oikea.äs = $edellinen.äs);
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
subrule omistusliite3_oikein ($kirjain, $liite):
Packit 1f3717
  return ((($liite = "an") and ($kirjain matches @a)) or
Packit 1f3717
          (($liite = "en") and ($kirjain matches @e)) or
Packit 1f3717
          (($liite = "in") and ($kirjain matches @i)) or
Packit 1f3717
          (($liite = "on") and ($kirjain matches @o)) or
Packit 1f3717
          (($liite = "un") and ($kirjain matches @u)) or
Packit 1f3717
          (($liite = "yn") and ($kirjain matches @y)) or
Packit 1f3717
          (($liite = "än") and ($kirjain matches @ä)) or
Packit 1f3717
          (($liite = "ön") and ($kirjain matches @ö)));
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# Taivutuspäätteessä annettua kirjainta vastaava pidennetty vokaali
Packit 1f3717
subrule taivutusvokaali($kirjain):
Packit 1f3717
  if     ($kirjain matches @a) then return "a";
Packit 1f3717
  elseif ($kirjain matches @e) then return "e";
Packit 1f3717
  elseif ($kirjain matches @i) then return "i";
Packit 1f3717
  elseif ($kirjain matches @o) then return "o";
Packit 1f3717
  elseif ($kirjain matches @u) then return "u";
Packit 1f3717
  elseif ($kirjain matches @y) then return "y";
Packit 1f3717
  elseif ($kirjain matches @ä) then return "ä";
Packit 1f3717
  elseif ($kirjain matches @ö) then return "ö";
Packit 1f3717
  end;
Packit 1f3717
  return "";
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
Packit 1f3717
#####################################################
Packit 1f3717
Packit 1f3717
Packit 1f3717
output_filter tulosta ($tulos):
Packit 1f3717
  foreach $j in length ($tulos):
Packit 1f3717
    result tulostus_v2($tulos.$j);
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
# Palauttaa tietueen rakenne-kentän mukaisen rakennekuvauksen oikean mittaisena.
Packit 1f3717
# Jos $pienet_kirjaimet = yes, niin rakenteen i-merkit muutetaan p-merkeiksi.
Packit 1f3717
subrule rakenne ($tietue, $pienet_kirjaimet):
Packit 1f3717
  define $alen := length($tietue.alku);
Packit 1f3717
  define $i := 0;
Packit 1f3717
  define $tuloste := "=";
Packit 1f3717
  define $kirjain := "";
Packit 1f3717
  foreach $k in length($tietue.rakenne):
Packit 1f3717
    $kirjain := substring($tietue.rakenne, $k);
Packit 1f3717
    if $i less $alen then
Packit 1f3717
      if $kirjain = "=" then
Packit 1f3717
        $tuloste :=+ "=";
Packit 1f3717
      else
Packit 1f3717
        if $pienet_kirjaimet and $kirjain = "i" then
Packit 1f3717
          $tuloste :=+ "p";
Packit 1f3717
        else
Packit 1f3717
          $tuloste :=+ $kirjain;
Packit 1f3717
        end;
Packit 1f3717
        $i :=+ 1;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  if $i less $alen then
Packit 1f3717
    foreach $j in $alen - $i:
Packit 1f3717
      $tuloste :=+ "p";
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return $tuloste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_rakenne ($tietue):
Packit 1f3717
  define $tuloste := "";
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  define $tind := 0;
Packit 1f3717
  define $arvattu_erisnimi := no;
Packit 1f3717
  foreach $t in $tietue:
Packit 1f3717
    $tind :=+ 1;
Packit 1f3717
    if $t.rakenne /= nil then
Packit 1f3717
      if ($t.luokka = paikannimi and
Packit 1f3717
          (
Packit 1f3717
            ($tlen greater $tind and $tietue.($tind+1).luokka = johdin_lAinen) or
Packit 1f3717
            ($tlen greater $tind + 2 and $tietue.($tind+3).luokka = johdin_lAinen)
Packit 1f3717
          )
Packit 1f3717
         ) then
Packit 1f3717
        $tuloste :=+ rakenne($t, yes);
Packit 1f3717
      else
Packit 1f3717
        $tuloste :=+ rakenne($t, no);
Packit 1f3717
      end;
Packit 1f3717
    elseif $t.luokka in 
Packit 1f3717
                         nimi_laatusana, asemosana, suhdesana, lukusanan_jälkiliite, etuliite, kieltosana> or
Packit 1f3717
                         ($t.luokka = lukusana and not $t.alaluokka in <numeromerkki, pilkku, piste>) then
Packit 1f3717
      $tuloste :=+ "=";
Packit 1f3717
      if $t.aluetta_tarkentava_etuliite = yes and
Packit 1f3717
         (($tind + 1 = $tlen and $tietue.($tind+1).luokka = tavuviiva) or
Packit 1f3717
          ($tlen + 1 greater $tind and $tietue.($tind+1).luokka = tavuviiva and $tietue.($tind+2).luokka = paikannimi) or
Packit 1f3717
          ($tlen + 2 greater $tind and $tietue.($tind+1).luokka in <johdin_inen, sijapääte> and $tietue.($tind+2).luokka = tavuviiva and $tietue.($tind+3).luokka = paikannimi)) then
Packit 1f3717
        $tuloste :=+ "i";
Packit 1f3717
      else
Packit 1f3717
        $tuloste :=+ "p";
Packit 1f3717
      end;
Packit 1f3717
      foreach $i in length($t.alku) - 1:
Packit 1f3717
        $tuloste :=+ "p";
Packit 1f3717
      end;
Packit 1f3717
    elseif $t.luokka in <etunimi, sukunimi, nimi, paikannimi> then
Packit 1f3717
      $tuloste :=+ "=";
Packit 1f3717
      if ($t.luokka = paikannimi and
Packit 1f3717
          (
Packit 1f3717
            ($tlen greater $tind and $tietue.($tind+1).luokka = johdin_lAinen) or
Packit 1f3717
            ($tlen greater $tind + 2 and $tietue.($tind+3).luokka = johdin_lAinen) or
Packit 1f3717
            ($tlen greater $tind + 1 and $tietue.($tind+1).luokka = sijapääte and $tietue.($tind+2).inen_loppu = yes)
Packit 1f3717
          )
Packit 1f3717
         ) or $t.erisnimen_pääte = yes then
Packit 1f3717
        foreach $i in length($t.alku):
Packit 1f3717
          $tuloste :=+ "p";
Packit 1f3717
        end;
Packit 1f3717
        if $t.erisnimen_pääte = yes then
Packit 1f3717
          $arvattu_erisnimi := yes;
Packit 1f3717
        end;
Packit 1f3717
      else
Packit 1f3717
        $tuloste :=+ "i";
Packit 1f3717
        foreach $i in length($t.alku) - 1:
Packit 1f3717
          $tuloste :=+ "p";
Packit 1f3717
        end;
Packit 1f3717
      end;
Packit 1f3717
    elseif $t.luokka = lyhenne then
Packit 1f3717
      $tuloste :=+ "=";
Packit 1f3717
      foreach $i in length($t.alku):
Packit 1f3717
        $tuloste :=+ "q";
Packit 1f3717
      end;
Packit 1f3717
    elseif $t.luokka = tavuviiva then
Packit 1f3717
      $tuloste :=+ "-";
Packit 1f3717
    elseif $t.luokka = kaksoispiste then
Packit 1f3717
      $tuloste :=+ ":";
Packit 1f3717
    elseif $t.luokka = lukusana then
Packit 1f3717
      $tuloste :=+ "q";
Packit 1f3717
    else
Packit 1f3717
      foreach $i in length($t.alku):
Packit 1f3717
        $tuloste :=+ "p";
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  if $arvattu_erisnimi = yes then
Packit 1f3717
    return "=i" + substring($tuloste, 3, length($tuloste));
Packit 1f3717
  end;
Packit 1f3717
  return $tuloste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_luokka($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  define $omistusliite := no;
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.jluokka /= nil then
Packit 1f3717
      return $allomorfi.jluokka;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = johdin_inen then
Packit 1f3717
      return laatusana;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in @johtimet_laatusana_nimisanasta then
Packit 1f3717
      if $omistusliite then
Packit 1f3717
        return nimisana;
Packit 1f3717
      else
Packit 1f3717
        return laatusana;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in 
Packit 1f3717
                             nimi_laatusana, asemosana, suhdesana,
Packit 1f3717
                             huudahdussana, sidesana, etunimi, sukunimi,
Packit 1f3717
                             paikannimi, nimi, kieltosana,
Packit 1f3717
                             lukusana, etuliite> then
Packit 1f3717
      return $allomorfi.luokka;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = tavuviiva then
Packit 1f3717
      return etuliite;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = lyhenne then
Packit 1f3717
      if $allomorfi.alaluokka = roomalainen then
Packit 1f3717
        return lukusana;
Packit 1f3717
      end;
Packit 1f3717
      return lyhenne;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in @johtimet_nimisana_laatusanasta then
Packit 1f3717
      return nimisana;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = johdin_ittAin then
Packit 1f3717
      return seikkasana;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = johdin_lAinen then
Packit 1f3717
      return laatusana;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = omistusliite then
Packit 1f3717
      $omistusliite := yes;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return nil;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_sijamuoto($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.sijamuoto /= nil then
Packit 1f3717
      return $allomorfi.sijamuoto;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in <tavuviiva, johdin_ittAin, seikkasana> then
Packit 1f3717
      return nil;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.alaluokka = erikoisluku then
Packit 1f3717
      return nil;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.tapaluokka = nimitapa_5 then
Packit 1f3717
      return nil;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in 
Packit 1f3717
                             etunimi, sukunimi, paikannimi, nimi, lukusana, nimitapa_45, lukusanan_jälkiliite> then
Packit 1f3717
      return nimentö;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return nil;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_luku($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.luku /= nil then
Packit 1f3717
      return $allomorfi.luku;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in <tavuviiva, johdin_ittAin, seikkasana> then
Packit 1f3717
      return nil;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.sija = kerronto_sti then
Packit 1f3717
      return nil;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.alaluokka = erikoisluku then
Packit 1f3717
      return nil;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.tapaluokka = nimitapa_5 then
Packit 1f3717
      return nil;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in 
Packit 1f3717
                             etunimi, sukunimi, paikannimi, nimi, lukusana, nimitapa_45, lukusanan_jälkiliite> then
Packit 1f3717
      return yksikkö;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return nil;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_tekijä($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.tekijä /= nil then
Packit 1f3717
      return $allomorfi.tekijä;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return nil;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_tapaluokka($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.tapaluokka /= nil then
Packit 1f3717
      return $allomorfi.tapaluokka;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return nil;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_aikamuoto($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.aikamuoto /= nil then
Packit 1f3717
      return $allomorfi.aikamuoto;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in @kestämän_tekijäpääte then
Packit 1f3717
      return kestämä;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in @kertoman_tekijäpääte then
Packit 1f3717
      return kertoma;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return nil;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_vertailu($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.luokka in <voittoaste, yliaste> then
Packit 1f3717
      return $allomorfi.luokka;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = nimisana then
Packit 1f3717
      return perusaste;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return perusaste;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_partisiipit($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.laatutapa /= nil then
Packit 1f3717
      return [laatutapa: $allomorfi.laatutapa];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.jluokka = nimisana then
Packit 1f3717
      return [];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = johdin_vA then
Packit 1f3717
      return [laatutapa: johdin_vA];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in <johdin_tAvA, johdin_ttAvA> then
Packit 1f3717
      return [laatutapa: johdin_tAvA];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in @johdin_nUt then
Packit 1f3717
      return [laatutapa: johdin_nUt];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = johdin_tOn and $i less $tlen and
Packit 1f3717
       ($tietue.($tlen - $i).luokka = johdin_mA or $tietue.($tlen - $i).johdin_mA = yes) then
Packit 1f3717
      return [laatutapa: johdin_tOn];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka = johdin_mA or $allomorfi.johdin_mA = yes then
Packit 1f3717
      return [laatutapa: johdin_mA];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in <johdin_ttU, johdin_tU, johdin_dU, johdin_lU, johdin_nU, johdin_rU, johdin_tU_lU_oltu> then
Packit 1f3717
      return [laatutapa: johdin_ttU];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in <nimisana, laatusana, nimi_laatusana, teonsana, tavuviiva, johdin_Us, johdin_UUs> then
Packit 1f3717
      return [];
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return [];
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_omistusliitteet($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.omistusliite /= nil then
Packit 1f3717
      return [omistusliite: $allomorfi.omistusliite];
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return [];
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_liitepartikkelit($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  define $res := [];
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.kysymysliite /= nil then
Packit 1f3717
      $res :=+ [kysymysliite: yes];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.fokus /= nil then
Packit 1f3717
      $res :=+ [fokus: $allomorfi.fokus];
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return $res;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_kielto($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.kielto /= nil then
Packit 1f3717
      if $tlen greater $i then
Packit 1f3717
        define $edellinen := $tietue.($tlen - $i);
Packit 1f3717
        if $edellinen.luokka in <kertoman_tekijäpääte_vahva, kertoman_tekijäpääte_heikko, kestämän_tekijäpääte_heikko> or
Packit 1f3717
          ($edellinen.luokka = teonsana and $edellinen.tapaluokka = tositapa and $edellinen.aikamuoto = kestämä and $allomorfi.kielto = yes) then
Packit 1f3717
          return no;
Packit 1f3717
        end;
Packit 1f3717
      end;
Packit 1f3717
      return $allomorfi.kielto;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.tapaluokka = käskytapa or $allomorfi.luokka = omistusliite then
Packit 1f3717
      return molemmat;
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka /= liitesana then
Packit 1f3717
      return no;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return no;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_nimisanan_attribuutit($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.paikannimen_jälkiliite = yes then
Packit 1f3717
      return [paikannimen_jälkiliite: yes];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.luokka in <nimisana, nimi_laatusana, laatusana, tavuviiva, johdin_UUs> then
Packit 1f3717
      return [];
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return [];
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule debug_sanan_perusmuodon_osa ($tietue, $vain_alku):
Packit 1f3717
    define $res := "+";
Packit 1f3717
    if ($vain_alku or $tietue.perusmuoto = nil) then
Packit 1f3717
      $res :=+ $tietue.alku;
Packit 1f3717
    else
Packit 1f3717
      foreach $i in length($tietue.perusmuoto):
Packit 1f3717
        define $c := substring($tietue.perusmuoto, $i, $i);
Packit 1f3717
        if not $c in <"=", "|"> then
Packit 1f3717
          $res :=+ $c;
Packit 1f3717
        end;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
    if ($tietue.lähtösana /= nil) then
Packit 1f3717
      $res :=+ "(p=" + $tietue.lähtösana + ")";
Packit 1f3717
    elseif ($tietue.perusmuoto /= nil and $tietue.luokka in 
Packit 1f3717
                             seikkasana, laatusana, teonsana,
Packit 1f3717
                             nimi_laatusana, asemosana, suhdesana,
Packit 1f3717
                             huudahdussana, sidesana, etunimi, sukunimi,
Packit 1f3717
                             paikannimi, nimi, kieltosana, lyhenne,
Packit 1f3717
                             lukusana>) then
Packit 1f3717
      $res :=+ "(p=" + $tietue.perusmuoto + ")";
Packit 1f3717
    elseif ($tietue.luokka in @johdin_teonsanasta + @johdin_nimisanasta + @johtimet_laatusanasta) then
Packit 1f3717
      $res :=+ "(p=+";
Packit 1f3717
      if ($tietue.perusmuoto /= nil) then
Packit 1f3717
        $res :=+ $tietue.perusmuoto;
Packit 1f3717
      else
Packit 1f3717
        $res :=+ $tietue.alku;
Packit 1f3717
      end;
Packit 1f3717
      $res :=+ ")";
Packit 1f3717
    end;
Packit 1f3717
    if ($tietue.sourceid /= nil) then
Packit 1f3717
      $res :=+ "(s=" + $tietue.sourceid + ")";
Packit 1f3717
    end;
Packit 1f3717
    return $res;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule debug_lukusanan_perusmuodon_osa ($tietue):
Packit 1f3717
  if ($tietue.perusmuoto = "kymmenen") then
Packit 1f3717
    return "+kymmentä";
Packit 1f3717
  elseif ($tietue.perusmuoto = "tuhat") then
Packit 1f3717
    return "+tuhatta";
Packit 1f3717
  elseif ($tietue.alaluokka in <sata, miljoona> and $tietue.lukutyyppi = perusluku) then
Packit 1f3717
    return "+" + $tietue.perusmuoto + "a";
Packit 1f3717
  else
Packit 1f3717
    return debug_sanan_perusmuodon_osa($tietue, no);
Packit 1f3717
  end;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule debug_lukusanan_perusmuoto ($tietue, $i, $k, $s):
Packit 1f3717
  # Kopioitu Hannu Väisäsen Sukija-versiosta
Packit 1f3717
  if ($i = 1 and $tietue.$i.alaluokka in <sata, tuhat, miljoona>) then
Packit 1f3717
    return "+" + $tietue.$i.perusmuoto;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if ($tietue.$i.luokka = lukusanan_jälkiliite) then
Packit 1f3717
    return "+" + $tietue.$i.perusmuoto;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  if ($tietue.$i.alaluokka = yksiyhdeksän) then
Packit 1f3717
    if (($k greater 2) and ($i less $k) and ($tietue.($i+1).luokka = sijapääte) and ($tietue.($i+2).luokka /= lukusana)) then
Packit 1f3717
      return "+" + $tietue.$i.alku;
Packit 1f3717
    else
Packit 1f3717
      return "+" + $tietue.$i.perusmuoto;
Packit 1f3717
    end;
Packit 1f3717
  elseif ($tietue.$i.perusmuoto = "kymmenen") then
Packit 1f3717
    if (($i = $k) and (($s matches ".+sataa") or ($s = "sata"))) then
Packit 1f3717
      return "+" + "kymmenen";
Packit 1f3717
    else
Packit 1f3717
      return "+" + "kymmentä";
Packit 1f3717
    end;
Packit 1f3717
  elseif ($tietue.$i.alaluokka in <sata, tuhat, miljoona>) then
Packit 1f3717
    if ($tietue.($i+1).luokka in <lukusana, sijapääte>) then
Packit 1f3717
      return debug_lukusanan_perusmuodon_osa($tietue.$i);
Packit 1f3717
    else
Packit 1f3717
      return "+" + $tietue.$i.perusmuoto;
Packit 1f3717
    end;
Packit 1f3717
  elseif ($tietue.$i.luokka = sijapääte) then
Packit 1f3717
    if ($i less $k and $tietue.($i+1).luokka in <lukusana, lukusanan_jälkiliite>) then
Packit 1f3717
      return "";
Packit 1f3717
    else
Packit 1f3717
      return "+" + $tietue.$i.alku;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return debug_sanan_perusmuodon_osa($tietue.$i, no);
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_debug_perusmuoto($tietue, $luokka):
Packit 1f3717
  # Kopioitu Hannu Väisäsen Sukija-versiosta
Packit 1f3717
  define $n := length ($tietue);
Packit 1f3717
  define $k := $n;
Packit 1f3717
Packit 1f3717
  # Poistetaan sanan lopusta osat, jotka eivät vaikuta perusmuotoon.
Packit 1f3717
  #
Packit 1f3717
  repeat while ($tietue.$k.luokka in 
Packit 1f3717
                                      kieltosanan_liitesana, omistusliite, kaksoispiste,
Packit 1f3717
                                      voittoaste, yliaste,
Packit 1f3717
                                      nimitapa_1_pitkä, nimitapa_45>
Packit 1f3717
                                      + @tositavan_tekijäpääte_4 + @kertoman_tekijäpääte
Packit 1f3717
                                      + @kestämän_tekijäpääte + @ehtotapa + @mahtotapa + @käskytapa
Packit 1f3717
                                      + @nimitapa_1 + @nimitapa_2 + @nimitapa_3);
Packit 1f3717
    $k :=- 1;
Packit 1f3717
  end;
Packit 1f3717
Packit 1f3717
  define $s := "";
Packit 1f3717
  define $skip := no;
Packit 1f3717
  foreach $i in $k - 1:
Packit 1f3717
    if $skip then
Packit 1f3717
      $skip := no;
Packit 1f3717
    else
Packit 1f3717
      if ($tietue.$i.lukutyyppi /= nil and $luokka = lukusana) then
Packit 1f3717
        $s :=+ debug_lukusanan_perusmuoto ($tietue, $i, $k, $s);
Packit 1f3717
      elseif (($i+3) less $n and $tietue.$i.luokka = laatusana and $tietue.($i+1).luokka = sijapääte and
Packit 1f3717
              $tietue.($i+2).luokka = tavuviiva and $tietue.($i+3).luokka = paikannimi) then
Packit 1f3717
        # Uudessa-Seelannissa -> Uusi-Seelanti
Packit 1f3717
        $s :=+ debug_sanan_perusmuodon_osa($tietue.$i, no);
Packit 1f3717
        $skip := yes;
Packit 1f3717
      else
Packit 1f3717
        $s :=+ debug_sanan_perusmuodon_osa($tietue.$i, yes);
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  if ($k = 1) then
Packit 1f3717
    $s :=+ debug_sanan_perusmuodon_osa($tietue.$k, no);
Packit 1f3717
  elseif ($tietue.$k.lukutyyppi /= nil and $tietue.$k.lukutyyppi = perusluku) then
Packit 1f3717
    $s :=+ debug_lukusanan_perusmuoto ($tietue, $k, $k, $s);
Packit 1f3717
  else
Packit 1f3717
    $s :=+ debug_lukusanan_perusmuodon_osa($tietue.$k);
Packit 1f3717
  end;
Packit 1f3717
  return $s;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_teonsanan_attribuutit($tietue):
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  foreach $i in $tlen:
Packit 1f3717
    define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
    if $allomorfi.tapaluokka in <nimitapa_2, nimitapa_3, nimitapa_4, nimitapa_5> then
Packit 1f3717
      return [];
Packit 1f3717
    end;
Packit 1f3717
    if $allomorfi.vaatii_tapaluokan /= nil then
Packit 1f3717
      return [vaatii_tapaluokan: $allomorfi.vaatii_tapaluokan, kielto: tulostus_kielto($tietue)];
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return [kielto: tulostus_kielto($tietue)];
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
subrule tulostus_v2($tietue):
Packit 1f3717
  define $res := nil;
Packit 1f3717
  if @voikko_debug then
Packit 1f3717
    define $luokka := tulostus_luokka($tietue);
Packit 1f3717
    $res := [rakenne: tulostus_rakenne($tietue),
Packit 1f3717
            luokka: $luokka,
Packit 1f3717
            luku: tulostus_luku($tietue),
Packit 1f3717
            sijamuoto: tulostus_sijamuoto($tietue),
Packit 1f3717
            perusmuoto: tulostus_debug_perusmuoto($tietue, $luokka)]
Packit 1f3717
          + tulostus_partisiipit($tietue)
Packit 1f3717
          + tulostus_omistusliitteet($tietue)
Packit 1f3717
          + tulostus_liitepartikkelit($tietue);
Packit 1f3717
    if $res.luokka = teonsana then
Packit 1f3717
      $res :=+ [aikamuoto: tulostus_aikamuoto($tietue)];
Packit 1f3717
    elseif $res.luokka in <laatusana, nimi_laatusana> then
Packit 1f3717
      $res :=+ [vertailu: tulostus_vertailu($tietue)];
Packit 1f3717
    end;    
Packit 1f3717
  else
Packit 1f3717
    $res := [rakenne: tulostus_rakenne($tietue),
Packit 1f3717
            luokka:  tulostus_luokka($tietue),
Packit 1f3717
            luku: tulostus_luku($tietue),
Packit 1f3717
            sijamuoto: tulostus_sijamuoto($tietue)];
Packit 1f3717
  end;
Packit 1f3717
  if $res.luokka = teonsana then
Packit 1f3717
    $res :=+ [tekijä: tulostus_tekijä($tietue),
Packit 1f3717
              tapaluokka: tulostus_tapaluokka($tietue)]
Packit 1f3717
           + tulostus_teonsanan_attribuutit($tietue);
Packit 1f3717
  elseif $res.luokka = nimisana then
Packit 1f3717
    $res :=+ tulostus_nimisanan_attribuutit($tietue);
Packit 1f3717
  elseif $res.luokka = kieltosana then
Packit 1f3717
    $res :=+ [tekijä: tulostus_tekijä($tietue),
Packit 1f3717
              tapaluokka: tulostus_tapaluokka($tietue)];
Packit 1f3717
  end;
Packit 1f3717
  define $tlen := length($tietue);
Packit 1f3717
  if $tietue.<1, luokka> /= tavuviiva then
Packit 1f3717
    foreach $i in $tlen:
Packit 1f3717
      define $allomorfi := $tietue.($tlen + 1 - $i);
Packit 1f3717
      if $allomorfi.vapaa_jälkiosa = yes then
Packit 1f3717
        $res :=+ [vapaa_jälkiosa: yes];
Packit 1f3717
        break;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return $res;
Packit 1f3717
end;
Packit 1f3717
Packit 1f3717
pruning_rule prune ($list):
Packit 1f3717
  define $alut := <>;
Packit 1f3717
  define $filter := <>;
Packit 1f3717
  define $j := 0;
Packit 1f3717
  foreach $an in $list:
Packit 1f3717
    $alut :=+ <($an.1).alku>;
Packit 1f3717
  end;
Packit 1f3717
  $alut := set($alut);
Packit 1f3717
  foreach $an in $list:
Packit 1f3717
    if $j = 30 then
Packit 1f3717
      $filter :=+ <no>;
Packit 1f3717
    else
Packit 1f3717
      if (length($an) greater 1) and ($an.1).alku + ($an.2).alku in $alut then
Packit 1f3717
        $filter :=+ <no>;
Packit 1f3717
      else
Packit 1f3717
        $filter :=+ <yes>;
Packit 1f3717
        $j :=+ 1;
Packit 1f3717
      end;
Packit 1f3717
    end;
Packit 1f3717
  end;
Packit 1f3717
  return $filter;
Packit 1f3717
end;
Packit 1f3717