提升灵气:省略克莱恩星辰解析器中的元素
Boost Spirit Qi: Omit element in Kleene Star parser
我想解析特殊的结构并扔掉其余的。但我不想使用船长。
我想得到这些结构的向量,所以我使用 Kleene Star 解析器作为主要规则。但是,每次扔掉某些东西时,都会在向量中插入一个默认的构造元素。
这是一个虚构的例子。它只是寻找字符串Test
并扔掉其余的,至少这是计划。但是每次规则garbage
成功时,它都会在规则all
向量中添加一个默认构造项,给出 7 的输出 1。如果规则item
成功,我怎么能告诉 Spirit 只是添加到向量中?
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace qi = boost::spirit::qi;
struct container {
std::string name;
bool dummy;
};
BOOST_FUSION_ADAPT_STRUCT(::container,
(std::string, name)
(bool, dummy))
int main() {
typedef std::string::const_iterator iterator;
qi::rule<iterator, std::vector<container>()> all;
qi::rule<iterator, container()> item;
qi::rule<iterator, std::string()> string_rule;
qi::rule<iterator> garbage;
all = *(garbage | item);
garbage = qi::char_ - qi::lit("Test");
string_rule = qi::string("Test");
item = string_rule >> qi::attr(true);
std::vector<container> ast;
std::string input = "blaTestbla";
iterator first = input.begin();
iterator last = input.end();
bool result = qi::parse(first, last, all, ast);
if (result) {
result = first == last;
}
if (result) {
std::cout << "Parsed " << ast.size() << " element(s)" << std::endl;
} else {
std::cout << "failure" << std::endl;
}
}
由于 sehe 的回答或多或少是出于教育目的,我们现在有几种解决方案:
*garbage >> -(item % *garbage) >> *garbage
*garbage >> *(item >> *garbage)
all = *(garbage | item[phx::push_back(qi::_val,qi::_1)]);
cv_and_he的解决方案:
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/struct.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <iostream>
#include <string>
#include <vector>
namespace qi = boost::spirit::qi;
struct container {
std::string name;
bool dummy;
};
BOOST_FUSION_ADAPT_STRUCT(::container,
(std::string, name)
(bool, dummy))
struct container_vector { //ADDED
std::vector<container> data;
};
namespace boost{ namespace spirit{ namespace traits //ADDED
{
template <>
struct is_container<container_vector> : boost::mpl::true_ {};
template <>
struct container_value<container_vector> {
typedef optional<container> type;
};
template <>
struct push_back_container<container_vector,optional<container> > {
static bool call(container_vector& cont, const optional<container>& val) {
if(val)
cont.data.push_back(*val);
return true;
}
};
}}}
int main() {
typedef std::string::const_iterator iterator;
qi::rule<iterator, container_vector()> all; //CHANGED
qi::rule<iterator, container()> item;
qi::rule<iterator, std::string()> string_rule;
qi::rule<iterator> garbage;
all = *(garbage | item);
garbage = qi::char_ - qi::lit("Test");
string_rule = qi::string("Test");
item = string_rule >> qi::attr(true);
container_vector ast; //CHANGED
std::string input = "blaTestbla";
iterator first = input.begin();
iterator last = input.end();
bool result = qi::parse(first, last, all, ast);
if (result) {
result = first == last;
}
if (result) {
std::cout << "Parsed " << ast.data.size() << " element(s)" << std::endl; //CHANGED
} else {
std::cout << "failure" << std::endl;
}
}
虽然我不想使用船长,但我最终得到了:
start = qi::skip(garbage.alias())[*item];
最后一个解决方案是我使用Linux内核的c文件和我的生产规则进行不科学测试中最快的(1-2%)。
快速修复(不一定是性能最高的)是
all = -(item - garbage) % +garbage;
它打印:
Parsed 3 element(s)
在科里鲁现场观看
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- 芬威克树(BIT).找到具有给定累积频率的最小索引,单位为 O(logN)
- 莱克斯没有返回我想要的东西
- 增强精神解析器:绕过贪婪的克莱恩*
- C++记忆霍夫莱恩斯·
- 提升灵气:省略克莱恩星辰解析器中的元素
- 克洛克沃恩.无符号字符上的签名位
- 霍夫莱恩不工作
- 精神莱克斯->气语法问题
- 不急于提升灵气的克莱恩星
- 图书馆访问比格尔骨黑(3.8 克恩 - 埃)
- 提升::精神::莱克斯;如何指定令牌"||"?
- 提升::精神::业力:复制在重复或克莱恩星中不起作用?
- 使用Boost时的空白提示符.灵气和莱克斯
- 莱克斯:强制扫描