Разбор YAML файлов в C ++

Я хочу простой учебник, чтобы показать мне, чтобы загрузить файл yaml и проанализировать данные. Стиль Expat был бы хорош, но было бы полезно любое решение, которое фактически показывает мне данные в той или иной форме.

До сих пор я запускал несколько тестов в исходном коде yaml-0.1.1 для C, и я либо получал ошибку, но ничего не выводил, либо в случае run-emitter.c. Он читает в файле yaml и печатает его в STDOUT, он не создает текст с помощью функций / структур libyaml. В случаях с ошибкой я не знаю, был ли файл bc плохим или моя сборка неверна (я ничего не изменял ...) Файл был скопирован с yaml.org

Кто-нибудь может указать мне на учебник? (Я погуглил, по крайней мере, 30 минут, читая все, что выглядело уместно) или имя библиотеки, в которой есть хороший учебник или пример. Может быть, вы можете сказать мне, какой тест libyaml загружается в файлы и что-то с ним делает или почему я получил ошибки. Этот документ не объясняет, как использовать файл, только как его загрузить.

http://pyyaml.org/wiki/LibYAML#Documentation

13.12.2008 12:23:07
Пожалуйста, C и C ++ не совпадают. Есть отличные примеры решений для каждого, но, как вы видите, они очень разные. Я думаю, из тегов вы хотите C ++ больше, чем C. Если вы хотите C ++, попросите C ++. Запросы на C-решения часто могут сделать программу более запутанной.
Chris Lutz 7.03.2009 07:17:54
4 ОТВЕТА

Поиск кода Google (ныне несуществующий) для "yaml load lang: c ++" дал эту ссылку в качестве первой ссылки: 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;
}
5
15.10.2013 10:20:39

Пример C - синтаксический анализ дерева YAML для glib «N-арное дерево» :

#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);
}
10
7.03.2009 08:14:36
где вы yaml.h
maidamai 12.05.2019 03:56:59

Попробуйте yaml-cpp (как предполагает этот вопрос ) для синтаксического анализатора C ++.

Раскрытие: я автор.

Пример синтаксиса (из учебника ):

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;
47
23.05.2017 11:54:16
Какая настройка требуется для использования yaml-cpp ? Нужно ли просто загружать файлы заголовков и включать их в мою программу на C ++?
Bruce Wayne 1.06.2016 18:45:22
@BruceWayne вы должны собрать библиотеку и связать ее с вашим проектом.
Jesse Beder 1.06.2016 20:47:00
К сожалению, yaml-cpp почти не поддерживается. Релизы встречаются редко, иногда с ошибками (такие дистрибутивы, как Debian, ухудшаются из-за недостаточного обновления из апстрима), и по состоянию на начало 2018 года последний релиз все еще использует, auto_ptrчто запрещает использование yaml-cpp в любом проекте C ++ 17.
akim 28.01.2018 14:27:51
@akim Как ты это делаешь? Я потратил на это часы и не могу заставить его работать. Я продолжаю получать неопределенные ссылки, это сводит меня с ума.
darksky 28.01.2018 19:56:13

Я написал учебное пособие по адресу http://wpsoftware.net/andrew/pages/libyaml.html .

Это охватывает основы использования libyaml в C, использования анализа на основе токенов и событий. Он включает пример кода для вывода содержимого файла YAML.

11
12.01.2011 20:53:45