模板精神 X3 解析器
Templating Spirit X3 parser
本文关键字:X3 更新时间:2023-10-16
在Boost Spirit QI中,很容易对解析器进行模板化,以便它可以实例化为各种属性类型。 我不清楚如何使用 X3 执行此操作。 考虑这个精简版本的罗马数字解析器示例:
#include <iostream>
#include <iterator>
#include <string>
#include <boost/spirit/home/x3.hpp>
namespace parser {
namespace x3 = boost::spirit::x3;
struct numbers_ : x3::symbols<unsigned> {
numbers_() {
add
("I" , 1)
("II" , 2)
("III" , 3)
("IV" , 4)
("V" , 5)
("VI" , 6)
("VII" , 7)
("VIII" , 8)
("IX" , 9)
;
}
} numbers;
x3::rule<class roman, unsigned> const roman = "roman";
auto init = [](auto &x) { x3::_val(x) = 0; };
auto add = [](auto &x) { x3::_val(x) += x3::_attr(x); };
auto const roman_def = x3::eps [init] >> numbers [add];
BOOST_SPIRIT_DEFINE(roman);
}
int main()
{
std::string input = "V";
auto iter = input.begin();
auto end = input.end();
unsigned result;
bool r = parse(iter, end, parser::roman, result);
if (r && iter == end) {
std::cout << "Success :) Result = " << result << 'n';
} else {
std::cout << "Failed :(n";
}
}
我想在当前硬编码为 unsigned
的属性类型上模板化解析器。 我的第一个猜测是替换
namespace parser {
// ...
}
跟
template < typename int_t >
struct parser {
// ...
};
这显然太天真了。 如何正确执行此操作?
在 X3 中,动态组合解析器并没有那么痛苦。所以我把你的样本写成:
template <typename Attribute>
auto make_roman() {
using namespace boost::spirit::x3;
struct numbers_ : symbols<Attribute> {
numbers_() { this-> add
("I", Attribute{1}) ("II", Attribute{2}) ("III", Attribute{3}) ("IV", Attribute{4})
("V", Attribute{5}) ("VI", Attribute{6}) ("VII", Attribute{7}) ("VIII", Attribute{8})
("IX", Attribute{9}) ;
}
} numbers;
return rule<class roman, Attribute> {"roman"} =
eps [([](auto &x) { _val(x) = 0; })]
>> numbers [([](auto &x) { _val(x) += _attr(x); })];
}
在科里鲁现场观看
相关文章:
- 没有找到相关文章