summaryrefslogtreecommitdiff
path: root/contrib/eaglesconv/EaglesConv.hs
blob: aa89294962a042b2ae6700c735da0fb32b4ebe37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
-- Copyright (C) 2011 Nikita Frolov

-- No, we can't pipeline parsing and generation, because there is no guarantee
-- that we have collected all forms for a lemma before we've scanned the
-- complete file.

import qualified Data.Text as T
import qualified Data.Text.IO as UTF8
import System.IO
import System.Environment
import Control.Monad
import Control.Monad.State
import qualified Data.Map as M
import Codec.Text.IConv
import qualified Data.ByteString.Lazy as BS
import qualified Data.ByteString.Internal as BSI

import EaglesMatcher

type Lemmas = M.Map T.Text Forms

main :: IO ()
main = do
  args <- getArgs
  forM_ args $ \ f -> do
    entries <- UTF8.readFile f >>= (return . T.lines)
    lemmas <- return $ execState (collectLemmas entries) (M.empty :: Lemmas)
    mapM_ generateLin (M.assocs lemmas)

collectLemmas entries = do
  forM_ entries $ \ entry -> do
    let ws = T.words entry
        lemma = head ws
        tags = toPairs $ tail ws
    lemmas <- get
    forM_ tags $ \ (form, tag) -> do
      let forms = (case M.lookup lemma lemmas of
                     Just f -> f
                     Nothing -> M.empty) :: Forms
      if isOpenCat . T.unpack $ tag
       then put $ M.insert lemma (M.insert tag form forms) lemmas
       else return ()

generateLin :: (T.Text, Forms) -> IO ()
generateLin (lemma, forms) = do
  let lemma' = myVeryOwnCyrillicRomanizationIConvSucks lemma
  UTF8.putStr $ T.concat [T.pack "lin ", lemma']
  UTF8.putStr $ case T.unpack . head . M.keys $ forms of
                  ('N':_:_:_:g:a:'0':_) ->
                      T.concat $ [T.pack "_N = mkN "]
                               ++ map (quote . noun forms) [ ('N','S'), ('G','S')
                               , ('D','S'), ('F','S'), ('C','S'), ('O','S')
                               , ('L','S'), ('N','P'), ('G','P'), ('D','P')
                               , ('F','P'), ('C','P'), ('O','P') ]
                           ++ [showG g, sp, showAni a, ln]
                  ('N':_:c:n:g:a:_) ->
                      T.concat $ [T.pack "_PN = mkPN "
                       , quote $ noun forms ('N', 'S')
                       , showG g, sp
                       , showN n, sp, showAni a, ln]
                  ('A':_) ->
                      T.concat $ [T.pack "_A = mkA ", quote $ adj forms 'P',
                                   if adj forms 'P' /= adj forms 'C'
                                      then quote $ adj forms 'C'
                                      else T.pack ""
                                   , ln]
                  ('V':t) ->
                      let a = case t of
                                (_:_:_:_:'P':_:a':_) -> a'
                                (_:_:_:_:_:a':_) -> a'
                      in
                        T.concat $ [T.pack "_V = mkV ", showAsp a, sp]
                           ++ map (quote . verbPres forms) [ ('S','1'), ('S','2')
                                                           , ('S','3'), ('P','1')
                                                           , ('P','2'), ('P','3')]
                           ++ [ quote $ verbPast forms ('S', 'M')
                              , quote $ verbImp forms, quote $ verbInf forms, ln]
                  ('D':_) ->
                      T.concat $ [T.pack "_Adv = mkAdv "
                                 , quote . adv $ forms, ln]
  putStrLn ""
  hFlush stdout
      where quote x = T.concat [T.pack "\"", x, T.pack "\" "]
            showG 'F' = T.pack "Fem"
            showG 'A' = T.pack "Neut"
            showG _ = T.pack "Masc"
            showAni 'I' = T.pack "Inanimate"
            showAni _ = T.pack "Animate"
            showN 'P' = T.pack "Pl"
            showN _ = T.pack "Sg"
            showAsp 'F' = T.pack "Perfective"
            showAsp _ = T.pack "Imperfective"
            sp = T.singleton ' '
            ln = T.pack " ;"

toPairs xs = zip (stride 2 xs) (stride 2 (drop 1 xs))
    where stride _ [] = []
          stride n (x:xs) = x : stride n (drop (n-1) xs)

myVeryOwnCyrillicRomanizationIConvSucks s = T.pack . concatMap r . T.unpack $ s
    where r 'а' = "a"
          r 'б' = "b"
          r 'в' = "v"
          r 'г' = "g"
          r 'д' = "d"
          r 'е' = "je"
          r 'ё' = "jo"
          r 'ж' = "zh"
          r 'з' = "z"
          r 'и' = "i"
          r 'й' = "jj"
          r 'к' = "k"
          r 'л' = "l"
          r 'м' = "m"
          r 'н' = "n"
          r 'о' = "o"
          r 'п' = "p"
          r 'р' = "r"
          r 'с' = "s"
          r 'т' = "t"
          r 'у' = "u"
          r 'ф' = "f"
          r 'х' = "kh"
          r 'ц' = "c"
          r 'ч' = "ch"
          r 'ш' = "sh"
          r 'щ' = "shc"
          r 'ъ' = "yy"
          r 'ы' = "y"
          r 'ь' = "q"
          r 'э' = "e"
          r 'ю' = "ju"
          r 'я' = "ja"
          r '-' = "_"
          r o = [o]