如何在Boost.Spirit中跳过line / block / nested-block注释?

时间:2017-06-13 19:19:32

标签: c++ boost boost-spirit boost-spirit-qi

使用Boost.Spirit解析语言时,如何确保跳​​过

// line comments

/* block
   comments */ and

/* /* nested
   block */ comments */

在阅读代码时?目前,我只是phrase_parse进入预定义的qi::grammar。我想我需要的是某种跳过词法分析器,对吗?

1 个答案:

答案 0 :(得分:4)

不需要词法分析器。

以下是实现它的示例语法:Cross-platform way to get line number of an INI file where given option was found,但无论您是否可以使用这样的队长:

using Skipper = qi::rule<Iterator>;

Skipper block_comment, single_line_comment, skipper;

single_line_comment = "//" >> *(char_ - eol) >> (eol|eoi);
block_comment = "/*" >> *(block_comment | char_ - "*/") > "*/";

skipper = single_line_comment | block_comment;

当然,如果白色空间也可以跳过,请使用

skipper = space | single_line_comment | block_comment;

这支持嵌套的块注释,如果缺少qi::expectation_failure<>则抛出*/

请注意,它特别不支持以单行注释开始的块注释。

演示

<强> Live On Coliru

#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;

int main() {
    using Iterator = boost::spirit::istream_iterator;
    using Skipper  = qi::rule<Iterator>;

    Skipper block_comment, single_line_comment, skipper;

    {
        using namespace qi;
        single_line_comment = "//" >> *(char_ - eol) >> (eol|eoi);
        block_comment       = ("/*" >> *(block_comment | char_ - "*/")) > "*/";

        skipper             = space | single_line_comment | block_comment;
    }

    Iterator f(std::cin >> std::noskipws), l;

    std::vector<int> data;
    bool ok = phrase_parse(f, l, *qi::int_, skipper, data);
    if (ok) {
        std::copy(data.begin(), data.end(), std::ostream_iterator<int>(std::cout << "Parsed ", " "));
        std::cout << "\n";
    } else {
        std::cout << "Parse failed\n";
    }

    if (f!=l) {
        std::cout << "Remaining unparsed: '" << std::string(f,l) << "'\n";
    }
}

打印哪些:

Parsed 123 456 567 901 

给出输入

123 // line comments 234

/* block 345
   comments */ 456

567

/* 678 /* nested
   789 block */ comments 890 */

901