我试图了解如何使用Ada和AdaYaml库(https://github.com/yaml/AdaYaml/)。我有几个yaml文件,需要将它们转换为Ada记录以进行进一步处理。
使用库几个小时后,我不知道如何使用Accessor访问Yaml数据。
我的最低限度的工作代码是
with Ada.Text_IO;
with Ada.Command_Line;
with Yaml.Source.File;
with Yaml.Source.Text_IO;
with Yaml.Dom.Loading;
with Yaml.Dom.Node;
with Yaml; use Yaml;
with Text; use Text;
procedure Load_Dom is
Input : Source.Pointer;
begin
if Ada.Command_Line.Argument_Count = 0 then
Input := Yaml.Source.Text_IO.As_Source (Ada.Text_IO.Standard_Input);
else
Input := Yaml.Source.File.As_Source (Ada.Command_Line.Argument (1));
end if;
declare
Document : Yaml.Dom.Document_Reference :=
Yaml.Dom.Loading.From_Source (Input);
begin
Ada.Text_IO.Put_Line ("Root node is a " & Yaml.Dom.Node.Instance'(Document.Root.Value).Kind'Img);
Ada.Text_IO.Put_Line ("Root node is a " & Yaml.Dom.Node.Instance'(Document.Root.Value).Tag);
Ada.Text_IO.Put_Line ("Root node is a " & Yaml.Dom.Node.Instance'(Document.Root.Value).Mapping_Style'Img);
end;
end Load_Dom;
我认为显式转换Yaml.Dom.Node.Instance'(Document.Root.Value)
是不正确的,我必须缺少一些内容。
任何想法或代码示例如何以正确方式读取yaml文件?
答案 0 :(得分:3)
我是AdaYaml的作者。
由Accessor
返回的Document.Root.Value
定义如下:
type Accessor (Data : not null access Node.Instance) is limited private
with Implicit_Dereference => Data;
与任何可判别的类型一样,您可以通过其名称Node.Instance
访问Data
。因此,此显式表达式检索根节点的种类:
Document.Root.Value.Data.all.Kind
现在Ada允许我们隐式取消指针的引用,删除.all
:
Document.Root.Value.Data.Kind
并且Implicit_Dereference
的{{1}}属性允许我们删除Accessor
:
.Data
所以你要做的是
Document.Root.Value.Kind
这在the documentation中进行了简要显示,但没有说明。为了进一步阅读,可能会感兴趣this gem。
答案 1 :(得分:1)
这不是不是答案,但是(对于它的价值)是我对@flyx答案所作的评论的补充(实际上是正确的答案)。编译错误的问题(在GNAT CE 2020中)似乎由程序包limited with Yaml.Dom.Node
中使用的Yaml.Dom
结构以及类型{{1}的Implicit_Dereference
方面触发。 }。可以使用以下示例重现该问题。我目前不知道该错误是否真正合法。
parent.ads
Yaml.Dom.Accessor
parent-child.ads
limited with Parent.Child;
package Parent is
type Accessor (Data : not null access Child.Instance) is null record
with Implicit_Dereference => Data;
end Parent;
main.adb
package Parent.Child is
type Instance (Value : Integer) is null record;
end Parent.Child;
输出(编译器)
with Ada.Text_IO;
with Parent;
with Parent.Child;
procedure Main is
Ref : Parent.Accessor (new Parent.Child.Instance (0));
begin
Ada.Text_IO.Put_Line (Ref.Value'Image); -- Error
Ada.Text_IO.Put_Line (Ref.Data.Value'Image); -- OK
end Main;
答案 2 :(得分:1)
这是我设法工作的最小例子
with Ada.Text_IO;
with Ada.Command_Line;
with Yaml; use Yaml; -- this line is missing in https://ada.yaml.io/doc/Yaml.Dom/
with Yaml.Source.Text_IO;
with Yaml.Source.File;
with Yaml.Dom.Loading;
with Yaml.Dom.Node;
pragma Unreferenced (Yaml.Dom.Node);
procedure Load_Dom is
use type Dom.Node_Kind;
Input : Source.Pointer :=
(if Ada.Command_Line.Argument_Count = 0 then
Source.Text_IO.As_Source (Ada.Text_IO.Standard_Input)
else
Source.File.As_Source (Ada.Command_Line.Argument (1)));
Document : Yaml.Dom.Document_Reference :=
Dom.Loading.From_Source (Input);
Root : constant not null access Dom.Node.Instance
:= Document.Root.Value.Data;
begin
Ada.Text_IO.Put_Line
("Root node is a " & Root.Kind'Img);
end Load_Dom;