C libyaml 基于文档的解析

Posted

技术标签:

【中文标题】C libyaml 基于文档的解析【英文标题】:C libyaml document-based parsing 【发布时间】:2016-04-04 18:27:27 【问题描述】:

我正在尝试使用 C 和 libyaml 编写一个 yaml 格式的配置文件解析器。我的互联网搜索并没有给我带来任何运气,我找到了一份体面且完整的 API 文档和操作手册。 Andrew Poelstra here 的教程没有描述基于文档的[使用yaml_parser_load ()] 解析方法,在我看来,这比基于令牌的解析方法更合乎逻辑和合理。基于事件的方法。

所以目前我坚持使用来自yaml.h 的 doxygen 生成的文档,这让我对在将文档加载到解析器后如何实际解析某些内容感到困惑。具体来说,我不知道我们在 yaml_document_syaml_node_s 结构的定义中讨论的是哪个 stack

来自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;

我发现*start(在我的例子中)指向yaml_node_pair_t的数组,每个数组都包含一对keyvalue整数,它们是索引可以使用yaml_document_get_node () 函数获取相应的节点。 *end*top 指针的含义以及如何确定边界并使用它们迭代映射对我来说仍然是一个谜,因为 *end 不包含最终节点对索引。

如果有人至少向我澄清 stack 在这里的含义,或者更好地为我提供良好的文档和示例,我会非常高兴。提前致谢。

【问题讨论】:

我不知道有问题的 API,但是您提供的 struct 定义看起来像是建立在链表之上的堆栈。 startend 将分别指向列表中的第一个和最后一个节点,而top 将指向堆栈顶部的节点或其上方的第一个打开位置。这种数据结构将容纳一个堆栈,其元素(每个键/值对)不一定占据列表的所有已分配元素;人们可能会选择这一点,通过允许节点重用来减少分配和释放的数量。 【参考方案1】:

start 是栈底,top 是栈顶之上,end 指向最后分配给这个栈的内存块yaml_node_pair_t。我通过一些实验和查看 libyaml 源代码发现了这一点。查看yaml_document_get_nodeyaml_document_get_root_nodeyaml_document_add_scalar 提供了一些不错的提示。例如:

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;

但实际上,我想只要知道堆栈是什么,我们俩就应该很明显了。无论如何,您想从start 开始迭代,然后再到达top,就像我在基本实现中所做的那样:

http://codepad.org/W7StVSkV

(不保证完美,但它适用于我的测试用例)

【讨论】:

是的,谢谢,我已经想通了,但这仍然是一个很好且正确的答案,应该被接受。顺便说一句,我确实掌握了堆栈是什么的知识,但对我来说它在这里如何关联并不明显,因为堆栈通常不会被迭代,至少不是它们接口的一部分。所以无论如何我都会把它当作一个数组来考虑。 是的,我想你现在可能已经知道了,但我想我会写这个,以防其他人试图弄清楚并且无法通过搜索网络找到任何其他内容。我对显而易见性的评论并不意味着粗鲁,我想它并不那么明显。我把它放在那里主要是因为我花了多长时间才弄明白这件事让我觉得很傻。 这真的很有帮助,谢谢!

以上是关于C libyaml 基于文档的解析的主要内容,如果未能解决你的问题,请参考以下文章

使用 libyaml 解析树状结构

对于已编译的库,如 libyaml,Ruby(或 RVM)在文件系统中搜索何处以加载或解析它们?

浅谈用java解析xml文档

[Asp.Net Core]C#解析Markdown文档

[Asp.Net Core]C#解析Markdown文档

ini Nginx配置基于文件夹的静态文档读取,使用由本地dns代理(dnsmasq)解析的私有域。