You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Boost Spirit X3 编译期已知解析器惰性解析实现问题求助

多进制数字面量X3惰性解析实现问题

实现背景

  • 参考sehe在Stack Overflow发布的Boost Spirit X3惰性解析器相关回答,尝试将惰性解析方案适配到自身的多进制数字面量解析需求
  • 目标语法支持2、8、10、16四种进制的数字字面量表达,已对参考方案做最小化简化

AST设计

  • 设计思路:通过x3::raw将数字的整数部分、小数部分、指数部分以boost::iterator_range<>形式保留供后续计算,仅基数字段使用无符号整型存储
  • 考虑到暂未确定后续求值需求(不排除直接在解析器中完成整数/浮点数求值的可能,实际需求存在变数),简化示例中使用std::string存储原始字面量内容,对应结构体定义如下:
struct number {
    unsigned    base;
    std::string literal;
};
  • 由于基数和数字内容中可嵌入下划线分隔符,使用range-v3库的views::filter()函数做过滤处理;sehe在另一篇X3解析规则编译问题的回答中,也曾给出过带下划线分隔数字的处理方案

核心实现逻辑

参考早年使用Boost Spirit Qi时的Nabialek trick编写核心代码,逻辑如下:

auto const char_set = [](auto&& char_range, char const* name) {
    return x3::rule<struct _, std::string>{ name } = x3::as_parser(
        x3::raw[ x3::char_(char_range) >> *(-lit("_") >> x3::char_(char_range)) ]);
};
auto const bin_charset = char_set("01", "binary charset");
auto const oct_charset = char_set("0-7", "octal charset");
auto const dec_charset = char_set("0-9", "decimal charset");
auto const hex_charset = char_set("0-9a-fA-F", "hexadecimal charset");

using Value = ast::number;
using It    = std::string::const_iterator;
using Rule  = x3::any_parser<It, Value>;

x3::symbols<Rule> const based_parser({
        { 2,  as<std::string>[ bin_charset ] },
        { 8,  as<std::string>[ oct_charset ] },
        { 10, as<std::string>[ dec_charset ] },
        { 16, as<std::string>[ hex_charset ] }
    }, "based character set"
);

auto const base = x3::rule<struct _, unsigned>{ "base" } = dec_charset; // 简化实现

auto const parser = x3::with<Rule>(Rule{}) [
    x3::lexeme[ set_lazy<Rule>[based_parser] >> '#' >> do_lazy<Rule> ]
];

auto const grammar = x3::skip[ x3::space ]( parser >> x3::eoi );   

待解析输入示例

计划使用该解析器处理如下格式的输入:

for (std::string const input : {
        "2#0101",
        "8#42",
        "10#4711",
        "1_6#DEAD_BEEF",
    })
{
   // 解析逻辑
}

现存问题与扩展需求

  • 上述代码目前无法通过编译,无法验证逻辑是否正确;该方案相比多分支可选匹配的旧实现更优雅
  • 后续语法扩展需要新增前置数字位宽、UB/UO等特殊基数标识,需要了解可支撑后续扩展的代码设计方式,例如通过eps[get<std_tag>(ctx) == x42]这类上下文判断方式实现分支逻辑
  • 完整示例代码已上传至coliru

内容的提问来源于stack exchange,提问作者Olx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 02:30:54