tutorial - Archivos Parse YAML en C++
yaml-cpp (4)
Ejemplo C - analizar el árbol YAML a un "árbol N-aria" simplista :
#include <yaml.h>
#include <stdio.h>
#include <glib.h>
void process_layer(yaml_parser_t *parser, GNode *data);
gboolean dump(GNode *n, gpointer data);
int main (int argc, char **argv) {
char *file_path = "test.yaml";
GNode *cfg = g_node_new(file_path);
yaml_parser_t parser;
FILE *source = fopen(file_path, "rb");
yaml_parser_initialize(&parser);
yaml_parser_set_input_file(&parser, source);
process_layer(&parser, cfg); // Recursive parsing
yaml_parser_delete(&parser);
fclose(source);
printf("Results iteration:/n");
g_node_traverse(cfg, G_PRE_ORDER, G_TRAVERSE_ALL, -1, dump, NULL);
g_node_destroy(cfg);
return(0);
}
enum storage_flags { VAR, VAL, SEQ }; // "Store as" switch
void process_layer(yaml_parser_t *parser, GNode *data) {
GNode *last_leaf = data;
yaml_event_t event;
int storage = VAR; // mapping cannot start with VAL definition w/o VAR key
while (1) {
yaml_parser_parse(parser, &event);
// Parse value either as a new leaf in the mapping
// or as a leaf value (one of them, in case it''s a sequence)
if (event.type == YAML_SCALAR_EVENT) {
if (storage) g_node_append_data(last_leaf, g_strdup((gchar*) event.data.scalar.value));
else last_leaf = g_node_append(data, g_node_new(g_strdup((gchar*) event.data.scalar.value)));
storage ^= VAL; // Flip VAR/VAL switch for the next event
}
// Sequence - all the following scalars will be appended to the last_leaf
else if (event.type == YAML_SEQUENCE_START_EVENT) storage = SEQ;
else if (event.type == YAML_SEQUENCE_END_EVENT) storage = VAR;
// depth += 1
else if (event.type == YAML_MAPPING_START_EVENT) {
process_layer(parser, last_leaf);
storage ^= VAL; // Flip VAR/VAL, w/o touching SEQ
}
// depth -= 1
else if (
event.type == YAML_MAPPING_END_EVENT
|| event.type == YAML_STREAM_END_EVENT
) break;
yaml_event_delete(&event);
}
}
gboolean dump(GNode *node, gpointer data) {
int i = g_node_depth(node);
while (--i) printf(" ");
printf("%s/n", (char*) node->data);
return(FALSE);
}
Quiero un tutorial simple para mostrarme que cargue un archivo yaml y analice los datos. El estilo de expatriado sería genial, pero cualquier solución que realmente me muestre los datos de alguna forma sería útil.
Hasta el momento, ejecuté pruebas múltiples en la fuente yaml-0.1.1 para C y obtuve un error, sin salida alguna, o en el caso run-emitter.c. Lee en el archivo yaml y lo imprime en STDOUT, no produce el texto a través de funciones / estructuras libyaml. En los casos con un error, no sé si fue si el archivo era incorrecto o si mi compilación es incorrecta (no modifiqué nada ...) El archivo fue copiado de yaml.org
¿Alguien puede indicarme un tutorial? (Busqué en Google durante al menos 30 minutos leyendo cualquier cosa que pareciera relevante) o un nombre de una lib que tiene un buen tutorial o ejemplo. Quizás puedas decirme qué prueba de libyaml se carga en archivos y hace algo con ella o por qué recibí errores. Este documento no explica cómo usar el archivo, solo cómo cargarlo.
He escrito un tutorial en http://wpsoftware.net/andrew/pages/libyaml.html .
Esto cubre los aspectos básicos del uso de libyaml en C, utilizando un análisis basado en token y basado en eventos. Incluye código de muestra para generar el contenido de un archivo YAML.
Una búsqueda de código de Google (ahora desaparecida) para "yaml load lang: c ++" dio este como el primer enlace: demo.cc :
#include <iyaml++.hh>
#include <tr1/memory>
#include <iostream>
#include <stdexcept>
using namespace std;
// What should libyaml++ do when a YAML entity is parsed?
// NOTE: if any of the event handlers is not defined, a respective default
// no-op handler will be used. For example, not defining on_eos() is
// equivalent to defining void on_eos() { }.
class my_handler : public yaml::event_handler {
void on_string(const std::string& s) { cout << "parsed string: " << s << endl; }
void on_integer(const std::string& s) { cout << "parsed integer: " << s << endl; }
void on_sequence_begin() { cout << "parsed sequence-begin." << endl; }
void on_mapping_begin() { cout << "parsed mapping-begin." << endl; }
void on_sequence_end() { cout << "parsed sequence-end." << endl; }
void on_mapping_end() { cout << "parsed mapping-end." << endl; }
void on_document() { cout << "parsed document." << endl; }
void on_pair() { cout << "parsed pair." << endl; }
void on_eos() { cout << "parsed eos." << endl; }
};
// ok then, now that i know how to behave on each YAML entity encountered, just
// give me a stream to parse!
int main(int argc, char* argv[])
{
tr1::shared_ptr<my_handler> handler(new my_handler());
while( cin ) {
try { yaml::load(cin, handler); } // throws on syntax error
catch( const runtime_error& e ) {
cerr << e.what() << endl;
}
}
return 0;
}
Pruebe yaml-cpp (como lo sugiere esta pregunta ) para un analizador de C ++.
Divulgación: soy el autor.
Sintaxis de ejemplo (del Tutorial ):
YAML::Node config = YAML::LoadFile("config.yaml");
if (config["lastLogin"]) {
std::cout << "Last logged in: " << config["lastLogin"].as<DateTime>() << "/n";
}
const std::string username = config["username"].as<std::string>();
const std::string password = config["password"].as<std::string>();
login(username, password);
config["lastLogin"] = getCurrentDateTime();
std::ofstream fout("config.yaml");
fout << config;