1

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

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

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

我认为这些是每个的优点和缺点:

优点 1:

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

缺点 1:

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

2的优点:

  • 复杂的精神代码只写一次,很少接触

缺点 2:

  • 通用消息对象的验证和翻译将是精神应该首先消除的混乱代码

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

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

{"messageType": "messageTypeA", "numberParam": 1}
{"messageType": "messageTypeB", "stringParam": "Test"}

class MessageTypeA
{
public:
    double numberParam;
};

class MessageTypeB
{
public:
    std::string stringParam;
};
4

1 回答 1

0

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

  1. 答案#1采用通才方法,仅根据特定的“方案”进行解释
  2. 答案 #2采用临时方法,OP 认为这更容易

我的投票是第一个选项,因为

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

甚至链接问题中的 OP 似乎后来也需要我的第一个答案已经提供的灵活性:

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

于 2015-02-25T02:52:01.497 回答