/// <summary> /// 현재까지 추적한 단어를 감정 분석기에 넘기고 초기화합니다. /// </summary> /// <param name="args">없음</param> private static void ResetWord(object[] args) { if (!MainForm.ENABLE_SENTIMENT_ANALYZER) { return; } #pragma warning disable CS0162 // 접근할 수 없는 코드가 있습니다. if (wordState.Length > 0) { if (IsIMESetToEnglish()) { Console.WriteLine("wordState: " + wordState); EnglishSentimentAnalyzer.instance.Analyze(wordState); EnglishSentimentAnalyzer.instance.GetSentimentAndFlush().Print(); // TODO 음악 생성기에 넘기기 } else { Console.WriteLine("wordState: " + Hangul.Assemble(wordState)); KoreanSentimentAnalyzer.instance.Analyze(Hangul.Assemble(wordState)); KoreanSentimentAnalyzer.instance.GetSentimentAndFlush().Print(); // TODO 음악 생성기에 넘기기 } } wordState = ""; #pragma warning restore CS0162 // 접근할 수 없는 코드가 있습니다. }
public void Enter() { m_audio.PlayOneShot(m_audioEffect); hangul = new Hangul(); //hangul.chosung = hangul.jungsung = hangul.jongsung = hangul.jongsung2 = ""; Init_cursor(); }
/// <summary> /// 추적하고 있는 단어에서 Backspace 입력을 처리합니다. /// </summary> /// <param name="args">없음</param> private static void BackspaceWord(object[] args) { if (!MainForm.ENABLE_SENTIMENT_ANALYZER) { return; } #pragma warning disable CS0162 // 접근할 수 없는 코드가 있습니다. if (wordState.Length > 0) { if (IsIMESetToEnglish()) { wordState = wordState.Substring(0, wordState.Length - 1); } else { if (backspaceState is null) { backspaceState = Hangul.Assemble(wordState); backspaceState = backspaceState.Substring(0, backspaceState.Length - 1) + Hangul.Disassemble(backspaceState.Substring(backspaceState.Length - 1, 1)); } if (backspaceState.Length > 0) { backspaceState = backspaceState.Substring(0, backspaceState.Length - 1); wordState = backspaceState; } } } #pragma warning restore CS0162 // 접근할 수 없는 코드가 있습니다. }
public void splitChoseongDoubleConsonantTest() { //Arrange char[] testInput = new char[] { 'ᆪ', 'ᆬ', 'ᆭ', 'ᆰ', 'ᆱ', 'ᆲ', 'ᆳ', 'ᆴ', 'ᆵ', 'ᆶ', 'ᆹ' }; char[][] expected = new char[][] { new char[] { 'ᆨ', 'ᆺ' }, new char[] { 'ᆫ', 'ᆽ' }, new char[] { 'ᆫ', 'ᇂ' }, new char[] { 'ᆯ', 'ᆨ' }, new char[] { 'ᆯ', 'ᆷ' }, new char[] { 'ᆯ', 'ᆸ' }, new char[] { 'ᆯ', 'ᆺ' }, new char[] { 'ᆯ', 'ᇀ' }, new char[] { 'ᆯ', 'ᇁ' }, new char[] { 'ᆯ', 'ᇂ' }, new char[] { 'ᆸ', 'ᆺ' } }; int testArrLen = testInput.Length; char[][] result = new char[testArrLen][]; //Act for (int i = 0; i < testArrLen; i++) { result[i] = Hangul.splitChoseongDoubleConsonant(testInput[i]); } //Assert for (int i = 0; i < testArrLen; i++) { CollectionAssert.AreEqual(expected[i], result[i]); } }
//---------------------------------------------------------------- // J-->K方向の助詞翻訳 static public string TransJapanesePP(WordTable wt) { // ここにくるという事は posCategory == PosCategory.PPは確定している。 // 1つ前の語に対応する韓国語を取り出す(パッチム判定のため) string prevtrans = ""; if (wt.prev.transWord != "") { prevtrans = wt.prev.transWord; } else { prevtrans = wt.prev.GetTranslatedText(); } // J-->K方向の助詞変換 // こちらは前の語を翻訳しないと、変換すべき語を判断できない。 if (Hangul.withPachim(prevtrans)) { return(KJ_Filter.SearchPP_Pachim(wt.word)); } else { return(KJ_Filter.SearchPP_NoPachim(wt.word)); } }
private void DisplayStorage() { var sb = new StringBuilder(); sb.AppendLine($"위치: ({_aheui.X}, {_aheui.Y})"); sb.AppendLine($"명령: {_aheui.CurrentCode.Letter}"); foreach (var(c, s) in _aheui.StacksWithKey) { if (c == _aheui.CurrentStorage) { sb.Append('>'); } sb.AppendLine($"{Hangul.CombineLetter('ㅇ', 'ㅏ', c)}: {string.Join(", ", s)}"); } this.txtStorage.Text = sb.ToString(); }
public void choseongSingleToJongseongTest() { //Arrange char[] testInput = new char[] { 'ᆨ', 'ᆫ', 'ᆮ', 'ᆯ', 'ᆷ', 'ᆸ', 'ᆺ', 'ᆼ', 'ᆽ', 'ᆾ', 'ᆿ', 'ᇀ', 'ᇁ', 'ᇂ' }; char[] expected = new char[] { 'ᄀ', 'ᄂ', 'ᄃ', 'ᄅ', 'ᄆ', 'ᄇ', 'ᄉ', 'ᄋ', 'ᄌ', 'ᄎ', 'ᄏ', 'ᄐ', 'ᄑ', 'ᄒ' }; int testArrLen = testInput.Length; char[] result = new char[testArrLen]; //Act for (int i = 0; i < testArrLen; i++) { result[i] = Hangul.choseongSingleToJongseong(testInput[i]); } //Assert CollectionAssert.AreEqual(expected, result); }
//------------------------------------------------------------------------ // 辞書に見つからなかった語を自動変換する // ハングル <---> カタカナ private WordTable ConvAutoConv(WordTable wt) { if (wt.IsTranslated()) { return(wt); // 変換済みなら何もしない } if (!this.sTrans.AutoConv) { return(wt); // AutoConvをoffにしている場合は何もせず抜ける。 } if (KJ_dict.inputIsHangul) { // K-->J方向 if (CodeCheck.IsHangul(wt.word)) { wt.transWord = Hangul.Hangul2Kana(wt.word); } } else { // J-->方向 if (wt.charCategory == CharCategory.Katakana) { // カタカナの場合 wt.transWord = Kana.Kana2Hangul(wt.word); } else { if (wt.charCategory == CharCategory.Hiragana) { // ひらがなの場合 wt.transWord = Kana.Hira2Hangul(wt.word); } } } return(wt); }
/// <summary> /// 추적하고 있는 단어에 새 글자를 추가합니다. /// </summary> /// <param name="args">첫 번째 인자: 입력된 키 코드(int), 두 번째 인자: 키 입력 시 Shift가 함께 눌렸는지 여부(bool)</param> private static void AddCharToWord(object[] args) { if (!MainForm.ENABLE_SENTIMENT_ANALYZER) { return; } #pragma warning disable CS0162 // 접근할 수 없는 코드가 있습니다. int vkCode_ = (int)args[0]; bool hasShiftPressed_ = (bool)args[1]; StringBuilder charPressed = new StringBuilder(256); ToUnicode((uint)vkCode_, 0, new byte[256], charPressed, charPressed.Capacity, 0); // TODO 영어와 한글 구분하여 처리 if (IsIMESetToEnglish()) { wordState += Util.StringWithShift(charPressed.ToString(), hasShiftPressed_); } else { wordState += Hangul.EnglishToKorean(Util.StringWithShift(charPressed.ToString(), hasShiftPressed_)); } #pragma warning restore CS0162 // 접근할 수 없는 코드가 있습니다. }
public void decomposeHangulBlockTest() { //Arrange char[] testInput = new char[] { '안', '다' }; string[] expected = new string[] { "안", "다" }; int testArrLen = testInput.Length; string[] result = new string[testArrLen]; //Act for (int i = 0; i < testArrLen; i++) { result[i] = Hangul.decomposeHangulBlock(testInput[i]); } //Assert for (int i = 0; i < testArrLen; i++) { StringAssert.Equals(result[i], expected[i]); } }
//------------------------------------------------------- static private WordChain DivideJapanesePP(WordTable wTable) { StringDivider sd = new StringDivider(wTable.word); // 前から1文字ずつ落としつつ,検索。 string trans = ""; while (sd.eof() == false) { // 文字列を分割する HYAM.KJ_dict.Pair pair = sd.DivideForward(); if (Hangul.withPachim(pair.head)) { trans = KJ_Filter.SearchPP_Pachim(pair.tail); } else { trans = KJ_Filter.SearchPP_NoPachim(pair.tail); } if (trans == "") { continue; } SearchResult result = KJ_dict.SearchFull(pair.head); if (result != null) { // 助詞確定 // 助詞に先行しない語は除外 // 산은 (은が助詞なら、산は動詞[連体詞]ではない) // result = SearchResult.CheckPPConnectable(result); // もし語が全部落ちたならば何もしない if (result.documents.Count == 0) { // nop } else { // 先行語+助詞のチェーンを作る WordTable wt1 = new WordTable(pair.head); wt1.SetResult(result); wt1.divided = Divided.Lead; // wt2.transWord はまだ設定しない。 // 前の訳語のパッチムに影響されるため。 WordTable wt2 = new WordTable(pair.tail); wt2.posCategory = PosCategory.PP; wt2.divided = Divided.Trail; // 長い助詞ほどコストを低くする // wt2.Cost = 0; if (wt2.word.Length > 2) { wt2.Cost = 0; } else if (wt2.word.Length == 2) { wt2.Cost = 3; } else { wt2.Cost = 5; } WordChain rtnChain = new WordChain(wt1, wt2); return(rtnChain); } } } // end of while return(null); // 分離できなかったらnullを返す。 }
private void Compare(int c, int ce32, int baseCE32) { if (Collation.IsPrefixCE32(ce32)) { int dataIndex = Collation.IndexFromCE32(ce32); ce32 = data.GetFinalCE32(data.GetCE32FromContexts(dataIndex)); if (Collation.IsPrefixCE32(baseCE32)) { int baseIndex = Collation.IndexFromCE32(baseCE32); baseCE32 = baseData.GetFinalCE32(baseData.GetCE32FromContexts(baseIndex)); ComparePrefixes(c, data.contexts, dataIndex + 2, baseData.contexts, baseIndex + 2); } else { AddPrefixes(data, c, data.contexts, dataIndex + 2); } } else if (Collation.IsPrefixCE32(baseCE32)) { int baseIndex = Collation.IndexFromCE32(baseCE32); baseCE32 = baseData.GetFinalCE32(baseData.GetCE32FromContexts(baseIndex)); AddPrefixes(baseData, c, baseData.contexts, baseIndex + 2); } if (Collation.IsContractionCE32(ce32)) { int dataIndex = Collation.IndexFromCE32(ce32); if ((ce32 & Collation.CONTRACT_SINGLE_CP_NO_MATCH) != 0) { ce32 = Collation.NO_CE32; } else { ce32 = data.GetFinalCE32(data.GetCE32FromContexts(dataIndex)); } if (Collation.IsContractionCE32(baseCE32)) { int baseIndex = Collation.IndexFromCE32(baseCE32); if ((baseCE32 & Collation.CONTRACT_SINGLE_CP_NO_MATCH) != 0) { baseCE32 = Collation.NO_CE32; } else { baseCE32 = baseData.GetFinalCE32(baseData.GetCE32FromContexts(baseIndex)); } CompareContractions(c, data.contexts, dataIndex + 2, baseData.contexts, baseIndex + 2); } else { AddContractions(c, data.contexts, dataIndex + 2); } } else if (Collation.IsContractionCE32(baseCE32)) { int baseIndex = Collation.IndexFromCE32(baseCE32); baseCE32 = baseData.GetFinalCE32(baseData.GetCE32FromContexts(baseIndex)); AddContractions(c, baseData.contexts, baseIndex + 2); } int tag; if (Collation.IsSpecialCE32(ce32)) { tag = Collation.TagFromCE32(ce32); Debug.Assert(tag != Collation.PREFIX_TAG); Debug.Assert(tag != Collation.CONTRACTION_TAG); // Currently, the tailoring data builder does not write offset tags. // They might be useful for saving space, // but they would complicate the builder, // and in tailorings we assume that performance of tailored characters is more important. Debug.Assert(tag != Collation.OFFSET_TAG); } else { tag = -1; } int baseTag; if (Collation.IsSpecialCE32(baseCE32)) { baseTag = Collation.TagFromCE32(baseCE32); Debug.Assert(baseTag != Collation.PREFIX_TAG); Debug.Assert(baseTag != Collation.CONTRACTION_TAG); } else { baseTag = -1; } // Non-contextual mappings, expansions, etc. if (baseTag == Collation.OFFSET_TAG) { // We might be comparing a tailoring CE which is a copy of // a base offset-tag CE, via the [optimize [set]] syntax // or when a single-character mapping was copied for tailored contractions. // Offset tags always result in long-primary CEs, // with common secondary/tertiary weights. if (!Collation.IsLongPrimaryCE32(ce32)) { Add(c); return; } long dataCE = baseData.ces[Collation.IndexFromCE32(baseCE32)]; long p = Collation.GetThreeBytePrimaryForOffsetData(c, dataCE); if (Collation.PrimaryFromLongPrimaryCE32(ce32) != p) { Add(c); return; } } if (tag != baseTag) { Add(c); return; } if (tag == Collation.EXPANSION32_TAG) { int length = Collation.LengthFromCE32(ce32); int baseLength = Collation.LengthFromCE32(baseCE32); if (length != baseLength) { Add(c); return; } int idx0 = Collation.IndexFromCE32(ce32); int idx1 = Collation.IndexFromCE32(baseCE32); for (int i = 0; i < length; ++i) { if (data.ce32s[idx0 + i] != baseData.ce32s[idx1 + i]) { Add(c); break; } } } else if (tag == Collation.EXPANSION_TAG) { int length = Collation.LengthFromCE32(ce32); int baseLength = Collation.LengthFromCE32(baseCE32); if (length != baseLength) { Add(c); return; } int idx0 = Collation.IndexFromCE32(ce32); int idx1 = Collation.IndexFromCE32(baseCE32); for (int i = 0; i < length; ++i) { if (data.ces[idx0 + i] != baseData.ces[idx1 + i]) { Add(c); break; } } } else if (tag == Collation.HANGUL_TAG) { StringBuilder jamos = new StringBuilder(); int length = Hangul.Decompose(c, jamos); if (tailored.Contains(jamos[0]) || tailored.Contains(jamos[1]) || (length == 3 && tailored.Contains(jamos[2]))) { Add(c); } } else if (ce32 != baseCE32) { Add(c); } }
//---------------------------------------------------------------------- // 1つの語のデータの表示 (通常のKJ_dict用) // private string DisplayResult(string searchword, DocumentData sd) { StringBuilder rtn_str = new StringBuilder(); rtn_str.Length = 0; string key_from = ""; // 検索語 string key_to = ""; string word_from = ""; string word_to = ""; string detail = ""; string ex = ""; string cost = ""; string src = ""; string pos = ""; // 品詞情報、格変化 (暫定) String indent = ""; // 入力がハングルならfromがkey1(ハングル) // 入力が漢字・ひらがな・カタカナならfromがkey2(日本語) // // 入力が数字・英語の場合は,OSに依存。 // ・OSが"ja-JP"ならfromがkey1(ハングル) // ・OSが"ja-JP"以外ならfromがkey2(日本語) if (this.inputIsHangul) { key_from = sd.GetData("key1"); key_to = sd.GetData("key2"); word_from = sd.GetData("word1"); word_to = sd.GetData("word2"); ex = sd.GetData("ex1"); cost = sd.GetData("cost2"); } else { key_from = sd.GetData("key2"); // Jp key_to = sd.GetData("key1"); // Kr word_from = sd.GetData("word2"); word_to = sd.GetData("word1"); ex = sd.GetData("ex2"); cost = sd.GetData("cost1"); } // 表示の見た目を整える。インデントつけたり、括弧をつけたり。 // 入力語の表示 rtn_str.Append(key_from); if (word_from != "") { // 詳細情報は以下の場合だけ // ・韓国OSのとき // または // ・デバッグ情報表示時 if (this.cultureName == "ko-KR" || CodeCheck.IsKanji(word_from) || Setting.debugInfo) { // 詳細情報。ハングルの旧漢字、日本語の読み rtn_str.Append(" 〔 " + word_from + " 〕"); } } rtn_str.Append("\n"); // K-->Jの時の入力ハングルのカナ表記の表示 if (this.Setting.withPronunciation) { if (this.inputIsHangul) { if (this.Setting.PronunciationType == 1) { string kana = Hangul.Hangul2Kana(key_from); rtn_str.Append(" (" + kana + ")\n"); } else { rtn_str.Append(indent + " (" + sd.GetData("pronun1") + ")\n"); } } } // もしあれば品詞情報 pos = MakePosString(sd); if (pos != null && pos != "") { rtn_str.Append(indent + "【 " + pos + " 】\n"); } // もしあれば原形表示 string root = ""; if (inputIsHangul) { root = sd.GetData("root1"); } else { root = sd.GetData("root2"); } if (root != "") { string rootname = Pos.conjugationName("conjugation_root"); rtn_str.Append(indent + "〔(" + rootname + ") " + root + "〕\n"); } // 結果の表示 rtn_str.Append(indent + key_to); // 詳細情報は以下の場合だけ // ・韓国OSのとき // または // ・デバッグ情報表示時 if (word_to != "") { if (this.cultureName == "ko-KR" || CodeCheck.IsKanji(word_to) || Setting.debugInfo) { rtn_str.Append(" 〔 " + word_to + " 〕"); // 詳細情報。ハングルの旧漢字、日本語の読み } } rtn_str.Append("\n"); // J-->Kの時の結果ハングルのカナ表記の表示 if (this.Setting.withPronunciation) { // 表示の設定がされているときだけ if (!this.inputIsHangul) { if (this.Setting.PronunciationType == 1) { string kana = Hangul.Hangul2Kana(key_to); rtn_str.Append(indent + " (" + kana + ")\n"); } else { rtn_str.Append(indent + " (" + sd.GetData("pronun1") + ")\n"); } } } // その他付加情報 detail = MakeDetailString(sd); if (detail != null && detail != "") { rtn_str.Append(indent + "( " + detail + " )\n"); } if (ex != "") { rtn_str.Append(indent + "Ex. " + ex + "\n"); } // 「デバッグ情報表示」 を選んだ場合 if (Setting.debugInfo) { src = sd.GetData("src"); if (src != "") { rtn_str.Append(indent + "src:" + src + "\n"); } if (cost != "") { rtn_str.Append(indent + "cost:" + cost + "\n"); } string pos2 = sd.GetPos(); // posの生データ if (pos2 != "") { rtn_str.Append(indent + "pos:" + pos2 + "\n"); } } rtn_str.Append("\n"); prev_keyword = key_from; // 記憶 return(rtn_str.ToString()); }
public Korean() { Hangul katakana = new Hangul(); characterSets.Add(katakana); }
public void Stretch() { Assert.Equal("으아악", Hangul.Stretch("으악")); Assert.Equal("안녀어어어엉", Hangul.Stretch("안녕", 4)); }
public void MakeShortVowel() { for (int i = 0; i < Hangul.VowelCount; i++) { Vowel vowel = (Vowel)i; Vowel shortVowel = Hangul.MakeShortVowel(vowel); switch (vowel) { case Vowel.ㅏ: Assert.Equal(Vowel.ㅏ, shortVowel); break; case Vowel.ㅐ: Assert.Equal(Vowel.ㅐ, shortVowel); break; case Vowel.ㅑ: Assert.Equal(Vowel.ㅏ, shortVowel); break; case Vowel.ㅒ: Assert.Equal(Vowel.ㅐ, shortVowel); break; case Vowel.ㅓ: Assert.Equal(Vowel.ㅓ, shortVowel); break; case Vowel.ㅔ: Assert.Equal(Vowel.ㅔ, shortVowel); break; case Vowel.ㅕ: Assert.Equal(Vowel.ㅓ, shortVowel); break; case Vowel.ㅖ: Assert.Equal(Vowel.ㅔ, shortVowel); break; case Vowel.ㅗ: Assert.Equal(Vowel.ㅗ, shortVowel); break; case Vowel.ㅘ: Assert.Equal(Vowel.ㅏ, shortVowel); break; case Vowel.ㅙ: Assert.Equal(Vowel.ㅐ, shortVowel); break; case Vowel.ㅚ: Assert.Equal(Vowel.ㅔ, shortVowel); break; case Vowel.ㅛ: Assert.Equal(Vowel.ㅗ, shortVowel); break; case Vowel.ㅜ: Assert.Equal(Vowel.ㅜ, shortVowel); break; case Vowel.ㅝ: Assert.Equal(Vowel.ㅓ, shortVowel); break; case Vowel.ㅞ: Assert.Equal(Vowel.ㅔ, shortVowel); break; case Vowel.ㅟ: Assert.Equal(Vowel.ㅣ, shortVowel); break; case Vowel.ㅠ: Assert.Equal(Vowel.ㅜ, shortVowel); break; case Vowel.ㅡ: Assert.Equal(Vowel.ㅡ, shortVowel); break; case Vowel.ㅢ: Assert.Equal(Vowel.ㅣ, shortVowel); break; case Vowel.ㅣ: Assert.Equal(Vowel.ㅣ, shortVowel); break; } } }
//------------------------------------------------------- // 辞書チェックなしのハングル助詞チェック // // 末尾が助詞と一致するなら分離する。 // static public WordChain CheckPPwithoutDictKr(WordTable wt) { if (wt.IsTranslated()) { // 翻訳済みなら何もしない。 return(null); } if (wt.charCategory != CharCategory.Hangul && wt.charCategory != CharCategory.LetterMix) { // ハングルでないなら、または英字+ハングルでないなら何もしない。 return(null); } WordTable rtnWt = wt; // 戻りのdefault StringDivider sd = new StringDivider(wt.word); string trans = ""; // 前から1文字ずつ落としつつ,検索。 while (sd.eof() == false) { // 文字列を分割する HYAM.KJ_dict.Pair pair = sd.DivideForward(); if (Hangul.withPachim(pair.head)) { trans = KJ_Filter.SearchPP_Pachim(pair.tail); } else { trans = KJ_Filter.SearchPP_NoPachim(pair.tail); } if (trans == "") { continue; } // wtをwt1とwt2に分割 WordTable wt1 = new WordTable(pair.head); wt1.divided = Divided.Lead; // 分離できた。 wT2は助詞と仮定。訳語も入れておく WordTable wt2 = new WordTable(pair.tail, trans); wt2.posCategory = PosCategory.PP; wt2.Cost = 2; wt2.divided = Divided.Trail; WordChain rtnChain; // 返却チェーン // wt1を調査 // (未知語なので分割してみる) WordChain wc1 = KJ_Analyzer.WordPartProc(wt1); if (wc1 == null) { // 分割できなかった rtnChain = new WordChain(wt1, wt2); } else { wc1.Add(wt2); rtnChain = wc1; } return(rtnChain); } return(null); // 分離できなかったらnullを返す }