module Language.Lojban.Lujvo (rafsis,fixClusters) where import Prelude hiding ((^),(*),(/),(+)) import Text.ParserCombinators.Parsec hiding (notFollowedBy) import Control.Monad import Control.Applicative ((<$>)) data Rafsi = ShortRafsi [Char] | Rafsi4Let [Char] | Rafsi5Let [Char] instance Show Rafsi where show (ShortRafsi e) = e show (Rafsi4Let e) = e show (Rafsi5Let e) = e fixClusters :: String -> String fixClusters xs = go xs [] where go (x:y:xs) acc | validCluster (x:y:[]) = go (y:xs) (acc++[x]) | otherwise = go (y:xs) (acc++[x]++"y") go [x] acc = go [] (acc++[x]) go [] acc = acc validCluster :: [Char] -> Bool validCluster = either (const False) (const True) . parse cluster "" cluster = do diphthong / (do consonant / vowel; consonant / vowel) rafsis :: String -> [String] rafsis s = case parse lujvo "" s of Right rs -> map show rs Left _ -> [] lujvo = ((rafsi5 ((cvc / ccv / cvv) > y)) rafsi4 = Rafsi4Let <$> (ct & (vt & ct / ct & vt) & ct <&anyChar <&!(y?)) rafsi5 = do (Rafsi4Let ls) <- rafsi4; v <- vowel; return $ Rafsi5Let (ls++v) cvc = ct & vt & ct <&anyChar <&!(y?) ccv = ct & ct & vt <&!(((r / n) <& consonant)?) cvv = ct & (diphthong / vt & h & vt) <&!(((r / n) <& consonant)?) ct = consonant vt = vowel syllabic = l / m / n / r consonant = voiced / unvoiced / syllabic diphthong = (a & i / a & u / e & i / o & i) >= return . (:[]) (+) p = many1 (try p) (*) p = many (try p) (>= unexpected . show) <|> return r) infixl 2 a1) infixl 1 / (&) a a1 = (do r <- a; r1 <- a1; return $ mplus r r1) infixl 4 & (<&) a a1 = do r <- a; lookAhead a1; return r infixl 2 <& (?) p = (try p <|> return mzero)