如何在Boost.Spirit中跳过换行/块/嵌套块注释?

4
使用Boost.Spirit解析语言时,如何确保跳过某些内容?
// line comments

/* block
   comments */ and

/* /* nested
   block */ comments */

在阅读代码时?目前,我只是将phrase_parse应用于预定义的qi::grammar中。我猜我需要一种跳过词法分析器,对吧?


没错。Confix解析器可能会很有用。这里有一个例子:http://www.boost.org/doc/libs/1_64_0/libs/spirit/repository/example/qi/confix.cpp - Dan Mašek
1个回答

7

无需词法分析器。

以下是一个示例语法,实现了它:跨平台获取INI文件中包含指定选项的行号的方法,但是您也可以使用类似于这样的跳过器:

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<>异常。

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

演示

在 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

添加了一个演示Live On Coliru - sehe
1
参考此链接中的问题:https://stackoverflow.com/questions/59512152/skippers-in-boost-spirit-x3。 - Michaël

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接