- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想解析特殊的结构,把剩下的扔掉。但我不想使用 skipper 。
我想获得这些构造的 vector ,所以我使用 Kleene Star 解析器作为主要规则。但是,每当有东西被丢弃时,一个默认构造的元素就会被插入到 vector 中。
这是一个虚构的例子。它只查找字符串 Test
并丢弃其余部分,至少这是计划。但是每次规则 garbage
成功时,它都会将默认构造的项目添加到规则 all
中的 vector 中,输出 7 insteat 1。我如何告诉 Spirit如果规则 item
成功,就添加到 vector 中?
#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;
}
}
虽然我不想使用 skipper ,但我最终得到了:
start = qi::skip(garbage.alias())[*item];
在我使用 Linux 内核的 c 文件和我的生产规则进行的不科学测试中,最后一个解决方案是最快的(快 1-2%)。
关于c++ - boost 灵气 : Omit element in Kleene Star parser,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20038186/
我在我的 Swing 应用程序中使用了 Nimbus 外观,它非常酷。 我注意到它是一种“纯粹”的外观和感觉:它“蒙皮”组件,但不添加新的图形元素。 我想知道它的渲染技术的某些部分是否可以重用,例如类
我正在尝试执行以下操作来解析多个“a”,然后解析一个“a”: *(lit("a")) >> lit("a") 不幸的是,boost::spirit::qi 中的 Kleene star * 急切地消耗
我正在使用 boost spirit 解析语法,所有复杂的部分都运行良好;但是,我试图接受数字变量,但似乎无法正确解析它们。除了将数字存储为字符串外,我不想对这些数字做任何事情,但我似乎无法获得与通用
我有以下结构 struct MyStruct { char CODE; char NAME[5]; }; 我把它做成一个 fusion 结构 BOOST_FUSION_ADAPT_ST
我正在解析一些结构模糊如 C 语言代码的输入。像这样: Name0 { Name1 { //A COMMENT!! Param0 *= 2 Param2 = "lol" } } 其中
我想写一个可以使用的解析器(作为 qi 扩展)通过 my_parser(p1, p2, ...) 其中 p1, p2, ... 是 qi 解析器表达式。 实际上,我想实现一个 best_match 解
Boost Spirit Qi 解析当然是 C++ 的一个独特应用,它具有陡峭的学习曲线。在这种情况下,我试图解析一个字符串,该字符串包含一个 struct 的语法正确的 C++ 列表初始化。包含 s
我有一个运行良好的语法,它包含以下几行。 element = container | list | pair; container = name >> '(' >> -(arg % ',') >> '
我如何设置一个规则来返回预定义的输出而不是从我的输入文本中解析出来的内容? 像这个例子:GiveQuoteOrText 将首先尝试使用 Quoted 将输入解析为带引号的字符串,如果失败则应始终输出“
我刚刚在 Qi 中实现了一个基本的解析器来验证指定的 TCP 端口范围,例如80-444。 template struct port_range_grammar : qi::grammar
我正在编写一个小编译器只是为了好玩,我正在使用 Boost Spirit Qi 来描述我的语法。现在我想对语法做一个小改动,以准备一些进一步的补充。不幸的是,这些更改无法编译,我想了解为什么会这样。
我想解析特殊的结构,把剩下的扔掉。但我不想使用 skipper 。 我想获得这些构造的 vector ,所以我使用 Kleene Star 解析器作为主要规则。但是,每当有东西被丢弃时,一个默认构造的
我想解析特殊的结构,把剩下的扔掉。但我不想使用 skipper 。 我想获得这些构造的 vector ,所以我使用 Kleene Star 解析器作为主要规则。但是,每当有东西被丢弃时,一个默认构造的
我是一名优秀的程序员,十分优秀!