从Boost::spirit解析返回多个数据类型

Returning multiple data types from Boost::spirit parse

本文关键字:返回 数据类型 Boost spirit      更新时间:2023-10-16

我想解析大约5-10种不同的消息类型,它们共享一种通用格式(例如JSON),但每个类型都有需要验证的特定字段。每个消息最终都应该被解析为一个自定义类/结构,该类/结构的类型不需要任何类型的强制转换(例如,字段是int而不是变体/元组)。我看到了两种解决问题的方法:

  1. 为每个特定消息编写一个语法,处理消息格式(本例中为JSON样板)的验证和字段内容的验证,返回一个真正自定义的结构

  2. 编写一个语法,只验证结构(只验证JSON规则),并返回一个更通用的对象(具有变体/元组等字段),并在更高级别验证/转换为自定义结构(强制转换和检查各种变体字段)

我认为这是每种方法的优缺点:

优点1:

  • 所有验证都在boost::spirit内完成
  • 因果报应生成器(如果编写)看起来像现有的精神解析代码

1的缺点:

  • 必须为未来可能发明的每一种新消息类型编写和维护一种新的语法(而且精神语法不是直观的)

2的优点:

  • 复杂的精神密码只写一次,很少触及

2的缺点:

  • 通用消息对象的验证和翻译将是混乱的代码,spirit本应首先消除这些代码

哪种方法更可取?有没有第三种方法可以使用一种语法解析为多种类型?

以下是一些示例消息和它们最终应该驻留的类:

{"messageType": "messageTypeA", "numberParam": 1}
{"messageType": "messageTypeB", "stringParam": "Test"}
class MessageTypeA
{
public:
    double numberParam;
};
class MessageTypeB
{
public:
    std::string stringParam;
};

我认为这个问题非常接近最近的答案,我正是这样做的:我用两个答案回答:

  1. 答案#1采取通才方法,只根据特定的"方案"进行解释
  2. 答案2采取特别方法,OP认为这更容易

我投票支持第一个选项,因为

  • 在我的经验中,"复杂的代码只写一次,测试一次,很少接触"超过了其他因素
  • 事实上,语法从分离的职责和保持AST真正接近自然规则属性中受益匪浅
  • 我已经为我的Fusion适配类型(使用Fusion"反射")编写了多种"风格"的JSON后端(OData、Edm、版本、元数据级别)。这些共享相同的解析器/生成器

即使是相关问题中的OP后来似乎也需要我的第一个答案所提供的灵活性:

哦,好吧。我很惊讶你接受了这个答案,因为另一个答案完全一样,只是它接受并忽略了"其他"JSON内容。您是否错过了定义extract_from的更新?它使用的数据结构与您在问题中建议的完全相同–1月4日下午16:41