2011-01-23 3 views
0

Итак ... Существуют ли какие-либо стандартные libs в boost для создания некоторых скриптов/xmls-ридеров, которые отображали бы этот скрипт в объекты через какой-то ролл?Как создать интерпретатор сценария с Boost C++

+0

мой главный пункт - у меня есть много классов, которые начались в разном порядке, создадут разные результаты. Мне нужно что-то сделать в желаемом порядке. после того, как приложение было скомпилировано. – Rella

+0

Я не уверен, что вы хотите, но, возможно, это то, что вы ищете http://www.boost.org/doc/libs/1_45_0/doc/html/property_tree.html – MatiasFG

+1

ваш вопрос кажется немного смущенным; Я совсем не уверен, что вы хотите здесь. Можете ли вы попытаться дать более конкретный пример? Кстати, вы можете нажать ссылку «Изменить» под своим вопросом, чтобы добавить более подробную информацию; это может быть лучше комментариев, поскольку комментарии будут скрыты, если их слишком много – bdonlan

ответ

1

Если вы хотите, чтобы ваши классы запускались в определенном порядке, я думаю, что язык скриптов слишком убит. Вам нужен топографический вид.

Что вам нужно

подталкивание имеет topographical sort. Вы также можете ознакомиться с очень читаемой реализацией C#, которая должна быть легко перенесена на C++, если библиотека ускорения немного для вас. Это можно найти here.

Что она делает

В принципе, вы предоставляете алгоритм сортировки с классами, а затем добавить их зависимости (алгоритм сортировки рассматривает их в качестве вершин и ребер). Как только вы закончите, вы примените алгоритм. То, что вы выбрали, зависит от того, от каких объектов зависит.

Я использовал этот точный метод, когда у меня была куча подсистем, которые нужно было загрузить, некоторые из которых опирались на других, а некоторые - нет. Количество подсистем было произвольным и связано с природой программы, неизвестной во время компиляции.

Я назначил каждой подсистеме уникальный идентификатор (кстати, используя boost::uuid), и каждая подсистема указала идентификаторы других подсистем, которые полагались на нее. Это было подано в сортировщик, и мой порядок инициализации вышел на задний план.

Чтобы помочь вам на вашем пути, вот какой-то код (ПРИМЕЧАНИЕ. На данный момент я не знал, что библиотека boost существует, это моя собственная реализация на основе кода C# из ссылки, приведенной выше.)

 // class TopologicalSorter 
     template<typename TYPE> class TopologicalSorter 
     { 
     private: 

      std::vector<TYPE>    m_Vertices; 
      std::vector<std::vector<TYPE> > m_Matrix; 
      std::vector<TYPE>    m_Sorted; 
      TYPE       m_nNumVerts; 
      TYPE       m_nSize; 

      // private helpers 
      int noSuccessors() 
      { 
       bool isEdge; 
       for(TYPE row(0); row < m_nNumVerts; row++) 
       { 
        isEdge = false; 
        for(TYPE col(0); col < m_nNumVerts; col++) 
        { 
         if(m_Matrix[row][col] > 0) // edge to another? 
         { 
          isEdge = true; 
          break; 
         }; 
        }; 

        if(!isEdge) 
         return(row); 
       }; 

       return(-1); // nope! 
      }; // eo noSuccessors 

      void deleteVertex(TYPE _vertex) 
      { 
       if(_vertex != m_nNumVerts - 1) 
       { 
        for(TYPE j(_vertex); j < m_nNumVerts - 1; j++) 
         m_Vertices[j] = m_Vertices[j + 1]; 

        for(TYPE row(_vertex); row < m_nNumVerts - 1; row++) 
         moveRowUp(row, m_nNumVerts); 

        for(TYPE col(_vertex); col < m_nNumVerts - 1; col++) 
         moveColLeft(col, m_nNumVerts - 1); 
       }; 

       --m_nNumVerts; 
      }; // eo deleteVertex 

      void moveRowUp(TYPE _row, TYPE _length) 
      { 
       for(TYPE col(0); col < _length; col++) 
        m_Matrix[_row][col] = m_Matrix[_row + 1][col]; 
      }; // eo moveRowUp 

      void moveColLeft(TYPE _col, TYPE _length) 
      { 
       for(TYPE row(0); row < _length; row++) 
        m_Matrix[row][ _col] = m_Matrix[row][_col + 1]; 
      }; // eo moveColLeft 

     public: 
      TopologicalSorter(TYPE _size) : m_nNumVerts(0) 
              , m_Vertices(_size) 
              , m_Matrix(_size) 
              , m_Sorted(_size) 
              , m_nSize(_size) 
      { 
       assert(_size > 0); 
       for(TYPE i(0); i < m_nSize; ++i) 
       { 
        for(TYPE j(0); j < m_nSize; ++j) 
         m_Matrix[i].push_back(0); 
       }; 
      }; // eo ctor 


      ~TopologicalSorter(){}; 


      // public methods 


      TYPE addVertex(TYPE _vertex) 
      { 
       m_Vertices[m_nNumVerts++] = _vertex; 
       return(m_nNumVerts - 1); 
      }; // eo addVertex 

      void addEdge(TYPE _start, TYPE _end) 
      { 
       m_Matrix[_start][_end] = 1; 
      }; // eo addEdge 

      std::vector<TYPE> sort() 
      { 
       int currVertex; 
       while(m_nNumVerts) 
       { 
        currVertex = noSuccessors(); 
        coreAssert(currVertex != -1, "Graph has cycles"); 

        m_Sorted[m_nNumVerts - 1] = m_Vertices[currVertex]; 
        deleteVertex(currVertex); 
       }; // eo while(m_nNumVerts) 

       return(std::move(m_Sorted)); 
      }; // eo sort 

     }; // eo class TopologicalSorter 

Теперь, это то, как это было использовано с погрузкой и инициализацией подсистемы (UUID просто typedef для boost::uuids::uuid)

// create a topological sorter: 
    utility::TopologicalSorter<ManagerVector_sz> sorter(m_Managers.size()); 
    std::map<Uuid, ManagerVector_sz> indexes; 

    // add vertices and edges 
    for(ManagerVector_sz i(0); i < m_Managers.size(); ++i) 
     indexes.insert(std::pair<Uuid, ManagerVector_sz>(m_Managers[i]->getUuid(), sorter.addVertex(i))); 

    for(ManagerVector_sz i(0); i < m_Managers.size(); ++i) 
    { 
     if(m_Managers[i]->getDependencies().size()) 
     { 
      for(ManagerVector_sz j(0); j < m_Managers[i]->getDependencies().size(); ++j) 
       sorter.addEdge(i, indexes[m_Managers[i]->getDependencies()[j]]); 
     }; 
    }; 

    // get the order in which we should initialise 
    m_SortedIndexes = sorter.sort(); 

    // and initialise 
    ManagerVector* mv(&m_Managers); 
    std::for_each(m_SortedIndexes.rbegin(), 
        m_SortedIndexes.rend(), 
        [&mv](int i){mv->at(i)->initialise();}); 

Надеется, что это помогает и избежать не-нужного скрипта!

2

Библиотека Boost Spirit должна позволить вам легко определить формат конфигурации.

Смежные вопросы