提气赋值从子规则
boost spirit qi assign value from subrule
我试图解析2种不同类型的字符串并将值分配到结构中。对于性能,我正试图使用促进精神规则。
字符串可以是以下类型
Animal Type | Animal Attributes
Ex
DOG | Name=tim | Barks=Yes | Has a Tail=N | Address=3 infinite loop
BIRD| Name=poc | Tweets=Yes| Address=10 stack overflow street
值存储在
下面的Dog和Bird结构数组中。#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/repository/include/qi_subrule.hpp>
#include <boost/spirit/include/qi_symbols.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <iostream>
using std::cout;
using std::endl;
using std::cerr;
struct Dog
{
std::string Name;
bool Barks;
bool HasATail;
std::string Address;
};
struct Bird
{
std::string Name;
bool Tweets;
std::string Address;
};
namespace qi = boost::spirit::qi;
namespace repo = boost::spirit::repository;
namespace ascii = boost::spirit::ascii;
namespace phx = boost::phoenix;
template <typename Iterator>
struct ZooGrammar : public qi::grammar<Iterator, ascii::space_type>
{
ZooGrammar() : ZooGrammar::base_type(start_)
{
using qi::char_;
using qi::lit_;
using qi::_1;
using boost::phoenix::ref;
boost::spirit::qi::symbols<char, bool> yesno_;
yesno_.add("Y", true)("N", false);
start_ = (
dog_ | bird_,
dog_ = "DOG" >> lit_[ref(d.Name) = _1]>> '|'
>>"Barks=">>yesno_[ref(d.Barks) = _1] >>'|'
>>"Has a Tail=">>yesno_[ref(d.HasATail) = _1] >> '|'
>>lit_[ref(d.Address) = _1]
,
bird_ = "BIRD" >> lit_[ref(b.Name) = _1]>> '|'
>>"Tweets=">>yesno_[ref(b.Tweets) = _1] >>'|'
>>lit_[ref(b.Address) = _1]
);
}
qi::rule<Iterator, ascii::space_type> start_;
repo::qi::subrule<0> dog_;
repo::qi::subrule<1> bird_;
Bird b;
Dog d;
};
int main()
{
std::string test1="DOG | Name=tim | Barks=Yes | Has a Tail=N | Address=3 infinite loop";
std::string test2="BIRD| Name=poc | Tweets=Yes| Address=10 stack overflow street";
using boost::spirit::ascii::space;
typedef std::string::const_iterator iterator_type;
typedef ZooGrammar<iterator_type> grammar;
iterator_type start = test1.begin();
iterator_type end = test1.end();
ZooGrammar g;
if(boost::spirit::qi::phrase_parse(start, end, g, space))
{
cout<<"matched"<<endl;
}
}
上面的代码使编译器GCC 4.8和4.9崩溃。我不知道我哪里出错了。
请在Coliru link中测试运行上面的代码
提前感谢!
子规则有点过时了。老实说,我甚至不知道在Spirit V2中还有这样的东西。
我建议使用常规的Spirit V2属性传播,这使得事情更容易读:
dog_ = qi::lit("DOG") >> '|' >> "Name=" >> lit_ >> '|'
>> "Barks=" >> yesno_ >> '|'
>> "Has a Tail=" >> yesno_ >> '|'
>> "Address=" >> lit_
;
bird_ = qi::lit("BIRD") >> '|' >> "Name=" >> lit_ >> '|'
>> "Tweets=" >> yesno_ >> '|'
>> "Address=" >> lit_
;
start_ = dog_ | bird_;
我想象了一个lit_
规则(因为qi::lit_
不响任何铃):
lit_ = qi::lexeme [ *~qi::char_('|') ];
当然,您需要调整属性类型,因为它们没有内置支持(如boost::variant<Dog, Bird>
, std::string
和bool
,它们都没有任何额外的代码处理):
BOOST_FUSION_ADAPT_STRUCT(Dog,
(std::string, Name)(bool, Barks)(bool, HasATail)(std::string, Address))
BOOST_FUSION_ADAPT_STRUCT(Bird,
(std::string, Name)(bool, Tweets)(std::string, Address))
现在将程序扩展到打印一些调试信息,输出如下:Live On Coliru
Matched: [DOG|Name=tim |Barks=Yes|Has a Tail=No|Address=3 infinite loop]
Matched: [BIRD|Name=poc |Tweets=Yes|Address=10 stack overflow street]
完整示例代码
//#define BOOST_SPIRIT_DEBUG
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_symbols.hpp>
static const char* YesNo(bool b) { return b?"Yes":"No"; }
struct Dog {
std::string Name;
bool Barks;
bool HasATail;
std::string Address;
friend std::ostream& operator <<(std::ostream& os, Dog const& o) {
return os << "[DOG|Name=" << o.Name << "|Barks=" << YesNo(o.Barks) << "|Has a Tail=" << YesNo(o.HasATail) << "|Address=" << o.Address << "]";
}
};
struct Bird {
std::string Name;
bool Tweets;
std::string Address;
friend std::ostream& operator <<(std::ostream& os, Bird const& o) {
return os << "[BIRD|Name=" << o.Name << "|Tweets=" << YesNo(o.Tweets) << "|Address=" << o.Address << "]";
}
};
typedef boost::variant<Dog, Bird> ZooAnimal;
BOOST_FUSION_ADAPT_STRUCT(Dog, (std::string, Name)(bool, Barks)(bool, HasATail)(std::string, Address))
BOOST_FUSION_ADAPT_STRUCT(Bird, (std::string, Name)(bool, Tweets)(std::string, Address))
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template <typename Iterator>
struct ZooGrammar : public qi::grammar<Iterator, ZooAnimal(), ascii::space_type>
{
ZooGrammar() : ZooGrammar::base_type(start_)
{
using qi::_1;
yesno_.add("Yes", true)("Y", true)("No", false)("N", false);
dog_ = qi::lit("DOG") >> '|' >> "Name=" >> lit_ >> '|'
>> "Barks=" >> yesno_ >> '|'
>> "Has a Tail=" >> yesno_ >> '|'
>> "Address=" >> lit_
;
bird_ = qi::lit("BIRD") >> '|' >> "Name=" >> lit_ >> '|'
>> "Tweets=" >> yesno_ >> '|'
>> "Address=" >> lit_
;
start_ = dog_ | bird_;
lit_ = qi::lexeme [ *~qi::char_('|') ];
BOOST_SPIRIT_DEBUG_NODES((dog_)(bird_)(start_)(lit_))
}
private:
qi::rule<Iterator, ZooAnimal(), ascii::space_type> start_;
qi::rule<Iterator, std::string(), ascii::space_type> lit_;
qi::rule<Iterator, Dog(), ascii::space_type> dog_;
qi::rule<Iterator, Bird(), ascii::space_type> bird_;
qi::symbols<char, bool> yesno_;
};
int main()
{
typedef std::string::const_iterator iterator_type;
typedef ZooGrammar<iterator_type> grammar;
for (std::string const input : {
"DOG | Name=tim | Barks=Yes | Has a Tail=N | Address=3 infinite loop",
"BIRD| Name=poc | Tweets=Yes| Address=10 stack overflow street"
})
{
iterator_type start = input.begin();
iterator_type end = input.end();
grammar g;
ZooAnimal animal;
if(qi::phrase_parse(start, end, g, ascii::space, animal))
std::cout << "Matched: " << animal << "n";
else
std::cout << "Parse failedn";
if (start != end)
std::cout << "Remaining input: '" << std::string(start, end) << "'n";
}
}
相关文章:
- 为"adjacent"变量赋值时出现问题
- C++中的赋值发生,尽管右侧出现异常
- 用C++中的sscanf赋值
- 为std::string的某个索引赋值
- 重载Singly Linked List中的赋值运算符
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- gtest_使用setargpointee在函数中赋值
- 非常量变量只读位置的赋值
- 使用赋值运算符重载从类中返回jobject
- C++数据文件、数组和计算赋值
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 全局作用域中函数指针的赋值
- 错误:在为指针赋值时,void值没有被忽略
- 标准库类型的赋值运算符的引用限定符
- 关于 c++ 函数中指针赋值的简单问题
- 复制构造函数、赋值运算符C++
- 标准::变体的赋值运算符
- 哪些规则控制参数默认赋值?
- 应将复制赋值运算符利用std::swap作为一般规则
- 提气赋值从子规则