public static List<ItemDic> GeneraItemsDic(IEnumerable<Entrada> entrades, Marques filtre, Speller speller, Comparison<string> comparador) { List<ItemDic> llista = new List<ItemDic>(); Marques filtreExc = new Marques(filtre); Dictionary<string, string> dades; foreach (Entrada ent in entrades) { if (!filtre.Conte(ent.Marques)) continue; List<ItemDic> ids = new List<ItemDic>(); Paradigma par = null; if (ent.Excepcions == null) { par = ent.Identificador.IdentificaParadigma(ent.Dades, null); ids.AddRange(par.GeneraDic(ent.Dades, null, filtre, speller)); llista.AddRange(ids); } else { for (int g = 1; g <= 2; g++) { Marca grup = (g == 1) ? Marca.grup1 : Marca.grup2; if (!ent.Excepcions.Contingut.Conte(grup)) continue; filtreExc.Menys(Marca.grups12); filtreExc.Mes(grup); Dictionary<string, string> excepcions = ent.Excepcions.Contingut.Valors(filtreExc); dades = new Dictionary<string, string>(ent.Dades); if (excepcions.ContainsKey("MODEL")) { string[] model = excepcions["MODEL"].Split('/'); if (excepcions.Count == 1) AplicaModel(dades, out excepcions, model, ent.Identificador.Excepcio(model[0]).Contingut, filtreExc); else { // A part del model, hi ha més dades Dictionary<string, string> excepcionsOriginals = new Dictionary<string,string>(excepcions); AplicaModel(dades, out excepcions, model, ent.Identificador.Excepcio(model[0]).Contingut, filtreExc); foreach (KeyValuePair<string, string> kv in excepcionsOriginals) excepcions[kv.Key] = kv.Value; } } if (excepcions.ContainsKey("IGNORA")) // sempre deu ser IGNORA=1 continue; if (excepcions.ContainsKey("ALT")) dades["arrel"] = excepcions["ALT"]; if (excepcions.ContainsKey("NOVACAT")) dades["cat1"] = excepcions["NOVACAT"]; par = ent.Identificador.IdentificaParadigma(dades, excepcions); ids.AddRange(par.GeneraDic(dades, excepcions, filtre, speller)); } llista.AddRange(ids); } foreach (ItemDic id in ids) { id.Entrada = ent; if (id.Paradigma == null) id.Paradigma = par; } } llista.Sort(delegate(ItemDic id1, ItemDic id2) { return comparador(id1.Arrel, id2.Arrel); }); return llista; }
public override string Cont(Marques filtre) { if (filtre.Conte(marques) && ((object)excepte == null || !filtre.Conte(excepte))) return cont; else return null; }
/// <summary> /// Genera una llista de GrupMyspell /// </summary> public List<ReglaMyspell> GrupsMyspell(Regles regles, Marques filtre, GetAfinaReglaMyspell getAfina) { List<ReglaMyspell> grups = new List<ReglaMyspell>(); foreach (CasRegla cas in casos) { if (!filtre.Conte(cas.Marca)) continue; ReglaMyspell grup = grups.Find(delegate(ReglaMyspell g) { return g.CasPertany(cas); }); if (grup == null) { grup = new ReglaMyspell(this, regles, getAfina); grups.Add(grup); } grup.NouCas(cas); } return grups; }
/// <summary> /// Genera mots a partir d'una arrel. Els mots creats s'afegeixen a la llista donada. /// </summary> /// <param name="mots">La llista que recull els mots creats.</param> /// <param name="arrel">L'arrel a la qual s'ha d'aplicar el cas.</param> /// <param name="infoComuna">Informació morfològica que s'ha d'afegir a la del cas. /// Pot ser informació comuna a totes les formes d'una entrada.</param> /// <param name="regles">Llista de regles en vigor, per si està definit mesRegles</param> /// <param name="filtre">Només es generen mots que tenen marques contingudes en aquest filtre.</param> /// <param name="nomesAfixos">Si és true, només s'apliquen les regles amb la propietat EsAfix = true.</param> /// <returns>El nombre de mots afegits.</returns> public int Genera(string arrel, ref List<Mot> mots, MorfoGram infoComuna, Regles regles, Marques filtre, bool nomesAfixos) { if ((suprimir > arrel.Length) || (condicio != null && !condicio.IsMatch(arrel)) || !filtre.Conte(Marca)) return 0; int afegits = 0; string forma; if (sufix) forma = arrel.Substring(0, arrel.Length - suprimir) + afegir; else forma = afegir + arrel.Substring(suprimir); Mot motBase = new Mot(forma, this, infoComuna); mots.Add(motBase); afegits += 1; if (mesRegles != null) foreach (string idRegla in mesRegles) { Regla regla = regles.Llista[idRegla]; if (nomesAfixos && !regla.EsAfix) continue; List<Mot> nous = regla.Genera(forma, motBase.Info, regles, filtre, nomesAfixos); if (mesRegles.Count > 1) { foreach (string idRegla2 in mesRegles) { if (idRegla == idRegla2) continue; Regla regla2 = regles.Llista[idRegla2]; if (nomesAfixos && !regla2.EsAfix) continue; List<Mot> nous2; foreach (Mot mot in nous) { nous2 = regla2.Genera(mot.Forma, mot.Info, regles, filtre, nomesAfixos); mots.AddRange(nous2); afegits += nous2.Count; } } } mots.AddRange(nous); afegits += nous.Count; } return afegits; }
/// <summary> /// Genera les línies per al fitxer .aff /// </summary> /// <param name="filtre">Només posarem els casos amb marques contingudes dins el filtre.</param> /// <param name="nouId">L'identificador que farem servir per a la regla.</param> /// <param name="nouCombinable">El valor nou per a combinable.</param> /// <param name="regles">Les regles a les quals pertany aquesta.</param> public string[] GeneraAff(Marques filtre, string nouId, bool nouCombinable, Regles regles) { List<string> liniesCasos = new List<string>(); foreach (CasRegla cas in casos) if (filtre.Conte(cas.Marca)) liniesCasos.Add(cas.GeneraAff(this, nouId, regles)); List<string> linies = new List<string>(); linies.Add(string.Format("{0}FX {1} {2} {3}", sufix ? "S" : "P", nouId, nouCombinable ? "Y" : "N", liniesCasos.Count)); linies.AddRange(liniesCasos); return linies.ToArray(); }
/// <summary> /// Genera els mots per a una arrel. /// </summary> /// <param name="arrel">L'arrel que es vol expandir.</param> /// <param name="infoComuna"> /// Informació comuna a tots els mots que es generaran. /// Aquesta informació s'unifica amb la que va associada als casos. /// Per tant, només es generen els casos que tenen informació compatible. /// </param> /// <param name="regles">La llista completa de regles.</param> /// <param name="filtre">Només es generen mots que tenen marques contingudes en aquest filtre.</param> /// <param name="nomesAfixos">Si és true, només s'apliquen les regles amb la propietat EsAfix = true.</param> /// <returns>La llista generada de mots.</returns> public List<Mot> Genera(string arrel, MorfoGram infoComuna, Regles regles, Marques filtre, bool nomesAfixos) { List<Mot> mots = new List<Mot>(); if (nomesAfixos && !EsAfix) return mots; int afegits = 0; foreach (CasRegla cas in casos) { if (!MorfoGram.Unificables(cas.Info, infoComuna) || !filtre.Conte(cas.Marca)) continue; afegits += cas.Genera(arrel, ref mots, infoComuna, regles, filtre, nomesAfixos); if (afegits >= maxGenera) break; } return mots; }
/// <summary> /// Llegeix d'un stream obert. /// </summary> /// <param name="lector">L'stream d'on llegirem les regles.</param> /// <param name="nomFitxer">El nom del fitxer de regles.</param> /// <param name="filtre">Les marques que admetem. Els casos de les regles que no passin /// el filtre es rebutgen.</param> private void Llegeix(StreamReader lector, string nomFitxer, Marques filtre) { regles = new Dictionary<string, Regla>(); marques = new Dictionary<string, Marca>(); descripcio = new List<string>(); caracters = null; wordchars = null; rep = new List<string>(); set = null; Regla regla = null; // la regla que estam llegint int numLinia = 0; Llegint estat = Llegint.IGNORA; while (!lector.EndOfStream) { string liniaBruta = lector.ReadLine(); string linia = liniaBruta.Trim(); ++numLinia; if (linia.Length == 0 || linia.StartsWith("//")) continue; switch (estat) { case Llegint.IGNORA: if (linia.StartsWith("DESC")) estat = Llegint.DESC; else if (linia.StartsWith("GRUPS")) estat = Llegint.GRUPS; else if (linia.StartsWith("REGLA")) { regla = Regla.Crea(linia); regles[regla.Id] = regla; estat = Llegint.REGLA; } else if (linia.StartsWith("SET")) set = ContingutLinia(linia); else if (linia.StartsWith("WORDCHARS")) wordchars = ContingutLinia(linia); else if (linia.StartsWith("TRY")) caracters = ContingutLinia(linia); else if (linia.StartsWith("FIRST")) NouFirst(ContingutLinia(linia)); break; case Llegint.DESC: if (linia.StartsWith("/DESC")) estat = Llegint.IGNORA; else descripcio.Add(liniaBruta); break; case Llegint.GRUPS: if (linia.StartsWith("/GRUPS")) estat = Llegint.IGNORA; else { Match match = PartsGrup.Match(linia); if (match.Success) { String id = match.Groups[1].Value; String desc = match.Groups[2].Value; marques[id] = Marca.Crea(id, desc); } else throw new Exception(String.Format("Error llegint marques dialectals: {0} [{1}.{2}]", linia, nomFitxer, numLinia)); } break; case Llegint.REGLA: if (linia.StartsWith("/REGLA")) estat = Llegint.IGNORA; else { CasRegla cas = CasRegla.Crea(linia, regla, marques); if (filtre.Conte(cas.Marca)) regla.NouCas(cas); } break; default: throw new Exception(String.Format("No sé que fer amb l'estat {0}", estat)); } } foreach (KeyValuePair<string, Regla> sr in regles) sr.Value.CalculaCalCombinable(this); if (estat != Llegint.IGNORA) throw new Exception(String.Format("Error llegint regles, estat final = {0}", estat.ToString())); }
private void test_02(GrupTest arrel) { GrupTest grup = arrel.NouGrup("Fitxer de regles"); Regles regles = null; grup.NouTest("Llegeix fitxer .txt", delegate(RTest resultat) { //regles = new Regles(DirEntrades("regles.txt"); regles = new Regles(DirEntrades("regles.txt")); }); grup.NouTest("Llegeix fitxer .aff", delegate(RTest resultat) { Regles regles2 = Regles.LlegeixAff(DirResultats("prova.aff")); }); grup.NouTest("Marca de dialecte", delegate(RTest resultat) { Marca marca = regles.Marques["000"]; resultat.Esperat("000: Sense condicions", marca.ToString()); }); grup.NouTest("Marques", delegate(RTest resultat) { Marques m1 = new Marques(false, "001", "002", "005", "013", "014", "101", "102", "103"); Marques m1bis = new Marques(false, "001", "002", "005", "013", "014", "101", "102", "103"); resultat.Esperat("001, 002, 005, 013, 014, 101, 102, 103", m1.ToString()); resultat.Assert(m1.Conte("005"), "Conté 005"); resultat.Assert(!m1.Conte("000"), "No conté 000"); resultat.Assert(m1.Conte(Marca.Una("001").Mascara), "Conté 001"); resultat.Assert(!m1.Conte(Marca.Una("000").Mascara), "No conté 000"); Marques m2 = new Marques(false, "101", "102", "103"); resultat.Assert(m1.Conte(m2), "m1 >= m2"); resultat.Assert(!m2.Conte(m1), "!(m2 >= m1)"); resultat.Assert(m1 == m1bis, "Són iguals!"); m1.Mes(Marca.Una("003")); resultat.Esperat("001, 002, 003, 005, 013, 014, 101, 102, 103", m1.ToString()); m1.Menys(Marca.Una("013")); resultat.Esperat("001, 002, 003, 005, 014, 101, 102, 103", m1.ToString()); }); grup.NouTest("Línia amb condicions I", delegate(RTest resultat) { // Suposam la cadena "abc <<001 def 001>> ghi" LiniaMarques lm = new LiniaMarques(); Marca.Crea("_1_", "Grup 1"); Marca.Crea("_2_", "Grup 2"); Marques m = new Marques(false, "_1_"); lm.Nou("abc ", m); m.Mes(Marca.Una("001")); lm.Nou(" def ", m); m.Menys(Marca.Una("001")); lm.Nou(" ghi", m); resultat.Esperat("abc def ghi", lm.Valor(new Marques(false, "_1_", "001"))); resultat.Esperat("abc ghi", lm.Valor(new Marques(false, "_1_"))); resultat.Esperat("", lm.Valor(new Marques(false))); }); grup.NouTest("Línia amb condicions II", delegate(RTest resultat) { regles = new Regles(DirEntrades("regles.txt")); LiniaMarques lm = IdentificadorDIEC.LlegeixLiniaExc("abc <<001 def 001>> ghi <<!002 jkl !002>>"); resultat.Esperat("abc def ghi jkl", lm.Valor(new Marques(false, "_1_", "001")).Trim()); resultat.Esperat("abc ghi jkl", lm.Valor(new Marques(false, "_1_")).Trim()); resultat.Esperat("abc ghi", lm.Valor(new Marques(false, "_1_", "002")).Trim()); resultat.Esperat("", lm.Valor(new Marques(false)).Trim()); }); grup.NouTest("Genera mots", delegate(RTest resultat) { Regla regla = regles.Llista["E"]; List<Mot> mots = regla.Genera("aigua", null, regles, Marques.totes, true); resultat.Esperat("aigües", Mot.LlistaPlana(mots, Cat.Cmp, false)); for (int i = 0; i < mots.Count; i++) resultat.Nota("{0}: {1}", i, mots[i]); }); grup.NouTest("Regles aplicables", delegate(RTest resultat) { Regla regla = regles.Llista["A"]; resultat.Assert(regla.EsAplicable("cantava"), "Es pot aplicar la regla A a 'cantava'"); resultat.Assert(!regla.EsAplicable("cantar"), "No es pot aplicar la regla A a 'cantar'"); }); }
public override void Genera(Dictionary<string, string> dades, Dictionary<string, string> excepcions, Marques filtre, List<ItemDic> items) { string arrel = dades["arrel"]; string imp = arrel.Substring(0, arrel.Length - 2) + "ava"; AfegeixItem(items, imp, mgVerb, mgArrel, "A"); // Si el participi femení singular es pot apostrofar, l'afegim a la llista, // ja que la regla "A" no posa l'article en aquest cas, per evitar "l'ignorada". AfegeixParFemSg(items, imp, filtre); if (filtre.Conte("013") && ipr1BalAcc.IsMatch(arrel)) { Paraula pArrel = new Paraula(arrel); if (pArrel.Sillabes.Length >= 3) { // La forma resultant té més d'una síl·laba, per tant du accent ("supòs") string ipr1 = null; if (ProvaIpr1(arrel, ref ipr1, "às", "asar", "assar") || ProvaIpr1(arrel, ref ipr1, "ín", "inar") || ProvaIpr1(arrel, ref ipr1, "ís", "isar", "issar") || ProvaIpr1(arrel, ref ipr1, "pòs", "posar") || ProvaIpr1(arrel, ref ipr1, "ús", "usar", "ussar") ) { if (pArrel.VocalInicial) AfegeixItem(items, ipr1, mgVerb, mgIpr1, "Z"); else AfegeixItem(items, ipr1, mgVerb, mgIpr1); } } else { // La forma resultant té una sola síl·laba, no du accent ("pos") string ipr1 = null; if (ProvaIpr1(arrel, ref ipr1, "as", "asar", "assar") || ProvaIpr1(arrel, ref ipr1, "en", "enar") || ProvaIpr1(arrel, ref ipr1, "es", "esar", "essar") || ProvaIpr1(arrel, ref ipr1, "in", "inar") || ProvaIpr1(arrel, ref ipr1, "is", "isar", "issar") || ProvaIpr1(arrel, ref ipr1, "os", "osar", "ossar") || ProvaIpr1(arrel, ref ipr1, "us", "usar", "ussar")) { if (pArrel.VocalInicial) AfegeixItem(items, ipr1, mgVerb, mgIpr1, "Z"); else AfegeixItem(items, ipr1, mgVerb, mgIpr1); } } } AplicaMesMenys(items, excepcions, filtre); }