Re: boost::spirit и структура
От:
jazzer
Skype: enerjazzer
Дата: 14.05.09 00:34
Оценка:
3 (2)
Здравствуйте, TimurSPB, Вы писали:
TSP>Есть файл вида:
TSP>cmd1 10,20,15;cmd2 40 30 15;cmd3 2 1 15;
TSP>И массив структур вида:
TSP>TSP>typedef struct
TSP>{
TSP> int CmdID;
TSP> int x;
TSP> int y;
TSP> int z;
TSP>} CMD;
TSP>typedef std::vector< CMD > Commands;
TSP>
TSP>Как средствами spirit (!) заполнить Commands из такого файла?
Я бы не извращался и сделал по-простому (пишу прямо в браузере, не компилировал):
CMD tmp;
// read "cmd1 10,20,15" and store in tmp
rule<> cmd = "cmd" >> uint_p[ assign_a(tmp.CmdID) ]
>> uint_p[ assign_a(tmp.x) ] >> ','
>> uint_p[ assign_a(tmp.y) ] >> ','
>> uint_p[ assign_a(tmp.z) ];
// read "cmd1;cmd2..." and put everything to Commands мусещк
rule<> commands = list_p( cmd[ push_back_a(Commands, tmp) ], ';' );
потом скорми
Re[3]: boost::spirit и структура
От:
jazzer
Skype: enerjazzer
Дата: 14.05.09 09:34
Оценка:
3 (1)
Здравствуйте, TimurSPB, Вы писали:
TSP>Здравствуйте, jazzer, Вы писали:
J>>потом скорми
TSP>Если сделать вот так:
TSP>То выдает загадочную ошибку:
TSP>Error 2 error C2664: 'boost::spirit::impl::abstract_parser<ScannerT,AttrT>::do_parse_virtual' : cannot convert parameter 1 from 'const scanner_t' to 'const boost::spirit::scanner<> &' \trunk_out\.packages\win32.vc8\rootsboost\include\boost\spirit\core\non_terminal\impl\rule.ipp 190
TSP>Во всей документации не найти тривиального считывания данных в структурку.
То, что я написал — это и есть способ.
Твоя ошибка мне ни о чем не говорит, разбирайся, попробуй тривиальные правила, типа считать все в одну строку.
Я не компилировал свой код.
Кстати, если у тебя всегда точка с запятой стоит после команды, то лист-парсер тут не нужен, можешь просто использовать плюсик
bool parse_numbers(char const * str, vector< CMD >& v)
{
CMD tmp;
// read "cmd1 10,20,15" and store in tmp
rule<> cmd = "cmd" >> uint_p[ assign_a(tmp.CmdID) ]
>> uint_p[ assign_a(tmp.x) ] >> ','
>> uint_p[ assign_a(tmp.y) ] >> ','
>> uint_p[ assign_a(tmp.z) ] >> ';' ;
// read "cmd1;cmd2;..." and put everything to Commands
rule<> commands = +( cmd[ push_back_a(v, tmp) ] );
return parse(str, commands, space_p).full;
}
Еще раз — я не компилировал, пишу прямо в браузере.
Ошибки компиляции тебе придется побороть самому
Также я не уверен насчет space_p — не помню, чтоб я его явно указывал у себя...
Re[3]: boost::spirit и структура
От:
Аноним
Дата: 14.05.09 09:42
Оценка:
3 (1)
TSP>Во всей документации не найти тривиального считывания данных в структурку.
Плохо ищите мне кажется
вот вам мой примерчег
#include <boost/spirit/include/classic.hpp>
#include <boost/spirit/include/classic_assign_actor.hpp>
#include <boost/spirit/include/classic_insert_at_actor.hpp>
#include <iostream>
#include <vector>
#include <boost/foreach.hpp>
using namespace BOOST_SPIRIT_CLASSIC_NS;
typedef struct {
int m_id;
std::string m_text;
float m_value;
} my_struct_t;
typedef std::vector<my_struct_t> ms_array_t;
int main()
{
my_struct_t ms;
ms_array_t array;
const std::string text = "1;Gopa1;2.50|2;Gopa2;2.59|3;Gopa3;2.54|4;Gopa4;2.56" ;
rule<> my_rule = int_p[assign_a(ms.m_id)] >> ch_p(";" ) >>
(+(~ch_p(";" )))[assign_a(ms.m_text)] >> ch_p(";" ) >> real_p[assign_a(ms.m_value)];
rule<> my_rule2 = my_rule[push_back_a(array, ms)];
rule<> my_rule3 = my_rule2 >> *(ch_p("|" ) >> my_rule2);
if (parse(text.c_str(), my_rule3).full) {
BOOST_FOREACH(my_struct_t ms_, array) {
std::cout << "Id " << ms_.m_id << std::endl;
std::cout << "Text " << ms_.m_text << std::endl;
std::cout << "Value " << ms_.m_value << std::endl;
}
}
return 0;
}
Re[5]: boost::spirit и структура
От:
jazzer
Skype: enerjazzer
Дата: 14.05.09 11:56
Оценка:
2 (1)
Здравствуйте, TimurSPB, Вы писали:
TSP>Спасибо jazzer и Аноним =)
TSP>Вроде пришло мне просвлетние!
для спасибо кнопки есть специальные
Re[6]: boost::spirit и структура
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, TimurSPB, Вы писали:
TSP>>Спасибо jazzer и Аноним =)
не за что
ЗЫ Зарегался
boost::spirit и структура
От:
TimurSPB
Дата: 13.05.09 17:39
Оценка:
Есть файл вида:
cmd1 10,20,15;cmd2 40 30 15;cmd3 2 1 15;
И массив структур вида:
typedef struct
{
int CmdID;
int x;
int y;
int z;
} CMD;
typedef std::vector< CMD > Commands;
Как средствами spirit (!) заполнить Commands из такого файла?
В доках есть пример, который парсерит числа, разделенные запятыми в вектор:
bool
parse_numbers(char const * str, vector<double >& v)
{
return parse(str,
// Begin grammar
(
real_p[append(v)] >> *(',' >> real_p[append(v)])
)
,
// End grammar
space_p).full;
}
Можно ли сделать что-то такое?
bool
parse_numbers(char const * str, vector<CMD>& v)
{
//...
}
Make flame.politics Great Again!
Re[2]: boost::spirit и структура
От:
TimurSPB
Дата: 14.05.09 09:07
Оценка:
Здравствуйте, jazzer, Вы писали:
J>потом скорми
Если сделать вот так:
bool parse_numbers(char const * str, vector< CMD >& v)
{
CMD tmp;
// read "cmd1 10,20,15" and store in tmp
rule<> cmd = "cmd" >> uint_p[ assign_a(tmp.CmdID) ]
>> uint_p[ assign_a(tmp.x) ] >> ','
>> uint_p[ assign_a(tmp.y) ] >> ','
>> uint_p[ assign_a(tmp.z) ];
// read "cmd1;cmd2..." and put everything to Commands
rule<> commands = list_p( cmd[ push_back_a(Commands, tmp) ] >> ';' );
return parse(str, commands, space_p).full;
}
То выдает загадочную ошибку:
Error 2 error C2664: 'boost::spirit::impl::abstract_parser<ScannerT,AttrT>::do_parse_virtual' : cannot convert parameter 1 from 'const scanner_t' to 'const boost::spirit::scanner<> &' \trunk_out\.packages\win32.vc8\rootsboost\include\boost\spirit\core\non_terminal\impl\rule.ipp 190
Во всей документации не найти тривиального считывания данных в структурку.
Make flame.politics Great Again!
Re[4]: boost::spirit и структура
От:
TimurSPB
Дата: 14.05.09 11:41
Оценка:
Спасибо jazzer и Аноним =)
Вроде пришло мне просвлетние!
Make flame.politics Great Again!
Re[6]: boost::spirit и структура
От:
TimurSPB
Дата: 14.05.09 14:10
Оценка:
Снова возник вопрос:
Например:
uint_parser< unsigned , 10, n, n > uint_n_p;
выделяет РОВНО n цифр для преобразования в число
Как сделать что типа:
str_parser< n > str_n_p;
т. е. описать парсер, который выделяет равно n символов?
Make flame.politics Great Again!
Re[7]: boost::spirit и структура
От:
jazzer
Skype: enerjazzer
Дата: 14.05.09 15:19
Оценка:
Здравствуйте, TimurSPB, Вы писали:
TSP>т. е. описать парсер, который выделяет равно n символов?
lexeme_d[ repeat_p(n)[ anychar_p ] ]
Re: boost::spirit и структура
От:
Аноним
Дата: 28.05.09 11:57
Оценка:
Те примеры, которые приведены не очень хорошо работают (точнее не работают) при разборе больших грамматик. Скорее всего Вам прийдётся обявлять свои грамматики, которые отвечают за какое-либо подмножество грамматики.
В общем, способ такой:
struct SMyStruct
{
long _n1;
long _n2;
}
struct SClosureMy : boost::spirit::closure<Sxxx , SMyStruct>
{
member1 sResult;
};
struct CGrammMy: grammar<CGrammMy, SClosureMy ::context_t>
{
template <typename ScannerT>
struct definition
{
definition(CGrammMyconst& self)
{
xxx = uint_p [bind(&SMyStruct::_n1)(self.sResult) = arg1]
>> space_p
>> uint_p [bind(&SMyStruct::_n2)(self.sResult) = arg1]
>> space_p
>> eps_p [/*какие-либо действия по сохранению данных*/];
BOOST_SPIRIT_DEBUG_RULE(xxx );
}
rule<ScannerT> const& start() const { return xxx; }
rule<ScannerT> xxx;
}
}
Сохранить результат м
Вот из такого рода элементов можно уже состряпать сколь угодно сложную грамматику (я си-подобный синтаксис парсил, чтобы вытащить все определения типов и переменных).
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить