【发布时间】:2015-03-09 22:11:07
【问题描述】:
我在指定和解析一个相当简单的语法时遇到了一些问题。
vertex = char+
edge = vertex " -> " vertex
start = ((vertex | edge) eol)*
input = "a\nb\na -> b\n"
Spirit 正在做以下事情:
"a" -> vertex
"\n" -> eol
-> start
"b" -> vertex
"\n" -> eol
-> start
和
"a" -> vertex
terminate
而不是最终识别边缘并解析整个输入。 也就是说,它可以解析整个输入,但事实并非如此。 它不应该回溯并尝试使用备用规则进行解析吗?从而完成启动规则。
是因为 Spirit 使用 PEG 吗? (http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/abstracts/parsing_expression_grammar.html#spirit.abstracts.parsing_expression_grammar.alternatives)
最小的工作示例:
#include <cstdio>
#include <string>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
void print(const std::string & str) {
printf("%s\n", str.c_str());
}
void print_eol() {
printf("eol\n");
}
int main() {
std::string str = "a\nb\na -> b\n";
std::string::iterator it = str.begin(), begin = str.begin(), end = str.end();
qi::rule<std::string::iterator, std::string()> vertex = +qi::alnum;
qi::rule<std::string::iterator, std::string()> edge = vertex >> " -> " >> vertex;
qi::rule<std::string::iterator> start = (vertex[&print] | edge[&print]) % qi::eol[&print_eol];
bool matched = parse(it, end, start);
if (matched) {
printf("matched\n");
}
if (it == end) {
printf("all\n");
} else if (it != begin) {
printf("some\n");
} else {
printf("none\n");
}
return 0;
}
输出:
$ ./a.out
a
eol
b
eol
a
matched
some
我在 MSYS2 上使用 Boost 1.57.0 和 Clang 3.5.1。
【问题讨论】:
-
我假设你的意思是提升 1.57.0 而不是 1.57
-
@harmic 呵呵呵呵。我假设您的意思是“不是 1.5.7”,而不是“不是 1.57”o.O
标签: c++ boost boost-spirit boost-spirit-qi