YAML解析过程的不透明性和解析器实时补丁的预期行为



根据YAML规范,作者似乎想要明确区分数据/内容和"元数据"。(标签名、锚名等)。例如,它们多次警告避免使用!或其他指令干扰数据,并且解析器应该在完成解析后立即忘记预处理名称。

话虽如此,我想如果在单个文档的整个解析周期内保持解析器的行为恒定、静态也是强制性的吗?例如,YAML支持自定义/用户定义/本地标记。但是,如果我在运行时动态加载/添加新的支持标记,而正在进行一些文档处理,会怎么样呢?允许解析器在遇到相同的标记时改变其行为,第一次作为未定义的标记,但几秒钟后,正确地对待相同的标记,因为已经安装了解析扩展,这是可以的吗?比如可加载内核模块,或者Linux内核中的实时补丁。

并且,如果不受规范的限制,我们可能会遇到实现差距。那么,利比亚在野外的实现是否支持这种行为,或者在这种情况下可能崩溃或产生问题行为?

首先,根据您的意图和目的,标记不会立即丢弃或"忘记",而是保留到表示图中。这使它们与锚区别开来。可以提前丢弃的别名。

解析器通常不关心处理标记。当然,如果您使用%TAG指令,甚至只是预定义的!!!简写,解析器可能会替换它们(有些会,有些不会),但是解释例如!!str实际意味着什么要在稍后阶段发生。

YAML定义模式:

YAML模式是一组标记和一种用于解析非特定标记的机制的组合。

即使这样也只能在文档中的每个节点上使用特定的标记。将标签绑定到特定于实现的类型(例如,从YAML!!map到Pythondict)发生在构造步骤中,该步骤在规范中没有完全定义,并且实现在这里彼此相差很大。

我想说,规范强烈暗示(虽然没有明说),模式在文档加载过程中应该是恒定的,而支持模式意味着能够将模式中定义的所有标记加载为本机类型。

在加载过程中改变构造的行为与实时修补或加载内核模块完全不同,因为加载数据与操作可能长时间运行的内核是非常不同的用例。作为一名用户,我希望像YAML这样的反序列化器能够保证它加载的数据的一致性,但是当您在处理过程中开始修改行为时,这种情况就会中断。

同样,如果在某个点标签是未知的,加载失败(参见加载失败点)。标签以后是否可用并不重要。但是,如果您想让标记!foo首先做一件事,然后再做另一件事……遗憾的是,规范中没有明确禁止这样做的措辞,但至少推荐模式的描述暗示标记应始终加载到相同的结构中。我也认为绝对没有理由这样做,除非您明确希望破坏YAML实现。

libyaml根本不关心构建步骤,因此它不会有这个问题。一般来说,如果一个实现提供了构造,但没有明确声明这样做是可以的,我不会指望它。

坦率地说,我想知道你的用例是什么,是否使用互斥锁来确保加载语义只在文档之间更改会简单得多。

最新更新