/// <summary> It expands the morpheme chart to deal with the phoneme change phenomenon.</summary> /// <param name="from">- the index of the start segment position /// </param> /// <param name="front">- the front part of the string /// </param> /// <param name="back">- the next part of the string /// </param> /// <param name="ftag">- the morpheme tag of the front part /// </param> /// <param name="btag">- the morpheme tag of the next part /// </param> /// <param name="phoneme">- phoneme /// </param> public virtual void phonemeChange(int from, System.String front, System.String back, int ftag, int btag, int phoneme) { TNODE node = null; int size = 0; bool x, y; int next; int nc_idx; // searches the system dictionary for the front part node = systemDic.fetch(front.ToCharArray()); if (node != null && node.info_list != null) { size = node.info_list.Count; } Position pos = sp.getPosition(from); for (int i = 0; i < size; i++) { INFO info = node.info_list.Get_Renamed(i); // comparison of the morpheme tag of the front part x = tagSet.checkTagType(ftag, info.tag); // comparison of the phoneme of the front part y = tagSet.checkPhonemeType(phoneme, info.phoneme); if (x && y) { next = altSegment(back); if (checkChart(pos.morpheme, pos.morphCount, info.tag, info.phoneme, next, btag, front) == false) { nc_idx = addMorpheme(info.tag, info.phoneme, next, btag); chart[nc_idx].str = front; pos.morpheme[pos.morphCount++] = nc_idx; } else { System.Console.Error.WriteLine("phonemeChange: exit"); System.Environment.Exit(0); } } } }
/// <summary> It performs morphological anlysis on the morpheme chart from the specified index in the chart.</summary> /// <param name="chartIndex">- the index of the chart to analyze /// </param> /// <param name="tagType">- the type of next morpheme /// </param> /// <returns> the number of analysis results /// </returns> private int analyze(int chartIndex, int tagType) { int from, to; int i, j, x, y; int mp; char c; int nc_idx; TNODE node; LinkedList <INFO> infoList = null; INFO info = null; int sidx = 1; int uidx = 1; int nidx = 1; Position fromPos = null; Position toPos = null; Morpheme morph = chart[chartIndex]; from = morph.nextPosition; fromPos = sp.getPosition(from); switch (sp.getPosition(from).state) { default: return(0); /* dictionary search */ case SegmentPosition.SP_STATE_N: i = 0; bufString = ""; // searches all combinations of words segmented through the dictionaries for (to = from; to != SegmentPosition.POSITION_START_KEY; to = sp.nextPosition(to)) { toPos = sp.getPosition(to); c = toPos.key; if (sidx != 0) { sidx = systemDic.node_look(c, sidx); } if (uidx != 0) { uidx = userDic.node_look(c, uidx); } if (nidx != 0) { nidx = numDic.node_look(c, nidx); } toPos.sIndex = sidx; toPos.uIndex = uidx; toPos.nIndex = nidx; bufString += c; segmentPath[i++] = to; } nidx = 0; for (; i > 0; i--) { to = segmentPath[i - 1]; toPos = sp.getPosition(to); // system dictionary if (toPos.sIndex != 0) { node = systemDic.get_node(toPos.sIndex); if ((infoList = node.info_list) != null) { for (j = 0; j < infoList.Count; j++) { info = infoList.Get_Renamed(j); nc_idx = addMorpheme(info.tag, info.phoneme, sp.nextPosition(to), 0); chart[nc_idx].str = bufString.Substring(0, (i) - (0)); fromPos.morpheme[fromPos.morphCount++] = nc_idx; } } } // user dictionary if (toPos.uIndex != 0) { node = userDic.get_node(toPos.uIndex); if ((infoList = node.info_list) != null) { for (j = 0; j < infoList.Count; j++) { info = infoList.Get_Renamed(j); nc_idx = addMorpheme(info.tag, info.phoneme, sp.nextPosition(to), 0); chart[nc_idx].str = bufString.Substring(0, (i) - (0)); fromPos.morpheme[fromPos.morphCount++] = nc_idx; } } } // number dictionary if (nidx == 0 && toPos.nIndex != 0) { if (numDic.isNum(toPos.nIndex)) { nc_idx = addMorpheme(tagSet.numTag, TagSet.PHONEME_TYPE_ALL, sp.nextPosition(to), 0); chart[nc_idx].str = bufString.Substring(0, (i) - (0)); fromPos.morpheme[fromPos.morphCount++] = nc_idx; nidx = toPos.nIndex; } else { nidx = 0; } } } fromPos.state = SegmentPosition.SP_STATE_D; /* chart expansion regarding various rules */ goto case SegmentPosition.SP_STATE_D; case SegmentPosition.SP_STATE_D: exp.prule(from, morph.str, bufString, sp); sp.getPosition(from).state = SegmentPosition.SP_STATE_R; /* recursive processing */ goto case SegmentPosition.SP_STATE_R; case SegmentPosition.SP_STATE_R: x = 0; for (i = 0; i < fromPos.morphCount; i++) { mp = fromPos.morpheme[i]; // It prevents a recursive call for '습니다', which needs to be improved. if (tagSet.checkTagType(tagType, chart[mp].tag) == false) { continue; } // It prevents some redundant processing if (chart[mp].state == MORPHEME_STATE_INCOMPLETE) { y = analyze(mp, chart[mp].nextTagType); x += y; if (y != 0) { chart[mp].state = MORPHEME_STATE_SUCCESS; } else { chart[mp].state = MORPHEME_STATE_FAIL; } } else { x += chart[mp].connectionCount; } } if (x == 0) { if (tagType == TagSet.TAG_TYPE_ALL) { fromPos.state = SegmentPosition.SP_STATE_F; } return(0); } if (tagType == TagSet.TAG_TYPE_ALL) { fromPos.state = SegmentPosition.SP_STATE_M; } /* connecton rule */ goto case SegmentPosition.SP_STATE_M; case SegmentPosition.SP_STATE_M: for (i = 0; i < fromPos.morphCount; i++) { mp = fromPos.morpheme[i]; if (chart[mp].state == MORPHEME_STATE_SUCCESS && connection.checkConnection(tagSet, morph.tag, chart[mp].tag, morph.str.Length, chart[mp].str.Length, morph.nextTagType)) { morph.connection[morph.connectionCount++] = mp; } } break; } return(morph.connectionCount); }