- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
按照几个教程(例如 http://boost-spirit.com/home/articles/qi-example/nabialek-trick/ ),我想使用 Nabialek 技巧来拥有一个动态解析器。解析已经可以正常工作,但我没有得到传输的属性。解释如 https://stackoverflow.com/a/9109972/2524462建议,属性应该是可能的,但不是参数。
这只是一个将字符串和数字解析为结构的小示例。这只是为了展示我的问题;这种方法应该在以后真正需要动态解析器的更大系统中使用。
问题:如何使用 Nabialek 技巧传输属性?
我不是精神专家,所以请多多包涵。我正在使用 gcc 4.8.1 和 boost 1.54。
#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/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
//------------------------------------------------------------------------------
// Data structure
struct myline {
myline()
: _n(0), _s("") {
}
myline(int n, std::string s)
: _n(n), _s(s) {
}
void set(int n, std::string s) {
_n = n;
_s = s;
}
int _n;
std::string _s;
};
BOOST_FUSION_ADAPT_STRUCT(::myline, (int, _n) (std::string, _s))
//------------------------------------------------------------------------------
// Parser grammar
template<typename It, typename Skipper = qi::space_type>
struct parser: qi::grammar<It, myline(), Skipper> {
parser()
: parser::base_type(start) {
using namespace qi;
start = line;
string %= qi::lexeme["'" >> *~qi::char_("'") >> "'"];
one = (string >> "@" >> qi::int_)[_val = phx::construct<myline>(_2, _1)];
two = (qi::int_ >> "@" >> string);
keyword.add("one", &one)("two", &two);
line = keyword[_a = _1] >> qi::lazy(*_a);
on_error<fail>(
start,
std::cout << phx::val("Error! Expecting ") << _4
<< phx::val(" here: \"") << phx::construct<std::string>(_3, _2)
<< phx::val("\"\n"));
BOOST_SPIRIT_DEBUG_NODES((start)(line)(one)(two))
}
private:
template<typename Attr> using Rule = qi::rule<It, Attr(), Skipper>;
Rule<myline> start, one, two;
qi::rule<It, myline, Skipper, qi::locals<Rule<myline>*> > line;
Rule<std::string> string;
qi::symbols<char, Rule<myline>*> keyword;
};
//------------------------------------------------------------------------------
int main() {
for (const std::string input : std::vector<std::string> { "one 'test'@1",
"two 2@'test'" }) {
auto f(std::begin(input)), l(std::end(input));
const static parser<decltype(f)> p;
myline parsed_script;
bool ok = qi::phrase_parse(f, l, p, qi::space, parsed_script);
if (!ok) {
std::cout << "invalid input\n";
}
std::cout << parsed_script._n << ": " << parsed_script._s << std::endl;
if (f != l) {
std::cout << "unparsed: '" << std::string(f, l) << "'" << std::endl;
}
}
}
解析结果:
<start>
<try>one 'test'@1</try>
<line>
<try>one 'test'@1</try>
<one>
<try> 'test'@1</try>
<success></success>
<attributes>[[1, [t, e, s, t]]]</attributes>
</one>
<success></success>
<attributes>[]</attributes><locals>(0x43b0e0)</locals>
</line>
<success></success>
<attributes>[[0, []]]</attributes>
</start>
<start>
<try>two 2@'test'</try>
<line>
<try>two 2@'test'</try>
<two>
<try> 2@'test'</try>
<success></success>
<attributes>[[2, [t, e, s, t]]]</attributes>
</two>
<success></success>
<attributes>[]</attributes><locals>(0x43b110)</locals>
</line>
<success></success>
<attributes>[[0, []]]</attributes>
</start>
最佳答案
你在精神课上一直很关注:)
有很多问题:
line
的属性声明规则错误:
qi::rule<It, myline, Skipper, qi::locals<Rule<myline>*> > line;
需要
qi::rule<It, myline(), Skipper, qi::locals<Rule<myline>*> > line;
在存在语义 Action 时禁止自动属性传播。有关更多信息,请参阅最近的答案:Boost.spirit: parsing number char and string .因此,您需要使用 %=
明确参与 Spirit 的自动规则行为。 :
line = keyword[_a = _1] >> qi::lazy(*_a);
需要
// NOTE the %=
line %= omit [ keyword[_a = _1] ] >> qi::lazy(*_a);
注意事项:
%=
可以继续string
规则(没有语义 Action 意味着自动属性传播)omit[]
关键字匹配的结果,因为我们不能真正分配 Rule<>*
到我们的myline
属性这是固定版本:
#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/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
//------------------------------------------------------------------------------
// Data structure
struct myline {
myline()
: _n(0), _s("") {
}
myline(int n, std::string s)
: _n(n), _s(s) {
}
void set(int n, std::string s) {
_n = n;
_s = s;
}
int _n;
std::string _s;
};
BOOST_FUSION_ADAPT_STRUCT(::myline, (int, _n) (std::string, _s))
//------------------------------------------------------------------------------
// Parser grammar
template<typename It, typename Skipper = qi::space_type>
struct parser: qi::grammar<It, myline(), Skipper> {
parser()
: parser::base_type(start) {
using namespace qi;
start = line;
string = qi::lexeme["'" >> *~qi::char_("'") >> "'"];
one = (string >> "@" >> qi::int_) [_val = phx::construct<myline>(_2, _1)];
two = (qi::int_ >> "@" >> string);
keyword.add("one", &one)("two", &two);
// NOTE the %=
line %= omit [ keyword[_a = _1] ] >> qi::lazy(*_a);
on_error<fail>(
start,
std::cout << phx::val("Error! Expecting ") << _4
<< phx::val(" here: \"") << phx::construct<std::string>(_3, _2)
<< phx::val("\"\n"));
BOOST_SPIRIT_DEBUG_NODES((start)(line)(one)(two))
}
private:
template<typename Attr> using Rule = qi::rule<It, Attr(), Skipper>;
Rule<myline> start, one, two;
qi::rule<It, myline(), Skipper, qi::locals<Rule<myline>* > > line;
Rule<std::string> string;
qi::symbols<char, Rule<myline>* > keyword;
};
//------------------------------------------------------------------------------
int main() {
for (const std::string input : std::vector<std::string> { "one 'test1'@1",
"two 2@'test2'" }) {
auto f(std::begin(input)), l(std::end(input));
const static parser<decltype(f)> p;
myline parsed_script;
bool ok = qi::phrase_parse(f, l, p, qi::space, parsed_script);
if (!ok) {
std::cout << "invalid input\n";
}
std::cout << parsed_script._n << ": " << parsed_script._s << std::endl;
if (f != l) {
std::cout << "unparsed: '" << std::string(f, l) << "'" << std::endl;
}
}
}
打印:
<start>
<try>one 'test1'@1</try>
<line>
<try>one 'test1'@1</try>
<one>
<try> 'test1'@1</try>
<success></success>
<attributes>[[1, [t, e, s, t, 1]]]</attributes>
</one>
<success></success>
<attributes>[[1, [t, e, s, t, 1]]]</attributes><locals>(0x6386c0)</locals>
</line>
<success></success>
<attributes>[[1, [t, e, s, t, 1]]]</attributes>
</start>
1: test1
<start>
<try>two 2@'test2'</try>
<line>
<try>two 2@'test2'</try>
<two>
<try> 2@'test2'</try>
<success></success>
<attributes>[[2, [t, e, s, t, 2]]]</attributes>
</two>
<success></success>
<attributes>[[2, [t, e, s, t, 2]]]</attributes><locals>(0x6386f0)</locals>
</line>
<success></success>
<attributes>[[2, [t, e, s, t, 2]]]</attributes>
</start>
2: test2
关于c++ - Boost.Spirit.Qi : How to return attributes with Nabialek trick,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17717590/
trick大意 我对于这个trick的理解为:支持位运算的高精度 维护一个以 \(b\) 为基数的大数 \(N\) ,并支持以下功能: 给定(可能是负)整数 \(|x|
我正在为 Java 考试进行培训,我在去年的科目中遇到了一些我不理解的东西。这是代码 class Mother { int var = 2; int getVar() {
在一点帮助下,它几乎是华丽的:TheZoo.com/shapes 除此之外,标题图标和我想要控制的文本之间没有空格。那么,如何在 css pseudo:before 形状中添加边距(或填充),同时避免
是否有一些使用媒体查询的新标准。或者我应该说,应该做出一些新的考虑。 CSS tricks article似乎效果不是很好,因为“智能手机景观”似乎劫持了一切。 我直接使用的代码(打印屏幕应该是什么除
我有一个名为 memory_region 的类,有点像未类型化的 gsl::span (即它本质上是一个 void* 和一个 size_t ),我也将其用于类型删除。因此它有一个 as_span()方
在阅读了 Douglas Crockford 的“JavaScript:The Good Parts”和 Stoyan Stevanov 的“JavaScript Patterns”之后,我试图确定“
最近我发现,如果我需要查看变量是否为偶数(或奇数),我可以只查看变量的最后一位是否等于 0。这一发现在实现后取代了一些 modulo 2 计算,因此整个函数运行得更快。 是否有任何其他像这个一样的“技
我一直在玩这个,到目前为止我还没有找到任何方法来隐藏或欺骗 instanceof 通过隐藏它的类型来返回 false混淆层,但这并不意味着它是不可能的,因为我远不是最了解 Java 的人。所以才来请教
我知道特征散列 (hashing-trick) 用于降低维度和处理位向量的稀疏性,但我不明白它是如何工作的。谁能给我解释一下。是否有任何 python 库可用于进行特征散列? 谢谢。 最佳答案 在 P
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我正在查看“dlib”库,更具体地说是用于“优化”的“find_min”函数( http://dlib.net/optimization_ex.cpp.html)。 “find_min”函数可让您将自
有据可查的是,IE 中的原生 DOM 元素不包含 hasOwnProperty() 方法。有几个解决方案;其中最优雅的是直接在 Object.prototype 中访问 hasOwnProperty(
This question状态: It is amazing how many users don't know about the rm ./-rf or rm -- -rf tricks. 我不敢
我已经提到了 this site用于布局技巧。 在那里,一个属性被声明为 android:layout_weight="1"。 所以我的困惑是关于 android:layout_weight: and
我正在尝试使一个元素垂直居中,该元素使用 padding-bottom 来创建所需的宽高比(对于视频)。我想要顶部和底部的黑色边框,就像电影以比拍摄时更高的纵横比显示时一样: body{ pa
你能解释一下下一个代码示例背后的机制吗(我想我知道,但我需要第二个意见): 1)---------------------------- using namespace std; int * f(in
滚动浏览 http://git.suckless.org/st/plain/st.c我偶然发现 #define LEN(a) (sizeof(a) / sizeof(a)[0]) 我知道预编译魔法很难
我正在阅读有关 Java 泛型的文章,我偶然发现了这个主题,我对此感到有些困惑。 发件人:http://www.angelikalanger.com/GenericsFAQ/FAQSections/P
我有一点挑战。 在我们产品的早期版本中,我们有一个错误消息窗口(不得已,未处理的异常)显示异常消息、类型、堆栈跟踪 + 各种信息。 这个窗口是打印屏幕友好的,因为如果用户简单地进行打印屏幕捕获,并将屏
可以在 C 中将某些类型的泛型函数作为宏来执行,例如: #define SQRT(x) (sizeof(x) == sizeof(float) ? sqrtf((x)) : \
我是一名优秀的程序员,十分优秀!