wiki:LibYAML

Version 10 (modified by xi, 8 years ago) (diff)

Update the API synopsis.

LibYAML

LibYAML is a YAML 1.1 parser and emitter written in C. It's in an early stage of development.

You may leave your remarks here at the end of the page or post your comments to  the YAML-core mailing list.

Important Note

From June 26 to July 7, I'm at  the OT21 conference. Unfortunately, I'm not.

Progress

  • Scanner
  • Parser
  • Emitter

Scope

LibYAML covers presenting and parsing  processes. Thus LibYAML defines the following two processors:

  • Parser, which takes an input stream of bytes and produces a sequence of parsing events.
  • Emitter, which takes a sequence of events and produces a stream of bytes.

The processes of parsing and presenting are inverse to each other. Any sequence of events produced by parsing a well-formed YAML document should be acceptable by the Emitter, which should produce an equivalent document. Similarly, any document produced by emitting a sequence of events should be acceptable for the Parser, which should produce an equivalent sequence of events.

The job of resolving implicit tags, composing and serializing representation trees, as well as constructing and representing native objects is left to applications and bindings. Although some of these processes may be covered in the latter releases, they are not in the scope of the initial release of LibYAML.

Events

Event Types

The Parser produces while the Emitter accepts the following types of events:

  • STREAM-START
  • STREAM-END
  • DOCUMENT-START
  • DOCUMENT-END
  • ALIAS
  • SCALAR
  • SEQUENCE-START
  • SEQUENCE-END
  • MAPPING-START
  • MAPPING-END

A valid sequence of events should obey the grammar:

stream ::= STREAM-START document* STREAM-END
document ::= DOCUMENT-START node DOCUMENT-END
node ::= ALIAS | SCALAR | sequence | mapping
sequence ::= SEQUENCE-START node* SEQUENCE-END
mapping ::= MAPPING-START (node node)* MAPPING-END

Essential Event Attributes

The following attributes affect the intepretation of a YAML document.

  • ALIAS
    • anchor - the alias anchor; [0-9a-zA-Z_-]+; not NULL.
  • SCALAR
    • anchor - the node anchor; [0-9a-zA-Z_-]+; may be NULL.
    • tag - the node tag; should either start with ! (local tag) or be a valid URL (global tag); may be NULL or ! in which case either plain_implicit or quoted_implicit should be True.
    • plain_implicit - True if the node tag may be omitted whenever the scalar value is presented in the plain style.
    • quoted_implicit - True if the node tag may be omitted whenever the scalar value is presented in any non-plain style.
    • value - the scalar value; a valid utf-8 sequence; NULL means empty.
  • SEQUENCE-START
    • anchor - the node anchor; [0-9a-zA-Z_-]+; may be NULL.
    • tag - the node tag; should either start with ! (local tag) or be a valid URL (global tag); may be NULL or ! in which case implicit should be True.
    • implicit - True if the node tag may be omitted.
  • MAPPING-START
    • anchor - the node anchor; [0-9a-zA-Z_-]+; may be NULL.
    • tag - the node tag; should either start with ! (local tag) or be a valid URL (global tag); may be NULL or ! in which case implicit should be True.
    • implicit - True if the node tag may be omitted.

Stylistic Event Attributes

The following attributes don't affect the interpretation of a YAML document. While parsing a YAML document, an application should not consider these attributes for resolving implicit tags and constructing representation graphs or native objects. The Emitter may ignore these attributes if they cannot be satisfied.

  • STREAM-START
    • encoding - the document encoding; utf-8|utf-16-le|utf-16-be.
  • DOCUMENT-START
    • version_directive - the version specified with the %YAML directive; the only valid value is 1.1; may be NULL.
    • tag_directives - a set of tag handles and the corresponding tag prefixes specified with the %TAG directive; tag handles should match !|!!|![0-9a-zA-Z_-]+! while tag prefixes should be prefixes of valid local or global tags; may be NULL.
    • implicit - True if the document start indicator --- is not present.
  • DOCUMENT-END
    • implicit - True if the document end indicator ... is not present.
  • SCALAR
    • style - the value style; plain|single-quoted|double-quoted|literal|folded.
  • SEQUENCE-START
    • style - the sequence style; block|flow.
  • MAPPING-START
    • style - the mapping style; block|flow.
  • any event
    • start_mark - the position of the event beginning; offset (in bytes), index (in characters), line and column (starting from 0).
    • end_mark - the position of the event end; offset (in bytes), index (in characters), line and column (starting from 0).

