void Word_Form::LoadPreciser( CompilationContext &context, Macro_Parser& txtfile, SynGram& gram, int iclass ) { // Тапереча в {} могет быть идти список уточняющих координат. // // Каждая уточняющая координата должна следовать такому формату: // // [~]имя_координаты:имя_состояния // // Причем, только если вместо имени статьи указан квантор всеобщности, // то разрешается задавать АТРИБУТЫ как координаты. // // Особо обрабатываются координаты с неявно объявленными состояниями // TRUE/FALSE. Следует учесть, что само упоминание имени такой координаты // равносильно упоминанию также и имени состояния TRUE, а для объявлени // состояния FALSE необходимо использовать конструкцию с оператором // отрицания НЕ. while(!txtfile.eof()) { // Считываем имя координаты. BethToken coord_name = txtfile.read(); // Может, список закончился, то есть встретилась '{' ? if( coord_name.GetToken()==B_CFIGPAREN ) break; // В двойных апострофах может идти имя формы, которую надо использовать вместо // имени словарной статьи. if( lem::in_quotes(coord_name.string()) ) { Lexem *mname = new Lexem( strip_quotes(coord_name) ); gram.GetDict().GetLexAuto().TranslateLexem(*mname,false); mname->Translate( gram.GetDict().GetGraphGram(), 2 ); name = RC_Lexem( mname ); } else { bool AFFIRM=true; if( coord_name.GetToken()==B_NEGATIVE ) { // Оператор отрицания перед определением координаты! AFFIRM=false; coord_name = txtfile.read(); } const GramCoordAdr iglob_coord = gram.FindCoord(coord_name.string()); // Попытаемся найти координату среди списка атрибутов и тэгов. int iloc_coord = gram.classes()[iclass].attrs().find(iglob_coord); // Нашли? if( iloc_coord!=UNKNOWN ) { // Да! Примем к сведению, что если для опорной точки задано // имя словарной статьи, то мы не имеем право по логике вещей // определять также и атрибуты, так как само определение словарной // статьи определяет необходимые атрибуты. if( entry_key!=ANY_STATE ) { lem::Iridium::Print_Error(coord_name,txtfile); gram.GetIO().merr().printf( "The attribute can not be declared here, because entry is already declared\n" ); throw E_ParserError(); } } else { // Попробуем найти координату среди списка измерений. iloc_coord = gram.classes()[iclass].dims().find(iglob_coord); if( iloc_coord==UNKNOWN ) iloc_coord = gram.classes()[iclass].tags().find(iglob_coord); // Нашли? if( iloc_coord==UNKNOWN && iclass!=SOL_EQUIL_INDEX ) { // Нет. Таким образом, имя координаты не определяет // ни тэг, ни измерение. Генерируем сообщение // об ошибке. lem::Iridium::Print_Error(coord_name,txtfile); gram.GetIO().merr() .printf( "Coordinate [%us] is neither tag" " nor dimention for the class [%us]\n" , coord_name.string().c_str() , gram.classes()[ iclass ].GetName().c_str() ); throw E_ParserError(); } } /*------------------------------------------------------------------------- Теперь считываем определение состояния. В некоторых случаях допускается такой формат записи: имя_координаты:=индекс Обычно так указываются те состояния, которые имеет данная координата у заданной индексом опорной точки контекста. Внутреннее описание в этом случае отличается от обычного лишь тем, что состояние имеет знак минус и хранит на самом деле числовое значение индекса минус единица, так что состояние -1 означает опорную точку 0, и так далее. Это сделано, чтобы корректно отличать случай состояния с нулевым индексом. -------------------------------------------------------------------------*/ int istate; const BSourceState back = txtfile.tellp(); if( txtfile.read().GetToken()==B_COLON && txtfile.read().GetToken()==B_EQUAL ) istate = -txtfile.read_int()-1; // Да, это формат ИМЯ_КООРД:=ИНДЕКС else { txtfile.seekp(back); // Является ли она бистабильной? if( gram.coords()[iglob_coord.GetIndex()].states().empty() ) { // Да - считывать имя состояния не надо. istate=AFFIRM; } else { // Индекс состояния у найденной координаты. txtfile.read_it(B_COLON); const BethToken state_name = txtfile.read(); istate = gram.coords()[iglob_coord.GetIndex()].FindState(state_name.string()); if( istate==UNKNOWN ) { lem::Iridium::Print_Error(state_name,txtfile); gram.GetIO().merr().printf( "State [%us] is not declared for coordinate [%us]\n" , state_name.c_str(), coord_name.c_str() ); throw E_ParserError(); } } } pair.push_back(GramCoordEx(iglob_coord,istate,AFFIRM)); } } // конец цикла считывания уточненных координат return; }
SG_calibrator::SG_calibrator(const lem::UCString & keyword, const SynGram &sg, const Sol_IO &io, Macro_Parser &txtfile) { if (keyword.eqi(L"wordentry_freq")) freq_type = WordEntryFreq; else if (keyword.eqi(L"wordform_score")) freq_type = WordFormScore; else if (keyword.eqi(L"wordforms_score")) freq_type = WordFormsScore; id_class = UNKNOWN; freq = 0; word = txtfile.read().string(); word.strip(L'"'); // если далее идет открывающая фигурная скобка, то значит конкретизируется словоформа (или несколько // словоформ). if (txtfile.probe(B_OFIGPAREN)) { while (!txtfile.eof()) { if (txtfile.pick().GetToken() == B_CFIGPAREN) { txtfile.read(); break; } // для обычных: координата:состояние // для бистабильных: координата lem::Iridium::BethToken coord_name = txtfile.read(); if (id_class == UNKNOWN) { const int id_class0 = sg.FindClass(coord_name); if (id_class0 != UNKNOWN) { id_class = id_class0; continue; } } bool AFFIRM = true; if (coord_name.GetToken() == B_NEGATIVE) { // Оператор отрицания перед определением координаты! AFFIRM = false; coord_name = txtfile.read(); } const GramCoordAdr iglob_coord = sg.FindCoord(coord_name.string()); if (!iglob_coord.IsDefined()) { sg.GetIO().merr().printf("Unknown coordinate %us\n", coord_name.c_str()); lem::Iridium::Print_Error(coord_name, txtfile); throw lem::E_BaseException(); } if (sg.coords()[iglob_coord.GetIndex()].IsBistable()) { // Имя состояния не может быть указано. coords.push_back(GramCoordPair(iglob_coord, AFFIRM)); } else { // После двоеточия должно идти имя состояния для координаты. txtfile.read_it(B_COLON); // Имя состояния. BethToken state_name = txtfile.read(); // Получим индекс состояния для определенной координаты. const int istate = sg.coords()[iglob_coord.GetIndex()] .FindState(state_name.string()); if (istate == UNKNOWN) { // Нет такого состояния для этого измерения. lem::Iridium::Print_Error(state_name, txtfile); sg.GetIO().merr().printf( "State [%vfE%us%vn] is not declared for coordinate [%vfE%us%vn]\n" , state_name.c_str(), coord_name.c_str() ); throw E_ParserError(); } coords.push_back(GramCoordEx(iglob_coord, istate, AFFIRM)); } } } txtfile.read_it(B_EQUAL); if (txtfile.probe(B_SUB)) freq = -txtfile.read_int(); else freq = txtfile.read_int(); return; }