cocos2d-x 高效稳定的 YAML 解析器

Posted

技术标签:

【中文标题】cocos2d-x 高效稳定的 YAML 解析器【英文标题】:Efficient and stable YAML parser for cocos2d-x 【发布时间】:2013-11-26 09:35:00 【问题描述】:

我正在使用 cocos2d-x 和 C++ 开发游戏,我需要为此应用程序加载一堆 YAML 文件。我尝试使用yaml-cpp 库,结果非常好。

问题是这个库似乎非常不稳定(至少在 ios 上的 cocos2d-x 下),因为几乎 20% 的时间它无法加载相同的 YAML 文件并抛出“未找到地图结尾”、“无效地图元素”,或类似的错误。

我遵循了HowToParseADocument 指南,所以我认为我的理解是正确的。但是,由于它不是 100% 可靠的,我正在寻找更稳定的东西。例如:

long size = 0;
unsigned char *yaml = FileUtils::getInstance()->getFileData("file.yml", "r", &size);
std::stringstream is;
is << yaml;

YAML::Parser parser(is);
YAML::Node doc;
while(parser.GetNextDocument(doc)) 
  instance->settings = doc.Clone();

解析器通常在parser.GetNextDocument(doc) 调用时中断。我要阅读的文档是带有key: value 列表的纯 YAML,格式如下:

# Comment
section1:
  param1: value1
  param2: value2

# Comment
section2:
  param1: value1
  param2: value2

编辑

我不允许透露原始 YAML 文件的内容,但我可以给你一些信息:

    它只包含映射,而不包含数组、别名或其他特定结构 那些values 是整数、浮点数或字符串 它已被this free tool linted,成功。

我用来阅读它的代码,贴在那里,它总是采用这种形式,我不会修改它以使应用程序正确运行。只是应用程序启动并工作或启动但不工作。由于我中间什么都没改变,我真的不明白发生了什么。

【问题讨论】:

你现在如何使用 yaml 解析器?也许您通过引用传入一个对象,该对象成为一个悬空指针,解析器最终从被覆盖的内存中读取。这是一种可能。 我正在使用它,如问题所示(我扩展了这段代码以包括源文件打开)。与指南中显示的内容没有什么不同。在第一次调用解析器时,它会中断(并非总是如此)。 我想这可能是 CR/LF 类型问题,或者文本文件可能被编码为 UTF16 或 YAML 解析器未正确处理的其他编码。或者混合制表符和空格。只是猜测。 问题不在于我无法阅读它。它可以正确读取,但 20% 的时间 yaml-cpp 库会中断。我的意思是,我启动了应用程序,它很好。又一次,仍然很好。第三次断了。等等…… 您能否发布您正在使用的 exact YAML 文件和 exact 代码?如果文件或代码太大,请尝试将其缩减,直到获得可以在此处发布的内容。 (如果当你删除某些东西时它停止破坏,那么也在这里发布发生的事情,因为这是一个有用的线索!) 【参考方案1】:

解决方案有点难以猜测,因为您不会提供实际示例,但是:

谁拥有getFileData 返回的unsigned char* 处的数据?如果这个函数本身拥有数据,那么在函数返回后它就不再有效,那么各种疯狂的事情就可能发生。

要验证这里发生了什么(除了查看getFileData 的实现),您可以在调用YAML::Parser parser(is); 之前打印出is.string(),看看是否打印出预期的YAML。

【讨论】:

getFileData 函数在这里定义:github.com/cocos2d/cocos2d-x/blob/develop/cocos/2d/platform/…。 unsigned char * 对象仅存在于该函数中,并且仅在该函数中使用,如图所示。 好的,is.str() 输出显示当前两个不同的文件已在该流中“合并”。奇怪的事实是,我正在使用不同的类和静态方法读取两个不同的 YAML 文件,它们只是共享来自 cocos2d-x 框架的FileUtils 调用。 这似乎是cocos2d-x的一个错误,但我不明白为什么该函数能够合并两个单独的内存分配。 当你用 cocos2d-x 提交 bug 时,你能把 bug tracker 的链接贴在这里吗?这将帮助其他有同样问题的人。

以上是关于cocos2d-x 高效稳定的 YAML 解析器的主要内容,如果未能解决你的问题,请参考以下文章

Helm 升级引发 YAML 解析器错误

PHP YAML 解析器 [关闭]

Java端ACM输入解析器(高效)

你如何防止 yaml-cpp 解析器删除所有注释?

C libyaml 基于文档的解析

Yaml 中的三元运算符