mirror of
https://github.com/GrammaticalFramework/gf-rgl.git
synced 2026-05-28 01:18:57 -06:00
Atempted at implementing all the remaining Functions under Noun.gf and its dependencies in CatCgg.gf, LexiconCgg.gf, ParadigmCgg.gf, StructuralCgg.gf and ResCgg.gf
This commit is contained in:
@@ -71,8 +71,10 @@ lincat
|
|||||||
IAdv = {s : Str ; requiresSubjPrefix: Bool};
|
IAdv = {s : Str ; requiresSubjPrefix: Bool};
|
||||||
IDet = {s : Str ; n : Res.Number; requiresSubjPrefix: Bool};
|
IDet = {s : Str ; n : Res.Number; requiresSubjPrefix: Bool};
|
||||||
IQuant = {s : Res.Number =>Str ; requiresSubjPrefix: Bool};
|
IQuant = {s : Res.Number =>Str ; requiresSubjPrefix: Bool};
|
||||||
DAP = Res.Determiner ;
|
DAP = Res.Determiner ;
|
||||||
|
N2 = Res.Noun ** {c2 : Res.Agreement =>Str}; -- relational noun e.g. "son"
|
||||||
|
Prep = Res.Preposition; -- preposition, or just case e.g. "in"
|
||||||
|
N3 = N2 ** {c3 : Res.Agreement =>Str};
|
||||||
--VV =
|
--VV =
|
||||||
|
|
||||||
linref
|
linref
|
||||||
|
|||||||
@@ -131,8 +131,22 @@ lin
|
|||||||
|
|
||||||
--today_Adv = mkAdv "erizooba" AgrNo;
|
--today_Adv = mkAdv "erizooba" AgrNo;
|
||||||
|
|
||||||
|
father_N2 = mkN2 (mkN "tata" MU_BA) (mkPrep [] [] True) ;
|
||||||
|
|
||||||
|
distance_N3 = mkN3 (mkN "oburaingwa" ZERO_BU) (mkPrep "kurunga" "" False) (mkPrep "mpáka" "" False);
|
||||||
|
|
||||||
|
|
||||||
|
oper
|
||||||
|
aboutP = mkPrep "about" ;
|
||||||
|
atP = mkPrep "at" ;
|
||||||
|
forP = mkPrep "for" ;
|
||||||
|
fromP = mkPrep "kurunga" "" False;
|
||||||
|
inP = mkPrep "omu" "omuri" False;
|
||||||
|
onP = mkPrep "aha" "ahari" False;
|
||||||
|
toP = mkPrep "aha" [] False;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{-
|
{-
|
||||||
--Old LexiconCgg.gf
|
--Old LexiconCgg.gf
|
||||||
|
|||||||
@@ -89,11 +89,18 @@ lin
|
|||||||
RelNP np rs ={s = \\c => np.s ! c ++ rs.s; agr =np.agr};
|
RelNP np rs ={s = \\c => np.s ! c ++ rs.s; agr =np.agr};
|
||||||
-- The determiner has a fine-grained structure, in which a 'nucleus'
|
-- The determiner has a fine-grained structure, in which a 'nucleus'
|
||||||
-- quantifier and an optional numeral can be discerned.
|
-- quantifier and an optional numeral can be discerned.
|
||||||
--DetQuant : Quant -> Num -> Det ; -- these five
|
--DetQuant : Quant -> Num -> Det ; -- these five
|
||||||
DetQuant quant num = {s=[]; s2 = quant.s2; ntype = Incomplete; num = num.n; pos=PreDeterminer; doesAgree = quant.doesAgree}; --
|
DetQuant quant num = {s=[]; s2 = quant.s2; ntype = Incomplete; num = num.n; pos=PreDeterminer; doesAgree = quant.doesAgree}; --
|
||||||
|
|
||||||
--DetQuantOrd : Quant -> Num -> Ord -> Det ; -- these five best
|
--DetQuantOrd : Quant -> Num -> Ord -> Det ; -- these five best
|
||||||
--DetQuantOrd quant num ord = {};
|
DetQuantOrd quant num ord = {
|
||||||
|
s =[];
|
||||||
|
s2 =\\agr => mkThis!agr ++ quant.s2 ! agr ++ ord.s!agr;
|
||||||
|
ntype = Complete;
|
||||||
|
num = num.n;
|
||||||
|
pos = PreDeterminer;
|
||||||
|
doesAgree = True
|
||||||
|
};
|
||||||
|
|
||||||
NumSg = {s=[]; n=Sg}; --Num
|
NumSg = {s=[]; n=Sg}; --Num
|
||||||
NumPl = {s=[]; n=Pl}; --Num
|
NumPl = {s=[]; n=Pl}; --Num
|
||||||
@@ -126,19 +133,69 @@ lin
|
|||||||
--3 Conjoinable determiners and ones with adjectives
|
--3 Conjoinable determiners and ones with adjectives
|
||||||
|
|
||||||
--AdjDAP : DAP -> AP -> DAP ; -- the large (one)
|
--AdjDAP : DAP -> AP -> DAP ; -- the large (one)
|
||||||
{-
|
|
||||||
AdjDAP dap ap ={
|
AdjDAP dap ap =
|
||||||
s = dap.s ++ ap.s ;
|
{ s = dap.s ++ ap.s ;
|
||||||
s2: Res.Agreement;
|
s2 = dap.s2;
|
||||||
ntype : NounState ;
|
ntype = dap.ntype ;
|
||||||
num : Number ;
|
num = dap.num ;
|
||||||
pos : Position;
|
pos = dap.pos;
|
||||||
doesAgree: Bool };
|
doesAgree= True
|
||||||
-}
|
};
|
||||||
--DetDAP : Det -> DAP ; -- this (or that)
|
|
||||||
|
--DetDAP : Det -> DAP ; -- this (or that)
|
||||||
|
DetDAP det =det;
|
||||||
|
|
||||||
|
--AdNum : AdN -> Card -> Card ; -- almost 51
|
||||||
|
AdNum adn card = {s = \\a => adn.s ++ card.s ! a; n = card.n};
|
||||||
|
--ComplN2 : N2->NP -> CN
|
||||||
|
|
||||||
|
ComplN2 n2 np =
|
||||||
|
{ s = \\n, ns => n2.s ! n ! ns ++ n2.c2 ! mkAgreement n2.gender P1 n ++ np.s !Acc;
|
||||||
|
gender=n2.gender};
|
||||||
|
--ComplN3 : N3 -> NP -> N2 ; -- distance from this city (to Paris)
|
||||||
|
|
||||||
|
ComplN3 n3 np =
|
||||||
|
{s = \\n, ns => n3.s ! n ! ns ++ n3.c2 ! mkAgreement n3.gender P1 n ++ np.s !Acc;
|
||||||
|
c2 = n3.c3;
|
||||||
|
gender=n3.gender};
|
||||||
|
|
||||||
|
--2 Apposition
|
||||||
|
|
||||||
|
-- This is certainly overgenerating.
|
||||||
|
|
||||||
|
--ApposCN : CN -> NP -> CN ; -- city Paris (, numbers x and y)
|
||||||
|
ApposCN cn np ={s = \\n, ns => cn.s! n!ns ++ np.s !Nom; gender = cn.gender};
|
||||||
|
-- This is different from the partitive, as shown by many languages.
|
||||||
|
|
||||||
|
--CountNP : Det -> NP -> NP ; -- three of them, some of the boys
|
||||||
|
CountNP det np = case det.doesAgree of {
|
||||||
|
True => {s=\\c=> np.s!c ++ det.s2 ! np.agr; agr = np.agr};
|
||||||
|
False => {s=\\c=> np.s!c ++ det.s; agr = np.agr}
|
||||||
|
};
|
||||||
|
|
||||||
|
--Determiners can form noun phrases directly.
|
||||||
|
--DetNP : Det -> NP ; -- these five
|
||||||
|
DetNP det = case det.doesAgree of {
|
||||||
|
True => {s=\\_=> det.s2 ! AgP3 Sg KI_BI; agr = AgP3 Sg KI_BI};
|
||||||
|
False => {s=\\c=> det.s; agr = AgP3 Sg KI_BI}
|
||||||
|
};
|
||||||
|
-- Nouns can also be modified by embedded sentences and questions.
|
||||||
|
-- For some nouns this makes little sense, but we leave this for applications
|
||||||
|
-- to decide. Sentential complements are defined in [Verb Verb.html].
|
||||||
|
--SentCN : CN -> SC -> CN
|
||||||
|
SentCN cn sc = {s = \\ n, ns => cn.s!n!ns ++ sc.s; gender = cn.gender};
|
||||||
|
|
||||||
|
|
||||||
|
-- Relational nouns can also be used without their arguments.
|
||||||
|
-- The semantics is typically derivative of the relational meaning.
|
||||||
|
|
||||||
|
--UseN2 : N2 -> CN ; -- mother
|
||||||
|
UseN2 n2 = {s = n2.s; gender = n2.gender};
|
||||||
|
--Use2N3 : N3 -> N2 ; -- distance (from this city)
|
||||||
|
Use2N3 n3 = {s = n3.s; gender = n3.gender; c2 = n3.c2};
|
||||||
|
--Use3N3 : N3 -> N2 ; -- distance (to Paris)
|
||||||
|
Use3N3 n3 = {s = n3.s; gender = n3.gender; c2 = n3.c3};
|
||||||
{-
|
{-
|
||||||
--1 Noun: Nouns, noun phrases, and determiners
|
--1 Noun: Nouns, noun phrases, and determiners
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,40 @@ oper
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
--3 Relational nouns
|
||||||
|
|
||||||
|
mkN2 : overload {
|
||||||
|
mkN2 : Str -> N2 ; -- reg. noun, prep. "of" --%
|
||||||
|
mkN2 : N -> N2 ; -- e.g. wife of (default prep. to)
|
||||||
|
mkN2 : N -> Str -> N2 ; -- access to --%
|
||||||
|
mkN2 : N -> Prep -> N2 ; -- e.g. access to
|
||||||
|
mkN2 : Str -> Str -> N2 ; -- access to (regular noun) --%
|
||||||
|
} ;
|
||||||
|
|
||||||
|
--3 Relational nouns
|
||||||
|
|
||||||
|
mkN2 : overload {
|
||||||
|
mkN2 : Str -> N2; -- reg. noun, prep. "of" --%
|
||||||
|
mkN2 : N -> N2 ; -- e.g. wife of (default prep. to)
|
||||||
|
mkN2 : N -> Str -> N2 ; -- access to --%
|
||||||
|
mkN2 : N -> Prep -> N2 ; -- e.g. access to
|
||||||
|
mkN2 : Str -> Str -> N2 ; -- access to (regular noun) --%
|
||||||
|
} ;
|
||||||
|
|
||||||
|
mkN2 : N -> Prep -> N2 ;
|
||||||
|
mkN2 : N -> Prep -> N2 = \n,p -> case p.isGenPrep of{
|
||||||
|
False => n ** {c2 =\\_=> p.s; lock_N2 = <>} ;
|
||||||
|
True => n ** {c2 = mkGenPrepWithIVClitic; lock_N2 = <>}
|
||||||
|
};
|
||||||
|
-- Three-place relational nouns ("the connection from x to y") need two prepositions.
|
||||||
|
|
||||||
|
mkN3 : N -> Prep -> Prep -> N3 ; -- e.g. connection from x to y
|
||||||
|
mkN3 = \n,p,q -> case <p.isGenPrep,q.isGenPrep> of{
|
||||||
|
<False,False> => n ** {c2 =\\_=> p.s; c3 =\\_=> q.s; lock_N3 = <>} ;
|
||||||
|
<True, False> => n ** {c2 = mkGenPrepWithIVClitic ; c3 =\\_=> q.s; lock_N3 = <>} ;
|
||||||
|
<Fasle,True> => n ** {c2 =\\_=> p.s ; c3 = mkGenPrepWithIVClitic; lock_N3 = <>} ;
|
||||||
|
<True,True> => n ** {c2 = mkGenPrepWithIVClitic; c3 = mkGenPrepWithIVClitic; lock_N3 = <>}
|
||||||
|
};
|
||||||
{-
|
{-
|
||||||
prepV2 v p = lin V2 {s = v.s ; p = v.p ; c2 = p.s ; isRefl = v.isRefl} ;
|
prepV2 v p = lin V2 {s = v.s ; p = v.p ; c2 = p.s ; isRefl = v.isRefl} ;
|
||||||
dirV2 v = prepV2 v noPrep ;
|
dirV2 v = prepV2 v noPrep ;
|
||||||
|
|||||||
@@ -346,7 +346,77 @@ mkSubjPrefix : Agreement -> Str =\a ->case a of {
|
|||||||
_ => mkClitic "SubjNotKnown" --for checking if there is some class unaccounted for
|
_ => mkClitic "SubjNotKnown" --for checking if there is some class unaccounted for
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mkSubjCliticTableSg : Agreement => Str = table {
|
||||||
|
AgMUBAP1 Sg => mkClitic "n" ;
|
||||||
|
--AgMUBAP1 Pl => "tu" ;
|
||||||
|
AgMUBAP2 Sg => mkClitic "o" ;
|
||||||
|
--AgMUBAP2 Pl => "mu" ;
|
||||||
|
AgP3 Sg MU_BA => mkClitic "a";
|
||||||
|
--AgP3 Pl MU_BA => "ba" ;
|
||||||
|
AgP3 Sg KI_BI => mkClitic "ki" ;
|
||||||
|
--AgP3 Pl (KI_BI | ZERO_BI) => mkClitic "bi" ;
|
||||||
|
AgP3 Sg (RU_N | RU_MA | RU_ZERO | RU_BU) => mkClitic "ru" ;
|
||||||
|
--AgP3 Pl RU_N => mkClitic "zi"; --| "i";
|
||||||
|
AgP3 Sg N_N => mkClitic "e";
|
||||||
|
--AgP3 Pl N_N => mkClitic "zi"; --| "i";
|
||||||
|
AgP3 Sg (MU_MI | MU_ZERO) => mkClitic "gu" ;
|
||||||
|
--AgP3 Pl MU_MI => "e" ;
|
||||||
|
AgP3 Sg (RI_MA | RI_ZERO | I_ZERO) =>mkClitic "ri";
|
||||||
|
--AgP3 Pl (RI_MA | BU_MA | KU_MA | ZERO_MA | I_MA |RU_MA) => mkClitic "ga" ;
|
||||||
|
AgP3 Sg (KA_BU | KA_ZERO | KA_TU) => mkClitic "ka" ;
|
||||||
|
--AgP3 Pl (KA_BU | RU_BU) => mkClitic "bu" ;
|
||||||
|
AgP3 Sg ZERO_BU => mkClitic "bu" ;
|
||||||
|
--AgP3 Pl ZERO_BU => mkClitic "bu" ;
|
||||||
|
AgP3 Sg ZERO_BI => mkClitic "bi" ;
|
||||||
|
AgP3 Sg ZERO_MA => mkClitic "ga" ;
|
||||||
|
--AgP3 Pl RI_ZERO => mkClitic "ga" ;
|
||||||
|
AgP3 Sg KU_ZERO => mkClitic "ku" ;
|
||||||
|
--AgP3 Pl KU_ZERO => mkClitic "ku" ;
|
||||||
|
--AgP3 Pl MU_ZERO => mkClitic "gu" ;
|
||||||
|
--AgP3 Pl RU_ZERO => mkClitic "ru" ;
|
||||||
|
AgP3 Sg ZERO_TU => mkClitic "tu" ;
|
||||||
|
--AgP3 Pl ZERO_TU => mkClitic "tu" ;
|
||||||
|
AgP3 Sg (ZERO_MI | ZERO_ZERO) => mkClitic "" ;
|
||||||
|
--AgP3 Pl ZERO_MI => mkClitic "e" ;
|
||||||
|
--AgP3 Pl KA_ZERO => mkClitic "" ;
|
||||||
|
_ => mkClitic "Non-Signular" --for checking if there is some class unaccounted for
|
||||||
|
};
|
||||||
|
|
||||||
|
mkSubjCliticTablePl : Agreement => Str = table {
|
||||||
|
--AgMUBAP1 Sg => mkClitic "n" ;
|
||||||
|
AgMUBAP1 Pl => mkClitic "tu" ;
|
||||||
|
--AgMUBAP2 Sg => mkClitic "o" ;
|
||||||
|
AgMUBAP2 Pl => mkClitic "mu" ;
|
||||||
|
--AgP3 Sg MU_BA => mkClitic "a";
|
||||||
|
AgP3 Pl MU_BA => mkClitic "ba" ;
|
||||||
|
--AgP3 Sg KI_BI => mkClitic "ki" ;
|
||||||
|
AgP3 Pl (KI_BI | ZERO_BI) => mkClitic "bi" ;
|
||||||
|
--AgP3 Sg (RU_N | RU_MA | RU_ZERO | RU_BU) => mkClitic "ru" ;
|
||||||
|
AgP3 Pl RU_N => mkClitic "zi"; --| "i";
|
||||||
|
--AgP3 Sg N_N => mkClitic "e";
|
||||||
|
AgP3 Pl N_N => mkClitic "zi"; --| "i";
|
||||||
|
--AgP3 Sg (MU_MI | MU_ZERO) => mkClitic "gu" ;
|
||||||
|
AgP3 Pl MU_MI => "e" ;
|
||||||
|
--AgP3 Sg (RI_MA | RI_ZERO | I_ZERO) =>mkClitic "ri";
|
||||||
|
AgP3 Pl (RI_MA | BU_MA | KU_MA | ZERO_MA | I_MA |RU_MA) => mkClitic "ga" ;
|
||||||
|
--AgP3 Sg (KA_BU | KA_ZERO | KA_TU) => mkClitic "ka" ;
|
||||||
|
AgP3 Pl (KA_BU | RU_BU) => mkClitic "bu" ;
|
||||||
|
--AgP3 Sg ZERO_BU => mkClitic "bu" ;
|
||||||
|
AgP3 Pl ZERO_BU => mkClitic "bu" ;
|
||||||
|
--AgP3 Sg ZERO_BI => mkClitic "bi" ;
|
||||||
|
--AgP3 Sg ZERO_MA => mkClitic "ga" ;
|
||||||
|
AgP3 Pl RI_ZERO => mkClitic "ga" ;
|
||||||
|
--AgP3 Sg KU_ZERO => mkClitic "ku" ;
|
||||||
|
AgP3 Pl KU_ZERO => mkClitic "ku" ;
|
||||||
|
AgP3 Pl MU_ZERO => mkClitic "gu" ;
|
||||||
|
AgP3 Pl RU_ZERO => mkClitic "ru" ;
|
||||||
|
--AgP3 Sg ZERO_TU => mkClitic "tu" ;
|
||||||
|
AgP3 Pl ZERO_TU => mkClitic "tu" ;
|
||||||
|
--AgP3 Sg (ZERO_MI | ZERO_ZERO) => mkClitic "" ;
|
||||||
|
AgP3 Pl ZERO_MI => mkClitic "e" ;
|
||||||
|
AgP3 Pl KA_ZERO => mkClitic "" ;
|
||||||
|
_ => mkClitic "Plural" --for checking if there is some class unaccounted for
|
||||||
|
};
|
||||||
{-Object particle may be used as
|
{-Object particle may be used as
|
||||||
1. a prefix: e.g mu-kwate = catch him,
|
1. a prefix: e.g mu-kwate = catch him,
|
||||||
2. an infix: o-mu-kwate = you catch him
|
2. an infix: o-mu-kwate = you catch him
|
||||||
@@ -969,10 +1039,13 @@ mkSubjPrefix : Agreement -> Str =\a ->case a of {
|
|||||||
PolTemp = {s : Agreement => Str * Str ; end : Str} ; -- a tupple of two strings
|
PolTemp = {s : Agreement => Str * Str ; end : Str} ; -- a tupple of two strings
|
||||||
|
|
||||||
-- Structural
|
-- Structural
|
||||||
Preposition = {s,other : Str}; -- prepositions sometimes have two kinds
|
-- prepositions sometimes have two kinds, near or far i.e omu or omuri
|
||||||
mkPrep : Str -> Str -> Preposition = \ first, other -> {
|
-- ho
|
||||||
|
Preposition = {s,other : Str; isGenPrep : Bool};
|
||||||
|
mkPrep : Str -> Str ->Bool -> Preposition = \ first, other, isGenPrep -> {
|
||||||
s = first ;
|
s = first ;
|
||||||
other = other
|
other = other;
|
||||||
|
isGenPrep = isGenPrep
|
||||||
};
|
};
|
||||||
NounPhrase : Type = {s :Case => Str; agr : Agreement};
|
NounPhrase : Type = {s :Case => Str; agr : Agreement};
|
||||||
{-
|
{-
|
||||||
|
|||||||
@@ -35,20 +35,20 @@ lin
|
|||||||
agr = AgrNo
|
agr = AgrNo
|
||||||
}; --mkPron "kyo" "kyo" (AgP3 Sg KI_BI); -- should form an it_Pron_NClass in extra module
|
}; --mkPron "kyo" "kyo" (AgP3 Sg KI_BI); -- should form an it_Pron_NClass in extra module
|
||||||
|
|
||||||
behind_Prep ={s="enyuma ya"};
|
behind_Prep = mkPrep "enyuma ya" [] False;
|
||||||
between_Prep = {s="hagati ya"};
|
between_Prep =mkPrep "hagati ya" [] False;
|
||||||
to_Prep ={s="aha"};
|
to_Prep = mkPrep "aha" [] False;
|
||||||
-- several words depending on use omuri??
|
-- several words depending on use omuri??
|
||||||
in_Prep = mkPrep "omu" "omuri";
|
in_Prep = mkPrep "omu" "omuri" False;
|
||||||
--aha-ri Kamukuzi??? works for places
|
--aha-ri Kamukuzi??? works for places
|
||||||
on_Prep = mkPrep "aha" "ahari";
|
on_Prep = mkPrep "aha" "ahari" False;
|
||||||
|
|
||||||
--na --please this string varies with vowels use combine_morphemes or
|
--na --please this string varies with vowels use combine_morphemes or
|
||||||
--combine_words when using it.
|
--combine_words when using it.
|
||||||
with_Prep = mkPrep "na" [];
|
with_Prep = mkPrep "na" [] False;
|
||||||
|
|
||||||
from_Prep ={s="kuruga"};
|
from_Prep =mkPrep "kurunga" "" False;
|
||||||
under_Prep = {s="hansi ya"};
|
under_Prep = mkPrep "hansi ya" "" False;
|
||||||
|
|
||||||
---Structural
|
---Structural
|
||||||
{-
|
{-
|
||||||
@@ -173,6 +173,35 @@ lin
|
|||||||
how8many_IDet ={s ="ngahe"; other =[]; n =Pl; requiresSubjPrefix = False; endOfSentence = True};--: IDet ;
|
how8many_IDet ={s ="ngahe"; other =[]; n =Pl; requiresSubjPrefix = False; endOfSentence = True};--: IDet ;
|
||||||
|
|
||||||
which_IQuant ={s =\\_ =>"ha"; requiresSubjPrefix = False};--: IQuant ;
|
which_IQuant ={s =\\_ =>"ha"; requiresSubjPrefix = False};--: IQuant ;
|
||||||
|
|
||||||
|
|
||||||
|
almost_AdN = {s="hihi"}; --: AdN ; -- what about nika
|
||||||
|
at_least_AdN ={s= " hakiri"}; --: AdN ; --need advice from linguist. What about akakye?
|
||||||
|
|
||||||
|
{-
|
||||||
|
The following require some reflection from a linguist.
|
||||||
|
-}
|
||||||
|
someSg_Det =
|
||||||
|
{
|
||||||
|
s =[];
|
||||||
|
s2 =\\agr => mkSubjCliticTableSg ! agr ++ "mwe";
|
||||||
|
ntype = Complete;
|
||||||
|
num = Sg;
|
||||||
|
pos = PreDeterminer;
|
||||||
|
doesAgree = True
|
||||||
|
};
|
||||||
|
somePl_Det =
|
||||||
|
{
|
||||||
|
s =[];
|
||||||
|
s2 =\\agr => mkSubjCliticTablePl ! agr ++ "mwe";
|
||||||
|
ntype = Complete;
|
||||||
|
num = Pl;
|
||||||
|
pos = PreDeterminer;
|
||||||
|
doesAgree = True
|
||||||
|
};--: Det ;
|
||||||
|
--somebody_NP = {}; --: NP ;
|
||||||
|
--something_NP : NP ;
|
||||||
|
--somewhere_Adv : Adv ;
|
||||||
{-
|
{-
|
||||||
--1 Structural: Structural Words
|
--1 Structural: Structural Words
|
||||||
--
|
--
|
||||||
|
|||||||
Reference in New Issue
Block a user