【问题标题】:Boost Spirit X3 Skip Parser Implementation?Boost Spirit X3 跳过解析器实现?
【发布时间】:2016-02-09 22:53:44
【问题描述】:

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

在我看来,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. 这样的实现是否存在性能问题?如何改进?

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

【问题讨论】:

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


    【解决方案1】:

    是的,没关系。

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

    【讨论】:

    • 感谢优化提示和答案。
    • 也许space_comment 最好使用seek directive?
    • 好的。手机很难用。 “我不建议依赖不受支持的贡献者代码” ...
    • 存储库是否包含质量差的代码?我在上面提出它不是为了优化,而是出于可读性的原因。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多