你能帮助我理解Boost.Spirit中a % b解析器和它的扩展a >> *(b >> a)形式之间的区别吗?即使参考手册指出它们是等效的,
列表运算符
a % b是一个二元运算符,它匹配a由出现次数分隔的一个或多个重复的列表b.这相当于a >> *(b >> a).
以下程序根据使用的结果产生不同的结果:
#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
struct Record {
int id;
std::vector<int> values;
};
BOOST_FUSION_ADAPT_STRUCT(Record,
(int, id)
(std::vector<int>, values)
)
int main() {
namespace qi = boost::spirit::qi;
const auto str = std::string{"1: 2, 3, 4"};
const auto rule1 = qi::int_ >> ':' >> (qi::int_ % ',') >> …Run Code Online (Sandbox Code Playgroud) 该boost::spirit文档有重要的警示
有不同的方式来写语义动作为Spirit.Qi:使用普通函数
Boost.Bind,Boost.Lambda或Phoenix.后三种允许你使用特殊的占位符来控制参数配置(_1,_2,等).每个库都有自己的占位符实现,所有这些都在不同的命名空间中.您必须确保不将占位符与不属于的库混合,并且在编写语义操作时不使用不同的库.通常,for
Boost.Bind,use::_1,::_2等等(是的,这些占位符在全局命名空间中定义).对于
Boost.Lambda使用在命名空间中定义的占位符boost::lambda.对于使用Phoenix编写的语义操作,请使用命名空间中定义的占位符
boost::spirit.请注意,为方便起见,所有现有占位符也可从命名空间中获得boost::spirit::qi
(文件)
好的,所以我写了这段代码
template <typename Iterator>
struct ruleset_grammar : qi::grammar<Iterator>
{
template <typename TokenDef>
ruleset_grammar(TokenDef const& tok)
: ruleset_grammar::base_type(start)
{
start = *( tok.set_name [ boost::bind( &cRuleSet::setName, &theRuleSet, ::_1 ) ]
)
;
}
qi::rule<Iterator> start;
};
Run Code Online (Sandbox Code Playgroud)
请注意使用 ::_1
但是,我仍然得到此编译器错误
c:\documents and settings\james\spirit_test.cpp(138) : error C2872: '_1' : ambiguous …Run Code Online (Sandbox Code Playgroud) 尝试使用最新版本的MinGW(GCC 4.5.2)在Windows Vista Home Premium 64位下编译代码时,我遇到了一些奇怪的问题.在编译此文件时,我收到"cc1plus.exe已停止工作"的消息,编译失败,没有错误消息.我试图将文件剥离到仍然产生问题的绝对最低限度:
#include <boost/spirit/include/classic_file_iterator.hpp>
#include <boost/spirit/include/classic_position_iterator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <vector>
#define BOOST_SPIRIT_AUTO(domain_, name, expr) \
typedef boost::proto::result_of:: \
deep_copy<BOOST_TYPEOF(expr)>::type name##_expr_type; \
BOOST_SPIRIT_ASSERT_MATCH( \
boost::spirit::domain_::domain, name##_expr_type); \
BOOST_AUTO(name, boost::proto::deep_copy(expr)); \
using namespace std;
//This structure is used to determine the situation in which a certain tile sprite is used.
struct TileCase {
//A vector of bit fields for which adjacent tiles which must be filled.
vector<unsigned> filled;
//A vector …Run Code Online (Sandbox Code Playgroud) 我很少问及编译错误,但是我遇到了一些错误.
我成功编译了Android的boost库,我正在尝试使用它的Spirit库来构建解析器.但是当我试图编译时.我得到以下错误.
至于endian.hpp中的第一个错误,我想我需要在文件中包含它的cpu类型(Android).但我不知道为什么我会得到其他错误.任何线索或提示将不胜感激.
> In file included from > C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/support/detail/integer/endian.hpp:37, > from C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/support/detail/endian.hpp:24, > from C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/qi/binary/binary.hpp:16, > from C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/qi/binary.hpp:14, > from C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/qi.hpp:18, > from C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/include/qi.hpp:16, > from D:/mywork/dev/eclWork/BoostTest/jni/ndkfoo.cpp:24: > C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/detail/endian.hpp:74:3: > error: #error The file boost/detail/endian.hpp needs to be set up for > your CPU type. In file included from > C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/qi/directive.hpp:14, > from C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/qi.hpp:19, > from C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/include/qi.hpp:16, > from D:/mywork/dev/eclWork/BoostTest/jni/ndkfoo.cpp:24: > C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/qi/directive/as.hpp:128: > error: 'wstring' is not a member of 'std' > C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/qi/directive/as.hpp:128: > error: 'wstring' is not a member of 'std' > C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/qi/directive/as.hpp:128: > error: template argument 2 is invalid In file included from > C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/math/special_functions/fpclassify.hpp:20, > from C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/support/detail/sign.hpp:22, > from C:/Progra~1/Android/android-ndk-r6b/sources/boost/boost/spirit/home/qi/numeric/detail/real_impl.hpp:22, …
大家好,我是新手,以提升和提升::精神,所以我很抱歉没有问题.
当我使用qi::phrase_parse函数时,该函数只返回bool变量,它指示解析是否成功,但我不知道在哪里可以找到解析的结果...某种语法树等.
如果我使用宏的#define BOOST_SPIRIT_DEBUGXML表示在标准输出上打印树,但这些节点必须存储在某处.你能帮我吗?
是否有可能(使用Boost :: Spirit :: QI)从逗号分隔的字符串中解析数字,以便获得每个已解析数字的索引?
假设我有一个字符串"23,123,65,1",我想将这些数字中的每一个插入到给定位置(0,1,2,3)的矩阵中.一种方法是将数字解析为std :: vector,然后将它们复制到矩阵行,但速度并不是特别快.
目前我正在使用矢量变体:
Matrix data(10, 4);
int row = 0;
int col = 0;
std::string str = "23,123,65,1";
std::vector<double> res;
if (qi::parse(str.begin(), str.end(), qi::double_ % ',', res))
{
std::for_each(res.begin(), res.end(), [&col, &data, &row](double elem) {
data(row, col) = elem;
col++;
});
}
Run Code Online (Sandbox Code Playgroud)
如果解析器有一个成功的回调,它需要一个lambda函数或类似的功能,那就太棒了.
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#define BOOST_SPIRIT_UNICODE // We'll use unicode (UTF8) all throughout
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_parse.hpp>
#include <boost/spirit/include/support_standard_wide.hpp>
void parse_simple_string()
{
namespace qi = boost::spirit::qi;
namespace encoding = boost::spirit::unicode;
//namespace stw = boost::spirit::standard_wide;
typedef std::wstring::const_iterator iterator_type;
std::vector<std::wstring> result;
std::wstring const input = LR"(12,3","ab,cd","G,G\"GG","kkk","10,\"0","99987","PPP","??)";
qi::rule<iterator_type, std::wstring()> key = +(qi::unicode::char_ - qi::lit(L"\",\""));
qi::phrase_parse(input.begin(), input.end(),
key % qi::lit(L"\",\""),
encoding::space,
result);
//std::copy(result.rbegin(), result.rend(), std::ostream_iterator<std::wstring, wchar_t> (std::wcout, L"\n"));
for(auto const &data : result) std::wcout<<data<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我研究了这篇文章如何使用Boost Spirit来解析中文(unicode utf-16)? 并按照指南,但无法解析"你好" …
编辑:我已经删除了词法分析器,因为它没有与Qi完全集成,只是混淆了语法(见这里).
on_success没有很好的文档记录,我正在尝试将其连接到我的解析器.on_success处理解析器的例子只是构建在qi--ie,no lex.
这就是我试图介绍构造的方式:
using namespace qi::labels;
qi::on_success(event_entry_,std::cout << _val << _1);
Run Code Online (Sandbox Code Playgroud)
但它不会编译.我担心这个问题lex.有人可以告诉我我做错了什么,然后告诉我所有占位符可用,类型和它们代表什么(因为它们没有记录).
完整文件如下:
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/home/phoenix/bind/bind_member_variable.hpp>
#include <boost/spirit/include/lex_lexertl.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/none.hpp>
#include <boost/cstdint.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <string>
#include <exception>
#include <vector>
namespace lex = boost::spirit::lex;
namespace px = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
template <typename Lexer>
struct tokens : lex::lexer<Lexer>
{
tokens()
: left_curly("\"{\""),
right_curly("\"}\""),
left_paren("\"(\""),
right_paren("\")\""),
colon(":"),
scolon(";"),
namespace_("(?i:namespace)"),
event("(?i:event)"),
optional("(?i:optional)"), …Run Code Online (Sandbox Code Playgroud) 我正在尝试用boost.spirit.qi编写一些解析器,但是当我编译时,我得到以下不推荐的警告:
In file included from /usr/include/boost/iostreams/detail/is_dereferenceable.hpp:12:0 ...
#pragma message: NOTE: Use of this header (bool_trait_def.hpp) is deprecated
#pragma message: NOTE: Use of this header (template_arity_spec.hpp) is deprecated
Run Code Online (Sandbox Code Playgroud)
我使用错误的解析器还是旧的?我怎样才能摆脱这些警告?
编辑:我/usr/include/boost/iostreams/detail/is_dereferenceable.hpp正在以某种方式包括/usr/include/boost/spirit/include/qi.hpp
使用Boost版本1.61
我正在尝试用Spirit X3编写一个解析器,但我还没有走得太远,因为我遇到了一个我无法弄清楚的编译错误.我想我知道编译器在抱怨什么,但我不明白为什么它会关心.以下代码编译(clang 3.9,Boost 1.62.0)并且有效.(我意识到它的结构很差,并且有常量的内置解析器;我只是试图证明这个问题.)
#define BOOST_SPIRIT_X3_DEBUG
#include <iostream>
#include <boost/spirit/home/x3.hpp>
using namespace std;
namespace x3 = boost::spirit::x3;
namespace lang {
using namespace x3;
struct Constant {
};
rule<class constant_id, Constant> const constant = "constant";
auto const integer_literal = -char_('-') >> +digit;
auto const float_literal = -char_('-') >> +digit >> -(char_('.') >> *digit);
auto const constant_def = (integer_literal)[([](auto &ctx) { _val(ctx) = Constant(); })];
BOOST_SPIRIT_DEFINE(constant);
}
int main(int argc, char *argv[]) {
string s("3.14159");
if (x3::phrase_parse(s.begin(), s.end(), lang::constant, x3::space)) {
cout …Run Code Online (Sandbox Code Playgroud)