标签: boost-spirit

不赞成提升精神标题

我正在关注boost :: spirit的快速入门指南,当我包含时,我收到此编译器警告:"此标头已弃用.请使用:boost/spirit/include/classic_core.hpp"我应该担心这个吗?

(快速入门指南:http://spirit.sourceforge.net/distrib/spirit_1_8_5/libs/spirit/doc/quick_start.html,与节目我试图编译这里的全部源:HTTP://spirit.sourceforge. net/distrib/spirit_1_8_5/libs/spirit/example/fundamental/number_list.cpp)

编辑:此外,当我尝试使用推荐的classic_core.hpp和classic_push_back_actor.hpp标头编译时,我得到以下编译器错误:

test7.cpp: In function 'bool parse_numbers(const char*, __gnu_debug_def::vector<double, std::allocator<double> >&)':
test7.cpp:18: error: 'real_p' was not declared in this scope
test7.cpp:18: error: 'push_back_a' was not declared in this scope
test7.cpp:23: error: 'space_p' was not declared in this scope
test7.cpp:23: error: 'parse' was not declared in this scope
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit

6
推荐指数
1
解决办法
2909
查看次数

如何使用Boost :: Spirit :: Lex来调用文件而不先将整个文件读入内存?

我正在寻找使用boost :: spirit :: lex编写词法分析器,但我能找到的所有示例似乎都假设您已将整个文件首先读入RAM.我想写一个不需要整个字符串在RAM中的词法分析器,这可能吗?或者我需要使用其他东西吗?

我尝试使用istream_iterator,但是boost会给我一个编译错误,除非我使用const char*作为迭代器类型.

例如,我能找到的所有例子基本上都是这样做的:

lex_functor_type< lex::lexertl::lexer<> > lex_functor;

// assumes entire file is in memory
char const* first = str.c_str();
char const* last = &first[str.size()];

bool r = lex::tokenize(first, last, lex_functor, 
    boost::bind(lex_callback_functor(), _1, ... ));
Run Code Online (Sandbox Code Playgroud)

另外,是否有可能以某种方式确定lex令牌的行/列号?

谢谢!

c++ boost lex boost-spirit

6
推荐指数
1
解决办法
1259
查看次数

Spirit无法将属性赋给单元素结构(或融合序列)

我的目标是让我的qi::grammar返回属性.spirit::lexer尽管如此,我在这方面遇到了很大的困难.

我希望用下面给定的语法,如果我用它来调用它spirit::qi::parse(begin, end, grammar, output);,struct ident output它将具有解析的lexeme的内容.

该错误似乎主要流出这一行: start %= lexer.identifier;

系统说明

  • 提升1.47.0
  • Mac OS X 10.7.2
  • clang ++或g ++(下面显示的错误来自clang ++)

编译命令

g++ -g -c -O0 -Wall -DBOOST_SPIRIT_DEBUG -DBOOST_SPIRIT_LEXERTL_DEBUG -DBOOST_SPIRIT_USE_PHOENIX_V3 -DBOOST_SPIRIT_ACTIONS_ALLOW_ATTR_COMPAT reduced.cpp
Run Code Online (Sandbox Code Playgroud)

源代码

#include <boost/fusion/include/adapt_struct.hpp>

#include <boost/spirit/home/lex.hpp>
#include <boost/spirit/home/lex/lexer/lexertl/lexer.hpp>
#include <boost/spirit/home/qi.hpp>

namespace spirit = boost::spirit;

struct ident {
    std::string value;
};

BOOST_FUSION_ADAPT_STRUCT(ident,
        (std::string, value)
        )

struct my_lexer : spirit::lex::lexer< spirit::lex::lexertl::actor_lexer<> > {
    spirit::lex::token_def<std::string> identifier;
};

struct my_grammar : spirit::qi::grammar<my_lexer::iterator_type, ident()> {
    my_grammar(const …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit boost-spirit-qi

6
推荐指数
1
解决办法
1023
查看次数

如何在boost :: spirit规则中使用boost :: tuple作为属性?

我有以下规则boost::spirit:

typedef boost::tuple<int, int> Entry;
qi::rule<Iterator, Entry(), Skipper> entry;
entry = qi::int_ >> qi::int_;
Run Code Online (Sandbox Code Playgroud)

但第二个int没有写入元组.有没有办法让它工作不必使用boost::fusion::tuple

如果我使用它,它可以工作std::pair,为什么我不能使用boost::tuple

这是一个完整的编译示例:

#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/tuple.hpp>
#include <boost/tuple/tuple.hpp>
namespace qi = boost::spirit::qi;

// works:
// #include <boost/fusion/include/std_pair.hpp>
// typedef std::pair<int, int> Entry;

// doesn't work:
typedef boost::tuple<int, int> Entry;

template <typename Iterator, typename Skipper>
struct MyGrammar : qi::grammar<Iterator, Entry(), Skipper> {
  MyGrammar() : MyGrammar::base_type(entry) {
    entry = qi::int_ >> qi::int_;
  } …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit boost-spirit-qi

6
推荐指数
1
解决办法
1291
查看次数

如何从Boost Spirit中的函数抛出expectation_failure?

在Boost :: Spirit中,如何expectation_failure从绑定的函数中触发Boost::Bind

背景:我解析包含复杂条目的大文件.当一个条目与前一个条目不一致时,我想失败并抛出一个expectation_failure(包含正确的解析位置信息).当我解析一个条目时,我绑定了一个函数,该函数决定该条目是否与之前看到的内容不一致.

我编写了一个小玩具示例,说明了这一点.在这里,我只是想抛出expectation_failureint10是不能分开的:

#include <iostream>
#include <iomanip>
#include <boost/spirit/include/qi.hpp>
#include <boost/bind.hpp>
#include <boost/spirit/include/classic_position_iterator.hpp>
namespace qi = boost::spirit::qi;
namespace classic = boost::spirit::classic;

void checkNum(int const& i) {
  if (i % 10 != 0) // >> How to throw proper expectation_failure? <<
    std::cerr << "ERROR: Number check failed" << std::endl;
}

template <typename Iterator, typename Skipper>
struct MyGrammar : qi::grammar<Iterator, int(), Skipper> {
  MyGrammar() : MyGrammar::base_type(start) {
    start %= qi::eps …
Run Code Online (Sandbox Code Playgroud)

c++ boost boost-spirit boost-spirit-qi

6
推荐指数
1
解决办法
1058
查看次数

Phoenix :: bind for C++ 11 lambdas在boost :: spirit :: qi语义动作中

我的目标是创建一个解决方法,以便我可以在Boost Spirit Qi语义操作中使用C++ 11 lambdas,同时仍然可以访问更多扩展的qi占位符集,例如qi :: _ pass或qi :: _ r1,必须从上下文对象手动提取它们.我希望避免为一些非平凡的解析逻辑编写Phoenix lambdas,更喜欢C++ 11 lambdas中更直接的C++语法和语义.

下面的代码代表了我有一个解决方法的想法.我的想法是使用phoenix :: bind绑定到lambda并将它传递给我需要的特定占位符.但是,我得到了一个极长的模板编译器错误(gcc 4.7.0,Boost 1.54),我没有专业知识来解释.我选择了我认为最相关的部分并将其发布在代码下方.

我想知道我是否可以使用Boost Spirit在此代码中尝试做什么,如果有人能为我解释错误消息并告诉我出了什么问题.

#include <string>
#include <iostream>

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>

namespace qi = boost::spirit::qi;
namespace spirit = boost::spirit;
namespace phoenix = boost::phoenix;

int main() {

    std::string input{"test1 test2 test3 FOO!"};
    typedef decltype(input.begin()) StringIter;

    qi::rule<StringIter, std::string()> parser =
        *(
            qi::char_
            [
                phoenix::bind(
                    [] (char value) {
                        std::cerr << value << std::endl;
                    },
                    qi::_1
                )
            ]
        );

    qi::parse(input.begin(), input.end(), parser);
}
Run Code Online (Sandbox Code Playgroud)

(注意:我知道这个代码执行的特定任务对于直接的Phoenix结构会更简单,或者甚至可以通过Boost Spirit更新直接允许单参数C++ …

c++ lambda boost-spirit c++11

6
推荐指数
1
解决办法
1985
查看次数

Boost :: Spirit - on_error不打印

我正在尝试使用on_errorBoost :: Spirit :: qi 的机制来找出解析失败的原因.

我在on_error函数中设置了一个断点,并且正在调用函数,但没有输出(nada,nothing,void,...).

简单on_error:

on_error<fail>(level1,
    boost::phoenix::ref(std::cout) << "I've failed.\n"
    );
Run Code Online (Sandbox Code Playgroud)

复杂on_error(来自不同的网站):

on_error<fail>
(
    start,
    boost::phoenix::ref(std::cout)
        << val("Error! Expecting ")
        << _4
        << val(" here: \"")
        << construct<std::string>(qi::_3, qi::_2)
        << val("\"")
        << std::endl
    );
Run Code Online (Sandbox Code Playgroud)

这是我的类包含简单on_error:

template <typename Iterator, typename Skipper>
struct Event_Compound
    : qi::grammar<Iterator, Skipper>
{
    Event_Compound () 
        : Event_Compound::base_type(start, "Compound-Event")
        {
            using qi::lexeme;
            using qi::lit;
            using namespace qi;
            using boost::spirit::ascii::char_;

            relational_operator =
                lit("&&")[Matched_Relational_AND]
                || lit("||")[Matched_Relational_OR]
                ; …
Run Code Online (Sandbox Code Playgroud)

c++ error-handling parsing boost-spirit boost-spirit-qi

6
推荐指数
1
解决办法
868
查看次数

使用std :: array作为boost :: spirit :: x3的Attribute

我正在尝试std::array使用boost :: spirit的最新版本x3(包含在boost 1.54中)将数字列表解析为固定大小的容器.由于std::array具有必要的功能,因此它被检测为容器,但缺少插入功能,使其不兼容.这是我想要完成的一个简短示例:

#include <boost/spirit/home/x3.hpp>

#include <array>
#include <iostream>
#include <string>

namespace x3 = boost::spirit::x3;
namespace ascii = boost::spirit::x3::ascii;

typedef std::array<double, 3> Vertex;

int main(int, char**) {
  using x3::double_;
  using ascii::blank;

  std::string input = "3.1415 42 23.5";
  auto iter = input.begin();

  auto vertex = x3::rule<class vertex, Vertex>{} =
    double_ >> double_ >> double_;

  Vertex v;

  bool const res = x3::phrase_parse(iter, input.end(), vertex, blank, v);
  if (!res || iter != input.end()) return EXIT_FAILURE;

  std::cout << "Match:" …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit stdarray c++14 boost-spirit-x3

6
推荐指数
1
解决办法
401
查看次数

如何使用boost spirit x3的位置信息来注释AST?

所以,我已经编写了我的语法,并希望提供一些调试信息,如行号,以便能够使用我自己的调试器逐步生成生成的可执行代码.

经过一些谷歌搜索后,我发现可以完全定义规则中使用的标记类,如下所示:

x3::rule<class CodeLine, ast::InstructionOrDirectiveAndArgs> const code_line = "code_line";

auto const code_line_def = ...

class CodeLine {
public:
    template <typename T, typename Iterator, typename Context>
    inline void on_success(Iterator const& first, Iterator const& last, T& ast, Context const& context) {

        static std::uint64_t line = 0;
        auto& error_handler = x3::get<error_handler_tag>(context).get();
        error_handler.tag(ast, first, last);
        ast.line_no = line;
        if (*last == '\0') {
            line = 0;
        } else {
            line += 1;
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

在这个完全定义的标记类中,可以实现on_success方法,该方法在成功匹配规则时调用.所以我为匹配一行代码的规则实现了标记类.但由于我找不到从精神中获取当前行号的方法,因此我采用了跟踪当前行的静态变量.问题是要知道何时重置行计数器,正如你在我非常愚蠢的尝试中看到的那样.

这似乎是一种非常复杂的方式来跟踪行号,因此必须有更好的方法.

现在的问题是,获得当前行号的最佳或正确方法是什么?

谢谢阅读!

c++ boost boost-spirit c++14 boost-spirit-x3

6
推荐指数
0
解决办法
1170
查看次数

提升精神X3生产准备好了吗?

我正在将一个手写的解析器迁移到Boost.Spirit(2.5.4).第一印象是积极的,但由于我使用C++ 17,X3似乎是一个非常有吸引力的选择.

幸运的是,有很多关于X3的资源:

然而:

  • Boost.Org 上没有什么,给人的印象是,虽然Spirit X3是Boost的一部分,但它更像是一个偷渡者而不是头等舱乘客
  • 截至今天,似乎发展于2014年6月停止

所以我很担心:X3是个好赌注吗?不仅仅是维护,而且它与前一代产品相比还能保留其产品吗?

编辑

我的作业很糟糕,其他地方也有类似的问题:

boost-spirit boost-spirit-qi boost-spirit-x3

6
推荐指数
1
解决办法
1089
查看次数