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

为何boost::spirit::qi规则无法解析PureData画布字符串?

PureData画布记录解析问题:Boost Spirit规则修正

问题分析

你遇到的解析失败核心原因是字符串规则的匹配范围错误:默认的字符匹配规则会过度匹配后续的整数和分号,导致后续规则无法匹配;或者未正确处理空白跳过逻辑,导致字符串解析与skipper冲突。

常见错误规则示例

如果你的原始规则类似这样,必然会失败:

// 错误示例:qi::+qi::char_会匹配包括"1;"在内的所有后续字符
qi::rule<It, Canvas(), qi::space_type> canvas_rule = 
    "#N canvas" >> qi::int_ >> qi::int_ >> qi::int_ >> qi::int_ >> qi::+qi::char_ >> qi::int_ >> ';';

修正后的解析规则

基础版本(名称不含空白)

针对你提供的moo这类无空白的名称,定义精确匹配非空白、非分号字符的规则:

#include <boost/spirit/include/qi.hpp>
#include <string>

namespace qi = boost::spirit::qi;

// 画布数据结构
struct Canvas {
    int x, y, width, height;
    std::string name;
    int flag;
};

template <typename Iterator>
struct CanvasGrammar : qi::grammar<Iterator, Canvas(), qi::space_type> {
    CanvasGrammar() : CanvasGrammar::base_type(canvas_rule) {
        // 匹配不含空白和分号的字符串,用lexeme禁用内部空白跳过
        name_rule = qi::lexeme[+(qi::char_ - qi::space - ';')];
        
        canvas_rule = "#N canvas"
            >> qi::int_ >> qi::int_ >> qi::int_ >> qi::int_  // 解析四个坐标/尺寸整数
            >> name_rule                                     // 解析画布名称
            >> qi::int_                                      // 解析末尾标志位
            >> ';';                                          // 匹配终止分号
    }

    qi::rule<Iterator, std::string(), qi::space_type> name_rule;
    qi::rule<Iterator, Canvas(), qi::space_type> canvas_rule;
};

// 测试代码
int main() {
    const std::string input = "#N canvas 0 0 400 300 moo 1;";
    auto iter = input.begin();
    auto end_iter = input.end();

    CanvasGrammar<decltype(iter)> parser;
    Canvas canvas_data;

    bool success = qi::phrase_parse(iter, end_iter, parser, qi::space, canvas_data);
    if (success && iter == end_iter) {
        // 解析成功,可使用canvas_data
    }
    return 0;
}

进阶版本(支持带引号的空白名称)

如果PureData画布名称包含空白(会用双引号包裹),可以扩展名称规则:

name_rule = qi::lexeme[
    '"' >> *(qi::char_ - '"') >> '"'  // 匹配带双引号的字符串
    | +(qi::char_ - qi::space - ';')   // 兼容无空白的名称
];

关键修正点

  1. 使用qi::lexeme:确保解析字符串时禁用全局空白skipper,避免字符串内部的空白被错误跳过。
  2. 精确限制字符串匹配范围:通过qi::char_ - qi::space - ';'明确字符串只匹配到下一个空白或分号前的字符,不会过度匹配后续内容。
  3. 规则顺序与结构对齐:严格对应#N canvas <int> <int> <int> <int> <string> <int>;的格式顺序,确保每个字段规则正确对应。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:40:23