tags:

views:

1485

answers:

4

I cant believe i spent two hours and not found a solution. I want a simple tutorial to show me to load a yaml file and parse the data. Expat style would be great but any solution that actually shows me the data in some form would be useful.

So far i ran multiple test in yaml-0.1.1 source for C and i either get an error, no output whatso ever or in run-emitter.c case. It reads in the yaml file and prints it to STDOUT, it does not produce the text via libyaml functions/structs (WTF!). In the cases with an error i dont know if it was bc the file was bad or my build is incorrect (i didnt modify anything...) The file was copied from yaml.org

Can anyone point me to a tutorial? (i googled for at least 30mins reading anything that looked relevent) or a name of a lib that has a good tutorial or example. Maybe you can tell me which libyaml test loads in files and does something with it or why i gotten errors. This document does not explain how to use the file, only how to load it -_-. Please help http://pyyaml.org/wiki/LibYAML#Documentation

I need a C/C++ solution.

+3  A: 

Google code: yaml load lang:c++

The first link: 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;
}
J.F. Sebastian
+2  A: 

C example - parsing YAML tree to a glib "N-ary tree":

#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);
}
FraGGod
+2  A: 

Try yaml-cpp (as suggested by this question) for a C++ parser.

Disclosure: I'm the author.

Jesse Beder
A: 

Nice examples. Examples are a good complement but I'm looking for something like a reference or a relatively comprehensive tutorial, too. I don't like to use keywords when I not know what they really do and how they can be used (apart from the usage shown in the example). Ain't there a reference anywhere? Someone must have written the examples - where are the informations from they needed for doing this?

nitroklaus
This sounds like its own question. You should post it.
acidzombie24