How to Parse YAML from Files or Input Streams with yaml-cpp
You can parse YAML in yaml‑cpp using the header‑only convenience functions YAML::Load, YAML::LoadFile, and YAML::LoadAll, which internally instantiate a Parser and NodeBuilder to transform any std::istream or file into a tree of YAML::Node objects.
The yaml‑cpp library (available at jbeder/yaml‑cpp) provides a high‑level C++ API for consuming YAML documents. Whether you are reading from strings, files, or arbitrary input streams, the library exposes a concise interface that hides a sophisticated pipeline of lexical scanning, directive processing, and node construction. Understanding this architecture helps you choose the right entry point for your specific use case.
The Internal Parsing Pipeline
When you call any of the public Load* functions, the library creates a Parser object that orchestrates the conversion from raw text to structured data. The flow through src/parser.cpp follows four distinct phases:
- Stream initialization – The
Parser::Parser(std::istream&)constructor (defined insrc/parser.cppat line 22) initializes aScannerover the supplied stream and prepares a freshDirectivescontainer to track%YAMLand%TAGdirectives. - Directive processing –
Parser::ParseDirectives(line 56) consumes any leading directives and stores them in theDirectivesobject. - Document parsing –
Parser::HandleNextDocument(line 27) instantiates aSingleDocParserthat walks the token stream, generates parsing events, and feeds them to anEventHandler. - Node construction – A
NodeBuilderreceives the events and assembles the finalNodetree, returning the root node to the caller.
This design deliberately separates lexical scanning (Scanner), directive handling (Directives), document parsing (SingleDocParser), and node construction (NodeBuilder), making the internals extensible while keeping the public API simple.
Public API Functions for Loading YAML
The convenient entry points are implemented in src/parse.cpp and declared in include/yaml-cpp/parser.h. Each function handles a specific source type:
YAML::Load(std::istream&)– The core entry point that constructs aParser, attaches aNodeBuilder, and invokesHandleNextDocumentto return a singleNode.YAML::Load(const std::string&)– Wraps the string in astd::stringstreamand forwards to the stream overload.YAML::Load(const char*)– Identical to the string version for C‑string literals.YAML::LoadFile(const std::string&)– Opens anstd::ifstream, throwsYAML::BadFileon failure, and forwards toLoad(stream).YAML::LoadAll(std::istream&)– Parses multiple YAML documents from a single stream, loopingHandleNextDocumentuntil exhaustion and collecting each root node into astd::vector<Node>.YAML::LoadAllFromFile(const std::string&)– Combines file opening with multi‑document parsing.
These functions are defined at lines 12, 17, 22, 32, 50, and 65 of src/parse.cpp respectively.
Parsing a Single Document from a File
For configuration files or single‑document inputs, use YAML::LoadFile. This function handles stream lifetime internally and throws YAML::BadFile if the file cannot be opened.
#include <yaml-cpp/yaml.h>
#include <iostream>
int main() {
try {
YAML::Node config = YAML::LoadFile("config.yaml");
std::cout << "Host: " << config["host"].as<std::string>() << "\n";
std::cout << "Port: " << config["port"].as<int>() << "\n";
} catch (const YAML::BadFile& e) {
std::cerr << "Cannot open file: " << e.what() << "\n";
} catch (const YAML::ParserException& e) {
std::cerr << "YAML error: " << e.what() << "\n";
}
}
Parsing Multiple Documents from a String
YAML streams may contain multiple documents separated by ---. The YAML::LoadAll family returns a std::vector<YAML::Node> containing each document’s root node.
#include <yaml-cpp/yaml.h>
#include <iostream>
int main() {
const char* yaml = R"(---
name: Alice
---
name: Bob
---)";
std::vector<YAML::Node> docs = YAML::LoadAll(yaml);
for (std::size_t i = 0; i < docs.size(); ++i) {
std::cout << "Doc " << i << " name: " << docs[i]["name"].as<std::string>() << "\n";
}
}
Streaming Parsing from Standard Input
Because YAML::Load accepts any std::istream&, you can parse directly from std::cin, a std::stringstream, or a custom stream implementation without intermediate buffering.
#include <yaml-cpp/yaml.h>
#include <iostream>
int main() {
std::cout << "Enter YAML (Ctrl-D to finish):\n";
YAML::Node root = YAML::Load(std::cin);
if (root["greeting"]) {
std::cout << "Greeting: " << root["greeting"].as<std::string>() << "\n";
}
}
Summary
- High‑level convenience –
YAML::Load,YAML::LoadFile, andYAML::LoadAllinsrc/parse.cppprovide the primary interface for parsing YAML from files or input streams. - Internal architecture – The library constructs a
Parser(insrc/parser.cpp) that drives aScannerandSingleDocParser, feeding events to aNodeBuilderto produce the finalNodetree defined ininclude/yaml-cpp/node/node.h. - Flexible input – All public functions accept
std::istream&, allowing seamless integration with files, strings, and standard input. - Error handling – Expect
YAML::BadFilefor filesystem errors andYAML::ParserExceptionfor malformed YAML content.
Frequently Asked Questions
How do I parse YAML from a string instead of a file?
Use YAML::Load(const std::string&). According to the implementation in src/parse.cpp (line 12), this overload creates a std::stringstream internally and forwards it to the core Load(std::istream&) function, so you do not need to manually wrap your string.
What is the difference between Load and LoadAll?
YAML::Load parses exactly one document from the stream and returns a single Node, whereas YAML::LoadAll continues reading after document boundaries (---) and returns a std::vector<Node> containing every document found in the stream. The implementation in src/parse.cpp (lines 50–65) shows that LoadAll simply loops HandleNextDocument until the scanner reports no more content.
Can I parse from a custom C++ stream class?
Yes. Because YAML::Load takes a std::istream& reference (as seen in src/parse.cpp line 22), any class inheriting from std::istream—including std::stringstream, std::ifstream, or your own custom implementation—works transparently with the parser.
What exceptions should I catch when loading a file?
Catch YAML::BadFile (thrown in LoadFile at src/parse.cpp line 32 when the std::ifstream fails to open) and YAML::ParserException (thrown by the Parser or SingleDocParser when encountering invalid YAML syntax). Catching std::exception will also handle these cases, but specific catches allow more granular error reporting.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →