提振精神解析与源 [英] boost spirit parse with the source

查看:143
本文介绍了提振精神解析与源的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够解析一个数字,来储存其原始来源,并跟踪源$ P $其地位,在结构本身pserving它。

I would like to be able to parse a Number, to store its original source and to track its position in the source preserving it in the structure itself.

这是我迄今为止:

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/home/support/iterators/line_pos_iterator.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/io.hpp>

#include <iostream>
#include <iomanip>
#include <ios>
#include <string>
#include <complex>

#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>

struct Position
{
    Position()
        : line(-1)
    {
    }

    size_t line;
};

struct Number : public Position
{
    Number()
        : Position()
        , value(-1)
        , source()
    {
    }

    unsigned    value;
    std::string source;
};

using namespace boost::spirit;

BOOST_FUSION_ADAPT_STRUCT(Number,
                            (unsigned,    value)
                            (std::string, source)
                            (size_t,      line)
                          );

template <typename Iterator>
struct source_hex : qi::grammar<Iterator, Number()>
{
    source_hex() : source_hex::base_type(start)
    {
        using qi::eps;
        using qi::hex;
        using qi::lit;
        using qi::raw;
        using qi::_val;
        using qi::_1;
        using ascii::char_;

        namespace phx = boost::phoenix;
        using phx::at_c;
        using phx::begin;
        using phx::end;
        using phx::construct;

        start = raw[   (lit("0x") | lit("0X"))
                     >> hex [at_c<0>(_val) = _1]
                   ][at_c<2>(_val) = get_line(begin(_1))]
                    [at_c<1>(_val) = construct<std::string>(begin(_1), end(_1))]

        ;
    }

    qi::rule<Iterator, Number()> start;
};

和测试code是:

typedef line_pos_iterator<std::string::const_iterator> Iterator;
source_hex<Iterator> g;
Iterator iter(str.begin());
Iterator end(str.end());

Number number;
bool r = parse(iter, end, g, number);
if (r && iter == end) {
    std::cout << number.line << ": 0x" << std::setw(8) << std::setfill('0') << std::hex << number.value << " // " << number.source << "\n";
} else
    std::cout << "Parsing failed\n";

什么我没有得到就是为什么行迭代器:

what I am not getting is why the iterator on line:

[at_c<2>(_val) = get_line(begin(_1))]

是不是一个line_pos_iterator甚至这是我使用的解析器之一。
我将AP preciate解释以及想法如何解决这个问题 - 以任何方式。

is not a line_pos_iterator even this is the one I am using for the parser. I will appreciate explanation as well as ideas how to solve the problem - in whatever way.

推荐答案

看一看

#include <boost/spirit/repository/include/qi_iter_pos.hpp>

这定义了直接暴露位置的属性的解析器。让我在几分钟内添加一个例子。

This defines a parser that directly exposes the position as an attribute. Let me add an example in a few minutes.

修改我发现很难鞋拔 iter_pos 进入你的样品没有假设的东西,改变你的数据类型的布局。我倒是很赞成这个(我会努力失去语义动作一路)。然而,时间的限制。

Edit I found it hard to shoe-horn iter_pos into your sample without "assuming" things and changing your data type layout. I'd very much favour this (I'd strive to lose the semantic actions all the way.). However, time's limited.

下面是一个你可以用它来解决您的问题一个小帮手:

Here's a little helper that you can use to fix your problem:

struct get_line_f
{
    template <typename> struct result { typedef size_t type; };
    template <typename It> size_t operator()(It const& pos_iter) const
    {
        return get_line(pos_iter);
    }
};

^多态的演员,用这样:

^ The polymorphic actor, use as such:

    start = raw[ qi::no_case["0x"] >> hex [at_c<0>(_val) = _1] ]
               [ 
                   at_c<1>(_val) = construct<std::string>(begin(_1), end(_1)),
                   at_c<2>(_val) = get_line_(begin(_1)) 
               ]
    ;

    // with

boost::phoenix::function<get_line_f> get_line_;

请注意,我改变了一些小问题。

Note I changed a few minor points.

完全运行演示与输出: 住在Coliru

Fully running demo with output: Live On Coliru

这篇关于提振精神解析与源的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