Я новичок в boost :: spirit. Я хотел бы разобрать строку объектов, разделенных запятыми, в std :: vector (аналогично тому, как в руководствах). Строка может быть разных типов (известных во время компиляции): целые числа, например "1,2,3"
, строки "Apple, Orange, Banana"
и т.д. и т.д. Я хотел бы иметь единый интерфейс для всех типов.
Если я разбираю один элемент, я могу использовать выражение auto_
. Возможен ли аналогичный интерфейс с векторами? Могу ли я определить правило, которое, учитывая параметр шаблона, действительно может анализировать этот вектор?
Вот простой пример кода (который не компилируется из-за последнего вызова фразе_parse):
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <iostream>
#include <vector>
#include <boost/spirit/include/qi_auto.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
using qi::auto_;
using qi::phrase_parse;
using ascii::space;
using phoenix::push_back;
int main()
{
std::string line1 = "3";
std::string line2 = "1, 2, 3";
int v;
std::vector<int> vector;
typedef std::string::iterator stringIterator;
stringIterator first = line1.begin();
stringIterator last = line1.end();
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
bool r1 = qi::phrase_parse( first,
last,
qi::auto_,
ascii::space,
v );
first = line2.begin();
last = line2.end();
//The following call is wrong!
bool r2 = qi::phrase_parse( first,
last,
// Begin grammar
(
qi::auto_[push_back(phoenix::ref(vector), qi::_1)]
>> *(',' >> qi::auto_[push_back(phoenix::ref(vector),qi::_1)])
),
// End grammar
ascii::space,
vector);
return 0;
}
ОБНОВЛЕНИЕ
Я нашел решение, в случае, если размер вектора известен до разбора. С другой стороны, я не могу использовать синтаксис *( ',' >> qi::auto_ )
.
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
int main()
{
std::string s = "1, 2, 3";
std::vector<int> vector;
//This works
qi::phrase_parse(s.begin(), s.end(), qi::auto_ >> ',' >> qi::auto_ >> ',' >> qi::auto_ , qi::blank, vector);
//This does not compile
qi::phrase_parse(s.begin(), s.end(), qi::auto_ >> *( ',' >> qi::auto_ ) , qi::blank, vector);
for(int i = 0; i < vector.size() ; i++)
std::cout << i << ": " << vector[i] << std::endl;
return 0;
}
Более того, используя auto_
, я не могу разобрать строку. Можно ли определить функцию электронного шаблона, в которой грамматика может быть выведена с помощью параметра шаблона?
template< typename T >
void MyParse(std::string& line, std::vector<T> vec)
{
qi::phrase_parse( line.begin(),
line.end(),
/*
How do I define a grammar based on T
such as:
double_ >> *( ',' >> double_ ) for T = double
+qi::alnum >> *( ',' >> +qi::alnum ) for T = std::string
*/,
qi::blank,
vec);
}
auto_%','
). - person llonesmiz   schedule 25.01.2015+(char_-',')
на+alnum
, если хотите). - person llonesmiz   schedule 25.01.2015auto_
не подходит для std :: string, потому что он действительно может соответствовать чему угодно - person sehe   schedule 25.01.2015std::string
vs.auto_
, как я думаю в моем обновленном ответе. Вам, вероятно, следует опубликовать эту версию, основанную наcreate_parser<>
, в качестве ответа ... Она того стоит. - person sehe   schedule 25.01.2015