如何在Ada中读取yaml文件

时间:2020-06-21 21:04:57

标签: yaml ada

我试图了解如何使用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文件?

3 个答案:

答案 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;