Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> boost::spirit построение дерева из формулы, для последующих расчетов 
V
    Опции темы
bsa
Дата 3.7.2009, 15:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Есть набор сложных формул, кодирующих биты. Операции все логические:
Код
1 = 2 & 3 ^ (!5 | 4) #bit[1] = (bit[2] & bit[3]) ^ (!bit[5] | bit[4])
....
Хочу распарсить правую часть с помощью спирита. Взял пример калькулятора и немного его модифицировал:
Код
struct Calculator : boost::spirit::grammar< Calculator >
{
    Calculator() {}
    typedef unsigned Type;
    typedef boost::shared_ptr<Operation::Base<Type> > OperationPtr;

    struct ValueClosure : public boost::spirit::closure<ValueClosure, OperationPtr> {
        member1 value;
    };

    // Following is the grammar definition.
    template <typename ScannerT>
    struct definition {
        definition(Calculator const& self) {
            using namespace boost::spirit;
            using namespace phoenix;
    
            literal = int_p[bind(&definition::createBit, literal, arg1)];
            group = '(' >> expression[group.value = arg1] >> ')';
            factor = literal[factor.value = arg1] | group[factor.value = arg1];
            term = factor[term.value = arg1] >> *('!' >> factor[bind(&definition::createNot, term, arg1)]);

            expression
                = term[expression.value = arg1]
                >> *('&' >> term[bind(&definition::createAnd, expression, arg1)] )
                >> *('^' >> term[bind(&definition::createXor, expression, arg1)] )
                >> *('|' >> term[bind(&definition::createOr, expression, arg1)] )
                ;

            //statement = expression[bind(&calculator::do_print)(self, arg1)] >> end_p;
        }

        boost::spirit::rule<ScannerT> const& start() const { return statement; }
    private:
        boost::spirit::rule<ScannerT> statement;
        typedef boost::spirit::rule<ScannerT, ValueClosure::context_t> Context;
        Context expression, factor, group, literal, term;

        static void createBit(Context &context, Type n) {
            context.value = OperationPtr( new Operation::Bit<Type>(n) );
        }
        static void createNot(Context &context, OperationPtr op) {
            context.value = OperationPtr( new Operation::Not<Type>(op) );
        }
        static void createAnd(Context &context, OperationPtr op2) {
            context.value = OperationPtr( new Operation::And<Type>(context.value(), op2) );
        }
        static void createXor(Context &context, OperationPtr op2) {
            context.value = OperationPtr( new Operation::Xor<Type>(context.value(), op2) );
        }
        static void createOr(Context &context, OperationPtr op2) {
            context.value = OperationPtr( new Operation::Or<Type>(context.value(), op2) );
        }
    };
};
При попытке компиляции выдается страшная ошибка, что мол где-то внутри спирита void функция попыталась вернуть значение.
Проблема пропадает, если закоментировать все определения правил. Но смысла в этом нет.
Operation::Base - это абстрактный класс операции. Некоторые потомки принимают 1, а некоторые 2 параметра. В принципе, это несущественно. В принципе, Base - это нод дерева операций. Т.е. задача - построить дерево, которое будет обходиться каждый раз, когда мне то понадобится. Использование парсера для конечной обработки данных не подходит, так как данных очень много.

ошибки можно увидеть тут: http://pastebin.com/m1ad57c76

Это сообщение отредактировал(а) bsa - 3.7.2009, 16:30
PM   Вверх
bsa
Дата 3.7.2009, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Проблема оказалась в bind...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0408 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.