Parsing 使用Boost Spirit解析,获得额外项目

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

这很长,有很多代码,所以我希望堆栈溢出可以解决这一问题: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.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;