/// <summary> /// Calcula el paradigma per a paraules amb singular i plural. /// </summary> private ParadigmaCat Id2(string arrel, MorfoGram morfoGram, Dictionary<string, string> dades, Dictionary<string, string> exc) { // PERFER: mirar "dijous" bool admetArticle = (exc == null || !exc.ContainsKey("NOART")); string arrel0, arrel1; arrel0 = ParadigmaCat.Arrel0(arrel, out arrel1); if (arrel1 != arrel0) { // PER_FER: unificar amb Precalc() // Tenim una paraula amb trossos PC_multi par = new PC_multi(); string[] trossos = arrel.Split(' '); for (int i = 0; i < trossos.Length; i++) { if (trossos.Length == 0) continue; // PER_FER: la paraula pot tenir articles i preposicions Paraula ptros = new Paraula(trossos[i]); if (i == 0) par.Add(new PC_formaFixada("Entrada amb espais, primer tros", morfoGram, ptros, ptros.PotApostrofar(), ptros.PotApostrofar(morfoGram.Gen == MorfoGram.eGen.F))); else par.Add(new PC_formaFixada("Entrada amb espais, tros interior", morfoGram, ptros, false, false)); } return par; } Paraula paraula = new Paraula(arrel0); Debug.Assert(!paraula.Forma.Contains(" "), "No hi ha d'haver espais a l'arrel"); if (exc != null) { // suposam que el singular i el plural tenen el mateix valor de VocalInicial string plural = Dades(exc, "PLU"); if (plural != null) { if (plural.Contains(" ")) { // Hi ha més d'un plural string[] trossos = plural.Split(' '); PC_multi par = new PC_multi(); foreach (string tros in trossos) par.Add(new PC_plural_precalc(morfoGram, paraula, tros, paraula.VocalInicial, paraula.VocalInicial && admetArticle)); return par; } return new PC_plural_precalc(morfoGram, paraula, plural, paraula.VocalInicial, paraula.VocalInicial && admetArticle); } } string admet = String.Format("D{0}, L{1}", paraula.VocalInicial ? "+" : "-", paraula.VocalInicial && admetArticle ? "+" : "-"); if (morfoGram.Cat == MorfoGram.eCat.ADJ) { string id = null; if (paraula.VocalFinal && paraula.Aguda) id = "A2T, -ns, " + admet; else if (paraula.SxcFinal && paraula.Aguda) id = "A2T, -os, " + admet; else id = "A2T, -s, " + admet; return paradigmes[id]; } else // (no és un adjectiu, ho tractam com un nom) { string id = null; if (morfoGram.Gen == MorfoGram.eGen.F) { // exemples: mà, casa if (paraula.VocalFinal && paraula.Aguda) id = "NF, -ns, " + admet; else if (paraula.SxcFinal && paraula.Aguda) id = "NF, -s, " + admet; // PERFER: comprovar que el plural de "falç" és "falçs" else id = "NF, -s, " + admet; } else // (la paraula és masculina o no té gènere) { // exemples: ca, moix, peu if (paraula.VocalFinal && paraula.Aguda) id = "NM, -ns, " + admet; else if (paraula.SxcFinal && paraula.Aguda) id = "NM, -os, " + admet; else id = "NM, -s, " + admet; } return paradigmes[id]; } //throw new Exception("No sé què fer amb " + arrel); }
/// <summary> /// Calcula el paradigma per a adjectius i masculins/femenins. /// El resultat pot tenir dues terminacions (abacial), tres (feliç) o quatre (blanc). /// </summary> private ParadigmaCat Id4(string arrel, MorfoGram morfoGram, Dictionary<string, string> dades, Dictionary<string, string> exc) { bool admetArticle = (exc == null || !exc.ContainsKey("NOART")); string fem; string masc = ParadigmaCat.Arrel0(arrel, out fem); if (exc != null && exc.ContainsKey("PLU") && exc["PLU"].Contains(" ")) { string[] trossos = exc["PLU"].Split(' '); if (trossos.Length != 2) throw new Exception("S'esperaven dos trossos: " + exc["PLU"]); Dictionary<string, string> exc2 = new Dictionary<string, string>(exc); exc2["PLU"] = trossos[0]; ParadigmaCat parMasc = Id2(masc, morfoGram | mgMasc, dades, exc2); exc2["PLU"] = trossos[1]; ParadigmaCat parFem = Id2(fem, morfoGram | mgFem, dades, exc2); return new PC_multi(parMasc, parFem); } if (fem == masc) { // Si hi ha una forma, vol dir que és igual per al masculí i el femení, almenys en singular ParadigmaCat par = Id2(arrel, morfoGram, dades, exc); if (arrel.EndsWith("ç")) { // Si termina en 'ç', hi ha dues formes per al plural PC_multi pars = new PC_multi(par); Paraula fpl = new Paraula(arrel.Substring(0, arrel.Length - 1) + "ces"); pars.Add(new PC_formaFixada("plural en -ces", new MorfoGram(morfoGram.Cat, MorfoGram.eGen.F, MorfoGram.eNbre.PL), fpl, fpl.VocalInicial, false)); return pars; } else return par; } else // (fem != null) { Paraula pMasc = new Paraula(masc); foreach (char id in "FJBHKL") { if (id == 'H' && (!pMasc.Aguda || !pMasc.VocalFinal)) continue; Regla regla = regles.Llista[id.ToString()]; List<Mot> femenins = regla.Genera(masc, mgFemSg, regles, Marques.totes, true); if (femenins.Count == 0) continue; if (femenins.Exists(delegate(Mot mot) { return mot.Forma == fem; })) { string idPar = String.Format("{0}, MFSP, {1}, D{2}, L{3}", morfoGram.Cat == MorfoGram.eCat.ADJ ? "A" : "N", id.ToString(), pMasc.VocalInicial ? "+" : "-", pMasc.VocalInicial && admetArticle ? "+" : "-"); ParadigmaCat par = paradigmes[idPar]; Paraula pFem = new Paraula(fem); if (pFem.PotApostrofar(true)&& admetArticle) { MorfoGram mgFS = new MorfoGram(mgFemSg); mgFS.Cat = morfoGram.Cat; par = new PC_multi(par, new PC_formaFixada("femení singular, D+, L+", mgFS, pFem, true, true)); // PERFER: No hauríem d'admetre "d'" ja que està inclòs dins l'altre paradigma } return par; } } return new PC_multi(Id2(masc, mgMascSg, dades, exc), Id2(fem, mgFemSg, dades, exc)); } }
private void test_03(GrupTest arrel) { GrupTest grup = arrel.NouGrup("Eines per al català"); grup.NouTest("Comparacions simples", delegate(RTest resultat) { string[] mots = "a al alça alt cant canta cantà cantam cella cel·la celles cel·les".Split(" ".ToCharArray()); for (int i = 0; i < mots.Length; i++) { string m1 = mots[i]; resultat.Assert(Cat.Cmp(m1, m1) == 0, "{0} == {1}", m1, m1); for (int j = i + 1; j < mots.Length; j++) { string m2 = mots[j]; int cmp1 = Cat.Cmp(m1, m2); int cmp2 = Cat.Cmp(m2, m1); resultat.Assert((cmp1 < 0) && (cmp1 + cmp2 == 0), "{0} < {1} ({2}, {3})", m1, m2, cmp1, cmp2); } } }); grup.NouTest("Més comparacions I", delegate(RTest resultat) { string[] mots = "a1 a2 a3 a10 a30".Split(" ".ToCharArray()); for (int i = 0; i < mots.Length; i++) { string m1 = mots[i]; resultat.Assert(Cat.Cmp(m1, m1) == 0, "{0} == {1}", m1, m1); for (int j = i + 1; j < mots.Length; j++) { string m2 = mots[j]; int cmp1 = Cat.Cmp(m1, m2); int cmp2 = Cat.Cmp(m2, m1); resultat.Assert((cmp1 < 0) && (cmp1 + cmp2 == 0), "{0} < {1} ({2}, {3})", m1, m2, cmp1, cmp2); } } }); grup.NouTest("Més comparacions II", delegate(RTest resultat) { string str1 = "abstinguin/C"; string str2 = "abstinguin/Z"; resultat.Assert(Cat.Cmp(str1, str2) < 0, "{0} < {1}", str1, str2); }); grup.NouTest("Conversió a minúscules", delegate(RTest resultat) { string maj = "AÀBCÇDEÈÉFGHIÍÏJKLMNOÒÓPQRSTUÚÜVXYZaàbcçdeèéfghiíïjklmnoòópqrstuúüvxyz"; string min = "aàbcçdeèéfghiíïjklmnoòópqrstuúüvxyzaàbcçdeèéfghiíïjklmnoòópqrstuúüvxyz"; resultat.Esperat(min, Cat.Min(maj)); }); grup.NouTest("Divisió sil·làbica", delegate(RTest resultat) { string[] paraules = { "es/què/ieu", "hie/na", "ca/nya", "psi/cò/legs", "Àus/tri/a", "cui/nar", "xxx", "ha", "any", "i/ó", "i/ons", "i/o/nit/za/ci/ó", "" }; foreach (string s in paraules) { string forma = s.Replace("/", ""); Paraula sillabes = new Paraula(forma); string sil = String.Join("/", sillabes.Sillabes); resultat.Nota("\"{0}\" => \"{1}\", {2}", sillabes.Forma, sillabes.Prototip, sil); resultat.Esperat(s, sil); } }); grup.NouTest("Vocal inicial", delegate(RTest resultat) { string[] si = { "ara", "àrab", "humitat", "indi", "Henedina", "ARA", "ÀRAB", "HUMITAT", "INDI" }; foreach (string forma in si) { Paraula paraula = new Paraula(forma); resultat.Assert(Paraula.TeVocalInicial(forma) && paraula.VocalInicial, String.Format("\"{0}\" comença per vocal", forma)); } string[] no = { "casa", "hiena", "iode", "CASA", "HIENA", "IODE" }; foreach (string forma in no) { Paraula paraula = new Paraula(forma); resultat.Assert(!Paraula.TeVocalInicial(forma) && !paraula.VocalInicial, String.Format("\"{0}\" no comença per vocal", forma)); } }); grup.NouTest("Vocal final", delegate(RTest resultat) { string[] si = { "ara", "indi", "pagui", "ARA", "INDI", "PAGUI" }; foreach (string forma in si) { Paraula paraula = new Paraula(forma); resultat.Assert(paraula.VocalFinal, String.Format("\"{0}\" acaba per vocal", forma)); } string[] no = { "cau", "moix", "seguiu", "adscriu", "virrei", "CAU", "MOIX", "SEGUIU" }; foreach (string forma in no) { Paraula paraula = new Paraula(forma); resultat.Assert(!paraula.VocalFinal, String.Format("\"{0}\" no acaba per vocal", forma)); } }); grup.NouTest("Aguda", delegate(RTest resultat) { string[] si = { "pa", "ratolí", "forat", "PA", "RATOLÍ", "FORAT" }; foreach (string forma in si) { Paraula paraula = new Paraula(forma); resultat.Assert(paraula.Aguda, String.Format("\"{0}\" és aguda", forma)); } string[] no = { "panera", "rata", "pàmpol", "mèrlera", "PANERA", "RATA", "PÀMPOL", "MÈRLERA" }; foreach (string forma in no) { Paraula paraula = new Paraula(forma); resultat.Assert(!paraula.Aguda, String.Format("\"{0}\" no és aguda", forma)); } }); grup.NouTest("Síl·laba tònica", delegate(RTest resultat) { string[] paraules = { "aguiÀveu", "PA", "PÀMpol", "CAsa", "coLOR", "MÀquina" }; foreach (string forma in paraules) { Paraula paraula = new Paraula(forma.ToLower()); int tonica = paraula.Tonica; StringBuilder sb = new StringBuilder(); for (int i = 0; i < paraula.Sillabes.Length; i++) { string s = paraula.Sillabes[i]; if (i == tonica) sb.Append(s.ToUpper()); else sb.Append(s); } resultat.Nota("{0} => {1}", forma, sb); resultat.Esperat(forma, sb.ToString()); } }); grup.NouTest("Abans de la vocal tònica", delegate(RTest resultat) { string[] paraules = { "aguiÀVEU", "pA", "pÀMPOL", "cASA", "colOR", "mÀQUINA" }; foreach (string forma in paraules) { string minuscula = forma.ToLower(); Paraula paraula = new Paraula(minuscula); string preTonica = paraula.PreTonica; int mida = preTonica.Length; string nova = minuscula.Substring(0, mida) + minuscula.Substring(mida).ToUpper(); resultat.Nota("{0} => {1}", forma, nova); resultat.Esperat(forma, nova); } }); grup.NouTest("Es poden apostrofar", delegate(RTest resultat) { string[] noFemeninesSi = { "ara", "àrab", "indi", "unir" }; foreach (string forma in noFemeninesSi) { Paraula paraula = new Paraula(forma); resultat.Assert(paraula.PotApostrofar(), String.Format("\"{0}\" es pot apostrofar", forma)); } string[] noFemeninesNo = { "casa", "iode", "hiatus" }; foreach (string forma in noFemeninesNo) { Paraula paraula = new Paraula(forma); resultat.Assert(!paraula.PotApostrofar(), String.Format("\"{0}\" no es pot apostrofar", forma)); } string[] femeninesSi = { "índia", "alba", "hora", "ungla" }; foreach (string forma in femeninesSi) { Paraula paraula = new Paraula(forma); resultat.Assert(paraula.PotApostrofar(true), String.Format("\"{0}\" es pot apostrofar", forma)); } string[] femeninesNo = { "humitat", "casa", "il·lícita" }; foreach (string forma in femeninesNo) { Paraula paraula = new Paraula(forma); resultat.Assert(!paraula.PotApostrofar(true), String.Format("\"{0}\" no es pot apostrofar", forma)); } }); grup.NouTest("EsMin()", delegate(RTest resultat) { string[] si = { "un", "dos", "tres", "quatre-cinc", "" }; string[] no = { "Un", "DOS", "treS", "Quatre-cinc" }; foreach (string str in si) resultat.Assert(Cat.EsMin(str), "És minúscula"); foreach (string str in no) resultat.Assert(!Cat.EsMin(str), "No és minúscula"); }); }
/// <summary> /// Llegeix un fitxer com el generat pel web de tractament de propostes. /// Conté entrades en diversos formats: DIEC, topònims, antropònims, etc. /// </summary> private void LlegeixEntradesWeb(int mod, List<string> log, DateTime horaInici, Regles regles, List<Identificador> identificadors, List<Entrada> entrades) { var idDiec = new IdentificadorDIEC("web", regles, null); var idToponims = new IdentificadorToponims("web", regles); var idAntroponims = new IdentificadorAntroponims("web", regles, null); var idDiversos = new IdentificadorDiversos("web", regles); AfegeixLiniaLog("Llegeix les propostes del web", horaInici, log); var sr = new StreamReader(DirEntrades("web.txt"), Encoding.Default); var linies = new List<string>(); while (!sr.EndOfStream) linies.Add(sr.ReadLine()); var temp = DirEntrades("_part_web.txt"); // llista de topònims linies = TriaLinies(linies, temp, delegate(string lin) { Match m; if ((m = reTopo.Match(lin)).Success) return m.Groups["nom"].Value; else return ""; }); idToponims.LlegeixEntrades(temp, entrades, mod); // llista d'antropònims linies = TriaLinies(linies, temp, delegate(string lin) { Match m; if ((m = reAntro.Match(lin)).Success) { if (m.Groups["gen"].Value == "m") return m.Groups["nom"].Value; else { var nom = m.Groups["nom"].Value; var p = new Paraula(nom); return string.Format("{0}{1}", nom, p.PotApostrofar(true) ? " f" : ""); } } else return ""; }); idAntroponims.LlegeixEntrades(temp, entrades, mod); // llista de diversos linies = TriaLinies(linies, temp, delegate(string lin) { Match m; if ((m = reDivers.Match(lin)).Success) return m.Groups["nom"].Value; else return ""; }); idDiversos.LlegeixEntrades(temp, entrades, mod); // la resta, té el format DIEC TriaLinies(linies, temp, lin => lin); idDiec.LlegeixEntrades(temp, entrades, mod); if (File.Exists(temp)) File.Delete(temp); identificadors.Add(idToponims); identificadors.Add(idAntroponims); identificadors.Add(idDiversos); identificadors.Add(idDiec); }
/// <summary> /// Afegeix la forma femenina singular del participi amb el flag que permet posar-li l'article "l'", /// sempre que unaForma no comenci en "i" o "u" àtones. /// El paràmetre unaForma no ha de ser necessàriament el participi, sinó una paraula que es comporti /// igual que el el participi femení singular pel que fa a l'apostrofació. /// Si s'ha d'afegir la forma (femení singular del participi) a la llista, s'agafa dels ítems que ja hi /// a la llista. /// </summary> protected void AfegeixParFemSg(List<ItemDic> items, string unaForma, Marques filtre) { Paraula pForma = new Paraula(unaForma); if (pForma.PotApostrofar(true)) { List<Mot> parFem = GeneraMots(items, mgPartFemSg, filtre, true); foreach (Mot mot in parFem) AfegeixItem(items, mot.Forma, mgVerb, mot.Info, "V", "Y"); } }
public override void Genera(Dictionary<string, string> dades, Dictionary<string, string> excepcions, Marques filtre, List<ItemDic> items) { string arrel = dades["arrel"]; if (masc) { if (Paraula.TeVocalInicial(arrel)) AfegeixItem(items, arrel, mgMascSg, mgMascSg, "V", "Y"); else AfegeixItem(items, arrel, mgMascSg, mgMascSg); } else // (femení) { Paraula pArrel = new Paraula(arrel); if (pArrel.VocalInicial) { if (pArrel.PotApostrofar(true)) AfegeixItem(items, arrel, mgFemSg, mgFemSg, "V", "Y"); else AfegeixItem(items, arrel, mgFemSg, mgFemSg, "Y"); } else AfegeixItem(items, arrel, mgFemSg, mgFemSg); } }
public override void Genera(Dictionary<string, string> dades, Dictionary<string, string> excepcions, Marques filtre, List<ItemDic> items) { string arrel0, arrel1; arrel0 = Arrel0(dades["arrel"], out arrel1); int numArrel = (mgComuna.Gen == MorfoGram.eGen.F) ? 1 : 0; ItemDic item = new ItemDic((numArrel == 1) ? arrel1 : arrel0, regla); item.MesMorfoGram(mgComuna, mgArrel); if (admetD) item.MesFlags("Y"); if (admetL) { if (numArrel == 0) item.MesFlags("V"); else { Paraula paraula = new Paraula(arrel1); if (paraula.PotApostrofar(true)) item.MesFlags("V"); } } items.Add(item); }