艾达是新来的。尝试在一个项目中处理一些对象,比如下面的{name:'Hermann',age:33},我不想为此编写自己的json解析器。是否有:
Gnatcolls.JSON以解析和编写这些对象的方法或者
发布于 2021-04-06 15:21:03
在做其他事情时,我很快就从规范中编写了一个JSON解析器,它花费了一天半的时间;这并不特别困难,我将看看如何将它发布到github或其他地方。
--然而,,JSON5的不同之处在于,重新实现它与编写某种适配器的难度是一样的。编辑解析器以接受新的结构可能比人们预期的要困难,因为IdentifierName允许作为关键手段,不能简单地将序列(1)“获取-打开-支撑”、(2)“消费-空格”、(3)“获取-a-字符串”、(4)“消费-空格”、(5)“get-a-冒号”、(6)“消费-空白”、(7) "get-JSON-object“、(8)”消费-空白“,(9)“人格化”;如果是逗号,转到#1,否则它应该是尾大括号“。
也许,让事情变得更容易的一件事是将流和字符串操作等同起来,以便您的对象只有一个生产方法;有三种主要的方法可以做到这一点:
stream-operation.
generic,使其接受一个字符串并给出该generic的配置文件。包示例是-- String_Stream允许使用字符串来缓冲底层流--它可以使用字符串或给定长度的内容初始化--作为流基础的字符串。-这是为了构造和消费字符串-数据-使用流-操作类型String_Stream(<>)是带有私有的新Ada.Streams.Root_Stream_Type;子类型Root_Stream_Class是Ada.Streams.root_Stream_ Type‘’Class;--创建一个String_Stream。函数"+"(长度:自然)返回String_Stream;函数"+"(文本:字符串)返回String_Stream;函数"+"(长度:自然)返回非空访问Root_Stream_Class;函数"+"(文本:字符串)返回非空访问Root_Stream_Class;-检索剩余的字符串-数据;(位置.数据‘Length )切片。函数"-"(流: String_Stream )返回字符串;-检索字符串-数据;(1.数据‘’LENGTH)切片。函数数据(Stream : String_Stream )返回字符串;私有Pragma断言( Ada.Streams.Stream_Element'Size =String‘’Component_Size );重写过程读(Stream : in out String_Stream;Item : out Ada.Streams.Stream_Element_Array;Last : out Ada.Streams.Stream_Element_Offset);重写过程写(Stream: in out String_Stream;Item : Ada.Streams.Stream_Element_Array);类型String_Stream(长度: Ada.Streams.Stream_Element_Count)是新的Ada.Streams.Root_Stream_Type,其记录数据为: Ada.Streams.Stream_Element_Array(1..Length);位置: Ada.Streams.Stream_Element_Count;结束记录;结束示例;
执行:
Package Body Example is
Use Ada.Streams;
-------------------
-- INITALIZERS --
-------------------
Function From_String( Text : String ) return String_Stream
with Inline, Pure_Function;
Function Buffer ( Length : Natural ) return String_Stream
with Inline, Pure_Function;
--------------
-- R E A D --
--------------
Procedure Read
(Stream : in out String_Stream;
Item : out Ada.Streams.Stream_Element_Array;
Last : out Ada.Streams.Stream_Element_Offset) is
Use Ada.IO_Exceptions, Ada.Streams;
Begin
-- When there is a read of zero, do nothing.
-- When there is a read beyond the buffer's bounds, raise an exception.
-- Note: I've used two cases here-
-- 1) when the read is greater than the buffer,
-- 2) when the read would go beyond the buffer.
-- Finally, read the given amount of data and update the position.
if Item'Length = 0 then
null;
elsif Item'Length > Stream.Data'Length then
Raise End_Error with "Request is larger than the buffer's size.";
elsif Stream_Element_Offset'Pred(Stream.Position)+Item'Length > Stream.Data'Length then
Raise End_Error with "Buffer will over-read.";
else
Declare
Subtype Selection is Stream_Element_Offset range
Stream.Position..Stream.Position+Stream_Element_Offset'Pred(Item'Length);
Begin
Item(Item'Range):= Stream.Data(Selection);
Stream.Position:= Stream_Element_Offset'Succ(Selection'Last);
Last:= Selection'Last;--Stream.Position;
End;
end if;
End Read;
-----------------
-- W R I T E --
-----------------
Procedure Write
(Stream : in out String_Stream;
Item : Ada.Streams.Stream_Element_Array) is
Begin
Declare
Subtype Selection is Stream_Element_Offset range
Stream.Position..Stream.Position+Stream_Element_Offset'Pred(Item'Length);
Begin
Stream.Data(Selection):= Item(Item'Range);
Stream.Position:= Stream_Element_Offset'Succ(Selection'Last);
End;
End Write;
----------------------------------
-- INITALIZER IMPLEMENTATIONS --
----------------------------------
-- Create a buffer of the given length, zero-filled.
Function Buffer( Length : Natural ) return String_Stream is
Len : Constant Ada.Streams.Stream_Element_Offset :=
Ada.Streams.Stream_Element_Offset(Length);
Begin
Return Result : Constant String_Stream:=
(Root_Stream_Type with
Position => 1,
Data => (1..Len => 0),
Length => Len
);
End Buffer;
-- Create a buffer from the given string.
Function From_String( Text : String ) return String_Stream is
Use Ada.Streams;
Subtype Element_Range is Stream_Element_Offset range
Stream_Element_Offset(Text'First)..Stream_Element_Offset(Text'Last);
Subtype Constrained_Array is Stream_Element_Array(Element_Range);
Subtype Constrained_String is String(Text'Range);
Function Convert is new Ada.Unchecked_Conversion(
Source => Constrained_String,
Target => Constrained_Array
);
Begin
Return Result : Constant String_Stream:=
(Root_Stream_Type with
Position => Element_Range'First,
Data => Convert( Text ),
Length => Text'Length
);
End From_String;
-- Classwide returning renames, for consistancy/overload.
Function To_Stream( Text : String ) return Root_Stream_Class is
( From_String(Text) ) with Inline, Pure_Function;
Function To_Stream( Length : Natural ) return Root_Stream_Class is
( Buffer(Length) ) with Inline, Pure_Function;
----------------------------
-- CONVERSION OPERATORS --
----------------------------
-- Allocating / access-returning initalizing operations.
Function "+"( Length : Natural ) return not null access Root_Stream_Class is
( New Root_Stream_Class'(To_Stream(Length)) );
Function "+"( Text : String ) return not null access Root_Stream_Class is
( New Root_Stream_Class'(To_Stream(Text)) );
-- Conversion from text or integer to a stream; renaming of the initalizers.
Function "+"( Text : String ) return String_Stream renames From_String;
Function "+"( Length : Natural ) return String_Stream renames Buffer;
-- Convert a given Stream_Element_Array to a String.
Function "-"( Data : Ada.Streams.Stream_Element_Array ) Return String is
Subtype Element_Range is Natural range
Natural(Data'First)..Natural(Data'Last);
Subtype Constrained_Array is Stream_Element_Array(Data'Range);
Subtype Constrained_String is String(Element_Range);
Function Convert is new Ada.Unchecked_Conversion(
Source => Constrained_Array,
Target => Constrained_String
);
Begin
Return Convert( Data );
End "-";
----------------------
-- DATA RETRIEVAL --
----------------------
Function "-"( Stream : String_Stream ) return String is
Begin
Return -Stream.Data(Stream.Position..Stream.Length);
End "-";
Function Data(Stream : String_Stream ) return String is
Begin
Return -Stream.Data;
End Data;
End Example;https://stackoverflow.com/questions/66953897
复制相似问题