Russian Qt Forum
Ноябрь 24, 2024, 06:22 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 3 [4] 5   Вниз
  Печать  
Автор Тема: Парсинг строк  (Прочитано 32404 раз)
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #45 : Март 18, 2016, 09:26 »

может Вы просто не умеете ... хотите только "пользоваться готовым"?
Может и не умею, может хочу.

А Вы, вот Вы... сырыми массивами пользоваться не умеете, раз используете готовенький вектор.
Аргумент?  Подмигивающий
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #46 : Март 18, 2016, 09:59 »

Цитировать
Как-то развить пример я не могу. Напр как выйти при обнаружении "дальше примечания" (//)? Придется надыбать примерчик и опять передрать. Какое-то ветвление в разборе - то же самое.
Вы не можете, а между тем, спирит даёт возможность (нет, это больше - это часть его идеалогии) разбить сложную задачу на простые. Можно написать свой кирпичик - парсер для node
Код
C++ (Qt)
struct Node
{
   Node() : number(0) {}
   static constexpr uint nodeDimension = 3;
   uint number;
   std::array<float, nodeDimension> coordinates = {{-1, -1, -1}};
};
 
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace sw = boost::spirit::standard_wide;
 
 
template <class ForwardIterator>
class NodeParser : public qi::grammar<ForwardIterator, Node(), sw::space_type>
{
public:
   NodeParser() : NodeParser::base_type(start_, "NodeParser")
   {
       start_ = qi::lit("*node(")  >> qi::uint_[phx::bind(&NodeParser::set_number, qi::_val, qi::_1)] >> ','
                                   >> qi::float_[phx::bind(&NodeParser::set_x, qi::_val, qi::_1)] >> ','
                                   >> qi::float_[phx::bind(&NodeParser::set_y, qi::_val, qi::_1)] >> ','
                                   >> qi::float_[phx::bind(&NodeParser::set_z, qi::_val, qi::_1)] >> ','
                                   >> *(qi::uint_ >> ',')
                                   >> qi::uint_ >> ')';
   }
private:
   qi::rule<ForwardIterator, Node(), sw::space_type> start_;
 
   static void set_number(Node & node, uint number){ node.number = number; }
   static void set_x(Node & node, float x){ node.coordinates[0] = x; }
   static void set_y(Node & node, float y){ node.coordinates[1] = y; }
   static void set_z(Node & node, float z){ node.coordinates[2] = z; }
};
 
и потом использывать его уже в более сложных выражениях, где могут быть и всякие "примечания" и комментарии и секции и т.д.
И это правильный ООП подход.   
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #47 : Март 18, 2016, 10:12 »

m_ax, здравствуйте!
Спасибо за примерчик
Код
C++ (Qt)
struct Node
{
   Node() : number(0) {}
   static constexpr uint nodeDimension = 3;
   uint number;
   std::array<float, nodeDimension> coordinates = {{-1, -1, -1}};
};
 
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace sw = boost::spirit::standard_wide;
 
 
template <class ForwardIterator>
class NodeParser : public qi::grammar<ForwardIterator, Node(), sw::space_type>
{
public:
   NodeParser() : NodeParser::base_type(start_, "NodeParser")
   {
       start_ = qi::lit("*node(")  >> qi::uint_[phx::bind(&NodeParser::set_number, qi::_val, qi::_1)] >> ','
                                   >> qi::float_[phx::bind(&NodeParser::set_x, qi::_val, qi::_1)] >> ','
                                   >> qi::float_[phx::bind(&NodeParser::set_y, qi::_val, qi::_1)] >> ','
                                   >> qi::float_[phx::bind(&NodeParser::set_z, qi::_val, qi::_1)] >> ','
                                   >> *(qi::uint_ >> ',')
                                   >> qi::uint_ >> ')';
   }
private:
   qi::rule<ForwardIterator, Node(), sw::space_type> start_;
 
   static void set_number(Node & node, uint number){ node.number = number; }
   static void set_x(Node & node, float x){ node.coordinates[0] = x; }
   static void set_y(Node & node, float y){ node.coordinates[1] = y; }
   static void set_z(Node & node, float z){ node.coordinates[2] = z; }
};
 
Хотел бы спросить, намеренно ли вы в Node number инициализировали в конструкторе, а coordinates в объявлении?
Почему вы объявляете методы set_xyz в парсере, а не в Node?
phx::bind может быть заменён на std::bind?
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #48 : Март 18, 2016, 10:14 »

Блин, хотел в ЛС. Получилось тут. Ну ладно...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #49 : Март 18, 2016, 12:00 »

.. и потом использывать его уже в более сложных выражениях, где могут быть и всякие "примечания" и комментарии и секции и т.д.
Насчет отсечки комментов не понял. На моем незатейливом велике это делается так
Код
C++ (Qt)
QStringRef src(&text);
src = BeforeFirst(src, "//");
А что здесь надо сделать чтобы достичь того же? Спасибо
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #50 : Март 18, 2016, 13:27 »

Код
C++ (Qt)
start_ = qi::lit("*node(")  >> qi::uint_[phx::bind(&NodeParser::set_number, qi::_val, qi::_1)] >> ','
                                   >> qi::float_[phx::bind(&NodeParser::set_x, qi::_val, qi::_1)] >> ','
                                   >> qi::float_[phx::bind(&NodeParser::set_y, qi::_val, qi::_1)] >> ','
                                   >> qi::float_[phx::bind(&NodeParser::set_z, qi::_val, qi::_1)] >> ','
                                   >> *(qi::uint_ >> ',')
                                   >> qi::uint_ >> ')' >> '//' >> *(qi::char_);
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #51 : Март 18, 2016, 13:28 »

Это если комментарий обязательный
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #52 : Март 18, 2016, 13:43 »

Это если комментарий обязательный
Улыбающийся Если все "обязательно", то достаточно простого sscanf

Как по мне, так лучше потратить пару дней на изучение boost::xpressive http://www.boost.org/doc/libs/1_60_0/doc/html/xpressive.html или spirit, чем каждый раз лепить такое..
Ну наверное "пара дней" - это для очень молодых и талантливых Улыбающийся А я так вижу - не одну неделю пыль глотать
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #53 : Март 18, 2016, 13:47 »

Улыбающийся Если все "обязательно", то достаточно простого sscanf
Необязательные просто в скипер засовываются.

я так вижу - не одну неделю пыль глотать

сообщение #15 m_ax Март 10
моё сообщение #19 Март 14
Уделял изучению менее часа в день. Результата достиг.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #54 : Март 18, 2016, 14:22 »

Необязательные просто в скипер засовываются.
А куда это Непонимающий Улыбающийся Это Ваш пост #50 ?

сообщение #15 m_ax Март 10
моё сообщение #19 Март 14
Уделял изучению менее часа в день. Результата достиг.
Ну да, прогресс налицо  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #55 : Март 18, 2016, 14:36 »

А куда это Непонимающий Улыбающийся
Как скипать комментарии и обрабатывать ошибки мы с вами обсудили два года назад, когда с помощью spirit парсили bib и obj файлы.
Вы забыли? Вот ссылочка на тему, освежите. Улыбающийся
http://www.prog.org.ru/topic_26894_0.html
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #56 : Март 18, 2016, 14:38 »

А куда это Непонимающий Улыбающийся

В правило. Лучше один раз почитайте документацию, чем 100 раз спрашивать  Улыбающийся
Или память тренировать Подмигивающий
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #57 : Март 18, 2016, 17:02 »

В правило. Лучше один раз почитайте документацию, чем 100 раз спрашивать  Улыбающийся
Или память тренировать Подмигивающий
Ладно, обойдемся без сопливых советов Улыбающийся А вот и примерчик
Цитировать
Boost C++ Libraries

"...one of the most highly regarded and expertly designed C++ library projects in the world." — Herb Sutter and Andrei Alexandrescu, C++ Coding Standards
libs/spirit/example/qi/compiler_tutorial/mini_c/skipper.hpp

/*=============================================================================
    Copyright (c) 2001-2011 Joel de Guzman

    Distributed under the Boost Software License, Version 1.0. (See accompanying
    file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
#if !defined(BOOST_SPIRIT_MINIC_SKIPPER_HPP)
#define BOOST_SPIRIT_MINIC_SKIPPER_HPP

#include <boost/spirit/include/qi.hpp>

namespace client { namespace parser
{
    namespace qi = boost::spirit::qi;
    namespace ascii = boost::spirit::ascii;

    ///////////////////////////////////////////////////////////////////////////////
    //  The skipper grammar
    ///////////////////////////////////////////////////////////////////////////////
    template <typename Iterator>
    struct skipper : qi::grammar<Iterator>
    {
        skipper() : skipper::base_type(start)
        {
            qi::char_type char_;
            ascii::space_type space;

            start =
                    space                               // tab/space/cr/lf
                |   "/*" >> *(char_ - "*/") >> "*/"     // C-style comments
                ;
        }

        qi::rule<Iterator> start;
    };
}}

