我试图使用Boost Spirit X3指令重复一个可变的重复因子.基本思想是标头+有效负载,其中标头指定有效负载的大小.一个简单的例子"3 1 2 3"被解释为header = 3,data = {1,2,3}(3个整数).
我只能从精神qi文档中找到例子.它使用boost phoenix引用来包装变量因子:http://www.boost.org/doc/libs/1_50_0/libs/spirit/doc/html/spirit/qi/reference/directive/repeat.html
std::string str;
int n;
test_parser_attr("\x0bHello World",
char_[phx::ref(n) = _1] >> repeat(phx::ref(n))[char_], str);
std::cout << n << ',' << str << std::endl; // will print "11,Hello World"
Run Code Online (Sandbox Code Playgroud)
我为精神x3写了以下简单的例子,没有运气:
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <iostream>
namespace x3 = boost::spirit::x3;
using x3::uint_;
using x3::int_;
using x3::phrase_parse;
using x3::repeat;
using x3::space;
using std::string;
using std::cout;
using std::endl;
int main( int argc, char **argv )
{ …Run Code Online (Sandbox Code Playgroud) 你能帮助我理解Boost.Spirit中a % b解析器和它的扩展a >> *(b >> a)形式之间的区别吗?即使参考手册指出它们是等效的,
列表运算符
a % b是一个二元运算符,它匹配a由出现次数分隔的一个或多个重复的列表b.这相当于a >> *(b >> a).
以下程序根据使用的结果产生不同的结果:
#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
struct Record {
int id;
std::vector<int> values;
};
BOOST_FUSION_ADAPT_STRUCT(Record,
(int, id)
(std::vector<int>, values)
)
int main() {
namespace qi = boost::spirit::qi;
const auto str = std::string{"1: 2, 3, 4"};
const auto rule1 = qi::int_ >> ':' >> (qi::int_ % ',') >> …Run Code Online (Sandbox Code Playgroud) 我想编写一个解析器(作为qi扩展),可以通过qi解析器表达式my_parser(p1, p2, ...)在哪里使用p1, p2, ....
实际上,我想实现一个best_match像qi替代方案一样工作的解析器,但不选择第一个匹配规则,而是选择"解释"大部分输入的规则.
给出两个规则simple_id = +(qi::alpha),complex_id = simple_id >> *(qi::string("::") > simple_id)它将选择complex_id输入willy::anton.这样做不会产生中间属性.这些好处可以通过运行时获得,因为需要前瞻解析.
在我看来,这种解析器构造有几个用例.benchmark(p1, ...)作为优化的支持解析器,只是一个例子.一旦我知道如何做,我会提供.
该解析器将是非终端的.我试过(努力),但我无法在气中找到我的问题的答案.我的猜测是,C++机制与c qi紧密集成,至少对我来说,没有可理解的切入点.
实现我想引入的操作符非常容易.我附上下面的当前解决方案.它按预期编译但不完整.
一个qi运算符得到一个fusion :: vector/sequence(无论如何)现成的并作用于它.似乎没有图书馆产品来解决我的问题.甚至make_nary_composite已经预计会编译args Elements.
我尝试了很多,一切都失败了,所以我不想厌烦你.
我能想象的一种解决方法可能是提供一个有状态的运算符,,这将成为p1, ...一个合法的qi表达式.然后实现unary_parser best_match或指令来处理该表达式.该,会得到两种模式:让输入电流(成功)解析器消耗的长度和实际分析所选择的一个从相1.包装什么是运行逗号解析器首先在模式1,然后在模式2,这可能是丑陋的,但可以工作.
p1 |= p2 |= ...对于n> 2的运行时,运算符实现是最昂贵的.我很乐意解决这个问题.
最小(但仍然是合理的)开销会有best_match(p1, ...).这有可能吗?
因为我对boost :: fusion没有太多经验,我还在代码中添加了一些问题(如何关于融合).
将一些实际上是一个非终端解析器的东西压入一元解析器方案中感觉不对.但由于我的理解不足,它似乎是完成它的唯一方法.我非常感谢帮助我摆脱困境.
我的环境:Boost 1.61,MSVC 2015 Upd 2,目标是win32console.
进展:
我想,我慢慢地,但肯定地得到它.我很高兴看到一个error_invalid_expression.由于以下proto表达式,编译失败:
boost::proto::exprns_::expr<
boost::proto::tagns_::tag::function,boost::proto::argsns_::list5< …Run Code Online (Sandbox Code Playgroud) 我正在和一个朋友为一个小型个人项目做翻译;我们开始实现所有的类和一般结构,在这些结构中代码将被翻译,然后执行只是为了将实际的解析代码推迟到这些结构中。
现在我们必须构建解析器,经过一番搜索,我发现到处都是关于灵气和灵气 X3 的帖子和人,好像它们是(我认为它们是)两种不同的方式来制作解析器,但没有一个说不同,哪个更近,我应该从哪个开始。
目的是,给定一个代码字符串,输出最终错误,如果一切都遵守语法和逻辑,则将代码转换为我们已经构建的类的树。我们想在解析过程中检查一致性,例如“您正在使用未声明的变量”类型的错误。
我不确定这两个库如何以不同的方式对待事物。