Parsing 使用Boost Spirit解析,获得额外项目
这很长,有很多代码,所以我希望堆栈溢出可以解决这一问题:P 我正试图用Boost Spirit编写一个SVG解析器。我有一个用“轮廓”填充向量的语法,轮廓是“bezier点”的向量,可以表示常规点,也可以表示带有bezier控件的点 到目前为止,我有以下内容(尚未处理相对绘图命令): 重新格式化字符串以使其更易于阅读:Parsing 使用Boost Spirit解析,获得额外项目,parsing,boost,boost-spirit,boost-spirit-qi,boost-phoenix,Parsing,Boost,Boost Spirit,Boost Spirit Qi,Boost Phoenix,这很长,有很多代码,所以我希望堆栈溢出可以解决这一问题:P 我正试图用Boost Spirit编写一个SVG解析器。我有一个用“轮廓”填充向量的语法,轮廓是“bezier点”的向量,可以表示常规点,也可以表示带有bezier控件的点 到目前为止,我有以下内容(尚未处理相对绘图命令): 重新格式化字符串以使其更易于阅读: M 26.591, 0 L 0 , 22.348 l 25.46 , 23.479 L 12.306, 100 l 36.067, -23.619 L 85.00
M 26.591, 0
L 0 , 22.348
l 25.46 , 23.479
L 12.306, 100
l 36.067, -23.619
L 85.008, 28.43
L 26.591, 0
z
M 30.553, 34.23
l -8.487, -10.467
l 9.052, -5.234
l 25.601, 8.77
l -3.109, 12.729
L 30.553, 34.23
z
以下是输出:
Path:
77, 0
26.591, 0
76, 0
0, 22.348
108, 0
25.46, 23.479
76, 0
12.306, 100
108, 0
36.067, -23.619
76, 0
85.008, 28.43
76, 0
26.591, 0
Path:
77, 0
30.553, 34.23
108, 0
-8.487, -10.467
108, 0
9.052, -5.234
108, 0
25.601, 8.77
108, 0
-3.109, 12.729
76, 0
30.553, 34.23
语法已经看到了要点,但它一直在增加这些额外的要点,我不知道它们来自哪里
附笔。
我还想知道我的一些规则。首先有一条规则:
qi::rule<Iterator, BezierVec()> drawto_commands;
qi::rule<Iterator, BezierVec()> drawto_command;
...
drawto_commands = (drawto_command[
insert(_val, end(_val), begin(_1), end(_1))
] % *space) >> *space >> -closepath;
我有两条规则给出了一个BezierVec,我想把它合并成一个BezierVec作为第三条规则。到目前为止,实现这一点的唯一方法似乎是使用Phoenix手动插入。没有更简单的方法吗?输出中的附加值是从ASCII字符
'M'==77
,'L'==76
,'L'==108
等生成的。当您使用字符('M')
等匹配这些字符时,会发生这种情况,这将匹配的值作为字符
属性公开。编译器很高兴地将其分配给输出数组中的双值。为了避免这种情况,请使用lit('M')
,或仅使用'M'
。这两种方法都不公开任何属性,从而使表达式在生成的值方面保持中立
第二件可以改进的事情是从所有地方删除*空格
构造,并切换到短语解析(请参阅短语解析
API函数的文档)。如果您提供一个space
解析器组件作为skipper参数,并将space\u type
skipper模板类型参数添加到所有规则中,您将获得与语法中穿插的*space
构造相同的效果。例如:
qi::rule<Iterator, Contours(), space_type> path_data;
这已经假设您切换到短语解析,因此我删除了*空格
结构。为什么这样做有效?好的,Spirit.Qi对序列有一个特殊的属性传播规则,如果序列中的所有元素都公开了该属性类型或这些属性类型的容器,那么它必须将其元素公开的所有属性附加到提供的容器中。这里不需要语义操作。注意,这仅适用于序列,而不适用于单元素右侧构造
您的第二个相关问题可以用类似的方式解决:
moveto_drawto_command_group = moveto >> -drawto_commands;
同样,不需要语义操作
qi::rule<Iterator, BezierVec()> drawto_commands;
qi::rule<Iterator, BezierVec()> drawto_command;
...
drawto_commands = (drawto_command[
insert(_val, end(_val), begin(_1), end(_1))
] % *space) >> *space >> -closepath;
qi::rule<Iterator, BezierVec()> moveto_drawto_command_group;
qi::rule<Iterator, BezierVec()> moveto;
qi::rule<Iterator, BezierVec()> moveto_argument_sequence;
...
moveto_drawto_command_group = moveto[
insert(_val, end(_val), begin(_1), end(_1))
] >> *space
>> -drawto_commands[
insert(_val, end(_val), begin(_1), end(_1))
];
qi::rule<Iterator, Contours(), space_type> path_data;
drawto_commands = +drawto_command >> -closepath;
moveto_drawto_command_group = moveto >> -drawto_commands;