#endif
Значит наверное надо

Код
C++ (Qt)
start =
         space                               // tab/space/cr/lf
    |   "//" >> *(char_ - eol) >> eol     // C++ style comments
;
 
Все-таки как-то громоздко выглядит...
Записан
__Heaven__
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2130



Просмотр профиля
« Ответ #58 : Март 18, 2016, 17:14 »

Громоздко выглядит
Код
C++ (Qt)
       switch (e->type()) {
           case QEvent::MouseButtonDblClick:
               break;
           default:
               return false;
       }
 
Веселый Веселый Веселый

А данный код не громоздкий точно. Быть может не привычен на фоне Qt, но привычен тем кто с РБНФ знаком.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #59 : Март 18, 2016, 18:38 »

Цитировать
Хотел бы спросить, намеренно ли вы в Node number инициализировали в конструкторе, а coordinates в объявлении?
Почему вы объявляете методы set_xyz в парсере, а не в Node?
Node - просто пример. Я не знаю какие методы у вас там есть и т.д. Я просто взял то, что вы привели в качестве Node.

Методы set_XXX - это реализация сементик экшен. Их цель записать в Node (qi::_val) значение qi::_1.
Можно, например и подругому сделать через phoenix::at_c + BOOST_FUSION_ADAPT_STRUCT

Цитировать
phx::bind может быть заменён на std::bind?
Нет..
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Страниц: 1 2 3 [4] 5   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.175 секунд. Запросов: 23.