模板精神 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); })];
}

科里鲁现场观看

相关文章:
  • 没有找到相关文章