コード例 #1
0
void BinaryFile::OpenDiskFile( const char *amode, const wchar_t *umode, bool do_throw )
{
 if( lem::System_Config::SupportUnicodeFilenames() )
  {
   #if defined LEM_WINDOWS
   const UFString n = GetName().GetUnicode();

   // У стандартной CRT Borland CBuilder 6.0 проблема - не может
   // открыть файл "nul" через UNICODE-функцию.
   if( n==L"nul" )
    file=/*std::*/::fopen( "nul", amode );
   else
    #if defined LEM_BORLAND
     file=/*std::*/::fopen( GetName().GetAscii().c_str(), amode );
    #else
     file=_wfopen( n.c_str(), umode );
    #endif 

   #elif defined LEM_UNIX

   // перекодируем в utf-8

   if( GetName().IsAscii() )
    {
     file=::fopen( GetName().GetAscii().c_str(), amode );
    }
   else
    {
     file=::fopen( lem::to_utf8(GetName().GetUnicode()).c_str(), amode );
    }

   #endif
  }
 else
  {
   file=/*std::*/::fopen( GetName().GetAscii().c_str(), amode );
  }

 if( file==NULL )
  {
   if( do_throw )
    {
//printf( "File error: %s\n", filename.Get_Ascii().c_str() );
     lem::UFString fn( GetName().GetUnicode() );
     throw E_BaseException( wstring( L"File open error: " )+fn.c_str() );
    }
  }

 #if LEM_DEBUGGING==1
 n_opened++;
 #endif

// check_file(file,filename);
 closable=true;

 IFDEBUG(Assert());
 return;
}
コード例 #2
0
const UFString SyntaxShell::enter_cmd( const char *Prompt ) const
{
 UFString str;
 while( str.empty() )
  {
   mout->printf( "%vfF%s", Prompt ); // Command prompt
   str = mkey->ask_ufstring();
   mout->printf( "%vn" );
   str.trim();
  }

 return str;
}
コード例 #3
0
ファイル: cp_recodings.cpp プロジェクト: mcdir/GrammarEngine
 const FString lem::to_ascii( const UFString &str, const CodeConverter *_cp )
 {
  if( str.empty() )
   return FString();

  const CodeConverter *cp = _cp ? _cp : &lem::UI::get_UI().GetSessionCp();

  const int l = str.length();
  char *ascii = FString::Alloc( cp->EstimateAsciiLen(l+1) );

  cp->to_ascii( str.c_str(), ascii );
 
  return FString(ascii,true);
 }
