标签: boost-spirit-x3

Boost Spirit X3无法使用变量因子编译repeat指令

我试图使用Boost Spirit X3指令重复一个可变的重复因子.基本思想是标头+有效负载,其中标头指定有效负载的大小.一个简单的例子"3 1 2 3"被解释为header = 3,data = {1,2,3}(3个整数).

我只能从精神qi文档中找到例子.它使用boost phoenix引用来包装变量因子:http://www.boost.org/doc/libs/1_50_0/libs/spirit/doc/html/spirit/qi/reference/directive/repeat.html

std::string str;
int n;
test_parser_attr("\x0bHello World",
    char_[phx::ref(n) = _1] >> repeat(phx::ref(n))[char_], str);
std::cout << n << ',' << str << std::endl;  // will print "11,Hello World"
Run Code Online (Sandbox Code Playgroud)

我为精神x3写了以下简单的例子,没有运气:

#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <iostream>

namespace x3 = boost::spirit::x3;
using x3::uint_;
using x3::int_;
using x3::phrase_parse;
using x3::repeat;
using x3::space;
using std::string;
using std::cout;
using std::endl;

int main( int argc, char **argv )
{ …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit boost-spirit-x3

11
推荐指数
1
解决办法
1372
查看次数

在精神x3的解析器规则中终止左递归

我目前仍然坚持使用boost spirit x3解析的规则.对于我要解析的内容,这是te EBNF(使用精神列表中的%运算符):

type ::= class_type | lambda_type

lambda_type ::= more_arg_lambda | one_arg_lambda

more_arg_lambda ::= "(", type%",", ")", "=>", type

one_arg_lambda ::= type, "=>", type  <- here is the left recursion

class_type ::= identifier%"::", ["<", type%",", ">"]
Run Code Online (Sandbox Code Playgroud)

usng boost spirit x3,我试图解析下面的struct/variant:

typedef x3::variant<
        nil,
        x3::forward_ast<LambdaType>,
        x3::forward_ast<ClassType>
    > Type;

struct LambdaType {
        std::vector<Type> parameters_;
        Type return_type_;
    };
struct ClassType{
        std::vector<std::string> name_; 
        std::vector<Type> template_args_;
    };
Run Code Online (Sandbox Code Playgroud)

我有一个关于我目前在这里尝试的实例,它不起作用,我也尝试改变变体解析器的顺序,它没有帮助,我得到无尽的回忆,或者没有我期望(或希望)的行为.任何人都可以帮我调试这个解析器吗?我想我在解析器中有一些类型的左递归,是否有机会避免这种情况,或者没有机会重写语法?这个gramar甚至可以用boost spirit x3解析吗?

编辑:

我设法在这个语法中消除了左递归.现在te语法如下:

type ::= class_type | lambda_type

    lambda_type ::= more_arg_lambda | …
Run Code Online (Sandbox Code Playgroud)

c++ parsing boost-spirit boost-spirit-x3

11
推荐指数
1
解决办法
508
查看次数

暧昧变种和提升精神x3

试图调整boost spirit x3 calc示例来解析可以将函数作为参数的函数.但是它没有编译.

namespace client{ namespace ast{
    struct ts;
    struct fnc;
    typedef boost::variant<
    ts,
    boost::recursive_wrapper<fnc>
    > node;
    struct ts{
        unsigned int id;
    };
    struct fnc{
        std::vector<char> id;
        std::vector<node> args;
    };
}}
BOOST_FUSION_ADAPT_STRUCT(
    client::ast::ts,
    (unsigned int, id)
)
BOOST_FUSION_ADAPT_STRUCT(
    client::ast::fnc,
    (std::vector<char>, id)
    (std::vector<client::ast::node>, args)
)
namespace client{
    namespace x3 = boost::spirit::x3;
    namespace calc_grammar{
        using x3::uint_;
        using x3::alpha;
        using x3::alnum;
        using x3::lit;
        using x3::char_;
        x3::rule<class funct, ast::fnc> const funct("function");
        x3::rule<class ts, ast::ts> const ts("timeseries");
        x3::rule<class funct_name, std::vector<char>> const funct_name("function_name");
        auto const …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit visual-c++ boost-spirit-x3

10
推荐指数
1
解决办法
1519
查看次数

Boost.Spirit.x3避免将相同类型的两个连续属性折叠到向量中

我正在努力学习Boost.Spirit,但我发现了一个难点.

我试图将字符串解析为以下结构:

struct employee {
    std::string name;
    std::string location;
};
Run Code Online (Sandbox Code Playgroud)

似乎当两个具有相同类型的属性背靠背时,它们会崩溃(逻辑上)std::vector为该类型的一个.由于该规则,以下解析器

+x3::ascii::alnum >>
    +x3::space >>
    +x3::ascii::alnum
Run Code Online (Sandbox Code Playgroud)

会有的属性std::vector<std::string>.

但我试图将其解析为struct,这意味着我的理想属性将是一个boost::fusion::tuple<std::string, std::string>,所以我可以调整我的结构.

不工作代码的完整版本(如上所述):

// Example program
#include <iostream>
#include <string>

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


struct employee {
    std::string name;
    std::string location;
};

BOOST_FUSION_ADAPT_STRUCT(employee, 
    (std::string, name),
    (std::string, location)
)

namespace x3 = boost::spirit::x3;

x3::rule<struct parse_emp_id, employee> const parse_emp = "Employee Parser";
auto parse_emp_def = 
    +x3::ascii::alnum >>
    +x3::space >>
    +x3::ascii::alnum
    ;
BOOST_SPIRIT_DEFINE(parse_emp);

int main()
{
    std::string input …
Run Code Online (Sandbox Code Playgroud)

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

9
推荐指数
1
解决办法
311
查看次数

boost-spirit 3在哪里?它被抛弃了吗?

我找不到任何下载促进精神3.似乎官方网站在12月底停止谈论它?它去了哪里?

boost-spirit-x3

9
推荐指数
1
解决办法
1351
查看次数

使用boost spirit x3编译时间

我正试图抓住新的Spirit X3(升级1.61.0).

我的机器是运行Linux的MacBook Pro(i7-4750HQ).

使用Spirit的第2版我习惯了很长的编译时间,但这感觉不对.对于表达式解析器的以下第一步,编译需要20秒.

我以为X3会更快,这个合理吗?我的代码不是最理想的吗?

编译器设置(铿锵3.8.0)

clang++ -c -pipe -std=c++14 -ftemplate-depth=512 -g -w -Wall -Wno-unused-parameter -fPIC 
Run Code Online (Sandbox Code Playgroud)

码:

//#define BOOST_SPIRIT_X3_DEBUG
#include <iostream>

#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/home/x3/support/ast/variant.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

#include <string>
#include <vector>

//--------------------------------------------------------------------------------------------------
namespace client { namespace ast
{
    namespace fusion = boost::fusion;
    namespace x3 = boost::spirit::x3;

    struct number : x3::variant<int, double> {
        using base_type::base_type;
        using base_type::operator=;
    };

    struct add_ast;
    struct mult_ast;
    struct block_ast;
    struct function;

    struct expr_ast : x3::variant<
            number,
            x3::forward_ast<function>,
            x3::forward_ast<add_ast>,
            x3::forward_ast<mult_ast>,
            x3::forward_ast<block_ast>
        > {
        using base_type::base_type;
        using …
Run Code Online (Sandbox Code Playgroud)

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

8
推荐指数
2
解决办法
805
查看次数

Spirit X3,语义操作使编译失败:属性没有预期的大小

此代码不编译(gcc 5.3.1 + boost 1.60):

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

namespace x3 = boost::spirit::x3;

template <typename T>
void parse(T begin, T end) {
    auto dest = x3::lit('[') >> x3::int_ >> ';' >> x3::int_ >> ']';

    auto on_portal = [&](auto& ctx) {};
    auto portal    = (x3::char_('P') >> -dest)[on_portal];

    auto tiles = +portal;
    x3::phrase_parse(begin, end, tiles, x3::eol);
}

int main() {
    std::string x;
    parse(x.begin(), x.end());
}
Run Code Online (Sandbox Code Playgroud)

它失败并带有静态断言:

error: static assertion failed: Attribute does not have the expected size.
Run Code Online (Sandbox Code Playgroud)

感谢wandbox我也尝试了boost 1.61和clang,两者都产生了相同的结果.

如果我删除附加的语义动作portal,它编译得很好; 如果我dest …

c++ boost-spirit boost-spirit-x3

8
推荐指数
1
解决办法
255
查看次数

使用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
查看次数

提升精神(X3)符号表,产生UTF8字符串

我正在尝试将LaTeX转义码(例如\alpha)解析为Unicode(数学)字符(即U+1D6FC).

现在这意味着我正在使用这个symbols解析器(规则):

struct greek_lower_case_letters_ : x3::symbols<char32_t>
{
  greek_lower_case_letters_::greek_lower_case_letters_()
  {
    add("alpha",   U'\u03B1');
  }
} greek_lower_case_letter;
Run Code Online (Sandbox Code Playgroud)

这很好,但意味着我得到了std::u32string一个结果.我想要一种优雅的方法来保持代码中的Unicode代码点(可能是未来的自动化)和维护原因.有没有办法让这种解析器解析为UTF-8 std::string

我想过将symbolsstruct解析为a std::string,但这样效率非常低(我知道,早期优化bla bla).

我希望有一些优雅的方式,而不是通过一堆箍来使这工作(symbols将结果附加到字符串).

我担心使用代码点值并想要UTF8会产生转换的运行时成本(或者是否有constexprUTF32-> UTF8转换?).

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

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

如何使用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
查看次数