API

Note: the API may change drastically. You may also check the header files: http://pyyaml.org/browser/libyaml/trunk/include/yaml/.

Parser API Synopsis

#include <yaml.h>

yaml_parser_t parser;
yaml_event_t event;

/* Create the Parser object. */
yaml_parser_initialize(&parser);

/* Set a string input. */
char *input = "...";
size_t length = strlen(input);

yaml_parser_set_string_input(&parser, input, length);

/* Set a file input. */
FILE *input = fopen("...", "rb");

yaml_parser_set_file_input(&parser, input);

/* Set a generic reader. */
void *ext = ...;
int read_handler(void *ext, char *buffer, int size, int *length) {
    /* ... */
    *buffer = ...;
    *length = ...;
    /* ... */
    return error ? 0 : 1;
}

yaml_parser_set_input(&parser, read_handler, ext);

/* Read the event sequence. */
do {
    int result;

    /* Get the next event. */
    result = yaml_parser_parse(&parser, &event);

    if (!result) goto error;

    /*
      ...
      Process the event.
      ...
    */

    /* The application is responsible for destroying the event object. */
    yaml_event_delete(&event);

} while(event.type != YAML_STREAM_END_EVENT);

/* Destroy the Parser object. */
yaml_parser_delete(&parser);

/* On error. */
error: /* FIXME */

/* Error type: YAML_READER_ERROR, YAML_SCANNER_ERROR, YAML_PARSER_ERROR. */
yaml_error_t error;

/* What parser was doing when the problem occured (may be NULL). */
char *context;

/* The starting position of the context (valid only if context != NULL). */
yaml_mark_t context_mark;

/* The problem description. */
char *problem;

/* The exact position of the problematic place in the stream. */
yaml_mark_t problem_mark;

/* Get the error data. */
yaml_parser_get_error(parser, &error, &context, &context_mark, &problem, &problem_mark);

/*
  ...
  Report the problem to the user.
  ...
*/

/* Destroy the Parser object. */
yaml_parser_delete(parser);

Emitter API Synopsis

#include <yaml.h>

yaml_emitter_t emitter;

/* Create the Emitter object. */
yaml_emitter_initialize(&emitter);

/* Set a file output. */
FILE *output = fopen("...", "wb");

yaml_emitter_set_file_output(&emitter, output);

/* Set a generic writer. */
void *ext = ...;
int write_handler(void *ext, char *buffer, int size) {
    /*
       ...
       Write `size` bytes.
       ...
    */
    return error ? 0 : 1;
}

yaml_emitter_set_output(&emitter, write_handler, ext);

/* Emit the STREAM-START event. */
int result = yaml_emitter_emit_stream_start(&emitter, YAML_UTF8_ENCODING);

if (!result) goto error;

/*
  ...
  Emit more events.
  ...
*/

/* EMIT the STREAM-END event. */
if (!yaml_emitter_emit_stream_end(&emitter) goto error;

/* Destroy the Emitter object. */
yaml_emitter_delete(&emitter);

/* On error. */
error: /* FIXME */

/* Error type: YAML_WRITER_ERROR, YAML_EMITTER_ERROR. */
yaml_error_t error;

/* The problem description. */
char *problem;

/* Get the error data. */
yaml_emitter_get_error(emitter, &error, &problem);

/*
  ...
  Report the problem to the user.
  ...
*/

/* Destroy the Emitter object. */
yaml_emitter_delete(emitter);

Feedback

Leave your comments here.