コード例 #4
0
ファイル: xp_parser.cpp プロジェクト: mcdir/GrammarEngine
void Parser::Split_Path(
                        const UFString &path,
                        Collect<UFString> &steps
                       )
{
 int i=0;
 UFString new_step;
 while( true )
  {
   if( path[i] == L'.' || path[i]==0 )
    {
     if( !new_step.empty() )
      steps.push_back(new_step);

     new_step.clear();
     
     if( i>=path.length() )
      break;
    }
   else
    {
     new_step += path[i];
    }

   i++;
  }

 return; 
}
コード例 #5
0
ファイル: dsa_form.cpp プロジェクト: mcdir/GrammarEngine
void SG_DeclensionForm::ReadAdditionalInfo( Grammar &gram, const SG_DeclensionTable &table, Macro_Parser& txtfile )
{
 // :: flexer рег_выражение for регулярное_выражение
 
 while( !txtfile.eof() )
  {
   BethToken t = txtfile.read();

   if( t==B_FOR )
    {
     UFString re = strip_quotes( txtfile.read().string() ).c_str();
     if( table.GetClass()!=UNKNOWN )
      {
       const SG_Class &cls = (const SG_Class&)gram.classes()[ table.GetClass() ];

       const int id_lang = cls.GetLanguage();
       if( id_lang!=UNKNOWN )
        {
         const SG_Language &lang = gram.GetDict().GetSynGram().languages()[id_lang];
         lang.SubstParadigmPattern(re);
        }
      }

     condition_str = re;
     condition = boost::wregex( re.c_str(), boost::basic_regex<wchar_t>::icase );
     valid_condition = true;
    }
   else if( t==B_FLEXER )
    {
     UFString re = strip_quotes( txtfile.read().string() ).c_str();

     flexer_flags_str = re; 
     flexer_flags = boost::wregex( re.c_str(), boost::basic_regex<wchar_t>::icase );
     valid_flexer_flags = true;
    }
   else
    {
     txtfile.seekp(t);
     break;
    }
  }

 return;
}
コード例 #6
0
// *********************************************************************
// Возвращает следующий полный токен из входного потока, не перемещая
// курсор чтения.
// *********************************************************************
lem::UCString SentenceBroker::PickNextToken(void)
{
    UFString buffer;
    UCString res;

    // Сначала пропустим пробелы
    while (true)
    {
        const wchar_t c = GetChar();
        if (c == WEOF)
            break;

        buffer += c;
        if (!lem::is_uspace(c))
        {
            res = c;
            break;
        }
    }

    // Теперь считываем символы до любого разделителя
    while (true)
    {
        const wchar_t c = GetChar();
        if (c == WEOF)
            break;

        buffer += c;

        if (tokenizer->IsTokenDelimiter(c))
            break;

        res += c;
    }

    // Возвращаем обратно все считанные символы.
    for (int i = buffer.length() - 1; i >= 0; --i)
        UngetChar(buffer[i]);

    return res;
}
コード例 #7
0
ファイル: xp_parser.cpp プロジェクト: mcdir/GrammarEngine
static bool IsTextDelimiterTag( const UFString &tag )
{
 if( tags2.empty() )
  {
   const wchar_t* stags[] = { L"p", L"br", L"table", L"td", L"tr", L"th",
                              L"ol", L"ul", L"li", L"dd", L"input", L"frame", L"div",
                              NULL
                            };

   int i=0;
   while(stags[i]!=NULL)
    tags2.push_back( lem::UFString(stags[i++]) );
  }

 for( lem::Container::size_type i=0; i<tags2.size(); ++i )
  {
   const lem::UFString &t = tags2[i];
   if( tag.eq_begi(t) && (tag.length()==t.length() || tag[ t.length() ]==L' ' ) ) 
    return true;
  }

 return false;
}
コード例 #8
0
ファイル: dsa_form.cpp プロジェクト: mcdir/GrammarEngine
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
}
コード例 #9
0
ファイル: sg_language.cpp プロジェクト: Koziev/GrammarEngine
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;
}
コード例 #10
0
// ****************************************
// Entering the command processing loop.
// ****************************************
void SyntaxShell::main_loop(void)
{
 // Если язык по умолчанию не задан, то запросим его имя с консоли.
 if( default_language==UNKNOWN && !guess_language )
  {
   lem::MCollect<int> langs;
   default_language = sol_id->GetLanguages(langs);
   if( default_language==UNKNOWN || langs.size()>1 )
    {
     while(true)
      {
       mout->printf( "Please select the language:\n" );
       if( langs.empty() )
        {
         lem::Ptr<LanguageEnumerator> lenum( sol_id->GetSynGram().languages().Enumerate() );
         while( lenum->Fetch() )
          langs.push_back( lenum->GetId() );
        }

       for( lem::Container::size_type i=0; i<langs.size(); ++i )
        {
         mout->printf( "[%vfA%d%vn] - %vfE%us%vn\n", i, sol_id->GetSynGram().languages()[langs[i]].GetName().c_str() );
        } 

       mout->printf( "%vfA-1%vn - do not set default language for syntax analysis\n\n?" );
       int ilang = mkey->ask_int();
       if( ilang==UNKNOWN )
        {
         default_language = UNKNOWN;
         break;
        }

       if( ilang>=0 )
        {
         default_language = langs[ilang];
         break;
        }
      } 
    }
  }

 mout->eol();

#if LEM_DEBUGGING==1
//_CrtMemState ms1,ms2,ms3;
#endif

 int ipass=0;
 for(;;ipass++)
  {
   UFString str;

   if( !pre_entered_phrase.empty() )
    {
     str = pre_entered_phrase;
     pre_entered_phrase.clear();
     mout->printf( "\n> %us\n", str.c_str() );
    }
   else
    {
     str = enter_cmd( debugger.IsNull() ? ": " : ":> " );
    }

   if( str==L"#exit" )
    break;

   if( TryCommand(str) )
    continue;

   if( run_mode==TokenizerMode )
    {
     Tokenize(str);
    }
   else if( run_mode==LemmatizerMode )
    {
     Lemmatize(str);
    }
   else if( run_mode==SpeakerMode )
    {
     Speak(str);
    }
   else
    {
     lem::ElapsedTime total_et; total_et.start();
     PerformSyntacticAnalysis(str);
     total_et.stop();
     const int msec_elapsed = total_et.msec();

     if( traceon )
      lem::mout->printf( "Elapsed time: %d millisec\n", msec_elapsed );
    }
  }

 return;
}
コード例 #11
0
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;
}
コード例 #12
0
ファイル: gg_autom.cpp プロジェクト: Koziev/GrammarEngine
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;
}
コード例 #13
0
ファイル: xp_parser.cpp プロジェクト: mcdir/GrammarEngine
// ******************************************************
// Загружаем узел вместе со всеми его вложенными узлами.
// ******************************************************
Node* Parser::Load_Node( WideStream *reader ) const
{
 if( reader->eof() )
  return NULL;

 // Пропускаем пробелы.
 wchar_t c=0;

 while( !reader->eof() )
  {
   c = reader->wget();

   if( c==WEOF )
    return NULL;

   if( c!=L' ' && c!=L'\t' && c!=L'\r' && c!=L'\n' )
    break;
  }

 // Символ должен быть '<'.

 if( reader->eof() )
  return NULL;

 if( c!=L'<' )
  throw Invalid_Format();


 // Считываем тэг.
 UFString tag;
 Read_Tag( reader, tag );

 if( tag.empty() )
  throw Invalid_Format();

 Node *node = new Node;

 Break_Tag( tag, node->name, node->attrs, node->body );

 // Тэги бывают пяти видов - единичный <abc/>, открывающий <abc>,
 // закрывающий </abc>, комментарий <!--...-->, блок <![CDATA[ ... ]>
 // Для HTML требуется также специальная обработка тэгов <script>...</script>
 // и одиночных типа <br>
 if( tag.back() == L'/' )
  {
   // Единичный тэг.
   node->SetClosed(true);
  }
 else if( node->name==L"![CDATA[" )
  {
   node->node_type = Node::CDataNode;
   node->SetClosed(true);
  }
 // Для HTML надо проверить одиночные теги типа <br>
 else if( doctype==HtmlDoc && IsHtmlClosed(tag) )
  {
   // Единичный тэг.
   node->SetClosed(true);
  }
 else if( tag.front()==L'/' )
  {
   // Закрывающий тэг.
   // В имени убираем символ '/'
   node->name = remove_char( node->name, L'/' ); 

   node->SetClosing(true);
  }
 else if( tag.front()==L'!' )
  {
   if( tag.length()>=3 && tag.eq_beg( L"!--" ) )
    {
     // Комментарий <!-- ... -->
     node->SetClosed(true);
     node->node_type = Node::CommentNode;
    }
/*
   else if( tag.eq_beg( L"CDATA[") )
    {
     node->SetClosed(true);
     node->node_type = Node::CDataNode;
    }
*/
   else
    {
     if( doctype==Parser::XmlDoc )
      {
       delete node;
       throw Invalid_Format();
      }
     else
      {
       node->SetClosed(true);
       node->node_type = Node::InvalidNode;
      }
    }
  }
 else if( doctype==Parser::HtmlDoc && node->name.eqi(L"script") )
  {
   // Для пары тегов <script>...</script> правила особые - тело является 
   // произвольным набором символов, читаемых как единое целое в тело узла.
   node->node_type = Node::ScriptNode; 
   node->body.reserve(256);
   while( !reader->eof() )
    {
     wchar_t c = reader->wget();
     if( c==WEOF || reader->eof() )
      break;

     if( c==L'<' )
      { 
       // вдруг это начало закрывающего тэга </script>
       lem::UFString tbuf;
       tbuf.reserve(32);
       tbuf = c;
 
       while( !reader->eof() )
        {
         wchar_t c2 = reader->wget();
         if( c2==WEOF || reader->eof() )
          break;

         tbuf.Add_Dirty(c2);

         if( c2==L'>' )
          break;
        } 
      
       if( tbuf.eqi(L"</script>") )
        {
         node->SetClosed(true);
         break;
        }
       else
        {
         node->body.Add_Dirty( tbuf );
        }
      }
     else
      {
       node->body.Add_Dirty(c);
      }
    }

   node->body.calc_hash();
  } 
 else
  {
   // Открывающий тэг.
   // Дальше может идти либо список вложенных тэгов, либо строка - тело.

   wchar_t c=0;

   // Пропустим пробелы.
   while( !reader->eof() )
    {
     c = reader->wget();

     if( c!=L' ' && c!=L'\t' && c!=L'\n' && c!=L'\r' )
      // Встретили непустой символ!
      break;
    }

   if( c==L'<' )
    {
     reader->unget(c);

     // Теперь надо загрузить все вложенные тэги и построить дерево.
     while( !reader->eof() )
      {
       Node *nested = Load_Node( reader );

       if( !nested )
        { 
         lem_rub_off(node); 
         throw Invalid_Format();
        }  
 
       if( nested->IsComment() )
        {
         // Комментарии удаляем.
         lem_rub_off(nested);
        }        
       else if( nested->IsCData() )
        {
         // Блок <[CData[ ... ]]> добавляем к телу
         node->body += nested->body;
         lem_rub_off(nested);
        }   
       else if( nested->GetClosing() )
        {
         if( nested->GetName() != node->GetName() )
          {
           lem_rub_off(node); 
           lem_rub_off(nested); 
           throw Invalid_Format();
          }
  
         // Список вложенных узлов закончен.
         node->SetClosed(true);
         lem_rub_off(nested); 
         break;
        }
       else if( !nested->GetClosed() )
        {
         lem_rub_off(node); 
         lem_rub_off(nested); 
         throw Invalid_Format();
        }

       if( nested!=NULL )
        {
         node->GetNodes().push_back( nested );

         if( doctype==Parser::HtmlDoc )
          {
           node->visible_text += nested->visible_text;
          }

         nested = NULL;
        } 

       // Идем до следующего тэга.
       // Пропустим пробелы.
       while( !reader->eof() )
        {
         c = reader->wget();

         if( c!=L' ' && c!=L'\t' && c!=L'\n' && c!=L'\r' )
          {
           // Встретили непустой символ!
           reader->unget(c); 
           break;
          }
        }

       if( reader->eof() )
        break;

       if( c != L'<' )
        {
         if( doctype!=Parser::HtmlDoc )
          {
           lem_rub_off(node); 
           // Тело тэга может быть либо список вложенных тэгов, либо строкой.
           // У нас тут получается смесь.
           throw Invalid_Format();
          }
         else
          {
           reader->wget();
           goto load_tag_body;
          }  
        }
      }
    }
   else
    {

load_tag_body:

     // Собираем тело тэга - до закрывающего.
     node->body.reserve(128);
     bool just_started=true;

     while( !reader->eof() )
      {
       lem::Stream::pos_type tpos = reader->tellp();

       if( !just_started )
        c = reader->wget();
       else  
        just_started = false;

       if( c==L'<' )
        {
         // Начало нового тэга
         
         if( reader->wget()==L'/' )
          {
           // это закрывающий тэг, он должен закрывать текущий тэг.
           reader->seekp(tpos);
           break;
          }
         else
          {
           // Произвольный вложенный тэг (HTML)
           reader->seekp(tpos);
           Node *nested = Load_Node(reader);
           if( !nested || !nested->GetClosed() )
            {
             throw Invalid_Format();
            }
           else if( nested->IsComment() )
            {
             lem_rub_off(nested);
            }
           else if( nested->IsCData() )
            {
             node->body += nested->body;
             lem_rub_off(nested);
            } 
 
           if( nested!=NULL )
            {
             node->nodes.push_back(nested);

             if( doctype==Parser::HtmlDoc )
              {
               node->visible_text += nested->visible_text; 
              }
            } 

           continue;
          }
        }

       if( c==L'&' )
        {
         // Далее идет либо символическое имя символа, либо его числовой код.
         c = reader->wget();
         if( c==L'#' )
          {
           // Считываем hex код символа до ;
           UFString hex; hex.reserve(6);
           while( !reader->eof() )
            {
             c = reader->wget();
             if( c==L';' || c==WEOF )
              break;
             hex.Add_Dirty(c);
            }
             
           c = lem::to_int( hex ); 
          }    
         else
          {
           FString char_name; char_name.reserve(8);
           char_name.Add_Dirty( char(c) );
           while( !reader->eof() )
            {
             c = reader->wget();
             if( c==L';' || c==WEOF )
              break;

             char_name.Add_Dirty( char(c) );
            }

           c = lem::CodeConverter::Sgml_2_Char(char_name);
          }
        }

       node->body += c;

       if( doctype==Parser::HtmlDoc )
        {
         node->visible_text += c;
        }
      }

     if( reader->wget()!=L'<' )
      {
       lem_rub_off(node); 
       throw Invalid_Format();
      }

     // Сейчас должен быть закрывающий тэг!
     UFString close_tag;
     Read_Tag( reader, close_tag );

     UFString name2, body2;
     Collect< pair<UFString,UFString> > attrs2;
     Break_Tag( close_tag, name2, attrs2, body2 );

     if( doctype==Parser::HtmlDoc && !remove_char( name2,L'/').eqi(node->name) )
      { 
       lem_rub_off(node); 
       throw Invalid_Format();
      }
     else if( remove_char(name2,L'/') != node->name )
      {
       lem_rub_off(node); 
       throw Invalid_Format();
      }

     node->SetClosed(true); 
    }
  }


 if( doctype==Parser::HtmlDoc )
  {
   // Некоторые типы тэгов в HTML фактически вводят в текст разделитель.
   if( IsTextDelimiterTag( node->GetName() ) )
    {
     node->visible_text += L' ';
    }
  }

 return node;
}
コード例 #14
0
ファイル: xp_parser.cpp プロジェクト: mcdir/GrammarEngine
void Parser::Break_Tag(
                       const UFString &tag,
                       UFString &name,
                       Collect< pair<UFString,UFString> > &attrs,
                       UFString &body // для ![CDATA[ ... ]]
                      ) const
{
 int i=0;

 // Пропускаем пробелы
 while( tag[i] )
  {
   if(
      tag[i]!=L' '  &&
      tag[i]!=L'\t' &&
      tag[i]!=L'\r' &&
      tag[i]!=L'\n'
     )
    break;

   i++;
  }

 if( tag.eq_beg(L"![CDATA[") )
  {
   name = L"![CDATA[";
   body = lem::mid( tag, 8, tag.length()-10 );
   return; 
  }

 // Пропускаем имя тэга
 while( tag[i] )
  {
   if(
      tag[i]==L' '  ||
      tag[i]==L'\t' ||
      tag[i]==L'\r' ||
      tag[i]==L'\n' ||
      tag[i]==L'>'
     )
    break;

   name += tag[i];
   i++;
  }

 // Читаем атрибуты

 while( tag[i] )
  {
   // Читаем очередную пару имя=значение

   // Пропускаем пробелы
   while( tag[i] )
    {
     if(
        tag[i]!=L' '  &&
        tag[i]!=L'\t' &&
        tag[i]!=L'\r' &&
        tag[i]!=L'\n'
       )
      break;

     i++;
    }

   if( !tag[i] || tag[i]=='/' || tag[i]=='>' )
    return;

   // Читаем имя атрибута = до знака '=' или пробела или конца тэга
   UFString var, value;

   if( tag[i]==L'"' )
    {
     // В апострофах - читаем как есть до второго апострофа
     i++;
     while( tag[i] )
      {
       if( tag[i]==L'"' )
        {
         i++;
         break;
        }

       if( tag[i]==L'\n' || tag[i]=='\r' )
        throw Invalid_Format();

       var += tag[i];
       i++;
      }
    }
   else
    {
     while( tag[i] )
      {
       if(
          tag[i]==L'='  ||
          tag[i]==L'/'  ||
          tag[i]==L'>'  ||
          tag[i]==L' '  ||
          tag[i]==L'\t' ||
          tag[i]==L'\r' ||
          tag[i]==L'\n'
         )
        break;

       var += tag[i];
       i++;
      }
    }

   // После имени атрибута до знака '=' могут быть пробелы - пропускаем.
   while( tag[i] )
    {
     if(
        tag[i]!=L' '  &&
        tag[i]!=L'\t' &&
        tag[i]!=L'\r' &&
        tag[i]!=L'\n'
       )
      break;

     i++;
    }


   if( tag[i]==L'=' )
    {
     // Читаем значение атрибута - до пробела или конца тэга
     i++;

     // Пропускаем начальные пробелы
     while( tag[i] )
      {
       if(
          tag[i]!=L' '  &&
          tag[i]!=L'\t' &&
          tag[i]!=L'\r' &&
          tag[i]!=L'\n'
         )
        break;

       i++;
      }

     if( tag[i]==L'"' )
      {
       // Значение атрибута - в апострофах, читаем как есть
       i++;
       while( tag[i] )
        {
         if( tag[i]==L'"' )
          {
           i++;
           break;
          }

         if( tag[i]==L'\n' || tag[i]=='\r' )
          throw Invalid_Format();

         value += tag[i];
         i++;
        }
      }
     else
      {
       while( tag[i] )
        {
         if(
            tag[i]==L'='  ||
            tag[i]==L'/'  ||
            tag[i]==L'>'  ||
            tag[i]==L' '  ||
            tag[i]==L'\t' ||
            tag[i]==L'\r' ||
            tag[i]==L'\n'
           )
          break;

         value += tag[i];
         i++;
        }
      }
    }

   // Добавляем очередной атрибут
   attrs.push_back( make_pair( var, value ) );
  }

 return;
}
コード例 #15
0
ファイル: xp_parser.cpp プロジェクト: mcdir/GrammarEngine
// **********************************************************
// Загружаем тэг - все символы между < >.
// Открывающая угловая скобка уже считана!
// **********************************************************
void Parser::Read_Tag( WideStream *reader, UFString &tag ) const
{
 tag.clear();
 int count=0;

 while( !reader->eof() )
  {
   wchar_t c = reader->wget();

   if( c==L'>' )
    break;

   if( !count && c==L'!' )
    {
     // Или комментарий   <!-- ... -->
     // или блок кода     <![CDATA[ ... ]]>
     // или начальный тэг <!DOCTYPE

     tag.Add_Dirty(c);
     count++;

     wchar_t c = reader->wget();
     if( c==L'-' )
      {
       // комментарий...
       tag.Add_Dirty(c);
       count++;
       while( !reader->eof() ) 
        {
         wchar_t c = reader->wget();
         if( c==WEOF )
          break;

         if( count>3 && c==L'>' )
          {
           // Комментарий заканчивается на -->
           if( tag.back()==L'-' && tag[tag.length()-2]==L'-' )
            {
             goto tag_complete;
            } 
          }  

         tag.Add_Dirty(c);
         count++;
        }

       // Если комментарий не закончен нормально, то значит была ошибка 
       throw Invalid_Format(); 
      }    
     else if( c==L'D' )
      {
       // <!DOCTYPE ...>
       // загружаем как обычный тэг
       tag.Add_Dirty(c);
       count++;
       continue;
      }
     else if( c=='[' )
      {
       // <![CDATA[ продолжаем загружать...
       tag.Add_Dirty(c);
       count++;
       continue;
      }  
     else 
      {
       // Неизвестный тэг, для HTML проигнорируем ошибку
       if( doctype==Parser::HtmlDoc )
        {
         tag.Add_Dirty(c);
         count++;
        } 
       else
        {
         throw Invalid_Format();
        }
      } 
    }
   else if( count==7 && c==L'[' && tag==L"![CDATA" )
    {
     // блок кода после <![CDATA[

     tag.Add_Dirty(c);
     count++;

     while( !reader->eof() ) 
      {
       wchar_t c = reader->wget();
       if( c==WEOF )
        break;

       if( count>8 && c==L'>' )
        {
         // Блок кода заканчивается на ]]>
         if( tag.back()==L']' && tag[tag.length()-2]==L']' )
          {
           goto tag_complete;
          } 
        }  

       tag.Add_Dirty(c);
       count++;
      }

     if( doctype!=Parser::HtmlDoc )
      throw Invalid_Format(); 
    }
  
   if( c==WEOF || reader->eof() )
    break;

   tag.Add_Dirty(c);
   count++;
  }

tag_complete:
 tag.calc_hash();

 return;
}