你的问题描述得过于含糊不清。这总是促使我使用Boost Spirit提供一个过度膨胀的示例实现。
注意:请不要将此作为您的家庭作业提交。
查看Coliru上的演示,并使用以下示例输入:
ADD_STUDENT ALEX 5.11 175
ADD_STUDENT PUFF 6 7
ADD_STUDENT MAGIC 7 8
ADD_STUDENT DRAGON 8 9
ADD_TEACHER MERY 5.4 120 70000
PRINT MERY
ADD_TEACHER DUPLO 5.4 120 140000
PRINTALL 10
REMOVE ALEX
PRINT TEACHER SALARY
PRINT MERY PUFF MAGIC DRAGON
REMOVE MERY PUFF MAGIC DRAGON
PRINT TEACHER SALARY
完整代码:
更新:当包含make_visitor.hpp
,如此展示的这里,您可以更优雅地编写访问者代码:
auto print_salary = [&] ()
{
for(auto& p : names)
boost::apply_visitor(make_visitor(
[](Teacher const& v) { std::cout << "Teacher salary: " << v.salary << "\n"; },
[](Student const& v) {}),
p.second);
};
请查看适应的示例在 Coliru 上实时查看
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx= boost::phoenix;
struct Person
{
std::string name;
double height, weight;
friend std::ostream& operator<<(std::ostream& os, Person const& s) {
return os << "Person { name:" << s.name << ", height:" << s.height << ", weight:" << s.weight << " }";
}
};
struct Student : Person
{
Student() = default;
Student(std::string n, double h, double w) : Person {n,h,w} {}
};
struct Teacher : Person
{
Teacher() = default;
Teacher(std::string n, double h, double w, double s) : Person {n,h,w}, salary(s) {}
double salary;
};
int main()
{
std::stringstream ss;
ss << std::cin.rdbuf();
std::map<std::string, boost::variant<Student, Teacher> > names;
using namespace qi;
auto add_student = phx::ref(names)[_1] = phx::construct<Student>(_1, _2, _3);
auto add_teacher = phx::ref(names)[_1] = phx::construct<Teacher>(_1, _2, _3, _4);
auto remove = phx::erase(phx::ref(names), _1);
auto print_all = [&] (int i) { for(auto& p : names) { std::cout << p.second << "\n"; if (--i==0) break; } };
auto print_salary = [&] ()
{
struct _ : boost::static_visitor<> {
void operator()(Teacher const& v) const { std::cout << "Teacher salary: " << v.salary << "\n"; }
void operator()(Student const& v) const { }
} v_;
for(auto& p : names) boost::apply_visitor(v_, p.second);
};
auto name_ = as_string[lexeme[+graph]];
if (phrase_parse(begin(ss.str()), end(ss.str()),
(
("ADD_STUDENT" >> name_ >> double_ >> double_) [ add_student ]
| ("ADD_TEACHER" >> name_ >> double_ >> double_ >> double_) [ add_teacher ]
| (eps >> "PRINT" >> "TEACHER" >> "SALARY") [ print_salary ]
| ("PRINTALL" >> int_) [ phx::bind(print_all, _1) ]
| ("PRINT" >> +name_ [ std::cout << phx::ref(names)[_1] << std::endl ])
| ("REMOVE" >> +name_ [ remove ])
) % +eol,
qi::blank))
{
std::cout << "Success";
}
else
{
std::cout << "Parse failure";
}
}
输出:
Person { name:MERY, height:5.4, weight:120 }
Person { name:ALEX, height:5.11, weight:175 }
Person { name:DRAGON, height:8, weight:9 }
Person { name:DUPLO, height:5.4, weight:120 }
Person { name:MAGIC, height:7, weight:8 }
Person { name:MERY, height:5.4, weight:120 }
Person { name:PUFF, height:6, weight:7 }
Teacher salary: 140000
Teacher salary: 70000
Person { name:MERY, height:5.4, weight:120 }
Person { name:PUFF, height:6, weight:7 }
Person { name:MAGIC, height:7, weight:8 }
Person { name:DRAGON, height:8, weight:9 }
Teacher salary: 140000
Success