X3:这个解析器 *(char - eol) 是否消耗所有行?
X3: Is this parser, *(char - eol), consuming any and all lines?
我的应用程序基于此示例并获得了完全相同的结果。由于某种原因,输入字符串的内容全部被解析到融合结构'comments'中,而没有任何内容被解析到融合结构'numbers'中。所以不确定我哪里出错了。
namespace client {
namespace ast {
struct number {
int num1;
int num2;
};
struct comment {
std::string text;
bool dummy;
};
struct input {
std::vector<comment> comments;
std::vector<number> numbers;
};
}
}
BOOST_FUSION_ADAPT_STRUCT(client::ast::comment, text, dummy)
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, num1, num2)
BOOST_FUSION_ADAPT_STRUCT(client::ast::input, comments, numbers)
namespace client {
namespace parser {
namespace x3 = boost::spirit::x3;
using namespace x3;
x3::attr_gen dummy;
typedef std::string::const_iterator It;
using namespace x3;
auto const comment = *(char_ - eol) >> dummy(false);
auto const number = int_ >> int_;
auto lines = [](auto p) { return *(p >> eol); };
auto const input =
lines(comment) >>
lines(number);
}
}
int main()
{
namespace x3 = boost::spirit::x3;
std::string const iss("any char string here\n1 2\n");
auto iter = iss.begin(), eof = iss.end();
client::ast::input types;
bool ok = parse(iter, eof, client::parser::input, types);
if (iter != eof) {
std::cout << "Remaining unparsed: '" << std::string(iter, eof) << "'\n";
}
std::cout << "Parsed: " << (100.0 * std::distance(iss.begin(), iter) / iss.size()) << "%\n";
std::cout << "ok = " << ok << std::endl;
// This range loop prints all contents if input.
for (auto& item : types.comments) { std::cout << "comment: " << boost::fusion::as_deque(item) << "\n"; }
// This loop prints nothing.
for (auto& item : types.numbers) { std::cout << "number: " << boost::fusion::as_deque(item) << "\n"; }
}
我的大型应用程序对大型输入文件和多个 AST 执行相同的操作,但似乎我的所有示例都被评论解析器使用了。
这是完整的 运行 示例。
http://coliru.stacked-crooked.com/a/f983b26d673305a0
想法?
你从我这里的回答中吸取了语法思想:
它起作用了,因为行格式没有歧义。事实上,您需要特别注意 "variant" 方法,我在本项目符号中指出:
- departments need to be ordered before teams, or you get "team" matched instead of departments
你的语法中也存在同样的歧义。 *(char_ - eol)
匹配 "1 2"
就好了,所以很明显它是作为注释添加的。您将不得不消除语法歧义或以某种方式强制切换到 "parse number lines now" 模式。
如果您完全不关心数字行之前的内容,只需使用 x3::seek [ lines(number) ]
。
我的应用程序基于此示例并获得了完全相同的结果。由于某种原因,输入字符串的内容全部被解析到融合结构'comments'中,而没有任何内容被解析到融合结构'numbers'中。所以不确定我哪里出错了。
namespace client {
namespace ast {
struct number {
int num1;
int num2;
};
struct comment {
std::string text;
bool dummy;
};
struct input {
std::vector<comment> comments;
std::vector<number> numbers;
};
}
}
BOOST_FUSION_ADAPT_STRUCT(client::ast::comment, text, dummy)
BOOST_FUSION_ADAPT_STRUCT(client::ast::number, num1, num2)
BOOST_FUSION_ADAPT_STRUCT(client::ast::input, comments, numbers)
namespace client {
namespace parser {
namespace x3 = boost::spirit::x3;
using namespace x3;
x3::attr_gen dummy;
typedef std::string::const_iterator It;
using namespace x3;
auto const comment = *(char_ - eol) >> dummy(false);
auto const number = int_ >> int_;
auto lines = [](auto p) { return *(p >> eol); };
auto const input =
lines(comment) >>
lines(number);
}
}
int main()
{
namespace x3 = boost::spirit::x3;
std::string const iss("any char string here\n1 2\n");
auto iter = iss.begin(), eof = iss.end();
client::ast::input types;
bool ok = parse(iter, eof, client::parser::input, types);
if (iter != eof) {
std::cout << "Remaining unparsed: '" << std::string(iter, eof) << "'\n";
}
std::cout << "Parsed: " << (100.0 * std::distance(iss.begin(), iter) / iss.size()) << "%\n";
std::cout << "ok = " << ok << std::endl;
// This range loop prints all contents if input.
for (auto& item : types.comments) { std::cout << "comment: " << boost::fusion::as_deque(item) << "\n"; }
// This loop prints nothing.
for (auto& item : types.numbers) { std::cout << "number: " << boost::fusion::as_deque(item) << "\n"; }
}
我的大型应用程序对大型输入文件和多个 AST 执行相同的操作,但似乎我的所有示例都被评论解析器使用了。
这是完整的 运行 示例。
http://coliru.stacked-crooked.com/a/f983b26d673305a0
想法?
你从我这里的回答中吸取了语法思想:
它起作用了,因为行格式没有歧义。事实上,您需要特别注意 "variant" 方法,我在本项目符号中指出:
- departments need to be ordered before teams, or you get "team" matched instead of departments
你的语法中也存在同样的歧义。 *(char_ - eol)
匹配 "1 2"
就好了,所以很明显它是作为注释添加的。您将不得不消除语法歧义或以某种方式强制切换到 "parse number lines now" 模式。
如果您完全不关心数字行之前的内容,只需使用 x3::seek [ lines(number) ]
。