Boost :: Spirit :: Qi语法使用具有不同迭代剂类型的语法
boost::spirit::qi grammar using grammars with different iterator types
我正在面临boost::spirit::qi
的问题。我定义了以下两个解析器:
struct attr_1 { std::string a; };
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))
struct attr_2 { double a; };
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))
struct grammar_1 : boost::spirit::qi::grammar<const char*, attr_1()> {
grammar_1() : grammar_1::base_type{rule_} {
rule_ = boost::spirit::qi::eps >> +boost::spirit::ascii::upper;
}
private:
boost::spirit::qi::rule<const char*, attr_1()> rule_;
};
struct grammar_2 : boost::spirit::qi::grammar<std::string::iterator, attr_2()> {
grammar_2() : grammar_2::base_type{rule_} {
rule_ = boost::spirit::qi::double_;
}
private:
boost::spirit::qi::rule<std::string::iterator, attr_2()> rule_;
};
现在,我想使用以前的语法编写第三种语法,如下:
typedef boost::variant<attr_1, attr_2> attr_comp;
struct grammar_comp : boost::spirit::qi::grammar<????, attr_comp()> {
grammar_comp() : grammar_comp::base_type{rule_} {
rule_ = (g1_ | g2_);
}
private:
grammar_1 g1_;
grammar_2 g2_;
boost::spirit::qi::rule<????, attr_comp()> rule_;
};
由于grammar_1
和grammar_2
具有不同的迭代器类型,我应该在新语法的定义中放置哪种类型?
这是一个(非编译)简化示例:
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/qi.hpp>
#include <boost/variant.hpp>
#include <string>
#include <sstream>
struct attr_1 { std::string a; };
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))
struct attr_2 { double a; };
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))
struct grammar_1 : boost::spirit::qi::grammar<const char*, attr_1()> {
grammar_1() : grammar_1::base_type{rule_} {
rule_ = boost::spirit::qi::eps >> +boost::spirit::ascii::upper;
}
private:
boost::spirit::qi::rule<const char*, attr_1()> rule_;
};
struct grammar_2 : boost::spirit::qi::grammar<std::string::iterator, attr_2()> {
grammar_2() : grammar_2::base_type{rule_} {
rule_ = boost::spirit::qi::double_;
}
private:
boost::spirit::qi::rule<std::string::iterator, attr_2()> rule_;
};
typedef boost::variant<attr_1, attr_2> attr_comp;
struct grammar_comp : boost::spirit::qi::grammar<????, attr_comp()> {
grammar_comp() : grammar_comp::base_type{rule_} {
rule_ = (g1_ | g2_);
}
private:
grammar_1 g1_;
grammar_2 g2_;
boost::spirit::qi::rule<????, attr_comp()> rule_;
};
int main() {
std::string s;
std::istringstream iss("3n13.2nCIAOnFOOFOOfoon");
grammar_comp gg_;
attr_comp aa_;
while (std::getline(iss, s)){
auto it = s.begin();
if (boost::spirit::qi::parse(it, s.end(), gg_, aa_)) {
std::cout << s << std::endl;
std::cout << std::endl;
}
}
return 0;
}
您不能使用不同迭代器类型的子语法。出于明显的原因,您不会神奇地解析不同的输入集。
单个输入意味着单个输入迭代器范围。
只需将有关迭代类型的决定推迟到Toplevel Instantiator:
活在coliru
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/home/qi.hpp>
#include <boost/variant.hpp>
#include <sstream>
#include <string>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
struct attr_1 {
std::string a;
};
BOOST_FUSION_ADAPT_STRUCT(attr_1, (std::string, a))
struct attr_2 {
double a;
};
BOOST_FUSION_ADAPT_STRUCT(attr_2, (double, a))
template <typename It = const char *> struct grammar_1 : qi::grammar<It, attr_1()> {
grammar_1() : grammar_1::base_type{ rule_ } { rule_ = qi::eps >> +ascii::upper; }
private:
qi::rule<It, attr_1()> rule_;
};
template <typename It = std::string::const_iterator> struct grammar_2 : qi::grammar<It, attr_2()> {
grammar_2() : grammar_2::base_type{ rule_ } { rule_ = qi::double_; }
private:
qi::rule<It, attr_2()> rule_;
};
typedef boost::variant<attr_1, attr_2> attr_comp;
template <typename It = std::string::const_iterator> struct grammar_comp : qi::grammar<It, attr_comp()> {
grammar_comp() : grammar_comp::base_type{ rule_ } { rule_ = (g1_ | g2_); }
private:
grammar_1<It> g1_;
grammar_2<It> g2_;
qi::rule<It, attr_comp()> rule_;
};
int main() {
std::istringstream iss("3n13.2nCIAOnFOOFOOfoon");
grammar_comp<> gg_;
attr_comp aa_;
std::string s;
while (std::getline(iss, s)) {
auto it = s.cbegin();
if (qi::parse(it, s.cend(), gg_, aa_)) {
std::cout << s << std::endl;
std::cout << std::endl;
}
}
}
打印
3
13.2
CIAO
FOOFOOfoo
相关文章:
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 带有迭代器语法与发电机语法的循环
- 为什么我的地图迭代器中存在语法错误
- Boost :: Spirit :: Qi语法使用具有不同迭代剂类型的语法
- 使用 C++11 迭代语法时从 STL 列表中删除
- 矢量括号语法与迭代器
- 使用 foreach 语法迭代时如何检查我是否在最后一个元素上
- 对 STL 列表数组使用迭代器的语法
- 如何减轻在C++中检查迭代器值的语法开销
- 正确的迭代与删除列表语法
- c++11 foreach语法和自定义迭代器
- 将任意数量的迭代器对折叠成一个新的迭代器.元编程以获得良好的语法
- c++迭代器语法
- 迭代器中的非标准语法错误?(c++)
- c++迭代器有更好的语法吗?
- c++初学者:将索引语法转换为迭代器语法
- STL 容器基于范围的循环中的迭代器语法有什么区别