标签: boost-spirit-x3

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

Boost.Spirit X3中的错误处理和注释

使用boost::spirit::x3::position_tagged某些AST节点的基类(如何选择应标记哪些,例如用于类C语言?)以及在规则ID定义中使用的其他结构时的逻辑是什么,如:

struct error_handler_tag;

struct error_handler_base
{

    template< typename Iterator, typename Exception, typename Context >
    x3::error_handler_result
    on_error(Iterator & /*first*/, Iterator const & /*last*/,
             Exception const & x, Context const & context)
    {
        std::string message_ = "Error! Expecting: " + x.which() + " here:";
        auto & error_handler = x3::get< error_handler_tag >(context).get();
        error_handler(x.where(), message_);
        return x3::error_handler_result::fail;
    }

};

struct annotation_base
{

    template< typename T, typename Iterator, typename Context >
    void
    on_success(Iterator const & first, Iterator const & last,
               T & ast, …
Run Code Online (Sandbox Code Playgroud)

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

5
推荐指数
1
解决办法
1034
查看次数

在使用单独的规则定义和实例化时,Boost Spirit X3 AST不使用语义操作

我试图在将结构解析为AST时使用具有语义动作的Boost Spirit X3.如果我使用没有单独定义和实例化的规则它可以正常工作,例如:

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

namespace ast 
{

struct ast_struct
{
  int number;
  std::vector<int> numbers;
};

}

BOOST_FUSION_ADAPT_STRUCT(
    ast::ast_struct,
    (int, number)
    (std::vector<int>, numbers)
)

namespace x3 = boost::spirit::x3;
using namespace std;

void parse( const std::string &data )
{
  string::const_iterator begin = data.begin();
  string::const_iterator end = data.end();

  unsigned n(0);

  auto f = [&n]( auto &ctx )
    {
      n = x3::_attr(ctx);
    };

  ast::ast_struct ast;
  bool r = x3::parse( begin, end, 
                      x3::int_[f] >> +( x3::omit[+x3::blank] …
Run Code Online (Sandbox Code Playgroud)

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

5
推荐指数
1
解决办法
1069
查看次数

使用语义操作解析以逗号分隔的范围和数字列表

使用Boost.Spirit X3,我想将逗号分隔的范围列表和单个数字(例如1-4,6,7,9-12)解析为单个std::vector<int>.这是我想出的:

namespace ast {
    struct range 
    {
        int first_, last_;    
    };    

    using expr = std::vector<int>;    
}

namespace parser {        
    template<typename T>
    auto as_rule = [](auto p) { return x3::rule<struct _, T>{} = x3::as_parser(p); };

    auto const push = [](auto& ctx) { 
        x3::_val(ctx).push_back(x3::_attr(ctx)); 
    };  

    auto const expand = [](auto& ctx) { 
        for (auto i = x3::_attr(ctx).first_; i <= x3::_attr(ctx).last_; ++i) 
            x3::_val(ctx).push_back(i);  
    }; 

    auto const number = x3::uint_;
    auto const range  = as_rule<ast::range> (number >> …
Run Code Online (Sandbox Code Playgroud)

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

5
推荐指数
1
解决办法
617
查看次数

如何在Boost Spirit X3中进行“流式”解析?

我试图找出istream使用x3 解析的正确方法。较旧的文档指的是multi_pass东西,我仍然可以使用它吗?还是有其他方法来缓冲X3的流,以便它可以回溯?

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

5
推荐指数
1
解决办法
461
查看次数

提升精神X3:"属性没有预期的大小",但它为什么关心?

我正在尝试用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)

c++ boost-spirit boost-spirit-x3

5
推荐指数
0
解决办法
273
查看次数

如何在VS2017中的boost spirit x3中制作递归规则

我在boost :: spirit :: x3中编写了以下递归规则,但它似乎只在g ++/clang中编译,而不是VS2017(15.5.3):

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

namespace lex3
{
    namespace x3 = boost::spirit::x3;

    x3::rule<struct foo_class> const foo = "foo";
    x3::rule<struct bar_class> const bar = "bar";

    auto bar_def = *((x3::char_ - "/*") - "*/") >> *(foo > *((x3::char_ - "/*") - "*/"));
    auto foo_def = "/*" > bar > "*/";

    BOOST_SPIRIT_DEFINE(foo)
    BOOST_SPIRIT_DEFINE(bar)
}

int main(int argc, char** argv)
{
    std::string input = "/* a /* nested */ comment */";
    auto f = input.begin();
    auto l = input.end(); …
Run Code Online (Sandbox Code Playgroud)

c++ boost-spirit-x3 visual-studio-2017

5
推荐指数
1
解决办法
331
查看次数

提升精神x3 int32 | double_无法解析double

我正在尝试编写一个解析器,它解析a int32_t或a double.作为第一次尝试,我写了这个解析器:

const auto int_or_double = boost::spirit::x3::int32 | boost::spirit::x3::double_;
Run Code Online (Sandbox Code Playgroud)

我期望得到一个boost::variant<int32_t, double> 解析器成功解析整数,12, 100, -42, 7但它无法解析双打像13.243, 42.7, 12.0 -10000.3

这是一个现场演示

为什么这个解析器在双打时失败?

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

4
推荐指数
1
解决办法
259
查看次数

将两个整数的序列匹配到`std :: pair <int,int>`

我正在尝试使用Boost.Sprit x3将两个整数的序列匹配成一个std::pair<int, int>.根据文档判断,以下代码应该编译:


#include <string>
#include <boost/config/warning_disable.hpp>
#include <boost/spirit/home/x3.hpp>

int main()
{
    using namespace boost::spirit::x3;

    std::string input("1 2");
    std::pair<int, int> result;
    parse(input.begin(), input.end(), int_ >> int_, result);
}
Run Code Online (Sandbox Code Playgroud)

melpon.org链接


但是,它只匹配第一个整数.如果我改变std::pair<int, int> result;int result;,然后打印result,我得到1我的输出.

为什么会这样?这不是int_ >> int_定义匹配(并设置为属性)两个整数的解析器的正确方法吗?

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

4
推荐指数
1
解决办法
150
查看次数