forked from GitHub/gf-rgl
397 lines
10 KiB
Plaintext
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 ;
|
|
}
|