void AddElement(SpeechElement eElement) { Console.WriteLine("parser: Current element is a {0} ({1})", eElement.GetType(), (eElement is Vowel)?(eElement as Vowel).vowel.ToString():eElement.Latin); this.Emit(eElement); prevElement = eElement; prevVowel = prevElement as Vowel; prevConsonant = prevElement as Consonant; }
protected override void BeforeConsumption() { base.BeforeConsumption(); Console.WriteLine("parser started"); t = null; newElement = null; lastTag = null; prev = null; isFirstWindow = true; isLastWindow = false; prevVowel = null; prevConsonant = null; prevElement = null; }
protected override void Consume(Queue <Token> InQueue) { Token[] tokens; lock (InQueue) { tokens = InQueue.ToArray(); InQueue.Dequeue(); } int tokensToConsume = 1; if (tokensToConsume > windowSize) { tokensToConsume -= windowSize; } else { isLastWindow = !this.IsRunning; } for (int i = 0; i < tokensToConsume;) { newElement = null; t = tokens[i]; _ItemConsumed(t); if (!(t is LetterToken)) { if (t is TagToken) { newElement = new WordTag(((TagToken)t).Type); prev = null; i++; } else if (t is CantillationToken) { newElement = new Cantillation((t as CantillationToken).Value[0]); i++; } else { newElement = new Separator(t.Value); prev = null; i++; } } else { LetterToken next = null; LetterToken further = null; int nextIndex = -1 /*, furtherIndex = -1*/; int j; /*j=i-1; * while ((j>0)&&!(tokens[j] is LetterToken)) { * if (!(tokens[j] is CantillationToken)) * break; * j--; * } * if (j>=0) { * prev=tokens[j] as LetterToken; * prevIndex=j; * }*/ j = i + 1; while ((j < tokens.Length - 1) && !(tokens[j] is LetterToken)) { if (!(tokens[j] is CantillationToken)) { break; } j++; } if (j < tokens.Length) { next = tokens[j] as LetterToken; nextIndex = j; } j++; while ((j < tokens.Length - 1) && !(tokens[j] is LetterToken)) { if (!(tokens[j] is CantillationToken)) { break; } j++; } if (j < tokens.Length) { further = tokens[j] as LetterToken; // furtherIndex = j; } bool curIsWordEnd = (isLastWindow && (i == tokens.Length - 1)) || (next == null); bool curIsWordStart = (isFirstWindow && (i == 0)) || (prev == null); // Look for a consonant LetterToken l = (LetterToken)t; switch (l.Letter) { case 'א': newElement = new Consonant(Consonants.Aleph); break; case 'ב': if (l.HasDagesh) { newElement = new Consonant(Consonants.Bet); } else { newElement = new Consonant(Consonants.Vet); } break; case 'ג': if (l.HasApostrophe) { newElement = new Consonant(Consonants.Jimmel); } else { newElement = new Consonant(Consonants.Gimmel); } break; case 'ד': newElement = new Consonant(Consonants.Dalet); break; case 'ה': newElement = new Consonant(Consonants.He); break; case 'ו': if ((l.HasDagesh && l.HasAnyVowels) || l.HasAnyVowelsExcept('\u05B9')) { newElement = new Consonant(Consonants.Vav); } else if ((next != null) && (next.Letter == 'ו') && (next.HasAnyModifier('\u05B9', HebrewChar.Shuruk))) { newElement = new Consonant(Consonants.Vav); } else { v = l.FirstVowel; switch (v) { case '\u05B9': newElement = new Vowel(Vowels.HolamMale); break; case '\0': if (l.HasShuruk) { if (curIsWordStart) { AddElement(newElement = new Consonant(Consonants.Aleph)); // Log.Parser.WriteLine("Added consonant "+newElement.Latin+" (sonority "+((Consonant)newElement).Sonority+")"); } newElement = new Vowel(Vowels.Shuruk); } else { newElement = new Consonant(Consonants.Vav); } break; } } if ((newElement is Consonant) && (lastTag != null)) { if ((lastTag.Tag & TagTypes.Origin) == TagTypes.Foreign) { newElement = new Consonant(Consonants.W); } } break; case 'ז': if (l.HasApostrophe) { newElement = new Consonant(Consonants.Zhayin); } else { newElement = new Consonant(Consonants.Zayin); } break; case 'ח': if (l.HasApostrophe) { newElement = new Consonant(Consonants.Khaf); } else { newElement = new Consonant(Consonants.Het); } break; case 'י': newElement = new Consonant(Consonants.Yud); break; case 'ט': newElement = new Consonant(Consonants.Tet); break; case 'כ': case 'ך': if (l.HasDagesh) { newElement = new Consonant(Consonants.Kaf); } else { newElement = new Consonant(Consonants.Khaf); } break; case 'ל': newElement = new Consonant(Consonants.Lamed); break; case 'מ': case 'ם': newElement = new Consonant(Consonants.Mem); break; case 'נ': case 'ן': newElement = new Consonant(Consonants.Nun); break; case 'ס': newElement = new Consonant(Consonants.Samekh); break; case 'ע': newElement = new Consonant(Consonants.Ayin); break; case 'פ': case 'ף': if (l.HasDagesh) { newElement = new Consonant(Consonants.Pe); } else { newElement = new Consonant(Consonants.Fe); } break; case 'צ': case 'ץ': if (l.HasApostrophe) { newElement = new Consonant(Consonants.Tchaddik); } else { newElement = new Consonant(Consonants.Tsaddik); } break; case 'ק': newElement = new Consonant(Consonants.Quf); break; case 'ר': newElement = new Consonant(Consonants.Resh); break; case 'ש': if (l.HasModifier(HebrewChar.SinDot)) { newElement = new Consonant(Consonants.Sin); } else { newElement = new Consonant(Consonants.Shin); } break; case 'ת': newElement = new Consonant(Consonants.Tav); break; } if (newElement is Consonant) { TagTypes wordOrigin = TagTypes.Unrecognized; if (lastTag != null) { wordOrigin = lastTag.Tag & TagTypes.Origin; } Consonant curConsonant = (Consonant)newElement; if (l.HasDagesh) { if (wordOrigin == TagTypes.Foreign) { if (!HebrewChar.IsBegedKefet(l.Letter)) { curConsonant.Flags |= ConsonantFlags.LightDagesh; } } else if (!HebrewChar.IsGuttural(l.Letter) && l.Letter != 'י') { if (!HebrewChar.IsBegedKefet(l.Letter)) { curConsonant.Flags |= ConsonantFlags.StrongDagesh; } else { if ((prev == null) || (prevVowel == null) || (prevVowel.vowel == Vowels.SilentSchwa)) { curConsonant.Flags |= ConsonantFlags.LightDagesh; } else { curConsonant.Flags |= ConsonantFlags.StrongDagesh; } } } } v = l.FirstVowel; bool patahGnuva = false; if (curIsWordEnd && /*&& (v=='\u05B7')*/ ((curConsonant.Latin == Consonants.Het) || (curConsonant.Latin == Consonants.Ayin))) { if ((prevVowel != null) && prevVowel.IsVowelIn(Vowels.E | Vowels.I | Vowels.U | Vowels.O)) { if ((v == '\u05B7') || (v == '\0')) { AddElement(new Vowel(Vowels.PatahGnuva)); patahGnuva = true; } } } if (Options.EverydayRegister) { if ((newElement.Latin == Consonants.Ayin) || (newElement.Latin == Consonants.Aleph) || (newElement.Latin == Consonants.He)) { newElement.Silent = true; } } AddElement(newElement); // Log.Parser.WriteLine("Added consonant "+curConsonant.Latin+" (sonority "+curConsonant.Sonority+")"); newElement = null; bool nextIsUnvoicedEhevi = (next != null) && HebrewChar.IsEhevi(next.Letter) && !next.HasAnyVowels && !next.HasMappiq; if (nextIsUnvoicedEhevi) { if (next.Letter == 'ו') { nextIsUnvoicedEhevi &= !l.HasAnyModifier('\u05B7', '\u05B8'); } if (further != null) { if (further.Letter == 'ו') { nextIsUnvoicedEhevi &= !further.HasAnyModifier('\u05B9' /* holam */, HebrewChar.Shuruk); nextIsUnvoicedEhevi &= !further.HasAnyVowelsExcept(HebrewChar.Shuruk); } } else if (next.Letter == 'י') { nextIsUnvoicedEhevi &= (l.HasModifier('\u05B4')); } } bool nextHasHatafKamatz = (next != null) && next.HasModifier('\u05B3'); bool nextHasSchwa = (next != null) && next.HasModifier('\u05B0'); bool nextHasHataf = (next != null) && next.HasAnyModifier('\u05B1', '\u05B2', '\u05B3'); bool nextIsBegedKefet = (next != null) && HebrewChar.IsBegedKefet(next.Letter); /* if (nextIsUnvoicedEhevi) * Log.Parser.WriteLine("Next token is an extender אהו\"י");*/ i++; switch (v) { case '\u05B0': if (wordOrigin == TagTypes.Foreign) { newElement = new Vowel(Vowels.SilentSchwa); } else if (prev == null) { newElement = new Vowel(Vowels.AudibleSchwa); } else if (next == null) { newElement = new Vowel(Vowels.SilentSchwa); } else if (nextHasSchwa | nextHasHataf) { newElement = new Vowel(Vowels.SilentSchwa); } else if (nextIsBegedKefet) { if (next.HasDagesh) { newElement = new Vowel(Vowels.SilentSchwa); } else { newElement = new Vowel(Vowels.AudibleSchwa); } } /* else if (((curConsonant.Latin)==Consonants.Aleph) || * ((curConsonant.Latin)==Consonants.Ayin) || * ((curConsonant.Latin)==Consonants.Het) || * ((curConsonant.Latin)==Consonants.He) || * ((curConsonant.Latin)==Consonants.Resh)) * newElement=new Vowel(Vowels.AudibleSchwa);*/ else if (prevVowel != null) { switch (prevVowel.vowel) { case Vowels.SilentSchwa: newElement = new Vowel(Vowels.AudibleSchwa); break; default: if (prevVowel.IsVowelIn(Vowels.Short)) { newElement = new Vowel(Vowels.SilentSchwa); } else if ((curConsonant.Flags & ConsonantFlags.StrongDagesh) != 0) { newElement = new Vowel(Vowels.AudibleSchwa); } // else if (prevVowel.IsVowelIn(Vowels.Long|Vowels.VeryLong)) // newElement=new Vowel(Vowels.AudibleSchwa); else { newElement = new Vowel(Vowels.SilentSchwa); } break; } } else if ((curConsonant.Flags & ConsonantFlags.StrongDagesh) != 0) { newElement = new Vowel(Vowels.AudibleSchwa); } else { newElement = new Vowel(Vowels.SilentSchwa); } break; case '\u05B1': newElement = new Vowel(Vowels.HatafSegol); break; case '\u05B2': newElement = new Vowel(Vowels.HatafPatah); break; case '\u05B3': newElement = new Vowel(Vowels.HatafKamatz); break; case '\u05B4': if (nextIsUnvoicedEhevi) { newElement = new Vowel(Vowels.HirikMale); } else { newElement = new Vowel(Vowels.HirikHaser); } break; case '\u05B5': if (nextIsUnvoicedEhevi) { newElement = new Vowel(Vowels.TzereMale); } else { newElement = new Vowel(Vowels.Tzere); } break; case '\u05B6': if (nextIsUnvoicedEhevi) { newElement = new Vowel(Vowels.SegolMale); } else { newElement = new Vowel(Vowels.Segol); } break; case '\u05B7': if (!patahGnuva) { if (nextIsUnvoicedEhevi) { newElement = new Vowel(Vowels.PatahMale); } else { newElement = new Vowel(Vowels.Patah); } } break; case '\u05B8': if (nextIsUnvoicedEhevi) { newElement = new Vowel(Vowels.KamatzMale); } else if (nextHasHatafKamatz) { newElement = new Vowel(Vowels.KamatzKatan); } else { newElement = new Vowel(Vowels.KamatzIndeterminate); } break; case '\u05B9': if (nextIsUnvoicedEhevi) { newElement = new Vowel(Vowels.HolamMale); } else { newElement = new Vowel(Vowels.HolamHaser); } break; case '\u05BB': newElement = new Vowel(Vowels.Kubutz); break; default: // if (v!=(char)0) // Log.Parser.WriteLine("Unknown vowel char: {0:X4}",(int)v); break; } prev = l; if (newElement != null) { /*if (curIsWordEnd && (((Vowel)newElement).vowel==Vowels.Patah) * && ((curConsonant.Latin==Consonants.Het)||(curConsonant.Latin==Consonants.Ayin)||(curConsonant.Latin==Consonants.He))) { * ((Vowel)newElement).vowel=Vowels.PatahGnuva; * parsed.Insert(parsed.Count-1,newElement); * Log.Parser.WriteLine("Added element "+((Vowel)newElement).vowel+" as patah gnuva"); * } * else {*/ AddElement(newElement); // Log.Parser.WriteLine("Added element "+((Vowel)newElement).vowel); //} newElement = null; if (nextIsUnvoicedEhevi) { Log("UNVOICED EHEVI FOR CRYING OUT LOUD>>>>>>>>>>>>>"); for (int k = i; k < nextIndex; k++) { Token tk = tokens[k]; if (tk is CantillationToken) { newElement = new Cantillation((tk as CantillationToken).Value[0]); AddElement(newElement); Log("Added element " + newElement.Latin + " (" + newElement.GetType().Name + ") while skipping unvoiced ehevi"); newElement = null; } } lock (InQueue) for (int z = 0; z < nextIndex + 1 - tokensToConsume; z++) { _ItemConsumed(InQueue.Dequeue()); } i = nextIndex + 1; } } /*else if (i<tokensToConsume) { * t=tokens[i]; * if (t is LetterToken) { * l=(LetterToken)t; * if (l.Letter=='ו') { * * if (newElement!=null) { * AddElement(newElement); * newElement=null; * i++; * } * } * } * }*/ } else// if (newElement!=null) { i++; } } if (newElement != null) { AddElement(newElement); if (newElement is WordTag) { // Log.Parser.WriteLine("Added tag "+((WordTag)newElement).Tag); lastTag = (WordTag)newElement; } else { if (newElement is Separator) { lastTag = null; } // Log.Parser.WriteLine("Added element "+newElement.Latin+" ("+newElement.GetType().Name+")"); } newElement = null; } } if (isFirstWindow) { isFirstWindow = false; } }