2

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

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

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

在解析一个非常基本的输入(一对注释行和一个引用字符串行)时,这似乎运作良好。(住在科利鲁

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

  1. 这是定义“跳过解析器”的正确方法吗?有标准方法吗?
  2. 这样的实现是否存在性能问题?将如何改进?

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

4

1 回答 1

3

是的,没关系。

船长似乎非常理想。quoted_string您可以通过重新排序和使用字符集否定 ( )来优化规则operator~

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"`
于 2016-02-10T00:14:14.110 回答