1
0
forked from GitHub/gf-rgl
Files
gf-rgl/src/korean/ResKor.gf
2023-05-29 19:32:09 +02:00

397 lines
10 KiB
Plaintext

resource ResKor = ParamKor ** open Prelude, Predef, ParamKor in {
--------------------------------------------------------------------------------
-- Nouns
oper
Counter : Type = {
s : Str ;
origin : NumOrigin
} ;
baseCounter : Counter = {
s = "개" ;
origin = NK
} ;
mkCounter : Str -> NumOrigin -> Counter = \s,o -> baseCounter ** {
s = s ;
origin = o ;
} ;
BaseNoun : Type = {
s : NForm => Str ;
p : Phono ;
} ;
Noun : Type = BaseNoun ** {
c : Counter ;
} ;
Noun2 : Type = Noun ; -- TODO eventually more parameters?
Noun3 : Type = Noun ;
CNoun : Type = Noun ** {
rs : Str ; -- Relative clause comes before determiner
} ;
mkNoun : Str -> Noun = \str -> {
s = \\cas => str + allomorph cas str ;
p = if_then_else Phono (vowFinal str) Vowel Consonant ;
c = baseCounter
} ;
useN : Noun -> CNoun = \n -> n ** {
rs = []
} ;
---------------------------------------------
-- NP
NounPhrase = BaseNoun ** {
-- empty : Str ; -- standard trick for pro-drop
} ;
--------------------------------------------------------------------------------
-- Pronouns
Pronoun : Type = BaseNoun ** {
poss : Quant ;
} ;
mkPron = overload {
mkPron : (stem,poss : Str) -> Pronoun = \s,poss -> mkNoun s ** {
poss = mkQuant poss (poss ++ "것") ;
} ;
mkPron : (stem : Str) -> Pronoun = \s -> mkNoun s ** {
poss = mkQuant (s + "의") (s + "의" ++ "것") ;
}
} ;
--------------------------------------------------------------------------------
-- Det, Quant, Card, Ord
BaseQuant : Type = {
sp : NForm => Str ;
isPoss : Bool ;
p : Phono
} ;
Determiner : Type = BaseQuant ** {
s : NumOrigin => Str ; -- Chosen by the counter of CN
n : Number ;
numtype : NumType ; -- Whether its Num component is digit, numeral or Sg/Pl
} ;
Quant : Type = BaseQuant ** {
s : Str ;
} ;
Num : Type = {
s : NumOrigin -- Sino-Korean or native Korean
=> DForm -- Independent or attribute
=> Str ;
n : Number ;
numtype : NumType ; -- Digit, numeral or Sg/Pl
} ;
baseNum : Num = {
s = \\_,_ => [] ;
n = Sg ;
numtype = NoNum
} ;
Numeral : Type = Num ** {
ord : Str
} ;
baseQuant : BaseQuant = {
sp = \\_ => [] ;
isPoss = False ;
p = Vowel ;
} ;
mkQuant : (s,sp : Str) -> Quant = \s,sp -> baseQuant ** {
s = s ;
sp = (mkNoun sp).s ;
p = (mkNoun sp).p ;
} ;
mkDet : Str -> Number -> Determiner = \s,num -> baseQuant ** {
s = \\_ => (mkNoun s).s ! Bare ; -- NumOrigin irrelevant for non-numbers
sp = (mkNoun s).s ;
n = num ;
numtype = NoNum ;
} ;
plural : NForm => Str = table {
Bare => "들" ;
nf => "들" + allomorph nf "들"
} ;
--------------------------------------------------------------------------------
-- Postpositions
Postposition : Type = {s : Phono => Str ; attaches : Bool} ;
mkPrep : Str -> Postposition = \str -> {s=\\_ => str ; attaches=True} ;
mkPrep2 : (ro,euro : Str) -> Postposition = \ro,euro -> {
s = table {Vowel => ro ; Consonant => euro} ;
attaches = True
} ;
emptyPP : Postposition = mkPrep [] ** {attaches=False} ;
datPP : Postposition = mkPrep "에게" ;
--------------------------------------------------------------------------------
-- Adjectives
Adjective : Type = {
s : VForm => Str ; -- Adjectives are verbs
p, pNeg : Phono ; -- needed for attaching conjunction
} ;
Adjective2 : Type = Adjective ** {c2 : NForm ; p2 : Postposition} ;
v2a : (attrpos : Str) -> Verb -> Adjective = \attrpos,v -> v ** {
s = table {
VAttr Pos => attrpos ; -- Positive Attr is different in
vf => v.s ! vf } -- adjectives, otherwise adj forms == verb forms.
} ;
mkAdj : Str -> Adjective = \plain ->
let v : Verb = mkVerb plain ;
stem : Str = v.s ! VStem Pos ;
attrpos : Str = add_N stem ;
in v2a attrpos v ;
mkAdjReg : (x1,_,_,x4 : Str) -> Adjective = \plain,polite,formal,attr ->
v2a attr (mkVerbReg plain polite formal attr) ;
atoa2 : Adjective -> Adjective2 = \a -> a ** {c2=Bare ; p2=emptyPP} ;
AdjPhrase : Type = Adjective ** {compar : Str} ;
--------------------------------------------------------------------------------
-- Verbs
BaseVerb : Type = {
sc : NForm ; -- subject case
p, pNeg : Phono ; -- needed for attaching conjunction
} ;
Verb : Type = BaseVerb ** {
s : VForm => Str ;
} ;
Verb2 : Type = Verb ** {c2 : NForm ; p2 : Postposition} ;
Verb3 : Type = Verb2 ** {c3 : NForm ; p3 : Postposition} ;
-- VV : Type = Verb ** {vvtype : VVForm} ;
mkVerb : (plain : Str) -> Verb = \plain ->
let stem = init plain ;
informal = add_eo stem ; -- not used in grammar yet
polite = informal + "요" ;
formal = case vowFinal stem of {
True => add_B stem + "니다" ;
False => stem + "습니다" } ;
attrpos = stem + "는" ;
in mkVerbReg plain polite formal attrpos ;
mkVerb2 : (plain : Str) -> Verb2 = \plain -> vtov2 (mkVerb plain) ;
mkVerb3 : (plain : Str) -> Verb3 = \plain -> v2tov3 (mkVerb2 plain) ;
vtov2 : Verb -> Verb2 = \v -> v ** {c2 = Object ; p2 = emptyPP} ;
v2tov3 : Verb2 -> Verb3 = \v -> v ** {c3 = Bare ; p3 = datPP} ;
-- ㄹ-irregulars, ㅎ-irregular
mkVerbReg : (x1,_,_,x4 : Str) -> Verb =
\plain,polite,formal,attrpos ->
let stem = init plain ;
neg = stem + "지" ;
attrneg = neg ++ "않는" ;
planeg = neg ++ negForms ! Plain ;
polneg = neg ++ negForms ! Polite ;
formneg = neg ++ negForms ! Formal ;
impneg = neg ++ "마새요" ;
in mkVerbFull stem attrpos attrneg plain polite formal planeg polneg formneg impneg ;
mkVerbFull : (x1,_,_,_,_,_,_,_,_,x10 : Str) -> Verb =
\stem,attrpos,attrneg,plain,polite,formal,planeg,polneg,formneg,impneg -> {
s = table {
VStem Pos => stem ;
VStem Neg => init planeg ;
VAttr Pos => attrpos ;
VAttr Neg => attrneg ;
VF Plain Pos => plain ;
VF Plain Neg => planeg ;
VF Polite Pos => polite ;
VF Polite Neg => polneg ;
VF Formal Pos => formal ;
VF Formal Neg => formneg ;
VImpNeg => impneg
} ;
sc = Subject ;
p = if_then_else Phono (vowFinal stem) Vowel Consonant ;
pNeg = if_then_else Phono (vowFinal (init planeg)) Vowel Consonant ;
} ;
copula : Verb = mkVerbFull
"이"
"인"
"아닌"
"이다"
"이에요"
"입니다"
"아니다"
"아니에요"
"아닙니다"
"있지마세요" ;
copulaAfterVowel : Verb = copula ** {
s = \\vf => case vf of {
VAttr Pos => "는" ; -- TODO just guessing
VF Plain Pos => "다" ;
VF Polite Pos => "예요" ;
_ => copula.s ! vf }
} ;
have_V : Verb = mkVerbFull
"있"
"있는"
"없는"
"있다"
"있어요"
"있습니다"
"없다"
"없어요"
"없습니다"
"없지 마새요" ;
-- For building an adjective. Different attr from do_V.
do_A : Verb = mkVerbReg
"하다"
"해요"
"합니다"
"한" ;
hada_A = do_A ; -- Exposing both names (hada=transliteration, do=translation)
do_V : Verb = mkVerbReg
"하다"
"해요"
"합니다"
"하는" ;
negForms : Style => Str =
table { Plain => "않다" ;
Polite => "않아요" ;
Formal => "않습니다" } ;
------------------
-- Adv
Adverb : Type = SS ;
prepNP : NForm -> Postposition -> NounPhrase -> Adverb = \nf,pp,np -> {
s = case pp.attaches of {
True => glue (np.s ! nf) (pp.s ! np.p) ;
False => np.s ! nf ++ (pp.s ! np.p)}
} ;
------------------
-- Conj
Conj : Type = {
s1, s2 : Str ;
c : ConjType ; -- if it's And, Or, …
-- Need to add conjunction already in ConsX funs.
n : Number ;
} ;
-- Do not remove this. Used in a particular application grammar.
commaConj : Conj = {
s1, s2 = [] ;
c = Comma ;
n = Pl ;
} ;
------------------
-- VP
Complement : Type = {
s : VForm => Str ;
} ;
emptyComp : Complement = {
s = \\_ => [] ;
} ;
BaseVP : Type = {
adv,
vComp : Str ;
nObj : ObjectForm => Str ; -- may need diff form for imperative vs. declarative sentences
} ;
baseVP : BaseVP = {
adv,
vComp = [] ;
nObj = \\_ => []
} ;
VerbPhrase : Type = BaseVerb ** Complement ** BaseVP ;
VPSlash : Type = Verb2 ** BaseVP ;
useV : Verb -> VerbPhrase = \v -> baseVP ** v ;
useVc : Verb2 -> VPSlash = \v2 -> baseVP ** v2 ;
insertComp : VPSlash -> NounPhrase -> VerbPhrase = \v2,np -> useV v2 ** {
nObj = table {
DeclObj => np.s ! v2.c2 ++ v2.p2.s ! np.p ;
ImpObj => np.s ! Object ++ v2.p2.s ! np.p } -- use 을/를 always for imperative
} ;
insertAdv : VerbPhrase -> SS -> VerbPhrase = \vp,adv -> vp ** {adv = adv.s ++ vp.adv} ;
insertAdvSlash : VPSlash -> SS -> VPSlash = \v,a -> v ** insertAdv v a ;
--------------------------------------------------------------------------------
-- Cl, S
Clause : Type = {
s : Tense => Anteriority => Polarity => ClType => Str ;
p, pNeg : Phono} ;
{- After PredVP, we might still want to add more adverbs (QuestIAdv),
but we're done with verb inflection.
-}
ClSlash : Type = Clause ;
QClause : Type = Clause ;
RClause : Type = Clause ;
Sentence : Type = {
s : ClType => Str ;
p : Phono -- Needed for attaching conjunction
} ;
predVP : NounPhrase -> VerbPhrase -> ClSlash = \np,vp ->
let npstr : Str = np.s ! vp.sc in predVP' npstr vp ;
predVP' : (np : Str) -> VerbPhrase -> ClSlash = \np,vp -> vp ** {
s = \\t,a,p,cltyp =>
let vf = case cltyp of {
Subord => VAttr p ;
WithConj => VStem p ;
Statement st => VF st p } -- TODO: more tenses
in np
++ vp.nObj ! DeclObj -- an object, not copula complement
++ vp.adv
++ vp.s ! vf
} ;
--------------------------------------------------------------------------------
-- linrefs
linVerb : Verb -> Str = \v -> v.s ! VF Polite Pos ;
linVP : VForm -> VerbPhrase -> Str = \vf,vp -> vp.nObj ! DeclObj ++ vp.adv ++ vp.s ! vf ;
linImp : Polarity -> VerbPhrase -> Str = \pol,vp ->
let vf : VForm = case pol of {
Pos => VF Polite Pos ;
Neg => VImpNeg }
in vp.nObj ! ImpObj ++ vp.adv ++ vp.s ! vf ;
linAP : AdjPhrase -> Str = \ap -> ap.compar ++ ap.s ! linVF ;
}