Search code examples
yamlyaml-cppsnakeyaml

yaml scientific notation syntax


While working with a yaml document, I found that one of my values was getting parsed as a string with snakeyaml:

-8e-05

I found that ros, which uses yaml-cpp to write yamls is using the following code to write an array

out << YAML::BeginSeq;
for (int i = 0; i < m.rows*m.cols; ++i)
  out << m.data[i];
out << YAML::EndSeq;

but the c++ code above (copied from ros "parse_yml.cpp" in the camera_calibration package) creates -8e-05 while snakeyaml parses it as a string.

So who's right, should there be a bug report? if so to who? The 1.2 yaml specification seems to allow for optional decimal, but I couldn't figure out if the 1.1 yaml spec allows it which snakeyaml implements.


Solution

  • The output should be parsed as !!float according to YAML 1.2, but originally was !!str in YAML 1.1; as @psr says, this is to match the JSON spec.

    The YAML 1.2 spec gives a JSON schema and an extension, the "core schema". In both cases, the !!float regular expression is:

    [-+]? ( \. [0-9]+ | [0-9]+ ( \. [0-9]* )? ) ( [eE] [-+]? [0-9]+ )?
    

    which allows for an optional decimal. (The core schema adds support for infinity and not-a-number.)

    The YAML 1.1 spec didn't specify this type of tag resolution directly, but it gave several related pages for each type. The !!float page lists the regular expression:

    [-+]?([0-9][0-9_]*)?\.[0-9.]*([eE][-+][0-9]+)?
    

    (as well as versions for base-60, infinity, and not-a-number). This appears to require the decimal.

    This has been fixed in SnakeYAML (see http://code.google.com/p/snakeyaml/issues/detail?id=130), as of version 1.9.