我在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正确加载带序列的元素。
答案 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和在线验证器都将其正确解析为单个标量 - 为了成为地图,您需要在:
之后需要一个空格。
在简单的标量案例中:
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中必须是合法的。