如何使用 Ada 双向链表
How to use Ada doubly linked lists
我正在使用 Ada 编程语言进行学校项目。教授要我们用不熟悉的语言来写。我需要使用 Ada 双向链表来编写一个文本编辑器程序。该程序在调用时将采用一个可选的命令行参数,该参数将指定默认文件名。如果该文件已经存在,则应将其内容加载到文本缓冲区中。保存文件后,缓冲区的内容将转储到具有指定名称的文件中,覆盖任何现有文件。
例如,如果我输入
a -- 追加命令
你好
世界
.
文件将有
你好
世界
附加到文档末尾
如果我输入
3个
你好
世界
.
然后在文档的第 3 行之后追加同一行。
这是我到目前为止编写的代码,但我也不知道如何使用字符串作为我的 case 语句的条件。
有人可以帮我做这个项目吗?
with Ada.Containers.Doubly_Linked_Lists;
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure main is
package String_List is new Ada.Containers.Doubly_Linked_Lists(Unbounded_String);
use String_List;
--Userinput : String(1 .. 10) := (others => ' '); --This string length is 10
Last: Integer; --This is use to count input string length
currentAddress: Integer := 0;
text : List; -- List is from Doubly_Linked_Lists
type Userinput is (a, c, p, e);
--size: Integer; --This is use to count input string length
procedure Print(Position : Cursor) is -- this subprogram print all string from list
begin
Put_Line(To_String(Element(Position)));
--Put_Line("K");
end Print;
begin
loop
Put( Integer'Image (currentAddress) & " >> " );
Get_Line(Userinput);
case Userinput is
when a =>
Put( Integer'Image (currentAddress) & " >> " );
Get_Line(Userinput);
text.Append(To_Unbounded_String(Userinput)); -- if letter is a add it to the doubly link list
when c =>
--text.Insert(Before => text.Find(To_Unbounded_String(Userinput)), New_Item => To_Unbounded_String( ? ));
when p =>
text.Iterate(Print'access);
when e =>
Put_Line("Program Exit");
exit;
when others =>
Put_Line ("No command found ");
end case;
end loop;
end main;
您不能将 String
用作 case 语句 (ARM 5.4(4)) 的 "selecting expression",因为它不是离散类型(不仅仅是实数,或者一个记录,是)。
您可以尝试使用下面示例中的枚举(这留下了如何像您的示例 3 a
一样处理输入的问题):
with Ada.Text_IO;
with Ada.IO_Exceptions;
procedure Alan is
type Command is (A, C, P, E);
package Command_IO is new Ada.Text_IO.Enumeration_IO (Command);
begin
loop
declare
Cmd : Command;
begin
Command_IO.Get (Cmd);
Ada.Text_IO.Skip_Line;
Ada.Text_IO.Put_Line ("read " & Cmd'Image); -- ' to sort out the not-fully-Ada-aware syntax highlighting
case Cmd is
when A => ...
...
when E => exit;
end case;
exception
when Ada.IO_Exceptions.Data_Error =>
Ada.Text_IO.Put_Line ("unrecognised command");
end;
end loop;
end Alan;
通常我会 use Ada.Text_IO;
;为了清楚起见,不在这里。
实现应用程序的诀窍是将其分解为功能组件,并在单独的(系列)包中实现它们中的每一个。例如,您可以这样开始:
- 从命令作用于文本缓冲区的地方拆分命令的解析。定义并实现(作为示例)具有以下规范的包:
parser.ads
package Parser is
Parse_Error : exception;
type Command_Kind is (Insert, Delete, Clear);
subtype Line_Number is Natural;
No_Line_Number : constant Line_Number := 0;
type Command is record
Kind : Command_Kind;
Line : Line_Number;
end record;
function Parse (Str : String) return Command;
-- Parses the given string and returns a command data object on success.
end Parser;
- 实施抽象文本缓冲区。您可能希望使用
Indefinite_Vectors
而不是 Doubly_Linked_List
作为您选择的容器,因为您将广泛处理行号(与双向链表相比,向量可以更容易地建立索引)。定义并实现(作为示例)具有以下规范的包:
text_buffers.ads
with Ada.Containers.Indefinite_Vectors;
package Text_Buffers is
type Text_Buffer is private;
subtype Line_Number is Positive; -- Different from Parsers.Line_Number!
procedure Load
(Buffer : in out Text_Buffer;
Filename : String);
-- Loads a text file into the text buffer.
procedure Save
(Buffer : in out Text_Buffer;
Filename : String);
-- Saves a text buffer into a text file.
function Line_Count
(Buffer : Text_Buffer) return Natural;
-- Gets the number of lines in the buffer.
function Get_Line
(Buffer : Text_Buffer;
Line : Line_Number) return String;
-- Gets the text of the given line.
procedure Clear
(Buffer : in out Text_Buffer);
-- Clears the text buffer.
procedure Insert
(Buffer : in out Text_Buffer;
Text : String;
After : Line_Number);
-- Inserts line of text to the text buffer.
procedure Delete
(Buffer : in out Text_Buffer;
Line : Line_Number);
-- Deletes a line of text from the text buffer.
-- ... other actions.
private
package Vector_String is
new Ada.Containers.Indefinite_Vectors (Line_Number, String);
use Vector_String;
type Text_Buffer is new Vector with null record;
end Text_Buffers;
- 使用包
Parser
和 Text_Buffers
构建您最终的文本编辑器应用程序。我建议将应用程序逻辑(初始化和主循环)也放入一个单独的包中,并从 Main
调用 Run
(见下文):
editor.ads
package Editor is
procedure Run (Filename : String);
-- Runs the editor application.
end Editor;
editor.adb
with Parser;
with Text_Buffers;
package body Editor is
---------
-- Run --
---------
procedure Run (Filename : String) is
begin
-- Initialization & Program loop.
null;
end Run;
end Editor;
main.adb
with Ada.Command_Line;
with Editor;
procedure Main is
Filename : String;
begin
-- Process command line options, set Filename.
Editor.Run (Filename);
end Main;
我正在使用 Ada 编程语言进行学校项目。教授要我们用不熟悉的语言来写。我需要使用 Ada 双向链表来编写一个文本编辑器程序。该程序在调用时将采用一个可选的命令行参数,该参数将指定默认文件名。如果该文件已经存在,则应将其内容加载到文本缓冲区中。保存文件后,缓冲区的内容将转储到具有指定名称的文件中,覆盖任何现有文件。
例如,如果我输入
a -- 追加命令
你好
世界
.
文件将有
你好
世界
附加到文档末尾
如果我输入
3个
你好
世界
.
然后在文档的第 3 行之后追加同一行。
这是我到目前为止编写的代码,但我也不知道如何使用字符串作为我的 case 语句的条件。
有人可以帮我做这个项目吗?
with Ada.Containers.Doubly_Linked_Lists;
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure main is
package String_List is new Ada.Containers.Doubly_Linked_Lists(Unbounded_String);
use String_List;
--Userinput : String(1 .. 10) := (others => ' '); --This string length is 10
Last: Integer; --This is use to count input string length
currentAddress: Integer := 0;
text : List; -- List is from Doubly_Linked_Lists
type Userinput is (a, c, p, e);
--size: Integer; --This is use to count input string length
procedure Print(Position : Cursor) is -- this subprogram print all string from list
begin
Put_Line(To_String(Element(Position)));
--Put_Line("K");
end Print;
begin
loop
Put( Integer'Image (currentAddress) & " >> " );
Get_Line(Userinput);
case Userinput is
when a =>
Put( Integer'Image (currentAddress) & " >> " );
Get_Line(Userinput);
text.Append(To_Unbounded_String(Userinput)); -- if letter is a add it to the doubly link list
when c =>
--text.Insert(Before => text.Find(To_Unbounded_String(Userinput)), New_Item => To_Unbounded_String( ? ));
when p =>
text.Iterate(Print'access);
when e =>
Put_Line("Program Exit");
exit;
when others =>
Put_Line ("No command found ");
end case;
end loop;
end main;
您不能将 String
用作 case 语句 (ARM 5.4(4)) 的 "selecting expression",因为它不是离散类型(不仅仅是实数,或者一个记录,是)。
您可以尝试使用下面示例中的枚举(这留下了如何像您的示例 3 a
一样处理输入的问题):
with Ada.Text_IO;
with Ada.IO_Exceptions;
procedure Alan is
type Command is (A, C, P, E);
package Command_IO is new Ada.Text_IO.Enumeration_IO (Command);
begin
loop
declare
Cmd : Command;
begin
Command_IO.Get (Cmd);
Ada.Text_IO.Skip_Line;
Ada.Text_IO.Put_Line ("read " & Cmd'Image); -- ' to sort out the not-fully-Ada-aware syntax highlighting
case Cmd is
when A => ...
...
when E => exit;
end case;
exception
when Ada.IO_Exceptions.Data_Error =>
Ada.Text_IO.Put_Line ("unrecognised command");
end;
end loop;
end Alan;
通常我会 use Ada.Text_IO;
;为了清楚起见,不在这里。
实现应用程序的诀窍是将其分解为功能组件,并在单独的(系列)包中实现它们中的每一个。例如,您可以这样开始:
- 从命令作用于文本缓冲区的地方拆分命令的解析。定义并实现(作为示例)具有以下规范的包:
parser.ads
package Parser is
Parse_Error : exception;
type Command_Kind is (Insert, Delete, Clear);
subtype Line_Number is Natural;
No_Line_Number : constant Line_Number := 0;
type Command is record
Kind : Command_Kind;
Line : Line_Number;
end record;
function Parse (Str : String) return Command;
-- Parses the given string and returns a command data object on success.
end Parser;
- 实施抽象文本缓冲区。您可能希望使用
Indefinite_Vectors
而不是Doubly_Linked_List
作为您选择的容器,因为您将广泛处理行号(与双向链表相比,向量可以更容易地建立索引)。定义并实现(作为示例)具有以下规范的包:
text_buffers.ads
with Ada.Containers.Indefinite_Vectors;
package Text_Buffers is
type Text_Buffer is private;
subtype Line_Number is Positive; -- Different from Parsers.Line_Number!
procedure Load
(Buffer : in out Text_Buffer;
Filename : String);
-- Loads a text file into the text buffer.
procedure Save
(Buffer : in out Text_Buffer;
Filename : String);
-- Saves a text buffer into a text file.
function Line_Count
(Buffer : Text_Buffer) return Natural;
-- Gets the number of lines in the buffer.
function Get_Line
(Buffer : Text_Buffer;
Line : Line_Number) return String;
-- Gets the text of the given line.
procedure Clear
(Buffer : in out Text_Buffer);
-- Clears the text buffer.
procedure Insert
(Buffer : in out Text_Buffer;
Text : String;
After : Line_Number);
-- Inserts line of text to the text buffer.
procedure Delete
(Buffer : in out Text_Buffer;
Line : Line_Number);
-- Deletes a line of text from the text buffer.
-- ... other actions.
private
package Vector_String is
new Ada.Containers.Indefinite_Vectors (Line_Number, String);
use Vector_String;
type Text_Buffer is new Vector with null record;
end Text_Buffers;
- 使用包
Parser
和Text_Buffers
构建您最终的文本编辑器应用程序。我建议将应用程序逻辑(初始化和主循环)也放入一个单独的包中,并从Main
调用Run
(见下文):
editor.ads
package Editor is
procedure Run (Filename : String);
-- Runs the editor application.
end Editor;
editor.adb
with Parser;
with Text_Buffers;
package body Editor is
---------
-- Run --
---------
procedure Run (Filename : String) is
begin
-- Initialization & Program loop.
null;
end Run;
end Editor;
main.adb
with Ada.Command_Line;
with Editor;
procedure Main is
Filename : String;
begin
-- Process command line options, set Filename.
Editor.Run (Filename);
end Main;