Boost Spirit X3 跳过解析器实现?

Boost Spirit X3 Skip Parser Implementation?

对于我使用 X3 解析的当前语法,忽略空格和 Perl 风格的注释。

在我看来,X3 中的跳过解析器只是一个普通的解析器,它消耗的任何输入都被认为是 "skipped." 我想到了这个:

namespace x3 = boost::spirit::x3;
auto const blank_comment = 
   x3::blank | x3::lexeme[ '#' >> *(x3::char_ - x3::eol) >> x3::eol ];

在解析一个非常基本的输入(一对注释行和一个带引号的字符串行)时,这似乎很有效。 (Live on Coliru)

但是,由于我找不到任何关于此事的文档,而且当前跳过解析器的详细信息隐藏在复杂的模板系统中,我希望得到一些输入。

  1. 这是定义 "skip parser" 的正确方法吗?有没有标准的方法?
  2. 像这样的实现是否存在性能问题?如何改进?

我之前在 SO 中搜索过详细信息,并使用 Qi (Custom Skip Parser with Boost::Spirit) 找到了答案。因为我从来没有学过气,所以很多细节都很难理解。我上面描述的方法似乎更直观。

是的,没关系。

船长看起来很不错。您可以通过重新排序和使用字符集否定 (operator~):

来优化 quoted_string 规则

Live On Coliru

#include <boost/spirit/home/x3.hpp>

namespace parser {
    namespace x3 = boost::spirit::x3;
    auto const quoted_string = x3::lexeme [ '"' >>  *('\' >> x3::char_ | ~x3::char_("\"\n")) >> '"' ];
    auto const space_comment = x3::space | x3::lexeme[ '#' >> *(x3::char_ - x3::eol) >> x3::eol];
}

#include <iostream>
int main() {
    std::string result, s1 = "# foo\n\n#bar\n   \t\"This is a simple string, containing \\"escaped quotes\\"\"";

    phrase_parse(s1.begin(), s1.end(), parser::quoted_string, parser::space_comment, result);

    std::cout << "Original: `" << s1 << "`\nResult: `" << result << "`\n";
}

版画

Original: `# foo

#bar
    "This is a simple string, containing \"escaped quotes\""`
Result: `This is a simple string, containing "escaped quotes"`