在'之前应为不合格id;名称空间';使用“精神之气”时出错 我写了一个C++应用程序,有几个复杂的结构和
我想读取一个字符串并用文本中提供的数据填充这些结构 但为了便于理解和调试,我编写了带有相同问题的easy程序 这是我的代码:在'之前应为不合格id;名称空间';使用“精神之气”时出错 我写了一个C++应用程序,有几个复杂的结构和,c++,boost-spirit-qi,C++,Boost Spirit Qi,我想读取一个字符串并用文本中提供的数据填充这些结构 但为了便于理解和调试,我编写了带有相同问题的easy程序 这是我的代码: #include <string> #include <iostream> #define FUSION_MAX_VECTOR_SIZE 30 #define BOOST_PHOENIX_USE_V2_OVER_V3 #include <boost/spirit/home/phoenix/bind/bind_function.hpp&g
#include <string>
#include <iostream>
#define FUSION_MAX_VECTOR_SIZE 30
#define BOOST_PHOENIX_USE_V2_OVER_V3
#include <boost/spirit/home/phoenix/bind/bind_function.hpp>
#include <boost/phoenix/bind.hpp>
#include <boost/fusion/adapted.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
using qi::double_;
using qi::char_;
using qi::lexeme;
using qi::int_;
using qi::lit;
using qi::_1;
using ascii::space;
using phoenix::ref;
using qi::parser;
class Test
{
// Class fields
std::string test_str;
public:
Test(std::string& sample_str)
{
test_str = sample_str;
}
struct fruit
{
std::string name;
std::string color;
};
BOOST_FUSION_ADAPT_STRUCT
(
fruit,
(std::string, name)
(std::string, color)
);
struct person
{
std::string name;
int age;
};
BOOST_FUSION_ADAPT_STRUCT
(
person,
(std::string, name)
(int, age)
);
void received_person(person& p)
{
std::cout << p.name << " with age"<< p.age<< " has been seen!"<<std::endl;
}
void received_fruit(fruit& f)
{
std::cout << f.name<<" is "<<f.color<<std::endl;
}
template <typename Iterator>
struct MyGrammar : boost::spirit::qi::grammar<Iterator, void()>
{
MyGrammar() : MyGrammar::base_type(my_item)
{
my_item = *(fruit[ boost::phoenix::bind(&received_fruit, boost::spirit::_1 )]
|
_person[ boost::phoenix::bind(&received_person, boost::spirit::_1 )]
);
_person = qi::lit('(') >> *(qi::char_ - ',') >> ',' >> qi::int_ >> ')';
_fruit = qi::lit('[') >> *(qi::char_ - ',') >> ',' >> *(qi::char_) >> ']';
}
qi::rule<Iterator, void()> my_item;
qi::rule<Iterator, person()> _person;
qi::rule<Iterator, fruit()> _fruit;
};
void run()
{
typedef std::string::const_iterator iterator;
MyGrammar <std::string::const_iterator> my_grammar;
std::string::const_iterator begin = test_str.begin();
std::string::const_iterator end = test_str.end();
bool result_ = qi::parse(begin, end, my_grammar) && begin == end;
}
};
int main()
{
std::string input("(jane, 23000)(david, 19)(mary, 30)[yello,100][green, 60.6][red, 30.5]");
Test test(input);
test.run();
return 0;
}
我知道这段代码可以不用类来编写,但我想在主项目中使用类。
非常感谢 解决这些问题,首先:
- 这也意味着您需要
来提供一个跳过程序qi::phrase\u parse
- 这也意味着
是冗余的(因为begin==end
总是在AFAIR成功时消耗整个输入)qi::parse
- 这还意味着您需要
来控制何时将空白作为解析内容的一部分qi::lexeme
静态的
\u fruit
规则以读取,直到关闭]
namespace ast {
struct fruit {
std::string name;
std::string color;
};
struct person {
std::string name;
int age;
};
typedef boost::variant<fruit, person> record;
typedef std::vector<record> records;
// for our demo output:
static std::ostream& operator<<(std::ostream& os, fruit const& f);
static std::ostream& operator<<(std::ostream& os, person const& p);
}
以下是:
#include <string>
#include <iostream>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace ast {
struct fruit {
std::string name;
std::string color;
friend std::ostream& operator<<(std::ostream& os, fruit const& f) { return os << f.name << " is " << f.color; }
};
struct person {
std::string name;
int age;
friend std::ostream& operator<<(std::ostream& os, person const& p) { return os << p.name << " with age" << p.age << " has been seen!"; }
};
typedef boost::variant<fruit, person> record;
typedef std::vector<record> records;
}
BOOST_FUSION_ADAPT_STRUCT(ast::fruit,
(std::string, name)
(std::string, color))
BOOST_FUSION_ADAPT_STRUCT(ast::person,
(std::string, name)
(int, age))
template <typename Iterator, typename Skipper = qi::space_type>
struct MyGrammar : qi::grammar<Iterator, ast::records(), Skipper>
{
MyGrammar() : MyGrammar::base_type(_start)
{
_text = qi::lexeme [ *~qi::char_(",)]") ];
_person = qi::lit('(') >> _text >> ',' >> qi::int_ >> ')';
_fruit = qi::lit('[') >> _text >> ',' >> _text >> ']';
_start = *(_fruit | _person);
}
qi::rule<Iterator, ast::records(), Skipper> _start;
qi::rule<Iterator, ast::person(), Skipper> _person;
qi::rule<Iterator, ast::fruit(), Skipper> _fruit;
qi::rule<Iterator, std::string()> _text;
};
int main()
{
typedef std::string::const_iterator It;
std::string const input("(jane, 23000)(david, 19)(mary, 30)[yello,100][green, 60.6][red, 30.5]");
MyGrammar <It> my_grammar;
It begin(input.begin()), end(input.end());
ast::records data;
if (qi::phrase_parse(begin, end, my_grammar, qi::space, data))
{
std::cout << "Parse success\n";
for (auto& r : data)
std::cout << r << "\n";
}
else
std::cout << "Parse failed\n";
if (begin != end)
std::cout << "Remaining unparsed: '" << std::string(begin, end) << "'\n";
}
#包括
#包括
#包括
#包括
名称空间qi=boost::spirit::qi;
名称空间ast{
结构果{
std::字符串名;
字符串颜色;
friend std::ostream&operator>','>>_text>>'];
_开始=*(|水果|人);
}
qi::规则_开始;
齐:规则,人;
齐:规则,水果;
qi::规则_文本;
};
int main()
{
typedef std::string::const_迭代器It;
std::字符串常量输入(“(简,23000)(大卫,19)(玛丽,30)[yello,100][green,60.6][red,30.5]”);
我的语法我的语法;
它开始(input.begin()),结束(input.end());
ast::记录数据;
if(qi::短语解析(开始、结束、我的语法、qi::空格、数据))
{
std::cout哪一行有错误?第44行生成此错误!在BOOST\u FUSION\u ADAPT\u结构之前,上面没有行号。在为fruit结构定义BOOST\u FUSION\u ADAPT\u结构的行中,我猜BOOST\u FUSION\u ADAPT\u结构宏正在做一些不允许它作为类的子级的事情。我建议研究这正是BOOST_FUSION_ADAPT_STRUCT所做的。此外,您可以尝试将声明移到类之外,看看这是否有帮助(这可能不符合您的预期设计,但可能有助于诊断)。啊。我刚刚添加了一个没有phoenix的版本。请注意,我的版本重72行代码(少40行),而它可以说做的更多。PS(为什么要使用Phoenix V2而不是V3?我不推荐这样做,因为缺乏支持/bug)。请看,我使用Phoenix V2而不是V3来使用Phoenix bind。V3也有bind,它有更多的功能和更少的bug
int main()
{
typedef std::string::const_iterator It;
std::string const input("(jane, 23000)(david, 19)(mary, 30)[yello,100][green, 60.6][red, 30.5]");
MyGrammar <It> my_grammar;
It begin(input.begin()), end(input.end());
ast::records data;
if (qi::phrase_parse(begin, end, my_grammar, qi::space, data))
{
std::cout << "Parse success\n";
for (auto const& record : data)
std::cout << record << "\n";
}
else
std::cout << "Parse failed\n";
if (begin != end)
std::cout << "Remaining unparsed: '" << std::string(begin, end) << "'\n";
}
_text = qi::lexeme [ *~qi::char_(",)]") ];
_person = qi::lit('(') >> _text >> ',' >> qi::int_ >> ')';
_fruit = qi::lit('[') >> _text >> ',' >> _text >> ']';
_start = *(_fruit | _person);
#include <string>
#include <iostream>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
namespace ast {
struct fruit {
std::string name;
std::string color;
friend std::ostream& operator<<(std::ostream& os, fruit const& f) { return os << f.name << " is " << f.color; }
};
struct person {
std::string name;
int age;
friend std::ostream& operator<<(std::ostream& os, person const& p) { return os << p.name << " with age" << p.age << " has been seen!"; }
};
typedef boost::variant<fruit, person> record;
typedef std::vector<record> records;
}
BOOST_FUSION_ADAPT_STRUCT(ast::fruit,
(std::string, name)
(std::string, color))
BOOST_FUSION_ADAPT_STRUCT(ast::person,
(std::string, name)
(int, age))
template <typename Iterator, typename Skipper = qi::space_type>
struct MyGrammar : qi::grammar<Iterator, ast::records(), Skipper>
{
MyGrammar() : MyGrammar::base_type(_start)
{
_text = qi::lexeme [ *~qi::char_(",)]") ];
_person = qi::lit('(') >> _text >> ',' >> qi::int_ >> ')';
_fruit = qi::lit('[') >> _text >> ',' >> _text >> ']';
_start = *(_fruit | _person);
}
qi::rule<Iterator, ast::records(), Skipper> _start;
qi::rule<Iterator, ast::person(), Skipper> _person;
qi::rule<Iterator, ast::fruit(), Skipper> _fruit;
qi::rule<Iterator, std::string()> _text;
};
int main()
{
typedef std::string::const_iterator It;
std::string const input("(jane, 23000)(david, 19)(mary, 30)[yello,100][green, 60.6][red, 30.5]");
MyGrammar <It> my_grammar;
It begin(input.begin()), end(input.end());
ast::records data;
if (qi::phrase_parse(begin, end, my_grammar, qi::space, data))
{
std::cout << "Parse success\n";
for (auto& r : data)
std::cout << r << "\n";
}
else
std::cout << "Parse failed\n";
if (begin != end)
std::cout << "Remaining unparsed: '" << std::string(begin, end) << "'\n";
}