结肠后Yaml-cpp解析没有工作空间丢失

时间:2014-09-03 11:08:20

标签: c++ parsing yaml yaml-cpp

我在yaml-cpp解析器中遇到了问题。当我尝试加载以下定义时:

DsUniversity:
  university_typ: {type: enum, values:[Fachhochschule, Universitat, Berufsakademie]}
  students_at_university: {type: string(50)}

我收到了以下错误:

Error: yaml-cpp: error at line 2, column 39: end of map flow not found

我尝试验证http://yaml-online-parser.appspot.com/http://yamllint.com/的yaml有效性,并且两个服务都将yaml报告为有效。

问题是由“values:”定义后的空格丢失引起的。当yaml更新为以下格式时:

DsUniversity:
  university_typ: {type: enum, values: [Fachhochschule, Universitat, Berufsakademie]}
  students_at_university: {type: string(50)}

一切都按预期工作。

有没有办法如何配置/更新/修复yaml-cpp解析器以继续结肠后缺少空格的yamls?

添加了: 似乎问题是由空char作为分隔符的要求引起的。当我将测试片段简化为

DsUniversity:[Fachhochschule, Universitat, Berufsakademie]

yaml-cpp解析器将其读作标量值“DsUniversity:[Fachhochschule,Universitat,Berufsakademie]”。当冒号后添加空char时,yaml-cpp正确加载带序列的元素。

1 个答案:

答案 0 :(得分:5)

yaml-cpp在这里是正确的,那些在线验证器是不正确的。来自YAML 1.2 spec

  

7.4.2。流映射

     

通常,YAML坚持使用空格将“:”映射值指示符与值分开。这种限制的好处是“:”字符可以在普通标量中使用,只要它后面没有空格。这允许不带引号的URL和时间戳。它也是混淆的潜在来源,因为“a:1”是一个普通的标量,而不是一个关键:价值对。

     

...

     

为确保JSON兼容性,如果流映射中的键是类JSON ,则YAML允许在“:”旁边指定以下值。这不会引起歧义,因为所有类似JSON的键都被指示符包围。但是,由于这大大降低了可读性,YAML处理器应该在输出中将值与“:”分开,即使在这种情况下也是如此。

在您的示例中,您处于流程映射(意味着由{}包围的地图),但您的密钥不是 JSON-like :你只有一个普通的标量(values是不加引号的)。要像JSON一样,密钥需要是单引号或双引号,或者它可以是嵌套的流序列或映射本身。

在您的简化示例中,

DsUniversity:[Fachhochschule, Universitat, Berufsakademie]

yaml-cpp和在线验证器都将其正确解析为单个标量 - 为了成为地图,您需要在:之后需要一个空格。

为什么YAML需要那个空间?

在简单的标量案例中:

a:b

可能含糊不清:它可以被读作标量a:b或地图{a: b}。 YAML选择将其作为标量阅读,以便可以在不引用的情况下轻松地将URL嵌入到YAML中:

http://stackoverflow.com

是一个标量(就像你期待的那样),而不是地图{http: //stackoverflow.com}

在流程上下文中,有一种情况不明确:当引用密钥时,例如:

{"a":b}

这称为类JSON ,因为它类似于JSON,它需要围绕所有标量的引号。在这种情况下,YAML知道密钥在结束引用处结束,因此可以确保该值立即开始。

这种行为是明确允许的,因为JSON本身允许像

这样的东西
{"a":"b"}

由于YAML 1.2是JSON的严格超集,因此在YAML中必须是合法的。