我希望能够解析一个Number,以存储其原始源并跟踪其在源中的位置,并将其保留在结构本身中。
这是我到目前为止所拥有的:
#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;
};
测试代码是:
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";
我没有得到的是为什么迭代器在线:
[at_c<2>(_val) = get_line(begin(_1))]
不是line_pos_iterator,即使这是我用于解析器的也不是。我将不胜感激地解释以及以任何方式解决问题的想法。
看一下
#include <boost/spirit/repository/include/qi_iter_pos.hpp>
这定义了一个解析器,可直接将位置公开为属性。让我在几分钟内添加一个示例。
编辑我发现,iter_pos
在不“假设”事物和更改数据类型布局的情况下,很难涉足样本。我对此非常赞成(我将努力一路失去所有的语义动作。)。但是,时间有限。
您可以使用以下帮助程序来解决问题:
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);
}
};
^多态演员,按如下方式使用:
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_;
注意我更改了一些小要点。
带有输出的完全运行的演示:Live On Coliru
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句