2

I'm trying to code a yaml-formatted configuration file parser using C and libyaml. My Internet searches did not bring me any luck with finding a decent and complete documentation of the API with an operation manual. A tutorial by Andrew Poelstra here does not describe the document-based [with the use of yaml_parser_load ()] parsing method, which looks to me by far more logical and justified than the token-based and the event-based methods.

So currently I'm sticking to the doxygen-generated docs from yaml.h, and it really leaves me confused about how do I actually parse something after I load a document into a parser. Specifically I do not get which stack do we talk in the definitions of the yaml_document_s and yaml_node_s structs.

An example from yaml_node_s.data.mapping:

struct {
    /** The stack of mapping pairs (key, value). */
    struct {
        /** The beginning of the stack. */
        yaml_node_pair_t *start;
        /** The end of the stack. */
        yaml_node_pair_t *end;
        /** The top of the stack. */
        yaml_node_pair_t *top;
    } pairs;
    /** The mapping style. */
    yaml_mapping_style_t style;
} mapping;

I've figured out that *start (in my case) points to an array of yaml_node_pair_t's, each of which contains a pair of key and value integers, which are the indices by which the corresponding nodes can be acqured using the yaml_document_get_node () function. The meaning of the *end and *top pointers and how do I determine boundaries of and iterate a mapping using them remains a mystery to me, since *end does not contain the final node pair indices.

I would positively be happy if someone clarified to me at least the stack meaning here, or even better provided me with a good documentation and examples. Thanks in advance.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
ashpool
  • 179
  • 1
  • 8
  • I do not know the API in question, but the `struct` definition you present looks like a stack built on top of a linked list. `start` and `end` would point to the first and last nodes in the list, respectively, whereas `top` would point to either the node on top of the stack or the first open position above it. This kind of data structure would accommodate a stack whose elements (each a key/value pair) do not necessarily occupy all the allocated elements of the list; one might choose this to reduce the number of allocations and frees by allowing node reuse. – John Bollinger Apr 04 '16 at 18:49

1 Answers1

5

start is the bottom of the stack, top is above the top of the stack, and end points to the last yaml_node_pair_t piece of memory allocated for this stack. I figured this out with some experimentation and looking at the libyaml source. looking at yaml_document_get_node, yaml_document_get_root_node, and yaml_document_add_scalar provide some nice hints. for example:

YAML_DECLARE(yaml_node_t *)
yaml_document_get_node(yaml_document_t *document, int index)                                                    
{

    assert(document);   /* Non-NULL document object is expected. */

    if (index > 0 && document->nodes.start + index <= document->nodes.top) {
        return document->nodes.start + index - 1;
    }
    return NULL;
}

but really I guess it should have been obvious to both of us with just the knowledge of what a stack is. Anyway, you want to iterate starting at start stopping before reaching top like I've done here in a basic implementation:

http://codepad.org/W7StVSkV

(Not guaranteed to be perfect, but it worked for my test case)

DPena
  • 66
  • 2
  • Yes thanks, I've already figured this all out, but still this is a good and correct answer which should be accepted. I do, by the way, possess the knowledge of what a stack is, yet it was not obvious for me how could it be related here, since stacks do not usually get iterated, not as the part of their interface at least. So I'll think about it as an array, anyway. – ashpool Apr 23 '16 at 06:14
  • Yeah I figured you probably had by now, but I figured I would write this up in case someone else is trying to figure it out and can't find anything else from searching the web. My comment about the obviousness wasn't meant to be rude, I suppose it's not that obvious. I mostly put that in there because I felt silly for how long I took to figure it out. – DPena Apr 23 '16 at 07:28
  • This is really helpful thanks! – nicholaswogan Nov 07 '21 at 04:51