/******************************************************************** Подготавливаем кэш для работы: выделяем необходимую память для списка списков проекций. Эта процедура должна вызываться уже п_о_с_л_е загрузки графической грамматики, так как нам нужно узнать число символов в алфавите gram. Запомненные списки сейчас пусты, так как осуществленных проекций еще не было. *********************************************************************/ void LA_WordProjBuffer::Adjust( const GraphGram &gram ) { // Число символов в алфавите (не считая буквоформ) NTOT=0; const int nchar = CastSizeToInt(gram.entries().Count()); list.reserve(nchar); int i; // Будем поддерживать nchar списков списков проекций, каждый список хранит // начинающиеся с одной и той же буквы проекции мультилексем. lem::Ptr<SymbolEnumerator> senum( gram.entries().Enumerate() ); while( senum->Fetch() ) { list.push_back( LA_ProjList( senum->GetItem().GetName() ) ); } // Отсортируем список списков по возрастанию параметра КОД СИМВОЛА, // чтобы была возможность реализовать быстрый поиск нужного списка // методом дихотомии. int gap, j; const int N=nchar; for( gap=N/2; gap>0; gap/=2 ) for( i=gap; i<N; i++ ) for( j=i-gap; j>=0; j-=gap ) { if( list[j+gap].Char > list[j].Char ) break; std::swap( list[j], list[j+gap] ); } return; }
void LA_PhoneticCondictor::LoadTxt( Macro_Parser &txtfile, GraphGram &gram ) { txtfile.read_it(B_CONTEXT); const BethToken t = txtfile.read(); context = t.string(); context.strip_quotes(); // Каждый символ из строки должен быть известен как буква - то есть // быть определен через Алфавит. Допускается также специальный // кванторный символ '*'. // // В двух случаях допускается применение символа $ - для требования на // размещение символов: "$aaa" - приставка, "aaa$" - аффикс. if( context.front()==L'$' ) { loc = PREFIX; context.Remove(0); } else if( context.back()==L'$' ) { loc = AFFIX; context.Remove( context.length()-1 ); } else loc = UNLOCATED; const int cl=context.length(); for( int i=0; i<cl; i++ ) { const wchar_t ch = context[i]; if( ch==L'*' ) continue; const Word_Coord wc = gram.FindSymbol(ch); if( wc.GetEntry()==UNKNOWN ) { lem::Iridium::Print_Error( t, txtfile ); gram.GetIO().merr().printf( "Condictor [%us] contains unknown symbol (neither " "char nor quantor '*')\n" , context.c_str() ); throw E_ParserError(); } context.set( i, gram.entries()[wc.GetEntry()].GetName() ); } return; }
SyllabContext::SyllabContext(GraphGram &alphabet, const lem::UCString &word, int id_language) { LEM_CHECKIT_Z(id_language != UNKNOWN); const SG_Language &lang = alphabet.GetDict().GetSynGram().languages()[id_language]; const lem::MCollect<int> & id_alphabets = lang.GetAlphabets(); points.push_back(new SyllabContextLeftBoundary()); // Разбираем исходное слово по символам, каждый символ ищем в алфавите и создаем по результатам одну точку контекста lem::WideStringUcs4 ucs4(word.c_str()); lem::uint32_t c; while ((c = ucs4.Fetch()) != 0) { const Word_Coord wc = alphabet.entries().FindSymbol(c, id_alphabets); if (wc.IsUnknown()) { SyllabContextUnknownSymbol *point = new SyllabContextUnknownSymbol(c); points.push_back(point); } else { const GG_Entry &e = alphabet.entries()[wc.GetEntry()]; const int id_class = e.GetClass(); const GG_EntryForm & f = e.forms()[wc.GetForm()]; lem::MCollect<GramCoordPair> coords = f.dims(); for (lem::Container::size_type k = 0; k < e.attrs().size(); ++k) coords.push_back(e.attrs()[k]); SyllabContextSymbol *point = new SyllabContextSymbol(c, e.GetName(), wc.GetEntry(), id_class, coords); points.push_back(point); } } points.push_back(new SyllabContextRightBoundary()); return; }