Как создать интерпретатор сценариев с Boost C ++ - PullRequest
0 голосов
/ 23 января 2011

Итак ... Существуют ли какие-либо стандартные библиотеки для создания некоторых программ для чтения сценариев / xmls, которые отображали бы этот сценарий в объекты через некоторый rool?

Ответы [ 2 ]

2 голосов
/ 24 января 2011

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

1 голос
/ 24 января 2011

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

Что вам нужно

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

Что он делает

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

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

Я назначил каждой подсистеме уникальный идентификатор (кстати, используя 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();});

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...