无需词法分析器。
以下是一个示例语法,实现了它:跨平台获取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