提升精神X3 Skip Parser实现?

时间:2016-02-09 22:53:44

标签: c++ parsing boost boost-spirit-x3

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

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

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

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

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

  1. 这是定义"跳过解析器"的正确方法吗?有标准方法吗?
  2. 这样的实现是否存在性能问题?如何改进?
  3. 我之前搜索过SO以获取详细信息,并使用Qi(Custom Skip Parser with Boost::Spirit)找到答案。由于我从未学过气,很多细节都难以理解。我上面描述的方法看起来更直观。

1 个答案:

答案 0 :(得分:2)

是的,没关系。

船长似乎非常优秀。您可以通过重新排序和使用字符集否定(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"`