/**************************************************************************** Возвращается строка, состоящая из символов строки-аргумента s, начина с первого (индекс 0) и длиной nch. Если длина исходной строки недостаточна, то результат будет содержать соответственно меньшее количество символов. *****************************************************************************/ const UCString lem::left( const UCString &s, int NCH ) { LEM_CHECKIT_Z(NCH>=0); const int l=s.length(); if( l==NCH ) { return s; } else if( NCH<=0 ) { return UCString(); } else { UCString res; const int nch = NCH>l ? l : NCH; for( int i=0; i<nch; i++ ) res.set_dir( i, s[i] ); res.set_dir( nch, '\0' ); res.calc_hash(); return res; } }
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; }
const UCString lem::to_unicode( const lem::CString &src, const CodeConverter *cp ) { UCString res; lem_ascii_to_unicode( res.ptr(), src.c_str(), cp ? cp : &lem::UI::get_UI().GetSessionCp() ); res.ptr()[src.length()] = 0; res.calc_hash(); return res; }
bool SG_Stemmer::Stem( const UCString &org, UCString &stem ) const { if( hStemmer==NULL || org.length()<3 ) return false; stem = org; if( sol_Stem( hStemmer, (wchar_t*)stem.c_str() )==0 ) { stem.calc_hash(); return true; } return false; }
bool TrFunctions::IsType( const UCString &t ) const { return t.eqi(L"const") || t.eqi(L"bool") || t.eqi(L"int") || t.eqi(L"string") || t.eqi(L"tree") || t.eqi(L"trees") || t.eqi(L"variant") || t.eqi(L"fun") || t.eqi(L"tuple"); }
void TrContextInvokation::AddVar( const UCString &name, lem::Ptr<TrValue> value ) { LEM_CHECKIT_Z(!name.empty()); arg_name.push_back(name); arg_value.push_back( new TrValue(*value) ); return; }
/**************************************************************** Если каждому символу слова можно поставить в соответствие статью графической грамматики, то слово считаем корректной словоформой. *****************************************************************/ bool LexicalAutomat::IsCorrectWord( const UCString& word ) const { for( UCString::size_type i=0; i<word.length(); i++ ) if( GG->FindSymbol(word[i]).GetEntry()==UNKNOWN ) return false; return true; }
lem::Ptr<TrValue> TrContextInvokation::GetVar( const UCString &name ) { LEM_CHECKIT_Z(!name.empty()); for( lem::Container::size_type i=0; i<arg_name.size(); ++i ) if( arg_name[i].eqi(name) ) return lem::Ptr<TrValue>( arg_value[i], null_deleter() ); return TrFunContext::GetVar(name); }
/***************************************************************************** Возвращается строка, состоящая из последних nch символов строки-аргумента s. Если длина исходной строки недостаточна, то результат будет содержать соответственно меньшее количество символов. ******************************************************************************/ const UCString lem::right( const UCString &s, int NCH ) { LEM_CHECKIT_Z(NCH>=0); UCString res; if( NCH<=0 ) return res; const int l=s.length(); const int nch = NCH>l ? l : NCH; int i0=l-nch; for( int i=0; i<nch; i++ ) res.set_dir( i, s[i+i0] ); res.set_dir( nch, '\0' ); res.calc_hash(); return res; }
bool LA_PhoneticCondictor::Can_Subst( const UCString &lex ) const { if( context.length() > lex.length() ) return false; switch( loc ) { case PREFIX: // Начало слова lex должно содержать condictor return !memcmp( lex.c_str(), context.c_str(), context.length()*sizeof(*lex.c_str()) ); case AFFIX: // Конец слова lex должен содержать condictor return !memcmp( lex.c_str()+lex.length()-context.length(), context.c_str(), context.length()*sizeof(*lex.c_str()) ); case UNLOCATED: LEM_STOPIT; } return false; }
void ThesaurusTag::LoadTxt( lem::Iridium::Macro_Parser & txtfile, const lem::Sol_IO &sol_io, const Binarization_Options & options ) { lem::Iridium::BethToken t = txtfile.read(); name = t.string(); name.strip(L'"'); int ivalue = 0; if (txtfile.pick().GetToken() == B_EQUAL) { txtfile.read_it(B_EQUAL); txtfile.read_it(B_OFIGPAREN); while (!txtfile.eof()) { lem::Iridium::BethToken v = txtfile.read(); if (v.GetToken() == B_CFIGPAREN) break; UCString vs = v.string(); vs.strip(L'"'); if (operator[](vs) != UNKNOWN) { lem::Iridium::Print_Error(v, txtfile); sol_io.err->printf("Thesaurus tag [%us] value [%us] is already declared", name.c_str(), vs.c_str()); throw E_ParserError(); } values.push_back(vs); ivalues.push_back(ivalue++); } } return; }
// ************************************************************************** // Из строки, начиная с позиции i0, вырезается nch символов и возвращаются // как строка. Если i0<0, то подразумевается i0=0. Если (i0+nch) больше, // чем длина строки s, что в результатную строку будет занесено // соответственно меньше символов. // ************************************************************************** const UCString lem::mid( const UCString& s, int i0, int nch ) { LEM_CHECKIT_Z(nch>=0); if( nch<=0 || i0<0 || i0>=s.length() ) return lem::UCString(); wchar_t res[ LEM_CSTRING_LEN + 1 ]; const int I0 = i0<0 ? 0 : i0; const int l=s.length(); if( I0>=l ) return UCString(res); const int NCH = nch>(l-I0) ? l-I0 : nch; lem_strncpy( res, s.c_str()+I0, NCH ); res[NCH]=0; return UCString(res); }
void TrCompilationContext::RegisterVariable( const UCString &name ) { lem::UCString uname( lem::to_upper(name) ); if( vars.find(uname)!=UNKNOWN ) { lem::UFString msg( lem::format_str( L"Variable [%s] is already declared", name.c_str() ) ); throw E_ParserError(msg.c_str()); } vars.push_back(uname); return; }
void SyntaxShell::SetLanguage( const UCString &lang_name ) { if( lang_name.eqi(L"autodetect") || lang_name.eqi(L"auto") ) { // Язык нужно определять для каждой вводимой фразы. default_language = UNKNOWN; guess_language = true; } else { default_language = sol_id->GetSynGram().Find_Language(lang_name); // Проверим, что этот язык есть среди определенных в лексиконе lem::MCollect<int> langs; sol_id->GetLanguages(langs); if( langs.find(default_language)==UNKNOWN ) { merr->printf( "\n%vfCError:%vn target language %vfE%us%vn is not available in lexicon", lang_name.c_str() ); throw E_BaseException(); } } 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; }
int PM_Automat::GetSequenceValue( const UCString &name, int step ) const { #if defined LEM_THREADS lem::Process::CritSecLocker locker(const_cast<lem::Process::CriticalSection*>(&cs_sequence)); #endif std::map<UCString,int> &mutable_sequence = const_cast< std::map<UCString,int>& >(sequence); std::map<UCString,int>::iterator it = mutable_sequence.find( to_lower(name) ); if( it!=sequence.end() ) { return it->second += step; } else { throw E_BaseException( lem::format_str( L"Can not find sequence [%us]", name.c_str() ) ); } }
bool SG_DeclensionForm::MatchCondition( const UCString &str, const UFString &entry_flexer_flags ) const { #if !defined FAIND_NO_BOOST_REGEX if( (!valid_condition || condition.empty()) && (!valid_flexer_flags || flexer_flags.empty()) ) return true; if( valid_condition && !boost::regex_match( str.c_str(), condition ) ) return false; if( valid_flexer_flags && !boost::regex_search( entry_flexer_flags.c_str(), flexer_flags ) ) return false; return true; #else return false; #endif }
bool lem::is_int( const UCString &s ) { return lem::is_int(s.c_str()); }
bool TrFunction::CorrectName( const UCString &x ) { return lem::is_name(x.c_str()); }
void Resource_List::LoadTxt( WideStream &txt ) { // Формат ресурсов: NNN LANG string // // Допускаются директивы: // $include filename language int last_good_id=0; const lem::UCString INCLUDE(L"$include"); const UFString cur_lang( lem::to_unicode( lem::UI::get_UI().GetCurrLang() ) ); const UFString english(L"en"); UCString nnn; std::string lang; UFString string; while( !txt.eof() ) { txt.skip_white(); nnn.clear(); lang.clear(); string.clear(); // read the number identifier (primary key) of the string record. while( !txt.eof() ) { const wchar_t u = txt.wget(); if( u==WEOF ) break; if( nnn.front()==L'#' ) { // Commentary string - read until EOL. while( !txt.eof() ) { const wchar_t u = txt.wget(); if( u == L'\n' || u==L'\r' || u==WEOF ) break; } break; } if( is_uspace(u) ) { txt.unget(u); break; } nnn += u; } if( nnn.empty() ) continue; if( nnn == INCLUDE ) { // Next fields are: 1) filename and 2) language UFString filename, language; filename.reserve(64); language.reserve(4); txt.skip_white(); while( !txt.eof() ) { const wchar_t u = txt.wget(); if( u==WEOF ) break; if( is_uspace(u) || u==L'\n' || u==L'\r' ) { txt.unget(u); break; } filename.Add_Dirty(u); } txt.skip_white(); while( !txt.eof() ) { const wchar_t u = txt.wget(); if( u==WEOF ) break; if( is_uspace(u) || u==L'\n' || u==L'\r' ) { txt.unget(u); break; } language.Add_Dirty(u); } language.calc_hash(); filename.calc_hash(); // Recursively load the file if( load_all_languages || language == cur_lang || language==english ) { // Если задан файл без указания пути, то путь берем из исходного файла lem::Path inc(filename); inc.RemoveLastLeaf(); if( inc.empty() ) { inc = txt.GetName(); inc.RemoveLastLeaf(); inc.ConcateLeaf(lem::Path(filename)); LoadTxt( inc ); } else { LoadTxt( lem::Path(filename) ); } } continue; } int iname = 0; if( lem::to_int( nnn.c_str(), &iname )==false || iname<=0 ) throw E_BaseException( lem::format_str( L"Incorrect format of string resource file: id is not a number [%ls]", nnn.c_str() ).c_str() ); last_good_id = iname; // метка языка txt.skip_white(); while( !txt.eof() ) { wchar_t u = txt.wget(); if( u==WEOF ) break; if( is_uspace(u) ) { txt.unget(u); break; } lang += static_cast<char>(u); } // Ведем список языков, для которых есть локализация ресурсов. // ищем такой язык в справочнике int ilang = FindLang(lang,NULL); int il=0; for( std::vector<std::string>::const_iterator j=langs.begin(); j!=langs.end(); j++, il++ ) if( *j == lang ) { ilang = il; break; } if( ilang==UNKNOWN && !lang.empty() ) { ilang = langs.size(); langs.push_back( lang ); } txt.skip_white(); bool apostrophed=true; // теперь сама строка ресурсов while( !txt.eof() ) { wchar_t u = txt.wget(); if( u==WEOF /*EOF fixed 17.09.2009 */ ) break; if( u==L'\r' || u=='\n' ) { break; } if( u==L'"' && string.empty() ) { // Начало строки в апострофах apostrophed = true; continue; } if( u==L'"' && !string.empty() ) { // Конец строки в апострофах // Если далее идет символ +, то будет продолжение на следующей строке. wchar_t next = txt.wget(); if( next==L'+' ) { // Это продолжение. txt.skip_white(); next = txt.wget(); if( next==WEOF || next==0 ) continue; LEM_CHECKIT_Z( next==L'"' ); continue; } break; } if( u==L'\\' ) { // спецсимволы wchar_t u2 = txt.wget(); if( u2==WEOF ) break; if( u2==L'\r' || u2=='\n' ) break; if( u2==L'r' || u2==L'n' ) u = L'\n'; else if( u2==L'"' ) u = L'"'; else u = u2; } string.Add_Dirty(u); } string.calc_hash(); if( !nnn.empty() && !string.empty() ) { // Сохраняем ресурс. // Ветка ресурса для этого nnn уже есть? string.trim(); string.strip_quotes(); Resource *r = NULL; std::map<int,Resource*>::iterator it = iname_2_res.find(iname); if( it!=iname_2_res.end() ) { r = it->second; } else { r = new Resource; r->name = iname; list.push_back(r); iname_2_res.insert( std::make_pair(iname,r) ); } r->list.push_back( make_pair( ilang, string ) ); } } return; }