91 lines
2.6 KiB
Haskell
91 lines
2.6 KiB
Haskell
|
|
{-# LANGUAGE FlexibleInstances #-}
|
||
|
|
{-# LANGUAGE MultiWayIf #-}
|
||
|
|
{-# LANGUAGE TypeFamilies #-}
|
||
|
|
module Lib
|
||
|
|
( someFunc
|
||
|
|
)
|
||
|
|
where
|
||
|
|
|
||
|
|
import Data.Void
|
||
|
|
import qualified Text.Megaparsec as Parsec
|
||
|
|
import qualified Text.Megaparsec.Stream as Parsec
|
||
|
|
|
||
|
|
instance Parsec.Stream [Phoneme] where
|
||
|
|
type Token [Phoneme] = Phoneme
|
||
|
|
type Tokens [Phoneme] = [Phoneme]
|
||
|
|
tokensToChunk _ = id
|
||
|
|
chunkToTokens _ = id
|
||
|
|
chunkLength _ = length
|
||
|
|
take1_ [] = Nothing
|
||
|
|
take1_ (x : xs) = Just (x, xs)
|
||
|
|
takeN_ n xs = if length xs >= n then Just (splitAt n xs) else Nothing
|
||
|
|
takeWhile_ = span
|
||
|
|
showTokens _ = show
|
||
|
|
reachOffset offset posState =
|
||
|
|
Parsec.reachOffset' splitAt foldl' id id ('\n', '\t') o pst
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
parseRoot :: Parsec.Parsec Void [Phoneme] ()
|
||
|
|
parseRoot = () <$ do
|
||
|
|
Parsec.optional $ satisfyFeature (`elem` [Sibilant, Laryngeal])
|
||
|
|
Parsec.optional $ satisfyFeature isPlosive
|
||
|
|
satisfyFeature $ \p -> isPlosive p || p == Resonant
|
||
|
|
Parsec.single E
|
||
|
|
satisfyFeature $ \p -> isPlosive p || p == Resonant
|
||
|
|
Parsec.optional $ satisfyFeature isPlosive
|
||
|
|
Parsec.optional $ satisfyFeature (`elem` [Sibilant, Laryngeal])
|
||
|
|
where
|
||
|
|
satisfyFeature :: (FeatureSet -> Bool) -> Parsec.Parsec Void [Phoneme] Phoneme
|
||
|
|
satisfyFeature p = Parsec.satisfy (p . features)
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
data Manner = Tenuis | Media | MediaAspirata
|
||
|
|
deriving (Show, Eq)
|
||
|
|
|
||
|
|
data Place = Labial | Dental | Palatal | Velar | Labiovelar
|
||
|
|
deriving (Show, Eq)
|
||
|
|
|
||
|
|
data Phoneme
|
||
|
|
= E | O | A | E_ | O_ | A_
|
||
|
|
| I | U | N | M | R | L
|
||
|
|
| P | B | Bh | T | D | Dh | Kj | Gj | Gjh | K | G | Gh | Kw | Gw | Gwh | S | H1 | H2 | H3
|
||
|
|
deriving (Eq, Ord)
|
||
|
|
|
||
|
|
data FeatureSet
|
||
|
|
= Vowel
|
||
|
|
| Resonant
|
||
|
|
| Plosive { manner :: Manner, place :: Place }
|
||
|
|
| Sibilant
|
||
|
|
| Laryngeal
|
||
|
|
deriving (Show, Eq)
|
||
|
|
|
||
|
|
isPlosive :: FeatureSet -> Bool
|
||
|
|
isPlosive (Plosive _ _) = True
|
||
|
|
isPlosive _ = False
|
||
|
|
|
||
|
|
features :: Phoneme -> FeatureSet
|
||
|
|
features phoneme
|
||
|
|
| phoneme == S = Sibilant
|
||
|
|
| phoneme `elem` [E, O, A, E_, O_, A_] = Vowel
|
||
|
|
| phoneme `elem` [H1, H2, H3] = Laryngeal
|
||
|
|
| phoneme `elem` [I, U, N, M, R, L] = Resonant
|
||
|
|
| otherwise = Plosive
|
||
|
|
{ manner = if
|
||
|
|
| phoneme `elem` [P, T, K, Kj, Kw] -> Tenuis
|
||
|
|
| phoneme `elem` [B, D, G, Gj, Gw] -> Media
|
||
|
|
| phoneme `elem` [Bh, Dh, Gh, Gjh, Gwh] -> MediaAspirata
|
||
|
|
, place = if
|
||
|
|
| phoneme `elem` [P, B, Bh] -> Labial
|
||
|
|
| phoneme `elem` [T, D, Dh] -> Dental
|
||
|
|
| phoneme `elem` [Kj, Gj, Gjh] -> Palatal
|
||
|
|
| phoneme `elem` [K, G, Gh] -> Velar
|
||
|
|
| phoneme `elem` [Kw, Gw, Gwh] -> Labiovelar
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
someFunc :: IO ()
|
||
|
|
someFunc = Parsec.parseTest parseRoot [P, R, E, Kj]
|