// if(x) then ... else ... void TrFun_If::CompileDeclaration( PM_Automat &pm, lem::Iridium::Macro_Parser &txtfile, TrFunctions &functions, TrKnownVars &known_vars, const TrBuiltInFunSignature *signature ) { src_location = pm.GetDict().GetDebugSymbols().RegisterLocation( txtfile, txtfile.tellp() ); // ”словие опционально может быть заключено в круглые скобочки. const bool req_paren = txtfile.probe( B_OROUNDPAREN ); cond = functions.CompileCall( pm, txtfile, known_vars ); if( req_paren ) txtfile.read_it( B_CROUNDPAREN ); txtfile.read_it( B_THEN ); f_then = functions.CompileCall( pm, txtfile, known_vars ); txtfile.probe( B_SEMICOLON ); if( txtfile.pick().GetToken()==B_ELSE ) { txtfile.read_it(B_ELSE); f_else = functions.CompileCall( pm, txtfile, known_vars ); txtfile.probe( B_SEMICOLON ); } return; }
void SynPatterns::LoadTxt( Dictionary &dict, lem::Iridium::Macro_Parser & txtfile ) { lem::Iridium::BSourceState beg = txtfile.tellp(); SynPatternOptions *x = new SynPatternOptions(); x->LoadTxt( dict, txtfile ); if( IsPatternName(x->GetName()) ) { dict.GetIO().merr().printf( "Patterns group [%us] is already declared\n", x->GetName().c_str() ); lem::Iridium::Print_Error(beg,txtfile); throw lem::E_BaseException(); } if( dict.GetLexAuto().GetWordEntrySet().IsSetName(x->GetName()) ) { dict.GetIO().merr().printf( "%vfC%us%vn is a name of word entry set, word set or collocation set\n", x->GetName().c_str() ); lem::Iridium::Print_Error(beg,txtfile); throw lem::E_BaseException(); } const int id = GetNextTreeID(); options.push_back(x); lem::UCString uname( lem::to_upper(x->GetName() ) ); patterns.insert( std::make_pair( uname, x ) ); name2id.insert( std::make_pair( uname, id ) ); return; }
void LEMM_Compiler::LoadNGram( lem::Iridium::Macro_Parser & txtfile, Dictionary & dict, lem::MCollect<int> & terms, int order ) const { lem::Iridium::BSourceState beg = txtfile.tellp(); while( !txtfile.eof() ) { lem::Iridium::BethToken t = txtfile.read(); if( lem::is_int(t.string()) ) terms.push_back( lem::to_int(t.string()) ); else { txtfile.seekp(t); break; } } if( terms.size() != order+1 ) { dict.GetIO().merr().printf( "%vfDInvalid ngram%vn\n" ); lem::Iridium::Print_Error( beg, txtfile ); throw lem::E_ParserError(); } return; }
void TrFun_Lambda::CompileDeclaration( PM_Automat &pm, lem::Iridium::Macro_Parser &txtfile, TrFunctions &functions, TrKnownVars &known_vars, const TrBuiltInFunSignature *signature ) { src_location = pm.GetDict().GetDebugSymbols().RegisterLocation( txtfile, txtfile.tellp() ); ret_type = fun->ret_type; arg_name = fun->arg_name; return; }
void TrFun_Declare::CompileDeclaration( PM_Automat &pm, lem::Iridium::Macro_Parser &txtfile, TrFunctions &functions, const TrProcedureDeclaration &procs, TrKnownVars &known_vars, const TrBuiltInFunSignature *signature ) { src_location = pm.GetDict().GetDebugSymbols().RegisterLocation( txtfile, txtfile.tellp() ); var_type.LoadTxt(pm,txtfile,functions); while( !txtfile.eof() ) { TrFunCall *expr = NULL; const lem::Iridium::BethToken &vname = txtfile.read(); if( txtfile.pick().GetToken()==B_EQUAL ) { txtfile.read(); expr = functions.CompileCall( pm, txtfile, procs, known_vars ); } if( var_name.find(vname.string())!=UNKNOWN ) { lem::Iridium::Print_Error( vname, txtfile ); pm.GetIO().merr().printf( "Variable [%us] is already declared", vname.c_str() ); throw E_ParserError(); } var_name.push_back(vname); var_value.push_back(expr); known_vars.RegisterVar( var_type, vname ); if( txtfile.pick().GetToken()!=B_COMMA ) break; txtfile.read_it(B_COMMA); } txtfile.read_it(B_SEMICOLON); return; }
void PatternConstraints::LoadTxt( Dictionary &dict, lem::Iridium::Macro_Parser & txtfile, SynPatternCompilation & compilation_context ) { txtfile.read_it(B_OFIGPAREN); lem::Iridium::BSourceState beg = txtfile.tellp(); while (!txtfile.eof()) { if (txtfile.probe(B_CFIGPAREN)) break; PatternConstraint * c = new PatternConstraint(); c->LoadTxt(dict, txtfile, compilation_context); constraints.push_back(c); } return; }
void SyllabRule::LoadTxt( lem::Iridium::Macro_Parser &txtfile, Dictionary &dict ) { lem::Iridium::BSourceState point_begin = txtfile.tellp(); id_src = dict.GetDebugSymbols().RegisterLocation( txtfile, point_begin ); // шапка: syllab_rule XXXX language=YYY name = txtfile.read().string(); txtfile.read_it( B_LANGUAGE ); txtfile.read_it( B_EQUAL ); lem::Iridium::BethToken lang = txtfile.read(); id_language = dict.GetSynGram().Find_Language(lang.string()); if( id_language==UNKNOWN ) { lem::Iridium::Print_Error(lang,txtfile); dict.GetIO().merr().printf( "Unknown language name %us\n", lang.c_str() ); throw lem::E_BaseException(); } txtfile.read_it( B_OFIGPAREN ); txtfile.read_it( B_IF ); txtfile.read_it( B_CONTEXT ); condition.LoadTxt( txtfile, dict ); txtfile.read_it( B_THEN ); txtfile.read_it( B_OFIGPAREN ); txtfile.read_it( B_CONTEXT ); result.LoadTxt( txtfile, dict, condition ); txtfile.read_it( B_CFIGPAREN ); // закрываем блок then { ... } txtfile.read_it( B_CFIGPAREN ); // закрываем тело правила return; }
void TrFunction::CompileDeclaration( PM_Automat &pm, lem::Iridium::Macro_Parser &txtfile, TrFunctions &functions, const TrProcedureDeclaration &procs, const TrKnownVars *lambda_caller ) { const bool is_lambda = lambda_caller!=NULL; lem::Iridium::BSourceState fun_beg = txtfile.tellp(); ret_type.LoadTxt( pm, txtfile, functions ); lem::Iridium::BSourceState ss = txtfile.tellp(); try { if( is_lambda ) { // Формируем "невозможное" имя лямбда-функции, которое наверняка не будет // пересекаться с пользовательскими и встроенными функциями. static int lambda_number=0; name = L" $lambda"; name += to_ustr(lambda_number++); } else { name = txtfile.read(); } if( pm.GetDict().GetDebugLevel_ir()>=3 ) { // Печатаем имя транслируемой статьи для контроля за процессом // парсинга Словаря. pm.GetDict().GetIO().mecho().printf( "function [%vfA%us%vn]->", name.c_str() ); } if( !is_lambda && !CorrectName(name) ) { lem::Iridium::Print_Error( ss, txtfile ); pm.GetIO().merr().printf( "Invalid function name [%us]\n", name.c_str() ); throw E_ParserError(); } txtfile.read_it( B_OROUNDPAREN ); TrKnownVars call_vars( lambda_caller==NULL ? &functions.global_known_vars : lambda_caller ); // Список формальных аргументов while( !txtfile.eof() ) { if( txtfile.pick().GetToken()==B_CROUNDPAREN ) break; if( arg_name.size()>0 ) txtfile.read_it(B_COMMA); TrType at; at.LoadTxt(pm,txtfile,functions); const lem::Iridium::BethToken &an = txtfile.read(); if( arg_name.find(an)!=UNKNOWN ) { lem::Iridium::Print_Error( an, txtfile ); pm.GetIO().merr().printf( "Function [%us] call argument [%us] is already declared\n", name.c_str(), an.string().c_str() ); throw E_ParserError(); } arg_type.push_back(at); arg_name.push_back(an.string()); call_vars.RegisterVar( at, an.string() ); } txtfile.read_it( B_CROUNDPAREN ); if( txtfile.pick().GetToken()==B_SEMICOLON ) { txtfile.read(); // Это форвардное объявление функции, без определения тела. } else { // Чтобы компилировать рекурсивные функции, мы сейчас добавим в список функций свое форвардное объявление. if( !is_lambda && !functions.IsFunction(name) ) { TrFunction *forward = MakeForwardDeclaration(); functions.AddForwardDeclaration(forward); } // В фигурных скобочках - тело функции. Оно компилируется как вызов специальной функции-группы {} txtfile.read_it( B_OFIGPAREN ); txtfile.backward(); body = functions.CompileCall( pm, txtfile, procs, call_vars ); } if( pm.GetDict().GetDebugLevel_ir()>=3 ) pm.GetIO().mecho().printf( "%vfAOK%vn\n" ); } catch(...) { lem::Iridium::Print_Error( ss, txtfile ); pm.GetIO().merr().printf( "Error in function [%us] definition\n", name.c_str() ); throw; } return; }
void SynPattern::LoadTxt( Dictionary &dict, lem::Iridium::Macro_Parser & txtfile, const SynPatterns &patterns, WordEntrySet &wordentry_set, const TrProcedureDeclaration &procs, TrFunctions &functions ) { lem::Iridium::BSourceState pattern_beginning = txtfile.tellp(); id_src = dict.GetDebugSymbols().RegisterLocation( txtfile, txtfile.tellp() ); if( dict.GetDebugLevel_ir()>=3 ) { dict.GetIO().mecho().printf( "pattern " ); } // ќпционально могут быть заданы целевой ¤зык и опции. while( !txtfile.eof() ) { if( txtfile.probe( B_OFIGPAREN ) ) break; if( txtfile.probe( B_LANGUAGE ) ) { txtfile.read_it( B_EQUAL ); lem::Iridium::BethToken lang = txtfile.read(); id_language = dict.GetSynGram().Find_Language(lang.string()); if( id_language==UNKNOWN ) { lem::Iridium::Print_Error(lang,txtfile); dict.GetIO().merr().printf( "Unknown language name %us\n", lang.c_str() ); throw lem::E_BaseException(); } } else if( txtfile.probe( L"incomplete" ) ) { incomplete=true; } else { lem::Iridium::BethToken tname = txtfile.read(); name = tname.string(); if( dict.GetDebugLevel_ir()>=3 ) { dict.GetIO().mecho().printf( "%vfE%us%vn ", name.c_str() ); } if( !patterns.IsPatternName(name) ) { dict.GetIO().merr().printf( "Patterns group [%us] is not declared\n", name.c_str() ); lem::Iridium::Print_Error(tname,txtfile); throw lem::E_BaseException(); } const SynPatternOptions & group_options = patterns.GetOptions(name); id_language = group_options.GetLanguageId(); // —екци¤ export { ... } содержит объ¤влени¤ координат, которые паттерн выдает наружу // —начала попробуем вз¤ть содержимое экспорта по умолчанию, зарегистрированное в объ¤влении // группы паттернов. if( txtfile.probe(L"export") ) { export_info.LoadTxt( dict, txtfile ); } else { const SynPatternOptions & p_options = patterns.GetOptions(name); export_info = p_options.GetExport(); } export_info.RegisterExport( *compilation_context ); if( txtfile.probe( B_LANGUAGE ) ) { txtfile.read_it( B_EQUAL ); lem::Iridium::BethToken lang = txtfile.read(); id_language = dict.GetSynGram().Find_Language(lang.string()); if( id_language==UNKNOWN ) { lem::Iridium::Print_Error(lang,txtfile); dict.GetIO().merr().printf( "Unknown language name %us\n", lang.c_str() ); throw lem::E_BaseException(); } } txtfile.read_it( B_OFIGPAREN ); break; } } // —писок опорных точек в фигурных скобочках lem::Iridium::BSourceState beg = txtfile.tellp(); compilation_context->SetName( name ); compilation_context->Set(&wordentry_set); while( !txtfile.eof() ) { if( txtfile.pick().GetToken()==B_CFIGPAREN ) { txtfile.read(); break; } SlotProperties slot; slot.LoadTxt( dict, txtfile ); SynPatternPoint *p = new SynPatternPoint; p->LoadTxt( dict, txtfile, patterns, *compilation_context, procs, functions ); points.push_back(p); slots.push_back(slot); compilation_context->BeforeNextPointCompilation(); } if( points.empty() ) { lem::Iridium::Print_Error(beg,txtfile); dict.GetIO().merr().printf("Pattern must not be empty\n" ); throw E_Solarix(); } if( !compilation_context->PatternHasBeenCompiled(dict.GetSynGram()) ) { lem::Iridium::Print_Error(pattern_beginning,txtfile); dict.GetIO().merr().printf("Some export items are not actually exported\n" ); throw E_Solarix(); } points.back()->Terminator(); bool links_loaded=false, ngrams_loaded=false, predicates_loaded=false, constraints_loaded=false; while( !txtfile.eof() ) if( txtfile.probe(B_COLON) ) { lem::Iridium::BSourceState section_beg = txtfile.tellp(); if( txtfile.probe( L"links" ) ) { if( links_loaded ) { lem::Iridium::Print_Error(section_beg,txtfile); dict.GetIO().merr().printf("Redefinition of 'links'\n" ); throw E_Solarix(); } LoadLinks( dict, txtfile, *compilation_context ); links_loaded=true; } else if( txtfile.probe( L"ngrams" ) ) { if( ngrams_loaded ) { lem::Iridium::Print_Error(section_beg,txtfile); dict.GetIO().merr().printf("Redefinition of 'ngrams'\n" ); throw E_Solarix(); } LoadNGrams( dict, txtfile, *compilation_context ); ngrams_loaded=true; } else if( txtfile.probe( L"predicates" ) ) { if( predicates_loaded ) { lem::Iridium::Print_Error(section_beg,txtfile); dict.GetIO().merr().printf("Redefinition of 'predicates'\n" ); throw E_Solarix(); } LoadPredicates( dict, txtfile, *compilation_context ); predicates_loaded=true; } /* else if( sparse && txtfile.probe( L"constraints" ) ) { if( constraints_loaded ) { lem::Iridium::Print_Error(section_beg,txtfile); dict.GetIO().merr().printf("Redefinition of 'constraints'\n" ); throw E_Solarix(); } LoadConstraints( dict, txtfile, *compilation_context ); constraints_loaded=true; }*/ else { lem::Iridium::Print_Error(txtfile); dict.GetIO().merr().printf("Unexpected token\n" ); throw E_Solarix(); } } else { break; } // ќпорные точки могут теперь выполнить внутренние оптимизации, в частности - учесть использование // маркировок и улучшить эффективность директивы @mark() for( lem::Container::size_type i=0; i<points.size(); ++i ) points[i]->OptimizeAfterCompilation( *compilation_context ); // Ѕезым¤нные паттерны, то есть правила самого верхнего уровн¤, должны быть прив¤заны к ¤зыку с помощью директивы { language=XXX } if( id_language==UNKNOWN && name.empty() ) { lem::Iridium::Print_Error(pattern_beginning,txtfile); dict.GetIO().merr().printf("Pattern must be bound to a language\n" ); throw E_Solarix(); } if( dict.GetDebugLevel_ir()>=3 ) { dict.GetIO().mecho().printf( "%vfAOK%vn\n" ); } return; }
void TrFun_CreateWordform::CompileDeclaration( PM_Automat &pm, lem::Iridium::Macro_Parser &txtfile, TrFunctions &functions, const TrProcedureDeclaration &procs, TrKnownVars &known_vars, const TrBuiltInFunSignature *signature ) { lem::Iridium::BSourceState ebeg = txtfile.tellp(); SynGram &sg = pm.GetDict().GetSynGram(); const lem::Iridium::BethToken &class_name = txtfile.read(); const int iclass = sg.FindClass(class_name); txtfile.read_it( B_COLON ); lem::Iridium::BSourceState ename = txtfile.tellp(); UCString entry_name = sol_read_multyname( pm.GetIO(), txtfile, B_OFIGPAREN ); const int v_ientry = sg.FindEntry( entry_name, iclass, false ); if( v_ientry==UNKNOWN ) { lem::Iridium::Print_Error( ename, txtfile ); pm.GetIO().merr().printf( "Unknown entry [%vfE%us:%us%vn]\n", class_name.c_str(), entry_name.c_str() ); throw E_ParserError(); } ientry = new TrFun_Constant( TrIntValue(sg.GetEntry(v_ientry).GetKey()) ); while( !txtfile.eof() ) { if( txtfile.pick().GetToken()==B_CFIGPAREN ) { break; } // Координатная пара или имя формы слова в апострофах lem::Iridium::BethToken cn = txtfile.read(); if( lem::in_quotes(cn.string()) ) { form_name = strip_quotes(cn.string()); } else { bool AFFIRM=true; if( cn.GetToken()==B_NEGATIVE ) { // Оператор отрицания перед определением координаты! AFFIRM=false; cn = txtfile.read(); } // Для бистабильных - просто имя координаты. int icoord=UNKNOWN, istate=UNKNOWN; icoord = sg.FindCoord(cn).GetIndex(); if( icoord==UNKNOWN ) { lem::Iridium::Print_Error( cn, txtfile ); pm.GetIO().merr().printf( "Unknown coordinate [%vfE%us%vn]\n", cn.c_str() ); throw E_ParserError(); } if( sg.coords()[icoord].IsBistable() ) { istate=AFFIRM ? 1 : 0; } else { txtfile.read_it( B_COLON ); const lem::Iridium::BethToken & sn = txtfile.read(); istate = sg.coords()[icoord].FindState(sn); if( istate==UNKNOWN ) { // Нет такого состояния для этого измерения. lem::Iridium::Print_Error(sn,txtfile); sg.GetIO().merr().printf( "State [%vfE%us%vn] is not declared for coordinate [%vfE%us%vn]\n" , sn.c_str(), cn.c_str() ); throw E_ParserError(); } } TrIntValue v2( icoord ); coords.push_back( new TrFun_Constant(v2) ); TrIntValue v3( istate ); states.push_back( new TrFun_Constant(v3) ); } } txtfile.read_it( B_CFIGPAREN ); return; }