/********************************************************************
 Подготавливаем кэш для работы: выделяем необходимую память для
 списка списков проекций. Эта процедура должна вызываться уже
 п_о_с_л_е загрузки графической грамматики, так как нам нужно узнать
 число символов в алфавите gram. Запомненные списки сейчас пусты, так
 как осуществленных проекций еще не было.
*********************************************************************/
void LA_WordProjBuffer::Adjust( const GraphGram &gram )
{
 // Число символов в алфавите (не считая буквоформ)
 NTOT=0;
 const int nchar = CastSizeToInt(gram.entries().Count());
 list.reserve(nchar);
 int i;

 // Будем поддерживать nchar списков списков проекций, каждый список хранит
 // начинающиеся с одной и той же буквы проекции мультилексем.
 lem::Ptr<SymbolEnumerator> senum( gram.entries().Enumerate() );
 while( senum->Fetch() )
  {
   list.push_back( LA_ProjList( senum->GetItem().GetName() ) );
  }

 // Отсортируем список списков по возрастанию параметра КОД СИМВОЛА,
 // чтобы была возможность реализовать быстрый поиск нужного списка
 // методом дихотомии.
 int gap, j;
 const int N=nchar;
 for( gap=N/2; gap>0; gap/=2 )
  for( i=gap; i<N; i++ )
   for( j=i-gap; j>=0; j-=gap )
    {
     if( list[j+gap].Char > list[j].Char )
      break;

     std::swap( list[j], list[j+gap] );
    }

 return;
}
Example #2
0
/***********************************************************************
 Отыскиваем в Графической Грамматике буквы, из которых составлены части
 команды на формообразование. Сохраняем информацию о каждой букве: ее
 условное имя и номер буквоформы.
************************************************************************/
void SG_DeclensionForm::Translate( int id_class, const GraphGram &gram )
{
 if( !form.empty() )
  {
   int id_language=UNKNOWN;
   if( !lem::is_quantor(id_class) )
    {
     const SG_Class &c = gram.GetDict().GetSynGram().GetClass( id_class );
     id_language = c.GetLanguage();
    }
    
   if( id_language!=UNKNOWN )
    {
     const SG_Language &lang = gram.GetDict().GetSynGram().languages()[id_language];
     const lem::MCollect<int> &id_alphabets = lang.GetAlphabets();
     form.Translate(gram,2,id_alphabets);
    }
   else
    {
     form.Translate(gram,2);
    }
  } 

 return;
}
void LA_PhoneticCondictor::LoadTxt( Macro_Parser &txtfile, GraphGram &gram )
{
 txtfile.read_it(B_CONTEXT);
 const BethToken t = txtfile.read();

 context = t.string();

 context.strip_quotes();

 // Каждый символ из строки должен быть известен как буква - то есть
 // быть определен через Алфавит. Допускается также специальный
 // кванторный символ '*'.
 //
 // В двух случаях допускается применение символа $ - для требования на
 // размещение символов: "$aaa" - приставка, "aaa$" - аффикс.

 if( context.front()==L'$' )
  {
   loc = PREFIX;
   context.Remove(0);
  }
 else if( context.back()==L'$' )
  {
   loc = AFFIX;
   context.Remove( context.length()-1 );
  }
 else
  loc = UNLOCATED; 


 const int cl=context.length();
 for( int i=0; i<cl; i++ )
  {
   const wchar_t ch = context[i];

   if( ch==L'*' )
    continue;

   const Word_Coord wc = gram.FindSymbol(ch);
   if( wc.GetEntry()==UNKNOWN )
    {
     lem::Iridium::Print_Error( t, txtfile );
     gram.GetIO().merr().printf(
                            "Condictor [%us] contains unknown symbol (neither "
                            "char nor quantor '*')\n"
                            , context.c_str()
                           );
     throw E_ParserError();
    }

   context.set( i, gram.entries()[wc.GetEntry()].GetName() );
  }

 return;
}
Example #4
0
SyllabContext::SyllabContext(GraphGram &alphabet, const lem::UCString &word, int id_language)
{
    LEM_CHECKIT_Z(id_language != UNKNOWN);

    const SG_Language &lang = alphabet.GetDict().GetSynGram().languages()[id_language];
    const lem::MCollect<int> & id_alphabets = lang.GetAlphabets();

    points.push_back(new SyllabContextLeftBoundary());

    // Разбираем исходное слово по символам, каждый символ ищем в алфавите и создаем по результатам одну точку контекста 
    lem::WideStringUcs4 ucs4(word.c_str());
    lem::uint32_t c;
    while ((c = ucs4.Fetch()) != 0)
    {
        const Word_Coord wc = alphabet.entries().FindSymbol(c, id_alphabets);
        if (wc.IsUnknown())
        {
            SyllabContextUnknownSymbol *point = new SyllabContextUnknownSymbol(c);
            points.push_back(point);
        }
        else
        {
            const GG_Entry &e = alphabet.entries()[wc.GetEntry()];
            const int id_class = e.GetClass();

            const GG_EntryForm & f = e.forms()[wc.GetForm()];
            lem::MCollect<GramCoordPair> coords = f.dims();
            for (lem::Container::size_type k = 0; k < e.attrs().size(); ++k)
                coords.push_back(e.attrs()[k]);

            SyllabContextSymbol *point = new SyllabContextSymbol(c, e.GetName(), wc.GetEntry(), id_class, coords);
            points.push_back(point);
        }
    }

    points.push_back(new SyllabContextRightBoundary());

    return;
}
Example #5
0
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;
}