/******************************************************************** Читаем из текстового файла секции расширенного описания статьи. Под расширенным описанием подразумевается список координат-атрибутов, формы, грамматическая сеть и специфические для производных классов поля. *********************************************************************/ void Base_Entry::LoadTxtEx( Macro_Parser& txtfile, Grammar& gram ) { // *** Считываем описание статьи *** bool looping = true; BethToken token; CP_Array common; while (looping) { if (txtfile.eof()) { Print_Error(txtfile); gram.GetIO().merr().printf("End of file has been reached before entry body completely loaded\n"); throw E_ParserError(); } const BSourceState back = txtfile.tellp(); token = txtfile.read(); if (token.GetToken() == B_CFIGPAREN) { // Описание статьи закончено looping = false; break; } if (token.GetToken() == B_OTRIPAREN) { txtfile.seekp(token.GetBegin()); SkipNetSection(txtfile, gram); continue; } if (ProcessSection(txtfile, gram, token)) continue; txtfile.seekp(back); if (LoadAttribute(txtfile, gram)) continue; // Загружаем словоформу. LoadForm( txtfile, gram, common, GramCoordAdr(UNKNOWN, UNKNOWN), UNKNOWN, GramCoordAdr(UNKNOWN, UNKNOWN), UNKNOWN, UNKNOWN ); } // конец цикла считывания описания статьи return; }
void SG_Language::LoadTxt(int Id, Macro_Parser& txt, GraphGram& gram) { // Store the beginning of language specification BSourceState beg = txt.tellp(); id = Id; name = txt.read().string(); const bool Me = gram.GetDict().GetDebugLevel_ir() >= 3; if (Me) { // Эхо-сообщение: начали трансляцию языка. gram.GetIO().mecho().printf( "%us [%vfE%us%vn]->", sol_get_token(B_LANGUAGE).c_str(), name.c_str() ); } BethToken t = txt.read(); if (t.GetToken() == B_AS) { c_name = txt.read().string(); t = txt.read(); } if (t.GetToken() != B_OFIGPAREN) { // Пустое объявление языка. txt.seekp(t.GetBegin()); } else { // Load the list of alphabets, allowed for the language. Also do load other // language parameters. while (!txt.eof()) { BethToken t = txt.read(); if (t.GetToken() == B_CFIGPAREN) break; if (t.GetToken() == B_ALPHABET) { // Add the valid alphabet name for this language BethToken abc_name = txt.read(); int id_abc = gram.Find_Alphabet(abc_name.string()); if (id_abc == UNKNOWN) { lem::Iridium::Print_Error(abc_name, txt); gram.GetIO().merr().printf("Unknown alphabet [%us] used in in language [%us] specification\n", abc_name.string().c_str(), name.c_str()); throw E_ParserError(); } alphabet.push_back(id_abc); continue; } else if (t.GetToken() == B_LINK) { Tree_Link l; l.LoadTxt(txt, gram.GetDict().GetSynGram()); txt.read_it(B_LANGUAGE); BethToken lang_name = txt.read(); int id_lang = gram.GetDict().GetSynGram().Find_Language(lang_name); if (id_lang == UNKNOWN) { lem::Iridium::Print_Error(lang_name, txt); gram.GetIO().merr().printf("Unknown language [%us] used in in language [%us] specification\n", lang_name.string().c_str(), name.c_str()); throw E_ParserError(); } lang_links.push_back(std::make_pair(l, id_lang)); continue; } else { // Синтаксис задания параметра: // 1. скалярный param_name = value // 2. векторный param_name = { value1 values2 ... } if (txt.pick().GetToken() == B_EQUAL) { txt.read_it(B_EQUAL); SG_LanguageParam *param = new SG_LanguageParam; param->name = t; if (txt.pick().GetToken() == B_OFIGPAREN) { txt.read_it(B_OFIGPAREN); while (!txt.eof()) { if (txt.pick().GetToken() == B_CFIGPAREN) { txt.read_it(B_CFIGPAREN); break; } UFString v = txt.read().GetFullStr(); v.strip(L'"'); v.trim(); param->values.push_back(v); } } else { param->values.push_back(lem::trim(lem::UFString(txt.read().GetFullStr()))); } params.push_back(param); continue; } } lem::Iridium::Print_Error(t, txt); gram.GetIO().merr().printf("Invalid token in language [%us] specification\n", name.c_str()); throw E_ParserError(); } } if (Me) { // Эхо-сообщение: закончили трансляцию. gram.GetIO().mecho().printf("%vfAOK%vn\n"); } return; }
/************************************************************************ Собственно, загрузка содержимого тела секции Автомата. Дабы позволить производным классам автоматов разпознавать и загружать свои собственные структуры данных сверх того, что распознает и загружает наш класс, вызывается виртуальный метод ProcessLexem. *************************************************************************/ void Automaton::load( Macro_Parser &txtfile, const Binarization_Options &options ) { bool looping=true; while( looping ) { if( txtfile.eof() ) { Print_Error(txtfile); GetIO().merr().printf( "End of file has been reached before Automaton [%us] section completely loaded\n" , GetName().c_str() ); throw E_ParserError(); } const BethToken t=txtfile.read(); if( !ProcessLexem(t,txtfile,options) ) { switch(t.GetToken()) { case B_CRITERION: if( param!=NULL ) param->LoadTxt( GetIO(), txtfile ); break; case B_CFIGPAREN: looping=false; break; default: { const BSourceState back=txtfile.tellp(); if( param!=NULL ) { if( txtfile.read().GetToken()==B_EQUAL ) { txtfile.seekp( t.GetBegin() ); param->LoadTxt(GetIO(),txtfile); break; } } else { LEM_STOPIT; } txtfile.seekp(back); // Нераспознанная лексема. GetIO().merr().printf( "\nIncorrect lexem [%us]\n", t.string().c_str() ); Print_Error(t,txtfile); throw E_ParserError(); } } } } return; }