void SG_CoordContext::SaveTxt( OFormatter &txt, SynGram &sg ) const { const UCString &class_name = sg.classes()[iclass].GetName(); txt.printf( " %us:\"???\" { " , class_name.c_str() ); for( Container::size_type k=0; k<coords.size(); k++ ) { const int icoord = coords[k].GetCoord().GetIndex(); const int istate = coords[k].GetState(); const UCString &coord_name = sg.coords()[ icoord ].GetName().front(); if( !sg.coords()[icoord].states().size() ) { if( istate!=0 ) txt.printf( " %us", coord_name.c_str() ); else txt.printf( " ~%us", coord_name.c_str() ); } else { const UCString &state_name = sg.coords()[ icoord ].GetStateName( istate ); txt.printf( " %us:%us", coord_name.c_str(), state_name.c_str() ); } } txt.printf( " }" ); return; }
void SG_NetLink::SaveTagsTxt( OFormatter &txtfile, SynGram &gram ) const { if( tags!=0 ) { txtfile.printf( " tags { " ); SG_TagsList tags_ptr = gram.Get_Net().tag_sets->operator [](tags); for( lem::Container::size_type i=0; i<tags_ptr->size(); ++i ) { const int itag = (*tags_ptr)[i].first; const int ival = (*tags_ptr)[i].second; const ThesaurusTag &tag = gram.Get_Net().GetTagDefs()[itag]; txtfile.printf( " \"%us\"", tag.GetName().c_str() ); if( ival!=UNKNOWN ) { const lem::UCString &val = tag[ival]; txtfile.printf( "=\"%us\"", val.c_str() ); } txtfile.printf( " }" ); } } return; }
void SG_EntryForm::SaveTxt( OFormatter& txtfile, Grammar &gram, const SG_Entry &entry ) const { const GramClass &c = gram.classes()[ entry.GetClass() ]; txtfile.printf( " " ); for( Container::size_type i=0; i<coords().size(); i++ ) { const GramCoordPair cp = coords()[i]; if( find( c.attrs(), cp.GetCoord() )!=UNKNOWN ) continue; const GramCoord& c = gram.coords()[cp.GetCoord().GetIndex()]; const UCString& dim_name = c.GetName()[cp.GetCoord().GetVar()]; if( !c.states().empty() ) { const UCString &state_name = c.GetStateName(cp.GetState()); if( c.IsDefState(cp.GetState()) && c.IsHeadState(cp.GetState() ) ) txtfile.printf( "%us%us%us%us%us ", dim_name.c_str(), sol_get_token(B_COLON).c_str(), sol_get_token(B_OROUNDPAREN).c_str(), state_name.c_str(), sol_get_token(B_CROUNDPAREN).c_str() ); else txtfile.printf( "%us%us%us ", dim_name.c_str(), sol_get_token(B_COLON).c_str(), state_name.c_str() ); } else { UCString prefix; if(!cp.GetState()) prefix=sol_get_token(B_NEGATIVE); txtfile.printf( "%us%us ", prefix.c_str(), dim_name.c_str() ); } } txtfile.printf( " %us %us %us\n", sol_get_token(B_OFIGPAREN).c_str(), content->c_str(), sol_get_token(B_CFIGPAREN).c_str() ); return; }
void Tree_Node::SaveTxt( OFormatter &txtfile, SynGram &gram, int Offset, bool detailed ) const { int offset = Offset; ilink.SaveTxt(txtfile, gram); GetNode().SaveTxt(txtfile, gram, detailed); if (!child.Empty()) { if (detailed) { txtfile << sol_get_token(B_DOT); if (child.size() != 1) txtfile << sol_get_token(B_OFIGPAREN); } if (offset != -1) { offset = txtfile.GetPos(); txtfile.eol(); } for (Container::size_type i = 0; i < child.size(); i++) { int of = offset; if (of == -1 && i) txtfile.printf(' '); if (of != -1) txtfile.printf("%H ", of); child[i].SaveTxt(txtfile, gram, of, detailed); } if (detailed) { if (offset != -1) txtfile.printf("%H ", offset - 1); if (child.size() != 1) txtfile << sol_get_token(B_CFIGPAREN); } } if (offset != -1) txtfile.eol(); return; }
void Word_Form::SaveTxtPreciser( OFormatter &txtfile, const SynGram *gram ) const { if( !gram ) return; const int npair = GetnPair(); for( int ipair=0; ipair<npair; ipair++ ) { if(ipair) txtfile.uprintf(L' '); const GramCoordAdr icoord = GetPair(ipair).GetCoord(); const int istate = GetPair(ipair).GetState(); const UCString dim_name = gram->coords()[icoord.GetIndex()].GetName().front(); if( gram->coords()[icoord.GetIndex()].states().empty() ) { if( istate==ANY_STATE ) txtfile.printf( "%us%us%us" , dim_name.c_str() , sol_get_token(B_COLON).c_str() , sol_get_token(B_ANY).c_str() ); else { // Бистабильные координаты выводим особым образом const UCString prefix = istate ? UCString("") : sol_get_token(B_NEGATIVE); txtfile.printf( "%us%us", prefix.c_str(), dim_name.c_str() ); } } else { UCString state_name; if( istate!=ANY_STATE ) state_name = gram->coords()[icoord.GetIndex()].GetStateName(istate); else state_name = sol_get_token(B_ANY); txtfile.printf( "%us%us%us" , dim_name.c_str() , sol_get_token(B_COLON).c_str() , state_name.c_str() ); } } return; }
// ******************************************************************** // Распечатка карты: краткая информация для прочтения программистом в // отладочных целях. // ******************************************************************** void SG_EntryGroup::Print( OFormatter &out ) const { if( key.second==0 ) out.printf( "%uc -> ", key.first ); else if( key.third==0 ) out.printf( "%uc%uc -> ", key.first, key.second ); else out.printf( "%uc%uc%uc -> ", key.first, key.second, key.third ); const int n=CastSizeToInt(size()); out.printf( "%d item(s), ", n ); if( !int1.empty() ) out.printf( "[%d...%d] ", int1.from, int1.from+int1.n-1 ); if( !int2.empty() ) out.printf( "[%d...%d] ", int2.from, int2.from+int2.n-1 ); if( !ientry.empty() ) { out.printf( "{ " ); for( Container::size_type i=0; i<ientry.size(); i++ ) out.printf( "%d ", ientry[i] ); out.printf( "}" ); } return; }
void ThesaurusTag::Save_SQL(OFormatter &out, const SQL_Production &sql_version) const { out.printf("INSERT INTO sg_tag( id, name ) VALUES ( %d, %us'%us' );\n" , id, sql_version.GetNPrefix(), sql_version.SqlStr(name).c_str()); for (lem::Container::size_type i = 0; i < values.size(); ++i) { out.printf("INSERT INTO sg_tag_value( id_tag, ivalue, name ) VALUES ( %d, %d, %us'%us' );\n", id, ivalues[i], sql_version.GetNPrefix(), sql_version.SqlStr(values[i]).c_str()); } return; }
/************************************************** Распечатка краткой справки о состоянии кэша. ***************************************************/ void LA_WordProjBuffer::Report( OFormatter &s, const LexicalAutomat &la ) const { const int n=NTOT; const int perc = int(n_succ*100l/(n_calls ? n_calls : 1)); const int stor_use = int((n*100l)/(nmaxproj ? nmaxproj : 1)); const int pus = int( n_succ_prim*100l/(n_succ ? n_succ : 1)); s.printf( "Word Projection Cache:\n" "%23h primary buffer contains %d items\n" "%23h this buffer successfully does %d%% of all projections through cache\n" "%23h secondary buffer contains %d items (%d%%)\n" "%23h maximum capacity of the secondary buffer is %d items\n" "%23h there were %d cache call(s)\n" "%23h there were %d successful cache hit(s) (%d%%)\n\n" , buffer.size() , pus , n , stor_use , nmaxproj , n_calls , n_succ , perc ); return; }
/********************************************************************* Свободная печать содержимого множества. Обычно вызывается при печати имен словарных статей во время компиляции с трассировкой. **********************************************************************/ void UCStringSet::Print( OFormatter &s ) const { s.printf( "%vfE" ); const int n=CastSizeToInt(size()); for( int i=0; i<n; i++ ) { s << get(i); if( i<n-1 ) s << " "; // Отдельные слова разделяем пробелом. } s.printf( "%vn" ); return; }
void Word_Form::PrintPlain( OFormatter &s, bool EntryKey ) const { if( EntryKey ) s.printf( "(" ); const int nver = 1+CastSizeToInt(GetAlts().size()); if( nver>1 ) s.printf( "%vf6((%vn" ); for( int iver=0; iver<nver; ++iver ) { if( iver>0 ) s.printf( " " ); const Word_Form &alt = iver==0 ? *this : *GetAlts()[iver-1]; if( name->Count_Lexems()==1 ) s.printf( "%vfE%us%vn", alt.name->c_str() ); else s.printf( "[%vfE%us%vn]", alt.name->c_str() ); if( EntryKey ) s.printf( " key=%d)", alt.GetEntryKey() ); } if( nver>1 ) s.printf( "%vf6))%vn" ); return; }
void Word_Form::SaveTxt( OFormatter &txtfile, SynGram &gram, bool detailed ) const { /* if( GetTField().IsDefined() ) { GetTField().SaveTxt(txtfile,gram); return; }*/ switch( GetEntryKey() ) { case ANY_STATE: txtfile.printf( "\"%us\"", sol_get_token(B_ANY).c_str() ); break; case UNKNOWN_STATE: { txtfile.printf( "\"%us\"", name->ToString().c_str() ); break; } default: { // ЏҐз в Ґ¬ Љ‹Ђ‘‘:‘’Ђ’њџ sol_print_class_entry( txtfile, gram, GetEntryKey() ); txtfile<<" "; break; } } // Ќ «ЁзЁҐ дЁЈгале бЄ®Ў®Є ў ®ЎйҐ¬ б«гз Ґ ®Ўп§ вҐ«м® - ®Ё пў«повбп // ®Ја ЁзЁвҐ«Ґ¬ ¬г«мвЁ«ҐЄбҐ¬®Ј® Ё¬ҐЁ бв вмЁ. txtfile<<sol_get_token(B_OFIGPAREN); if( detailed ) SaveTxtPreciser( txtfile, &gram ); txtfile<<sol_get_token(B_CFIGPAREN)<<" "; return; }
/******************************************************************** Метод вызывается обычно для печати в Журнале сведений о занимаемой Автоматом памяти, числе загруженных структур и так далее. *********************************************************************/ void Automaton::Report( OFormatter &mrep ) { mrep.printf( "Automaton [%us]:\n" , GetName().c_str() ); return; }
void GraphGram::SaveRules_SQL(OFormatter &out, OFormatter &alters, const SQL_Production &sql_version) { std::unique_ptr<CharOperationEnumerator> opers(GetCharOperations().ListOperations()); int id_seq = 1; while (opers->Fetch()) { const GG_CharOperation &op = opers->GetOperation(); out.printf("\n\nINSERT INTO abc_operation( id, name ) VALUES ( %d, '%us' );\n", op.GetId(), op.GetName().c_str()); for (std::map< lem::uint32_t, lem::uint32_t >::const_iterator it = op.Items().begin(); it != op.Items().end(); ++it) { out.printf("INSERT INTO abc_operation_item( id, id_operation, src_char_ucs4, res_char_ucs4, src_char, res_char )" " VALUES( %d, %d, %d, %d, '%uc', '%uc' );\n", id_seq++, op.GetId(), it->first, it->second, it->first, it->second); } } return; }
void Tree_Node::PrintPlain(OFormatter &s, bool EntryKey) const { GetNode().PrintPlain(s, EntryKey); if (!child.Empty()) { s.printf(" ( "); for (Container::size_type i = 0; i < child.size(); i++) { if (i) s.printf(", "); child[i].PrintPlain(s, EntryKey); } s.printf(" ) "); } return; }
void LA_WordProjBuffer::PrintMap( OFormatter &txtfile, SynGram &gram ) const { Report(txtfile,gram.GetDict().GetLexAuto()); txtfile.printf( "There are %d item(s) in word projection cache:\n", list.size() ); for( Container::size_type i=0; i<list.size(); i++ ) { list[i].PrintInfo(txtfile,gram); } txtfile.printf( "The end of word projection cache map.\n" ); return; }
void TreeScorerCall::PrintContext( Dictionary & dict, OFormatter & out ) const { out.printf( "Edges count=%d:\n", edges.size() ); for( int i=0; i<edges.size(); ++i ) { edges[i].from->Print( out, & dict.GetSynGram(), true ); const int lt = edges[i].link_type; out.printf( " --" ); if( lt==UNKNOWN ) out.printf( "<<UNKNOWN>>" ); else out.printf( "%us", dict.GetSynGram().GetLink(lt).c_str() ); out.printf( "--> " ); edges[i].to->Print( out, & dict.GetSynGram(), true ); out.eol(); } out.eol(); return; }
/***************************************************** Восстановление исходного кода реализации координаты. Код печатается в указанный текстовый поток. *****************************************************/ void GramCoord::SaveTxt(OFormatter& txtfile) const { txtfile.printf( " %us %us", sol_get_token(B_COORDINATE).c_str(), GetName().front().c_str() ); for (lem::Container::size_type ivar = 1; ivar < name.size(); ivar++) txtfile << sol_get_token(B_COMMA) << name[ivar]; if (state.empty()) txtfile.printf(" /* no states */\n"); else txtfile.printf( " /* %d state(s) */\n" , state.size() ); if (!state.empty()) { txtfile.printf(" %s ", sol_get_token(B_OFIGPAREN).c_str()); for (lem::Container::size_type i = 0; i < state.size(); i++) { GetTopState(i).SaveTxt(txtfile); txtfile.printf(' '); } txtfile << sol_get_token(B_CFIGPAREN); } txtfile.eol(); txtfile.eol(); return; }
void SaveSQL(OFormatter &out, const SQL_Production &sql_version) { const wchar_t* NPrefix = sql_version.GetNPrefix(); int id_pair = 0; for (lem::Container::size_type i = 0; i < ints_list.size(); ++i) { int id_pairs = CastSizeToInt(i); out.printf("INSERT INTO abc_pairs( id, str_pairs )" " VALUES( %d, %us'%us' );\n", id_pairs, NPrefix, ints_list[i]->c_str()); const CP_Array &p = *pairs_list[i]; for (lem::Container::size_type j = 0; j < p.size(); ++j) { out.printf("INSERT INTO abc_pair( id, id_pairs, id_coord, id_state )" " VALUES ( %d, %d, %d, %d );\n", id_pair++, id_pairs, p[j].GetCoord().GetIndex(), p[j].GetState()); } } return; }
/*********************************************************** Печатаем краткий отчет о состоянии Графической Грамматики. ************************************************************/ void GraphGram::Report(OFormatter &s) { Grammar::Report(s); // Подсчитываем общее число хранимых буквоформ. s.printf( "%W7d alphabet(s)\n" "%W7d entry(s)\n" "%W7d form(s)\n" , alphabet->Count() , symbols->Count() , symbols->CountForms() ); return; }
void LA_ProjList::PrintInfo( OFormatter &txtfile, SynGram &gram ) const { if( empty() ) // Чтобы не засорять листинг, пропускаем пустые списки... return; txtfile.printf( "\nList of cached projections beginning with symbol [%uc]:\n" , Char ); for( Container::size_type i=0; i<size(); i++ ) get(CastSizeToInt(i)).PrintInfo(txtfile,gram); return; }
void WordEntries_File::DetailedReport(OFormatter &txtfile) { txtfile.printf("\n%80h-\nLexical LookUp Table:\n"); /* for( std::map< SG_EntryGroup::KEY, SG_EntryGroup* >::const_iterator it=group.begin(); it!=group.end(); ++it ) { it->second->Print(txtfile); txtfile.eol(); } */ txtfile.printf("\n\n%10h- MULTILEXEM DICTIONARY %10h-\n\n"); txtfile.printf( "Multilexem dictionary contains %d unique items\n" , ml_ref.get_list().size() ); int n_real = 0; // счетчик реально многолексемных int max_len = 0; for (lem::Container::size_type i = 0; i < ml_ref.get_list().size(); i++) { if (ml_ref.get_list()[i].Count_Lexems() > 1) n_real++; max_len = std::max(max_len, ml_ref.get_list()[i].length()); } txtfile.printf("%d of them have more than 1 lexem:\n", n_real); txtfile.printf("Max length of a lexem=%d\n", max_len); for (lem::Container::size_type i4 = 0; i4 < ml_ref.get_list().size(); i4++) if (ml_ref.get_list()[i4].Count_Lexems() > 1) txtfile.printf("%us\n", ml_ref.get_list()[i4].c_str()); txtfile.printf("%10h- END OF MULTILEXEM DICTIONARY %10h-\n"); return; }
void PM_Automat::SaveRules_SQL( const char *marker, OFormatter &out, OFormatter &alters, const SQL_Production &sql_version ) { TrFunctions & funs = GetFunctions().Get(); lem::MemStream mem(true); funs.SaveBin(mem); const int sz = mem.tellp(); const char* bytes = mem.get_Block(); lem::FString hex; Solarix::Storage_Data2Hex( bytes, sz, hex ); if( sql_version.type==SQL_Production::SQLite ) { out.printf( "%s\n\n", sql_version.BeginTx().c_str() ); } if( sql_version.type==SQL_Production::SQLite ) { int segment_no=0; out.printf( "INSERT INTO tr_functions( segment_no, marker, bin ) VALUES ( %d, '%us', '%s' );\n\n", segment_no, sql_prefix, hex.c_str() ); } else { out.printf( "INSERT INTO tr_functions( marker, bin ) VALUES ( '%us', '%s' );\n\n", sql_prefix, hex.c_str() ); } /* lem::Ptr<ProcedureEnumerator> procs( procedures->ListProcedures() ); while( procs->Fetch() ) { const TrProcedure & p = procs->GetProcedure(); lem::MemStream mem(true); p.SaveBin(mem); const int sz = mem.tellp(); const char* bytes = mem.get_Block(); lem::FString hex; Storage_Data2Hex( bytes, sz, hex ); out.printf( "INSERT INTO tr_procedure( id, marker, name, bin, id_src ) VALUES ( %d, '%us', '%us', '%s', %d );\n" , procs->GetId(), sql_prefix, lem::to_upper(p.GetName()).c_str(), hex.c_str(), p.GetSourceLocation() ); } procs.Delete(); lem::Ptr<PatternMatcherEnumerator> matchers( procedures->ListMatchers() ); while( matchers->Fetch() ) { const int id = matchers->GetId(); const TrPatternMatcher & m = matchers->GetMatcher(); const int type = m.GetTypeForStorage(); lem::MemStream mem(true); m.SaveBin(mem); const int sz = mem.tellp(); const char* bytes = mem.get_Block(); lem::FString hex; Storage_Data2Hex( bytes, sz, hex ); if( sql_version.type==SQL_Production::SQLite ) { int id0=-1; int segment_no=-1; out.printf( "INSERT INTO pattern_matcher( id, id0, segment_no, type, marker, name, bin )" " VALUES ( %d, %d, %d, %d, '%us', '%us', '%s' );\n", id, id0, segment_no, type, sql_prefix, lem::to_upper(m.GetName()).c_str(), hex.c_str() ); } else { out.printf( "INSERT INTO pattern_matcher( id, type, marker, name, bin )" " VALUES ( %d, %d, '%us', '%us', '%s' );\n", id, type, sql_prefix, lem::to_upper(m.GetName()).c_str(), hex.c_str() ); } } matchers.Delete(); */ /* lem::Ptr<ProductionRuleEnumerator> rulz( production_rules->ListRules() ); while( rulz->Fetch() ) { const int id = rulz->GetId(); const PM_Rule & r = rulz->GetRule(); lem::MemStream mem(true); r.SaveBin(mem); const int sz = mem.tellp(); const char* bytes = mem.get_Block(); lem::FString hex; Storage_Data2Hex( bytes, sz, hex ); if( sql_version.type==SQL_Production::SQLite ) { int id0=-1; int segment_no=0; out.printf( "INSERT INTO production_rule( id, id0, segment_no, marker, name, id_language, bin, id_src )" " VALUES ( %d, %d, %d, '%us', '%us', %d, '%s', %d );\n" , id, id0, segment_no, sql_prefix, to_upper(r.GetName()).c_str(), r.GetLanguage(), hex.c_str(), r.GetSourceLocation() ); } else { out.printf( "INSERT INTO production_rule( id, marker, name, id_language, bin, id_src )" " VALUES ( %d, '%us', '%us', %d, '%s', %d );\n" , id, sql_prefix, to_upper(r.GetName()).c_str(), r.GetLanguage(), hex.c_str(), r.GetSourceLocation() ); } } rulz.Delete(); lem::Ptr<RuleCategoryEnumerator> groups( production_rules->ListGroups() ); while( groups->Fetch() ) { const int id = groups->GetId(); const PM_RulesInCategory & g = groups-> GetGroup(); lem::MemStream mem(true); g.SaveBin(mem); const int sz = mem.tellp(); const char* bytes = mem.get_Block(); lem::FString hex; Storage_Data2Hex( bytes, sz, hex ); out.printf( "INSERT INTO rules_in_category( id, marker, name, bin )" " VALUES ( %d, '%us', '%us', '%s' );\n", id, sql_prefix, lem::to_upper(g.GetName()).c_str(), hex.c_str() ); } groups.Delete(); */ if( sql_version.type==SQL_Production::SQLite ) { out.printf( "\n%s\n", sql_version.CommitTx().c_str() ); } return; }
void Tree_Node::PrintXML(OFormatter &xml, SynGram &gram) const { xml.printf("<node>"); xml.printf("<wordform>"); if (!node.IsNull()) node->PrintXML(xml, gram); xml.printf("</wordform>"); if (!child.Empty()) { xml.printf("<leaves count=\"%d\">", CastSizeToInt(child.size())); for (Container::size_type i = 0; i < child.size(); i++) { int link_type_id = child[i].GetLink().GetState(); lem::UCString link_name = link_type_id == UNKNOWN ? L"" : gram.GetLink(link_type_id); xml.printf("<leaf n=\"%d\" arc_type=\"%d\" arc_name=\"%us\">\n", CastSizeToInt(i), link_type_id, link_name.c_str()); child[i].PrintXML(xml, gram); xml.printf("</leaf>\n"); } xml.printf("</leaves>"); } if (!dims.empty()) { xml.printf("<dims count=\"%d\">", CastSizeToInt(dims.size())); for (lem::Container::size_type i = 0; i < dims.size(); ++i) { const TreeDimension &d = *dims[i]; xml.printf("<dim n=\"%d\" name=\"%us\">\n", CastSizeToInt(i), d.GetName().c_str()); d.PrintXML(xml, gram.GetDict()); xml.printf("</dim>\n"); } xml.printf("</dims>"); } if (!marks.empty()) { xml.printf("<marks count=\"%d\">", CastSizeToInt(marks.size())); for (lem::Container::size_type i = 0; i < marks.size(); ++i) { xml.printf("<mark n=\"%d\">\n", CastSizeToInt(i)); marks[i]->PrintXML(xml, gram.GetDict()); xml.printf("</mark>\n"); } xml.printf("</marks>"); } xml.printf("</node>"); return; }
void Tree_Node::Print(OFormatter &txtfile, SynGram &gram, int offset, bool detailed) const { int Offset = offset; if (offset > 0) txtfile.printf("%H ", offset); ilink.Print(txtfile, gram); if (node.IsNull()) txtfile.printf("%vfC(null)%vn"); else node->Print(txtfile, &gram, detailed); if (!child.Empty()) { if (detailed) { txtfile.printf('.'); if (child.size() != 1) txtfile.printf('{'); } if (Offset != -1) { txtfile.eol(); Offset++; } for (Container::size_type i = 0; i < child.size(); i++) { if (Offset == -1 && i) txtfile.printf(' '); if (Offset != -1) txtfile.printf("%H ", Offset); child[i].Print(txtfile, gram, Offset, detailed); } if (detailed) { if (offset != -1) txtfile.printf("%H ", Offset - 1); if (child.size() != 1) txtfile.printf('}'); } } if (!dims.empty()) { for (lem::Container::size_type i = 0; i < dims.size(); ++i) { const TreeDimension &d = *dims[i]; txtfile.printf(' '); d.Print(gram.GetDict(), txtfile, detailed); } } if (detailed && !marks.empty()) { txtfile.printf(" %vf6marks={%vn"); for (lem::Container::size_type i = 0; i < marks.size(); ++i) { txtfile.printf(' '); marks[i]->Print(gram.GetDict(), txtfile); } txtfile.printf(" %vf6}%vn"); } if (Offset != -1) txtfile.eol(); return; }
void LexicalAutomat::SaveRules_SQL( OFormatter &out, OFormatter &alters, const SQL_Production &sql_version ) { if( sql_version.norules ) return; PM_Automat::SaveRules_SQL( "la", out, alters, sql_version ); lem::Ptr<LS_ResultSet> rs_predicates( GetStorage().ListPredicateTemplate() ); while( rs_predicates->Fetch() ) { int id = rs_predicates->GetInt(0); lem::Ptr<PredicateTemplate> t( GetStorage().LoadPredicateTemplate(id) ); lem::UFString src( sql_version.SqlStr(t->GetSrc()) ); lem::UFString params; for( lem::Container::size_type i=0; i<t->GetParams().size(); ++i ) if( i>0 ) { params.Add_Dirty( L"," ); params.Add_Dirty( t->GetParams()[i].c_str() ); } else { params.Add_Dirty( t->GetParams()[i].c_str() ); } out.printf( "INSERT INTO predicate_template( src, params ) VALUES ( '%us', '%us' );\n", src.c_str(), params.c_str() ); } rs_predicates.Delete(); out.eol(); out.flush(); lem::Ptr<LS_ResultSet> rs_assocs( GetStorage().ListAssociatedEntries() ); while( rs_assocs->Fetch() ) { const int id = rs_assocs->GetInt(0); lem::Ptr<WordAssociation> assoc( GetStorage().LoadAssocitation(id) ); assoc->SaveSQL( out, sql_version ); } rs_assocs.Delete(); out.flush(); out.printf( "\n\n" ); lem::Ptr<LS_ResultSet> misspelling( GetStorage().ListMisspelling() ); while( misspelling->Fetch() ) { int id_language = misspelling->GetInt(1); UFString old_word = sql_version.SqlStr(misspelling->GetUFString(2)); UFString new_word = sql_version.SqlStr(misspelling->GetUFString(3)); old_word = sql_version.SqlStr(old_word); new_word = sql_version.SqlStr(new_word); out.printf( "INSERT INTO misspelling( id_language, original_word, substitution ) VALUES ( %d, '%us', '%us' );\n", id_language, old_word.c_str(), new_word.c_str() ); } misspelling.Delete(); out.eol(); lem::Ptr<WordEntrySetEnumerator> wordentry_sets( wordentry_set->ListWordEntrySets() ); while( wordentry_sets->Fetch() ) { const WordEntrySetItem &wes = wordentry_sets->GetItem(); lem::UFString s; for( std::set<int>::const_iterator it=wes.ies.begin(); it!=wes.ies.end(); ++it ) { if( !s.empty() ) s.Add_Dirty(L' '); s.Add_Dirty( lem::to_ustr(*it).c_str() ); } out.printf( "INSERT INTO word_entry_set( id, name, ies ) VALUES ( %d, '%us', '%us' );\n", wes.GetId(), lem::to_upper(wes.GetName()).c_str(), s.c_str() ); } wordentry_sets.Delete(); out.eol(); lem::Ptr<WordSetEnumerator> word_sets( wordentry_set->ListWordSets() ); while( word_sets->Fetch() ) { const WordSetItem &wes = word_sets->GetItem(); lem::UFString s; for( std::set<lem::UCString>::const_iterator it=wes.words.begin(); it!=wes.words.end(); ++it ) { if( !s.empty() ) s.Add_Dirty(LexiconStorage::WORD_SET_DELIMITER); s.Add_Dirty( sql_version.SqlStr(*it) ); } out.printf( "INSERT INTO word_set( id, name, words, case_sensitive ) VALUES ( %d, '%us', '%us', %d );\n", wes.GetId(), lem::to_upper(wes.GetName()).c_str(), s.c_str(), wes.case_sensitive ? 1 : 0 ); } word_sets.Delete(); out.eol(); // именованные наборы словосочетаний lem::Ptr<LS_ResultSet> rs_collocation_sets( storage->ListCollocationSets() ); while( rs_collocation_sets->Fetch() ) { int id = rs_collocation_sets->GetInt(0); lem::UFString name = sql_version.SqlStr(rs_collocation_sets->GetUFString(1)); int case_sensitive = rs_collocation_sets->GetInt(2); out.printf( "INSERT INTO collocation_set( id, name, case_sensitive ) VALUES ( %d, '%us', %d );\n", id, name.c_str(), case_sensitive ); } rs_collocation_sets.Delete(); lem::Ptr<LS_ResultSet> rs_collocation_items( storage->ListCollocationSetItems() ); while( rs_collocation_items->Fetch() ) { int id = rs_collocation_items->GetInt(0); int id_set = rs_collocation_items->GetInt(1); lem::UFString words = sql_version.SqlStr(rs_collocation_items->GetUFString(2)); int n_word = rs_collocation_items->GetInt(3); lem::UFString headword = sql_version.SqlStr(rs_collocation_items->GetUFString(4)); out.printf( "INSERT INTO collocation_set_item( id, id_set, words, n_word, headword ) VALUES ( %d, %d, '%us', %d, '%us' );\n", id, id_set, words.c_str(), n_word, headword.c_str() ); } rs_collocation_items.Delete(); lem::Ptr<LS_ResultSet> rs_collocation_headwords( storage->ListCollocationSetHeadwords() ); while( rs_collocation_headwords->Fetch() ) { int id = rs_collocation_headwords->GetInt(0); lem::UFString headword = sql_version.SqlStr(rs_collocation_headwords->GetUFString(1)); int min_len = rs_collocation_headwords->GetInt(2); int max_len = rs_collocation_headwords->GetInt(3); out.printf( "INSERT INTO collocation_headword( id, headword, min_len, max_len ) VALUES ( %d, '%us', %d, %d );\n", id, headword.c_str(), min_len, max_len ); } rs_collocation_headwords.Delete(); // -------------------------------------------- lem::Ptr<LS_ResultSet> rs_wordform_sets( storage->ListWordformSets() ); while( rs_wordform_sets->Fetch() ) { int id = rs_wordform_sets->GetInt(0); lem::UFString name = sql_version.SqlStr(rs_wordform_sets->GetUFString(1)); out.printf( "INSERT INTO wordform_set( id, name ) VALUES ( %d, '%us' );\n", id, name.c_str() ); } rs_wordform_sets.Delete(); lem::Ptr<LS_ResultSet> rs_wordform_set_coords( storage->ListWordformSetCoords() ); while( rs_wordform_set_coords->Fetch() ) { int id = rs_wordform_set_coords->GetInt(0); lem::UFString coords = rs_wordform_set_coords->GetUFString(1); out.printf( "INSERT INTO wordform_set_coords( id, coords ) VALUES ( %d, '%us' );\n", id, coords.c_str() ); } rs_wordform_set_coords.Delete(); lem::Ptr<LS_ResultSet> rs_wordform_set_items( storage->ListWordformSetItems() ); while( rs_wordform_set_items->Fetch() ) { const int id = rs_wordform_set_items->GetInt(0); const int id_set = rs_wordform_set_items->GetInt(1); lem::UFString word = sql_version.SqlStr( rs_wordform_set_items->GetUFString(2) ); const int id_entry = rs_wordform_set_items->GetInt(3); const int id_coords = rs_wordform_set_items->GetInt(4); out.printf( "INSERT INTO wordform_set_item( id, id_set, word, id_entry, id_coords ) VALUES ( %d, %d, '%us', %d, %d );\n", id, id_set, word.c_str(), id_entry, id_coords ); } rs_wordform_set_items.Delete(); // -------------------------------------------- lem::Ptr<LS_ResultSet> rs_unb( storage->ListUnbreakableRules(ANY_STATE) ); while( rs_unb->Fetch() ) { const int id_rule = rs_unb->GetInt(0); lem::Ptr<LA_UnbreakableRule> rule( storage->GetUnbreakableRule(id_rule) ); lem::UFString pattern(rule->GetPattern()); pattern = sql_version.SqlStr(pattern); out.printf( "INSERT INTO unbreakable( id, name, id_language, is_regex," " pattern, id_src ) VALUES ( %d, '%us', %d, %d, '%us', %d );\n", rule->GetId(), lem::to_upper(rule->GetName()).c_str(), rule->GetLanguage(), rule->IsRegex() ? 1 : 0, pattern.c_str(), rule->GetSourceLocation() ); } out.eol(); lem::Ptr<LS_ResultSet> rs_recog = storage->ListRecognitionRules(ANY_STATE,true); while( rs_recog->Fetch() ) { const int id = rs_recog->GetInt(0); lem::Ptr<LA_RecognitionRule> rule = storage->GetRecognitionRule(id); lem::UFString condition(rule->GetCondition()); condition = sql_version.SqlStr(condition); lem::UFString word; if( rule->IsWordMatcher() ) { word = sql_version.SqlStr(condition); word.dress(L'\''); } else word = L"NULL"; lem::UFString coords; coords.reserve(64); for( lem::Container::size_type i=0; i<rule->GetCoords().size(); ++i ) { if( i>0 ) coords.Add_Dirty(L' '); coords.Add_Dirty( to_ustr( rule->GetCoords()[i].GetCoord().GetIndex() ).c_str() ); coords.Add_Dirty( L':' ); coords.Add_Dirty( to_ustr( rule->GetCoords()[i].GetState() ).c_str() ); } out.printf( "INSERT INTO recog_rule( id, name, id_language, is_syllab, is_regex, is_prefix, is_affix," " r_condition, id_entry, rel, coords, id_src, word ) VALUES ( %d, '%us', %d, %d, %d, %d, %d, '%us', %d, %d, '%us', %d, %us );\n", rule->GetId(), lem::to_upper(rule->GetName()).c_str(), rule->GetLanguage(), rule->IsSyllab() ? 1 : 0, rule->IsRegex() ? 1 : 0, rule->IsPrefix() ? 1 : 0, rule->IsAffix() ? 1 : 0, condition.c_str(), rule->GetEntryKey(), rule->GetRel().GetInt(), coords.c_str(), rule->GetSourceLocation(), word.c_str() ); } out.eol(); lem::Ptr<LS_ResultSet> rs_ph( storage->ListPhoneticRules(ANY_STATE) ); while( rs_ph->Fetch() ) { int id = rs_ph->GetInt(0); lem::Ptr<LA_PhoneticRule> rule = storage->GetPhoneticRule(id); lem::UFString condition(rule->GetCondition().GetContext().c_str()); condition = sql_version.SqlStr(condition); lem::UFString result(rule->GetResult().GetContext().c_str()); result = sql_version.SqlStr(result); out.printf( "INSERT INTO ph_rule( id, name, id_language, is_prefix, is_affix," " r_condition, r_result, rel, id_src ) VALUES ( %d, '%us', %d, %d, %d, '%us', '%us', %d, %d );\n", rule->GetId(), lem::to_upper(rule->GetName()).c_str(), rule->GetLanguage(), rule->IsPrefix() ? 1 : 0, rule->IsAffix() ? 1 : 0, condition.c_str(), result.c_str(), rule->GetVal().GetInt(), rule->GetSourceLocation() ); } out.eol(); lem::Ptr<LS_ResultSet> rs_syn = storage->ListSynPatternTrees(); while( rs_syn->Fetch() ) { const int id_tree = rs_syn->GetInt(0); const lem::UCString name = rs_syn->GetUCString(1); const lem::UCString uname = rs_syn->GetUCString(2); const int id_language = rs_syn->GetInt(3); const int pattern_type = rs_syn->GetInt(4); std::pair<SynPatternTreeNode*,lem::UCString> tree_name = storage->GetSynPatternTree(id_tree); lem::Ptr<SynPatternTreeNode> tree = tree_name.first; lem::MemStream mem(true); tree->SaveBin(mem); const int sz = mem.tellp(); const char* bytes = mem.get_Block(); lem::FString hex; Storage_Data2Hex( bytes, sz, hex ); if( sql_version.type==SQL_Production::SQLite ) { int id0=-1; int segment_no=0; out.printf( "INSERT INTO SynPatternTree( id_tree, id0, segment_no, name, uname, id_language, pattern_type, bin )" " VALUES ( %d, %d, %d, '%us', '%us', %d, %d, X'%s' );\n", id_tree, id0, segment_no, name.c_str(), uname.c_str(), id_language, pattern_type, hex.c_str() ); } else { out.printf( "INSERT INTO SynPatternTree( id_tree, name, uname, id_language, pattern_type, bin )" " VALUES ( %d, '%us', '%us', %d, %d, 0x%s );\n", id_tree, name.c_str(), uname.c_str(), id_language, pattern_type, hex.c_str() ); } } out.eol(); lem::Ptr<LS_ResultSet> rs_c = storage->ListCropRules(ANY_STATE); while( rs_c->Fetch() ) { const int id = rs_c->GetInt(0); lem::Ptr<LA_CropRule> rule = storage->GetPreprocessorCropRule(id); lem::UFString condition(rule->GetCondition()); condition = sql_version.SqlStr(condition); lem::UFString result(rule->GetResult()); result = sql_version.SqlStr(result); out.printf( "INSERT INTO crop_rule( id, name, id_language, is_prefix, is_affix," " r_condition, r_result, is_regex, case_sensitive, id_src, rel )" " VALUES ( %d, '%us', %d, %d, %d, '%us', '%us', %d, %d, %d, %d );\n", id, lem::to_upper(rule->GetName()).c_str(), rule->GetLanguage(), rule->IsPrefix() ? 1 : 0, rule->IsAffix() ? 1 : 0, condition.c_str(), result.c_str(), rule->IsRegex() ? 1 : 0, rule->IsCaseSensitive() ? 1 : 0, rule->GetSourceLocation(), rule->GetRel().GetInt() ); } out.eol(); // ------------------ // база знаний // ------------------ lem::Ptr<LS_ResultSet> rs_kb1 = storage->ListFactGroups(); while( rs_kb1->Fetch() ) { const int id = rs_kb1->GetInt(0); const int id_language = rs_kb1->GetInt(1); lem::UCString name = rs_kb1->GetUCString(2); const int n_arg = rs_kb1->GetInt(3); const int n_ret = rs_kb1->GetInt(4); const int query_mode = rs_kb1->GetInt(5); const int ret_type = rs_kb1->GetInt(6); const int violation_score = rs_kb1->GetInt(7); const int violation_handler = rs_kb1->GetInt(8); out.printf( "INSERT INTO kb_facts( id, id_language, name, n_arg, n_ret, query_mode, ret_type, violation_score, violation_handler ) VALUES ( %d, %d, '%us', %d, %d, %d, %d, %d, %d );\n" , id, id_language, name.c_str(), n_arg, n_ret, query_mode, ret_type, violation_score, violation_handler ); } rs_kb1.Delete(); out.printf( "\n\n" ); lem::Ptr<LS_ResultSet> rs_kb2 = storage->ListFacts(); lem::UCString null_str(L"NULL"); while( rs_kb2->Fetch() ) { const int id = rs_kb2->GetInt(0); const int id_group = rs_kb2->GetInt(1); const int boolean_return = rs_kb2->GetInt(2); const int integer_return = rs_kb2->GetInt(3); lem::CString bool_ret, int_ret; if( boolean_return==-1 ) bool_ret = "NULL"; else bool_ret = lem::to_str(boolean_return); if( integer_return==-1 ) int_ret = "NULL"; else int_ret = lem::to_str(integer_return); const int false_score = rs_kb2->GetInt(14); out.printf( "INSERT INTO kb_fact( id, id_group, boolean_return, integer_return, false_score )" " VALUES ( %d, %d, %d, %d, %d );\n" , id, id_group, bool_ret.c_str(), int_ret.c_str(), false_score ); } rs_kb2.Delete(); out.printf( "\n\n" ); lem::Ptr<LS_ResultSet> rs_kbi1 = storage->ListFactIndex1(); while( rs_kbi1->Fetch() ) { const int id = rs_kbi1->GetInt(0); const int id_group = rs_kbi1->GetInt(1); const int id_fact = rs_kbi1->GetInt(2); lem::UCString word1 = rs_kbi1->GetUCString(9); lem::UCString word2 = rs_kbi1->GetUCString(10); lem::UCString word3 = rs_kbi1->GetUCString(11); lem::UCString word4 = rs_kbi1->GetUCString(12); lem::UCString word5 = rs_kbi1->GetUCString(13); if( word1.empty() ) word1 = null_str; else word1.dress_apostrophes(); if( word2.empty() ) word2 = null_str; else word2.dress_apostrophes(); if( word3.empty() ) word3 = null_str; else word3.dress_apostrophes(); if( word4.empty() ) word4 = null_str; else word4.dress_apostrophes(); if( word5.empty() ) word5 = null_str; else word5.dress_apostrophes(); const int false_score = rs_kbi1->GetInt(14); out.printf( "INSERT INTO kb_fact_index1( id, id_group, id_fact," " word1, word2, word3, word4, word5" " ) VALUES ( %d, %d, %d," " %s, %s, %s, %s, %s );\n" , id, id_group, id_fact , word1.c_str(), word2.c_str(), word3.c_str(), word4.c_str(), word5.c_str() ); } rs_kbi1.Delete(); out.printf( "\n\n" ); lem::Ptr<LS_ResultSet> rs_kbi2 = storage->ListFactIndex2(); while( rs_kbi2->Fetch() ) { const int id = rs_kbi2->GetInt(0); const int id_group = rs_kbi2->GetInt(1); const int id_fact = rs_kbi2->GetInt(2); const int id_entry1 = rs_kbi2->GetInt(4); const int id_entry2 = rs_kbi2->GetInt(5); const int id_entry3 = rs_kbi2->GetInt(6); const int id_entry4 = rs_kbi2->GetInt(7); const int id_entry5 = rs_kbi2->GetInt(8); CString entry1("NULL"), entry2("NULL"), entry3("NULL"), entry4("NULL"), entry5("NULL"); if( id_entry1!=-1 ) entry1 = lem::to_str(id_entry1); if( id_entry2!=-1 ) entry2 = lem::to_str(id_entry2); if( id_entry3!=-1 ) entry3 = lem::to_str(id_entry3); if( id_entry4!=-1 ) entry4 = lem::to_str(id_entry4); if( id_entry5!=-1 ) entry5 = lem::to_str(id_entry5); out.printf( "INSERT INTO kb_fact_index2( id, id_group, id_fact," " id_entry1, id_entry2, id_entry3, id_entry4, id_entry5" " ) VALUES ( %d, %d, %d," " %s, %s, %s, %s, %s );\n" , id, id_group, id_fact , entry1.c_str(), entry2.c_str(), entry3.c_str(), entry4.c_str(), entry5.c_str() ); } rs_kbi2.Delete(); out.printf( "\n\n" ); lem::Ptr<LS_ResultSet> rs_kb3 = storage->ListFactArguments(); while( rs_kb3->Fetch() ) { const int id = rs_kb3->GetInt(0); const int id_fact = rs_kb3->GetInt(1); const int argument_index = rs_kb3->GetInt(2); lem::UFString word_text( sql_version.SqlStr(rs_kb3->GetUFString(3)) ); const int id_entry = rs_kb3->GetInt(4); const int id_class = rs_kb3->GetInt(5); lem::UFString wordentryset_name( sql_version.SqlStr(rs_kb3->GetUFString(6)) ); lem::UFString wordset_name( sql_version.SqlStr(rs_kb3->GetUFString(7)) ); const int n_coords = rs_kb3->GetInt(8); const int id_coord1 = rs_kb3->GetInt(9); const int id_state1 = rs_kb3->GetInt(10); const int affirm1 = rs_kb3->GetInt(11); const int id_coord2 = rs_kb3->GetInt(12); const int id_state2 = rs_kb3->GetInt(13); const int affirm2 = rs_kb3->GetInt(14); const int id_coord3 = rs_kb3->GetInt(15); const int id_state3 = rs_kb3->GetInt(16); const int affirm3 = rs_kb3->GetInt(17); const int id_coord4 = rs_kb3->GetInt(18); const int id_state4 = rs_kb3->GetInt(19); const int affirm4 = rs_kb3->GetInt(20); const int thesauruscheck_link = rs_kb3->GetInt(21); const int thesauruscheck_entry = rs_kb3->GetInt(22); const int is_positive = rs_kb3->GetInt(23); const int is_regex = rs_kb3->GetInt(24); const int case_sensitive = rs_kb3->GetInt(25); const int id_metaentry = rs_kb3->GetInt(26); out.printf( "INSERT INTO kb_argument_point(" " id, id_fact, argument_index, word_text, id_entry," " id_class, wordentryset_name, wordset_name, n_coords, id_coord1," " id_state1, affirm1, id_coord2, id_state2, affirm2," " id_coord3, id_state3, affirm3, id_coord4, id_state4," " affirm4, thesauruscheck_link, thesauruscheck_entry, is_positive," " is_regex, case_sensitive, id_metaentry" " ) VALUES (" " %d, %d, %d, '%us', %d," " %d, '%us', '%us', %d, %d," " %d, %d, %d, %d, %d," " %d, %d, %d, %d, %d," " %d, %d, %d, %d," " %d, %d, %d );\n", id, id_fact, argument_index, word_text.c_str(), id_entry, id_class, wordentryset_name.c_str(), wordset_name.c_str(), n_coords, id_coord1, id_state1, affirm1, id_coord2, id_state2, affirm2, id_coord3, id_state3, affirm3, id_coord4, id_state4, affirm4, thesauruscheck_link, thesauruscheck_entry, is_positive, is_regex, case_sensitive, id_metaentry ); } rs_kb3.Delete(); out.printf( "\n\n" ); // ---- Выгружаем tree scorers lem::Ptr<LS_ResultSet> ts_head_lemma( GetStorage().ListTreeScorerLemmas() ); while( ts_head_lemma->Fetch() ) { int id_entry = ts_head_lemma->GetInt(0); int id_head_point = ts_head_lemma->GetInt(1); int score_type = ts_head_lemma->GetInt(2); UFString score_expr = ts_head_lemma->GetUFString(3); int root_node = ts_head_lemma->GetInt(4); int id_group = ts_head_lemma->GetInt(5); out.printf( "INSERT INTO ts_head_lemma( id_entry, id_head_point, score_type, score_expr, root_node, id_group ) VALUES ( %d, %d, %d, '%us', %d, %d );\n", id_entry, id_head_point, score_type, score_expr.c_str(), root_node, id_group ); } ts_head_lemma.Delete(); out.eol(); lem::Ptr<LS_ResultSet> ts_head_word( GetStorage().ListTreeScorerWords() ); while( ts_head_word->Fetch() ) { lem::UFString word_text( sql_version.SqlStr(ts_head_word->GetUFString(0)) ); int id_head_point = ts_head_word->GetInt(1); int score_type = ts_head_word->GetInt(2); UFString score_expr = ts_head_word->GetUFString(3); int root_node = ts_head_word->GetInt(4); int id_group = ts_head_word->GetInt(5); out.printf( "INSERT INTO ts_head_word( word, id_head_point, score_type, score_expr, root_node, id_group ) VALUES ( '%us', %d, %d, '%us', %d, %d );\n", word_text.c_str(), id_head_point, score_type, score_expr.c_str(), root_node, id_group ); } ts_head_word.Delete(); out.eol(); lem::Ptr<LS_ResultSet> ts_point = storage->ListTreeScorerPoints(); while( ts_point->Fetch() ) { const int id = ts_point->GetInt(0); const int id_parent = ts_point->GetInt(1); lem::UFString word_text( sql_version.SqlStr(ts_point->GetUFString(2)) ); const int id_entry = ts_point->GetInt(3); const int id_class = ts_point->GetInt(4); lem::UFString wordentryset_name( sql_version.SqlStr(ts_point->GetUFString(5)) ); lem::UFString wordset_name( sql_version.SqlStr(ts_point->GetUFString(6)) ); lem::UFString wordformset_name( sql_version.SqlStr(ts_point->GetUFString(7)) ); const int n_coords = ts_point->GetInt(8); const int id_coord1 = ts_point->GetInt(9); const int id_state1 = ts_point->GetInt(10); const int affirm1 = ts_point->GetInt(11); const int id_coord2 = ts_point->GetInt(12); const int id_state2 = ts_point->GetInt(13); const int affirm2 = ts_point->GetInt(14); const int id_coord3 = ts_point->GetInt(15); const int id_state3 = ts_point->GetInt(16); const int affirm3 = ts_point->GetInt(17); const int id_coord4 = ts_point->GetInt(18); const int id_state4 = ts_point->GetInt(19); const int affirm4 = ts_point->GetInt(20); const int thesauruscheck_link = ts_point->GetInt(21); const int thesauruscheck_entry = ts_point->GetInt(22); const int is_positive = ts_point->GetInt(23); const int children_quantification_min_count = ts_point->GetInt(24); const int children_quantification_max_count = ts_point->GetInt(25); const int n_set_checkers = ts_point->GetInt(26); lem::UFString set_name1( sql_version.SqlStr(ts_point->GetUFString(27)) ); const int set_type1 = ts_point->GetInt(28); const int set_affirm1 = ts_point->GetInt(29); lem::UFString set_name2( sql_version.SqlStr(ts_point->GetUFString(30)) ); const int set_type2 = ts_point->GetInt(31); const int set_affirm2 = ts_point->GetInt(32); lem::UFString set_name3( sql_version.SqlStr(ts_point->GetUFString(33)) ); const int set_type3 = ts_point->GetInt(34); const int set_affirm3 = ts_point->GetInt(35); const int link_type = ts_point->GetInt(36); const int id_metaentry = ts_point->GetInt(37); const int relative_position = ts_point->GetInt(38); const int id_src = ts_point->GetInt(39); const int id_group = ts_point->GetInt(40); const int quantification_min_count = ts_point->GetInt(41); const int quantification_max_count = ts_point->GetInt(42); lem::UFString marker( sql_version.SqlStr(ts_point->GetUFString(43)) ); const int n_backref = ts_point->GetInt(44); int br_affirm_0 = -1; int br_coord0_0 = -1; lem::UFString br_marker_0; int br_coord1_0 = -1; int br_for_group_0 = -1; int br_affirm_1 = -1; int br_coord0_1 = -1; lem::UFString br_marker_1; int br_coord1_1 = -1; int br_for_group_1 = -1; int br_affirm_2 = -1; int br_coord0_2 = -1; lem::UFString br_marker_2; int br_coord1_2 = -1; int br_for_group_2 = -1; if( n_backref>0 ) { br_affirm_0 = ts_point->GetInt(45); br_coord0_0 = ts_point->GetInt(46); br_marker_0 = sql_version.SqlStr(ts_point->GetUFString(47)); br_coord1_0 = ts_point->GetInt(48); br_for_group_0 = ts_point->GetInt(49); } if( n_backref>1 ) { br_affirm_1 = ts_point->GetInt(50); br_coord0_1 = ts_point->GetInt(51); br_marker_1 = sql_version.SqlStr(ts_point->GetUFString(52)); br_coord1_1 = ts_point->GetInt(53); br_for_group_1 = ts_point->GetInt(54); } if( n_backref>2 ) { br_affirm_2 = ts_point->GetInt(55); br_coord0_2 = ts_point->GetInt(56); br_marker_2 = sql_version.SqlStr(ts_point->GetUFString(57)); br_coord1_2 = ts_point->GetInt(58); br_for_group_2 = ts_point->GetInt(59); } LEM_CHECKIT_Z( n_backref<=3 ); out.printf( "INSERT INTO ts_point(" " id, id_parent, word_text, id_entry," " id_class, wordentryset_name, wordset_name, wordformset_name, " " n_coords, id_coord1, id_state1, affirm1," " id_coord2, id_state2, affirm2, id_coord3, id_state3," " affirm3, thesauruscheck_link, thesauruscheck_entry, is_positive, children_quantification_min_count, children_quantification_max_count," " id_coord4, id_state4, affirm4," " n_setcheckers, set_name1, set_type1, set_affirm1, set_name2," " set_type2, set_affirm2, set_name3, set_type3, set_affirm3," " link_type, id_metaentry, relative_position, id_src, id_group," " quantification_min_count, quantification_max_count, marker," "n_backref," "br_affirm_0, br_coord0_0, br_marker_0, br_coord1_0, br_for_group_0," "br_affirm_1, br_coord0_1, br_marker_1, br_coord1_1, br_for_group_1," "br_affirm_2, br_coord0_2, br_marker_2, br_coord1_2, br_for_group_2" " ) VALUES (" " %d, %d, '%us', %d," " %d, '%us', '%us', '%us'," " %d, %d, %d, %d," " %d, %d, %d, %d, %d," " %d, %d, %d, %d, %d, %d," " %d, %d, %d," " %d, '%us', %d, %d, '%us'," " %d, %d, '%us', %d, %d," " %d, %d, %d, %d, %d," " %d, %d, '%us'," " %d," " %d, %d, '%us', %d, %d," " %d, %d, '%us', %d, %d," " %d, %d, '%us', %d, %d" " );\n", id, id_parent, word_text.c_str(), id_entry, id_class, wordentryset_name.c_str(), wordset_name.c_str(), wordformset_name.c_str(), n_coords, id_coord1, id_state1, affirm1, id_coord2, id_state2, affirm2, id_coord3, id_state3, affirm3, thesauruscheck_link, thesauruscheck_entry, is_positive, children_quantification_min_count, children_quantification_max_count, id_coord4, id_state4, affirm4, n_set_checkers, set_name1.c_str(), set_type1, set_affirm1, set_name2.c_str(), set_type2, set_affirm2, set_name3.c_str(), set_type3, set_affirm3, link_type, id_metaentry, relative_position, id_src, id_group, quantification_min_count, quantification_max_count, marker.c_str(), n_backref, br_affirm_0, br_coord0_0, br_marker_0.c_str(), br_coord1_0, br_for_group_0, br_affirm_1, br_coord0_1, br_marker_1.c_str(), br_coord1_1, br_for_group_1, br_affirm_2, br_coord0_2, br_marker_2.c_str(), br_coord1_2, br_for_group_2 ); } ts_point.Delete(); out.printf( "\n\n" ); lem::Ptr<LS_ResultSet> ts_group = storage->ListTreeScorerGroups(); while( ts_group->Fetch() ) { const int id = ts_group->GetInt(0); lem::UFString name( sql_version.SqlStr(ts_group->GetUFString(1)) ); const int allow_unmatched_children = ts_group->GetInt(2); out.printf( "INSERT INTO ts_group(id,name,allow_unmatched_children) VALUES (%d,'%us',%d);\n", id, name.c_str(), allow_unmatched_children ); } ts_group.Delete(); out.printf( "\n\n" ); lem::Ptr<LS_ResultSet> ts_group2root = storage->ListTreeScoreGroupMembers(); while( ts_group2root->Fetch() ) { const int id_group = ts_group2root->GetInt(0); const int id_root = ts_group2root->GetInt(1); out.printf( "INSERT INTO ts_group2root(id_group,id_root) VALUES (%d,%d);\n", id_group, id_root ); } ts_group2root.Delete(); out.printf( "\n\n" ); lem::Ptr<LS_ResultSet> ts_gts = storage->ListGenericTreeScorers(); while( ts_gts->Fetch() ) { const int id = ts_gts->GetInt(0); const int id_head_point = ts_gts->GetInt(1); const int id_group = ts_gts->GetInt(2); lem::UFString score_expr = sql_version.SqlStr(ts_gts->GetUFString(3)); const int score_type = ts_gts->GetInt(4); out.printf( "INSERT INTO generic_tree_scorer(id,id_head_point,id_group,score_type,score_expr) VALUES (%d,%d,%d,%d,'%us');\n", id, id_head_point, id_group, score_type, score_expr.c_str() ); } ts_gts.Delete(); out.printf( "\n\n" ); lem::Ptr<LS_ResultSet> ts_pr = storage->ListTreeScorerPredicates(); while( ts_pr->Fetch() ) { const int id = ts_pr->GetInt(0); const int id_point = ts_pr->GetInt(1); UCString func_name = ts_pr->GetUCString(2); const int narg = ts_pr->GetInt(3); const int id_class1 = ts_pr->GetInt(4); out.printf( "INSERT INTO ts_predicate(id,id_point,func_name,narg,id_class1) VALUES (%d,%d,'%us',%d,%d);\n", id, id_point, func_name.c_str(), narg, id_class1 ); } ts_pr.Delete(); out.printf( "\n\n" ); out.printf( "\n\n" ); return; }
void GramCoord::Save_API(OFormatter &cpp, lem::Binding::Language lang) const { if (lang == lem::Binding::CPP || lang == lem::Binding::CSharp) { if (!state.empty()) { cpp.printf("// Coordiname %us states:\n", GetName().front().c_str()); } } else if (lang == lem::Binding::Pascal) { if (!state.empty()) { cpp.printf("{ Coordiname %us states: }\n", GetName().front().c_str()); } } else if (lang == lem::Binding::Python) { if (!state.empty()) { cpp.printf("# Coordiname %us states:\n", GetName().front().c_str()); } } else if (lang == lem::Binding::PHP) { if (!state.empty()) { cpp.printf("// Coordiname %us states:\n", GetName().front().c_str()); } } else { LEM_STOPIT; } int istate = 0; for (lem::Container::size_type i = 0; i < state.size(); i++) { const GramCoordState& s = state[i]; if (!s.get_C_Name().empty()) { if (lang == lem::Binding::CPP || lang == lem::Binding::CSharp) { if (lang == lem::Binding::CSharp) cpp.printf(" public "); cpp.printf( "const int %us = %d; %50t // %us : %us\n", s.get_C_Name().c_str(), istate, GetName().front().c_str(), s.front().c_str() ); } else if (lang == lem::Binding::Pascal) { cpp.printf( "const %us: integer = %d; %50t // %us : %us\n", s.get_C_Name().c_str(), istate, GetName().front().c_str(), s.front().c_str() ); } else if (lang == lem::Binding::Python) { cpp.printf( "%us = %d %50t # %us : %us\n", s.get_C_Name().c_str(), istate, GetName().front().c_str(), s.front().c_str() ); } else if (lang == lem::Binding::PHP) { cpp.printf( "define( '%us', %d ); %50t // %us : %us\n", s.get_C_Name().c_str(), istate, GetName().front().c_str(), s.front().c_str() ); } else { LEM_STOPIT; } } s.Save_API(istate, cpp, lang); istate += CastSizeToInt(s.size()); } return; }
void GraphGram::Save_SQL( OFormatter &out, OFormatter &alters, const SQL_Production &sql_version ) { if (sql_version.type == SQL_Production::MsSql) { out.printf("!! @echo Creating alphabets...\n"); } else if (sql_version.type == SQL_Production::Oracle) { out.printf("HOST echo Creating alphabets...\n"); } out.printf("%s\n", sql_version.BeginTx().c_str()); const wchar_t* NPrefix = sql_version.GetNPrefix(); // ПАРАМЕТРЫ -> SG_CRITERION std::unique_ptr<CriterionEnumerator> crenum(param->Enumerate()); while (crenum->Fetch()) { const int id = crenum->GetId(); const Criterion& x = crenum->GetItem(); lem::UFString name(sql_version.SqlStr(x.GetName())); lem::UFString strval(sql_version.SqlStr(x.GetString())); out.printf( "INSERT INTO sg_criterion( id, name, strval ) VALUES( %d, %us'%us', %us'%us' );\n" , id , NPrefix , name.c_str() , NPrefix , strval.c_str() ); } out.eol(); // АЛФАВИТЫ std::unique_ptr<AlphabetEnumerator> aenum(alphabets().List()); while (aenum->Fetch()) { const Alphabet &alphabet = aenum->GetItem(); const int id = aenum->GetId(); lem::UFString aname(sql_version.SqlStr(alphabet.get_Name())); out.printf( "INSERT INTO abc_alphabet( id, name ) VALUES( %d, %us'%us' );\n" , id , NPrefix , aname.c_str() ); } out.eol(); // КООРДИНАТЫ И СОСТОЯНИЯ std::unique_ptr<CoordEnumerator> cenum(coords().Enumerate()); while (cenum->Fetch()) { const int id_coord = cenum->GetId(); const GramCoord &c = cenum->GetItem(); out.printf( "INSERT INTO abc_coord( id, name, bistable ) VALUES ( %d, %us'%us', %d );\n", id_coord, NPrefix, c.GetName().front().c_str(), c.IsBistable() ? 1 : 0 ); int istate = 0; if (c.IsBistable()) { // Все-таки объявим в явном виде два состояния для бистабильных координат, чтобы // в реляционной схеме можно было создавать foreight key с таблиц SG_ENTRY_COORD и SG_FORM_COORD out.printf("INSERT INTO abc_state( id, id_coord, name ) VALUES ( 0, %d, '0' );\n", id_coord); out.printf("INSERT INTO abc_state( id, id_coord, name ) VALUES ( 1, %d, '1' );\n", id_coord); } else { for (lem::Container::size_type j = 0; j < c.states().size(); ++j) { const GramCoordState & s = c.states()[j]; const int id_parent = istate; for (lem::Container::size_type k = 0; k < s.size(); ++k, ++istate) { out.printf("INSERT INTO abc_state( id, id_coord, name ) VALUES ( %d, %d, %us'%us' );\n", istate, id_coord, NPrefix, s[k].c_str()); } } } } // КЛАССЫ -> ABC_CLASS std::unique_ptr<SymbolClassEnumerator> class_enum((SymbolClassEnumerator*)classes().Enumerate()); while (class_enum->Fetch()) { const int id = class_enum->GetId(); const GramClass & c = class_enum->GetItem(); out.printf( "INSERT INTO abc_class( id, name ) VALUES( %d, %us'%us' );\n" , id , NPrefix , sql_version.SqlStr(c.GetName()).c_str() ); // Сохраним в базе информацию о привязке координат (атрибутов, измерений, тэгов) к классам. for (lem::Container::size_type k = 0; k < c.attrs().size(); ++k) { const GramCoordAdr &atr = c.attrs()[k]; out.printf( "INSERT INTO abc_class_coord( id_class, id_coord, coord_type ) VALUES( %d, %d, 0 );\n" , id , atr.GetIndex() ); } for (lem::Container::size_type k = 0; k < c.dims().size(); ++k) { const GramCoordAdr &dim = c.dims()[k]; out.printf( "INSERT INTO abc_class_coord( id_class, id_coord, coord_type ) VALUES( %d, %d, 1 );\n" , id , dim.GetIndex() ); } } out.eol(); // ********************** // СТАТЬИ -> ABC_ENTRY // ********************** ABC_CoordPairsList coords_ref; std::unique_ptr<SymbolEnumerator> senum(entries().Enumerate()); int id_form = 0; while (senum->Fetch()) { const GG_Entry &e = senum->GetItem(); // некоторые версии MSSQL ругаются на unicode-символы с кодами более 2^16. // поэтому для этой СУБД не будем их реально загружать, но чтобы отсутствие этих // символов не вызывало удивления - впечатаем закомментированные операторы DML. bool wrap_in_comment = false; if (e.GetName() > 0x0000ffffU) { if (sql_version.type == SQL_Production::MsSql || sql_version.type == SQL_Production::Oracle || sql_version.type == SQL_Production::Postgres) { wrap_in_comment = true; } } const int id_pairs = coords_ref.Register(e.attrs()); const int id_entry = senum->GetId(); UFString s = lem::UFString(e.GetNameWide().c_str()); if (wrap_in_comment) out.printf("%s", sql_version.Get_Comment().c_str()); if (sql_version.type == SQL_Production::Oracle) { UFString s2 = SQL_Production::Oracle_UNISTR(s); out.printf( "INSERT INTO abc_entry( id, name, code, id_class, id_alphabet, id_pairs ) VALUES( %d, %us, %d, %d, %d, %d );\n" , id_entry , s2.c_str() , e.GetName() , e.GetClass() , e.GetAlphabet() , id_pairs ); } else { s = sql_version.ClearInvalidChars(s); s = sql_version.SqlStr(s); out.printf( "INSERT INTO abc_entry( id, name, code, id_class, id_alphabet, id_pairs ) VALUES( %d, %us'%us', %d, %d, %d, %d );\n" , id_entry , NPrefix , s.c_str() , e.GetName() , e.GetClass() , e.GetAlphabet() , id_pairs ); } for (Container::size_type j = 0; j < e.forms().size(); j++) { const GG_EntryForm &form = e.forms()[j]; lem::UFString fs(form.GetNameWide().c_str()); const int id_dims = coords_ref.Register(form.dims()); if (wrap_in_comment) out.printf("%s", sql_version.Get_Comment().c_str()); if (sql_version.type == SQL_Production::Oracle) { UFString s2 = SQL_Production::Oracle_UNISTR(fs); out.printf( "INSERT INTO abc_form( id, id_entry, ordnum, name, code, id_pairs )" " VALUES( %d, %d, %d, %us, %d, %d );\n" , id_form++ , id_entry , CastSizeToInt(j) , s2.c_str() , form.GetName() , id_dims ); } else { fs = sql_version.ClearInvalidChars(fs); fs = sql_version.SqlStr(fs); out.printf( "INSERT INTO abc_form( id, id_entry, ordnum, name, code, id_pairs )" " VALUES( %d, %d, %d, %us'%us', %d, %d );\n" , id_form++ , id_entry , CastSizeToInt(j) , NPrefix , fs.c_str() , form.GetName() , id_dims ); } } } if (!sql_version.norules) { // Правила слогоделителя std::unique_ptr<LS_ResultSet> rs_slb1(storage->ListSyllabRules()); while (rs_slb1->Fetch()) { const int id = rs_slb1->GetInt(0); lem::UCString name = rs_slb1->GetUCString(1); const int id_src = rs_slb1->GetInt(2); const int id_language = rs_slb1->GetInt(3); const int cursor_shift = rs_slb1->GetInt(4); out.printf("INSERT INTO slb_rule( id, name, id_src, id_language, cursor_shift ) VALUES ( %d, '%us', %d, %d, %d );\n", id, name.c_str(), id_src, id_language, cursor_shift); } rs_slb1.reset(); out.eol(); std::unique_ptr<LS_ResultSet> rs_slb2(storage->ListSyllabConditionPoints()); while (rs_slb2->Fetch()) { const int id = rs_slb2->GetInt(0); const int id_rule = rs_slb2->GetInt(1); const int point_index = rs_slb2->GetInt(2); const int n_char = rs_slb2->GetInt(3); lem::UFString char_text = rs_slb2->GetUFString(4); lem::UFString char_ucs4 = rs_slb2->GetUFString(5); const int id_class = rs_slb2->GetInt(6); const int id_entry = rs_slb2->GetInt(7); const int n_coord = rs_slb2->GetInt(8); const int id_coord0 = rs_slb2->GetInt(9); const int id_state0 = rs_slb2->GetInt(10); const int is_left_boundary = rs_slb2->GetInt(11); const int is_right_boundary = rs_slb2->GetInt(12); const int is_positive = rs_slb2->GetInt(13); out.printf("INSERT INTO slb_condition_point( id, id_rule, point_index, n_char, char_text, char_ucs4," " id_class, id_entry, id_coord0, id_state0, is_left_boundary," " is_right_boundary, n_coord, is_positive ) VALUES (" " %d, %d, %d, %d, '%us', '%us'," " %d, %d, %d, %d, %d," " %d, %d, %d );\n", id, id_rule, point_index, n_char, char_text.empty() ? L"" : char_text.c_str(), char_ucs4.empty() ? L"" : char_ucs4.c_str(), id_class, id_entry, id_coord0, id_state0, is_left_boundary, is_right_boundary, n_coord, is_positive ); } rs_slb2.reset(); out.eol(); std::unique_ptr<LS_ResultSet> rs_slb3(storage->ListSyllabResultPoints()); while (rs_slb3->Fetch()) { const int id = rs_slb3->GetInt(0); const int id_rule = rs_slb3->GetInt(1); const int point_index = rs_slb3->GetInt(2); const int copy_index = rs_slb3->GetInt(3); const int merge_index0 = rs_slb3->GetInt(4); const int merge_count = rs_slb3->GetInt(5); out.printf("INSERT INTO slb_result_point( id, id_rule, point_index, copy_index, merge_index0, merge_count )" " VALUES ( %d, %d, %d, %d, %d, %d );\n", id, id_rule, point_index, copy_index, merge_index0, merge_count); } rs_slb3.reset(); out.eol(); out.eol(); out.printf("%s\n", sql_version.CommitTx().c_str()); out.printf("%s\n", sql_version.BeginTx().c_str()); } coords_ref.SaveSQL(out, sql_version); out.eol(); out.printf("%s\n", sql_version.CommitTx().c_str()); if (sql_version.type == SQL_Production::MsSql) { out.printf("!! @echo Alphabets have been loaded.\n"); } else if (sql_version.type == SQL_Production::Oracle) { out.printf("HOST echo Alphabets have been loaded.\n"); } return; }
// ****************************************************** // Распечатка КАРТЫ - служебной информации об автомате в // указанный текстовый поток. // ****************************************************** void GraphGram::PrintMap(OFormatter &txtfile) { Grammar::PrintMap(txtfile); Report(txtfile); // The simple list of classes (not ordered - listed as they are in container) txtfile.printf( "\n%14h-List of classes:%14h-\nid class name number of entries\n" ); MCollect< pair<int/*id_class*/, int/*nentry*/> > class_info; class_info.reserve(classes().Count()); int max_entries = 0; std::unique_ptr<ClassEnumerator> cenum(classes().Enumerate()); while (cenum->Fetch()) { const int id_class = cenum->GetId(); // Сколько статей относится к данному классу int nentry = 0; std::unique_ptr<SymbolEnumerator> senum(symbols->Enumerate()); while (senum->Fetch()) { if (senum->GetItem().GetClass() == id_class) nentry++; } txtfile.printf( "%W3d %W20us %d\n" , id_class , classes()[id_class].GetName().c_str() , nentry ); class_info.push_back(make_pair(id_class, nentry)); max_entries = std::max(max_entries, nentry); } txtfile.eol(); // Going to make more impressing list of classes - ordered by number // of entries belong to each of them. sort_desc_pairs(class_info); if (!max_entries) max_entries = 1; txtfile.printf("Ordered list of classes (weighted by number of belonging entries\n"); for (int j = 0; j < classes().Count(); j++) { txtfile.printf( "%W3d %W20us %W4d |%H#\n" , class_info[j].first , classes()[class_info[j].first].GetName().c_str() , class_info[j].second , int(36 * class_info[j].second / max_entries) ); } txtfile.flush(); // Перечень имен координат txtfile.printf("\nList of coordinates:"); std::unique_ptr<CoordEnumerator> coenum(coords().Enumerate()); while (coenum->Fetch()) { const GramCoord &c = coenum->GetItem(); txtfile.printf( " %us (# of states: %d)" , c.GetName().front().c_str() , c.states().size() ); } txtfile.eol(); txtfile.flush(); txtfile.printf("%10h- END OF <GG> SECTION %10h-\n\n\n"); GetIO().mecho().printf("Ok\n"); txtfile.flush(); return; }
void Word_Form::PrintXML( OFormatter &xml, SynGram &gram ) const { xml.printf( "<wordform>\n" ); lem::UFString sword( lem::encode_chars_to_xml(GetName()->c_str()) ); xml.printf( "<word>%us</word>\n", sword.c_str() ); xml.printf( "<origin_pos>%d</origin_pos>\n", GetOriginPos() ); xml.printf( "<id_entry>%d</id_entry>\n", entry_key ); xml.printf( "<val>%4.2f</val>\n", val.GetFloat() ); xml.printf( "<score>%d</score>\n", score ); if( !pair.empty() ) { xml.printf( "<coord_pairs count=\"%d\">\n", CastSizeToInt(pair.size()) ); for( lem::Container::size_type i=0; i<pair.size(); ++i ) { xml.printf( "<coord_pair n=\"%d\" id_coord=\"%d\" id_state=\"%d\">", pair[i].GetCoord().GetIndex(), pair[i].GetState() ); pair[i].SaveTxt( xml, gram ); xml.printf( "</coord_pair>\n" ); } xml.printf( "</coord_pairs>\n" ); } if( HasAlt() ) { xml.printf( "<versions count=\"%d\">\n", CastSizeToInt(GetAlts().size()) ); for( lem::Container::size_type i=0; i<GetAlts().size(); ++i ) { xml.printf( "<version n=\"%d\">\n", CastSizeToInt(i) ); GetAlts()[i]->PrintXML( xml, gram ); xml.printf( "</version>\n" ); } xml.printf( "</versions>\n" ); } xml.printf( "</wordform>\n" ); return; }
void Word_Form::Print( OFormatter &s, SynGram *gram, bool detailed ) const { const int nver = 1+CastSizeToInt(GetAlts().size()); if( nver>1 ) s.printf( "%vf6((%vn" ); for( int iver=0; iver<nver; ++iver ) { if( iver>0 ) s.printf( " " ); const Word_Form &alt = iver==0 ? *this : *GetAlts()[iver-1]; if( nver>1 ) s.printf( "%vf6version=%d%vn ", alt.iversion ); if( detailed && !is_quantor( alt.GetEntryKey() ) && gram!=NULL ) { // Можем напечатать имя грамматического класса. const GramClass &c = gram->classes()[ gram->GetEntry(alt.GetEntryKey()).GetClass() ]; s.printf( "%vfA%us%vn%us", c.GetName().c_str(), sol_get_token(B_COLON).c_str() ); } // Мультилексемные имена - в квадратных скобках. int npart = alt.name->Count_Lexems(); if( npart>1 ) s.printf( "%vf6[%vn" ); s.printf( "%vfE%us%vn", alt.name->c_str() ); if( npart>1 ) s.printf( "%vf6]%vn" ); if( alt.GetScore()!=0 ) s.printf( "|%d|", alt.GetScore() ); if( detailed ) { s.printf( "%vf6%us%vn", sol_get_token(B_OFIGPAREN).c_str() ); alt.SaveTxtPreciser( s, gram ); if( tokenizer_flags.NotNull() && !tokenizer_flags->empty() ) { s.printf( " tokenizer_flag:%us", tokenizer_flags->c_str() ); } s.printf( "%vf6%us%vn", sol_get_token(B_CFIGPAREN).c_str() ); } } if( nver>1 ) s.printf( "%vf6))%vn" ); return; }