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

Boost Spirit X3:如何使用无任何作用的跳过解析器?

How to Completely Disable Skipping in Boost Spirit X3

Great question! Let's clear this up for you—you're right that using no_skip while still passing space to phrase_parse feels clunky, and there are much cleaner ways to achieve what you want.

The Simplest Solution: Use parse Instead of phrase_parse

The core issue here is that phrase_parse is designed to automatically skip whitespace (using the parser you pass as the 4th argument) between grammar elements. If you don't want any skipping at all, you don't need phrase_parse at all!

parse is the base parsing function in Spirit X3 that doesn't perform any automatic whitespace skipping. It will strictly parse the input exactly as written, which is exactly what you need for your comma-separated integer sequence (rejecting inputs like "2, 4,5" with spaces).

Here's your modified code using parse:

#include <iostream>
#include <string>
#include <vector>
#include <boost/spirit/home/x3.hpp>

int main() {
    using namespace boost::spirit::x3;
    const std::string input{"2,4,5"};
    const auto parser = int_ % ',';
    std::vector<int> numbers;
    auto start = input.cbegin();
    auto r = parse(start, input.end(), parser, numbers);
    if (r && start == input.cend()) {
        // Success
        for(const auto &item: numbers) std::cout << item << std::endl;
        return 0;
    }
    std::cerr << "Input was not parsed successfully" << std::endl;
    return 1;
}

This code will correctly parse "2,4,5" and fail on "2, 4,5" (since the space after the comma isn't part of your int_ % ',' grammar), which is exactly your desired behavior. No extra directives or awkward workarounds needed!

If You Must Use phrase_parse (For Edge Cases)

If you're in a scenario where you have to use phrase_parse (e.g., part of a larger grammar that sometimes needs skipping), you can use a skip parser that does absolutely nothing—without causing an infinite loop.

Your earlier attempt with eps failed because eps always matches an empty string, so phrase_parse would keep trying to "skip" forever (looping infinitely). Instead, use eps(false): a version of eps that never matches anything. This tells phrase_parse to not skip any input at all, and since it doesn't match, it won't loop.

Here's how that would look:

auto r = phrase_parse(start, input.end(), parser, eps(false), numbers);

This works because phrase_parse will attempt to run the skip parser before each element of your grammar, but eps(false) will always fail—so no skipping occurs, and no infinite loop is triggered.

Why no_skip Feels Clunky

You're right that wrapping your parser in no_skip while still passing space to phrase_parse is not ideal. no_skip disables skipping for the enclosed parser, but phrase_parse still tries to run the global skip parser around other parts of your grammar (even if you don't have any). It's a workaround, not a clean solution for completely disabling skipping.

Final Takeaways

  • Preferred Approach: Use parse instead of phrase_parse when you don't want any whitespace skipping. It's semantically clear and avoids unnecessary complexity.
  • Edge Case Fix: Use eps(false) as the skip parser for phrase_parse if you can't avoid using phrase_parse.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:30:28