コード例 #1
0
ファイル: word_form.cpp プロジェクト: mcdir/GrammarEngine
void Word_Form::LoadPreciser(
                             CompilationContext &context,
                             Macro_Parser& txtfile,
                             SynGram& gram,
                             int iclass
                            )
{
 // Тапереча в {} могет быть идти список уточняющих координат.
 //
 // Каждая уточняющая координата должна следовать такому формату:
 //
 //  [~]имя_координаты:имя_состояния
 //
 // Причем, только если вместо имени статьи указан квантор всеобщности,
 // то разрешается задавать АТРИБУТЫ как координаты.
 //
 // Особо обрабатываются координаты с неявно объявленными состояниями
 // TRUE/FALSE. Следует учесть, что само упоминание имени такой координаты
 // равносильно упоминанию также и имени состояния TRUE, а для объявлени
 // состояния FALSE необходимо использовать конструкцию с оператором
 // отрицания НЕ.

 while(!txtfile.eof())
  {
   // Считываем имя координаты.
   BethToken coord_name = txtfile.read();

   // Может, список закончился, то есть встретилась '{' ?
   if( coord_name.GetToken()==B_CFIGPAREN )
    break;


   // В двойных апострофах может идти имя формы, которую надо использовать вместо
   // имени словарной статьи.
   if( lem::in_quotes(coord_name.string()) )
    {
     Lexem *mname = new Lexem( strip_quotes(coord_name) );

     gram.GetDict().GetLexAuto().TranslateLexem(*mname,false);
     mname->Translate( gram.GetDict().GetGraphGram(), 2 );
     name = RC_Lexem( mname );
    }
   else 
    {
     bool AFFIRM=true;

     if( coord_name.GetToken()==B_NEGATIVE )
      {
       // Оператор отрицания перед определением координаты!
       AFFIRM=false;
       coord_name = txtfile.read();
      }

     const GramCoordAdr iglob_coord = gram.FindCoord(coord_name.string());

     // Попытаемся найти координату среди списка атрибутов и тэгов.
     int iloc_coord = gram.classes()[iclass].attrs().find(iglob_coord);
   
     // Нашли?
     if( iloc_coord!=UNKNOWN )
      {
       // Да! Примем к сведению, что если для опорной точки задано
       // имя словарной статьи, то мы не имеем право по логике вещей
       // определять также и атрибуты, так как само определение словарной
       // статьи определяет необходимые атрибуты.
       if( entry_key!=ANY_STATE )
        {
         lem::Iridium::Print_Error(coord_name,txtfile);
         gram.GetIO().merr().printf(
                "The attribute can not be declared here, because entry is already declared\n"
                                   );
         throw E_ParserError();
        }
      }
     else
      {
       // Попробуем найти координату среди списка измерений.
       iloc_coord = gram.classes()[iclass].dims().find(iglob_coord);

       if( iloc_coord==UNKNOWN )
        iloc_coord = gram.classes()[iclass].tags().find(iglob_coord);

       // Нашли?
       if( iloc_coord==UNKNOWN && iclass!=SOL_EQUIL_INDEX )
        {
         // Нет. Таким образом, имя координаты не определяет
         // ни тэг, ни измерение. Генерируем сообщение
         // об ошибке.

         lem::Iridium::Print_Error(coord_name,txtfile);
         gram.GetIO().merr()
          .printf(
                  "Coordinate [%us] is neither tag"
                  " nor dimention for the class [%us]\n"
                  , coord_name.string().c_str()
                  , gram.classes()[ iclass ].GetName().c_str()
                 );

         throw E_ParserError();
        }
      }

     /*-------------------------------------------------------------------------
  
     Теперь считываем определение состояния.

     В некоторых случаях допускается такой формат записи:

                          имя_координаты:=индекс

     Обычно так указываются те состояния, которые имеет данная координата
     у заданной индексом опорной точки контекста. Внутреннее описание в этом
     случае отличается от обычного лишь тем, что состояние имеет знак минус
     и хранит на самом деле числовое значение индекса минус единица, так
     что состояние -1 означает опорную точку 0, и так далее. Это сделано,
     чтобы корректно отличать случай состояния с нулевым индексом.

     -------------------------------------------------------------------------*/

     int istate;

     const BSourceState back = txtfile.tellp();
     if(
        txtfile.read().GetToken()==B_COLON &&
        txtfile.read().GetToken()==B_EQUAL
       )
      istate = -txtfile.read_int()-1; // Да, это формат ИМЯ_КООРД:=ИНДЕКС
     else
      {
       txtfile.seekp(back);

       // Является ли она бистабильной?
       if( gram.coords()[iglob_coord.GetIndex()].states().empty() )
        {
         // Да - считывать имя состояния не надо.
         istate=AFFIRM;
        }
       else
        {
         // Индекс состояния у найденной координаты.
         txtfile.read_it(B_COLON);
         const BethToken state_name = txtfile.read();
         istate = gram.coords()[iglob_coord.GetIndex()].FindState(state_name.string());

         if( istate==UNKNOWN )
          {
           lem::Iridium::Print_Error(state_name,txtfile);
           gram.GetIO().merr().printf(
                                      "State [%us] is not declared for coordinate [%us]\n"
                                      , state_name.c_str(), coord_name.c_str()
                                     );
           throw E_ParserError();
          }
        }
      }

     pair.push_back(GramCoordEx(iglob_coord,istate,AFFIRM));

    }

  } // конец цикла считывания уточненных координат

 return;
}
コード例 #2
0
SG_calibrator::SG_calibrator(const lem::UCString & keyword, const SynGram &sg, const Sol_IO &io, Macro_Parser &txtfile)
{
    if (keyword.eqi(L"wordentry_freq"))
        freq_type = WordEntryFreq;
    else if (keyword.eqi(L"wordform_score"))
        freq_type = WordFormScore;
    else if (keyword.eqi(L"wordforms_score"))
        freq_type = WordFormsScore;

    id_class = UNKNOWN;
    freq = 0;

    word = txtfile.read().string();
    word.strip(L'"');

    // если далее идет открывающая фигурная скобка, то значит конкретизируется словоформа (или несколько
    // словоформ).

    if (txtfile.probe(B_OFIGPAREN))
    {
        while (!txtfile.eof())
        {
            if (txtfile.pick().GetToken() == B_CFIGPAREN)
            {
                txtfile.read();
                break;
            }

            // для обычных: координата:состояние
            // для бистабильных: координата
            lem::Iridium::BethToken coord_name = txtfile.read();

            if (id_class == UNKNOWN)
            {
                const int id_class0 = sg.FindClass(coord_name);
                if (id_class0 != UNKNOWN)
                {
                    id_class = id_class0;
                    continue;
                }
            }

            bool AFFIRM = true;

            if (coord_name.GetToken() == B_NEGATIVE)
            {
                // Оператор отрицания перед определением координаты!
                AFFIRM = false;
                coord_name = txtfile.read();
            }

            const GramCoordAdr iglob_coord = sg.FindCoord(coord_name.string());

            if (!iglob_coord.IsDefined())
            {
                sg.GetIO().merr().printf("Unknown coordinate %us\n", coord_name.c_str());
                lem::Iridium::Print_Error(coord_name, txtfile);
                throw lem::E_BaseException();
            }

            if (sg.coords()[iglob_coord.GetIndex()].IsBistable())
            {
                // Имя состояния не может быть указано.
                coords.push_back(GramCoordPair(iglob_coord, AFFIRM));
            }
            else
            {
                // После двоеточия должно идти имя состояния для координаты.
                txtfile.read_it(B_COLON);

                // Имя состояния.
                BethToken state_name = txtfile.read();

                // Получим индекс состояния для определенной координаты.
                const int istate = sg.coords()[iglob_coord.GetIndex()]
                    .FindState(state_name.string());
                if (istate == UNKNOWN)
                {
                    // Нет такого состояния для этого измерения.
                    lem::Iridium::Print_Error(state_name, txtfile);
                    sg.GetIO().merr().printf(
                        "State [%vfE%us%vn] is not declared for coordinate [%vfE%us%vn]\n"
                        , state_name.c_str(), coord_name.c_str()
                    );
                    throw E_ParserError();
                }

                coords.push_back(GramCoordEx(iglob_coord, istate, AFFIRM));
            }
        }
    }

    txtfile.read_it(B_EQUAL);

    if (txtfile.probe(B_SUB))
        freq = -txtfile.read_int();
    else
        freq = txtfile.read_int();
    return;
}