【问题标题】:Boost Spirit and abstract syntax tree designBoost Spirit 和抽象语法树设计
【发布时间】:2013-02-14 16:03:37
【问题描述】:

我正在使用来自 Boost Spirit 的 Qi 来解析 VRML 1.0。有一个名为 Separator 的组节点,在 Separator 下方,可以容纳许多不同类型的节点。 AST 基于 Boost.Variant,到目前为止看起来很长。我已接近变体中 20 种类型的限制。我知道我可以扩展变体的类型数量,但我确信必须有更好的方法来设计它。欢迎提出想法。

typedef boost::variant<
    Nil,
    Coordinate3,
    Info,
    Material,
    MaterialBinding,
    Normal,
    NormalBinding,
    Texture2,
    Texture2Transform,
    TextureCoordinate2,
    ShapeHints,
    MatrixTransform,
    Rotation,
    Scale,
    Transform,
    Translation,
    boost::recursive_wrapper<Separator>
> VRML1Node;

【问题讨论】:

    标签: c++ boost boost-spirit abstract-syntax-tree boost-variant


    【解决方案1】:

    您确定没有过早优化?根据我的经验,变体的“认知开销”不会随着变体中元素类型的数量而增加[1]

    你可能想要

    Use a type sequence to specify bounded types

    typedef mpl::vector< Coordinate3 > types_initial;
    typedef mpl::push_front< types_initial, Nil >::type types;
    
    boost::make_variant_over< types >::type VRML1Node;
    

    或者

    在这种情况下,您可以选择动态多态,而不是静态多态。

    根据您的使用情况,性能不一定会受到严重影响。主要区别是

    1. 要获得完全可优化的访问者代码,您需要在变体现在为您执行类型擦除的情况下使用动态转换
    2. 内存分配的局部性可能不太理想(尽管自定义分配器可能会减轻您的负担)
    3. 实际上可能会改善存储要求(变体必须适应最大的元素类型;当大多数元素类型实际上更小时,将有效分配更少的内存)。

      1. 在实际方面,您可能必须使用 Phoenix(语义操作)来正确分配属性

    我不推荐,但很明显你甚至可以使用boost::any

    struct poorMansVariant
    {
          TypeCode discriminator; // TypeCode::Nil, TypeCode::Coordinate3...
          boost::any value;
    };
    

    [1] 虽然当某些元素类型是可转换/可分配的,或者一般来说,它们的构造函数变得不明确时,情况可能会变得稍微复杂一些。但这是另一个话题

    【讨论】:

    • sehe,我希望您能回答,因为我在其他地方看到了您的宝贵回复!对于第一个建议,我需要通过更改预处理器符号来增加 mpl/variant 中的类型数量,对吧?在回复this question 时,您建议有太多类型可能表明设计不佳,因此我试图找出最好的办法。在替代建议中,我的属性类型是否是指针和执行新的语义操作?
    • @PeteUK 是的:替代方法假定动态实例化(想想 smart 指针)。关于“糟糕的设计”,我想说,如果你自己设计了语法。在这种情况下,你只需要处理它,我猜 :) 我不知道 VRML 是什么样的,但这种语法似乎是极端通用性和高度特异性的不平衡组合。如果你明白我的意思。
    • 我将尝试在了解所有具体节点类型的情况下继续使用变体,并在必要时增加类型数量的界限。我也在考虑将一些节点“折叠”成 Separator 节点类型。例如,ShapeHints 和 Info 可以是 Separator 的属性,因为在 Separator AIUI 中只会指定一个 ShapeHints。我想这将需要语义动作和戳分离器融合序列中的位置。感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-11
    相关资源
    最近更新 更多