在Ada中运行程序遇到一些麻烦。我有以下三个项目文件(我使用GPS):
Types.ads
package types is
subtype T_valeurind is Integer range 2..14;
type T_couleur is (s, h, c, d);
type t_carte is record
valeur : T_valeurind;
couleur : T_couleur;
end record;
type T_jeu is array (1..7) of t_carte;
function trans(val: Character) return T_valeurind;
end types;
Trans.adb
with types;
use types;
WITH Text_Io , Ada.Integer_Text_Io;
USE Text_Io , Ada.Integer_Text_Io;
function trans(val : Character)
return T_valeurind is
ret: Integer;
begin
case val is
when '3' => ret:=3;
when '4' => ret:=4;
when '5' => ret:=5;
when '6' => ret:=6;
when '7' => ret:=7;
when '8' => ret:=8;
when '9' => ret:=9;
when 'T' => ret:=10;
when 'J' => ret:=11;
when 'Q' => ret:=12;
when 'K' => ret:=13;
when 'A' => ret:=14;
when others => null;
end case;
return ret;
end trans;
Test.adb
WITH Text_Io , Ada.Integer_Text_Io;
USE Text_Io , Ada.Integer_Text_Io;
with types;
use types;
procedure test is
begin
put(T_valeurind'Image(trans('c')));
end test;
我只是试图执行test.adb只是为了检查我的函数“ trans”是否运行良好。当我在GPS中构建文件时,一切正常。但是,当我想运行它们时,出现以下消息,并且没有执行:
无法为文件类型.ads(程序包规格)生成代码
gprbuild:***编译阶段失败
[2018-12-02 02:01:39]进程退出,状态为4,100%(2/2),耗时:01.65s
但是令人不安的是,我第一次尝试运行代码时,它就起作用了。没有进行任何更改,它停止工作。 我不知道该怎么办。我已经看到此消息只是告诉我.ads文件不可编译,但是我尝试编译并运行的是.adb文件,所以我不明白。 您知道为什么它不起作用吗?
谢谢大家!
答案 0 :(得分:3)
首先,这些不是项目文件,其类型为.gpr
;它们是您项目中的Ada源文件。
您的types.ads
承诺function trans
,这意味着它需要types.adb
中的程序包主体,
package body types is
function trans(val : Character)
return T_valeurind is
ret: Integer;
begin
case val is
when '3' => ret:=3;
when '4' => ret:=4;
when '5' => ret:=5;
when '6' => ret:=6;
when '7' => ret:=7;
when '8' => ret:=8;
when '9' => ret:=9;
when 'T' => ret:=10;
when 'J' => ret:=11;
when 'Q' => ret:=12;
when 'K' => ret:=13;
when 'A' => ret:=14;
when others => null;
end case;
return ret;
end trans;
end types;
(嗯。如果传入无效字符,您将返回未初始化的数据,就像没有得到Constraint_Error
一样; T_valeurind
包含值2,是否不应该覆盖它? ?)
您的trans.adb
改为指定库级别的函数。
当我在GPS中构建文件时,一切正常。但是,当我想运行它们时,出现以下消息,并且没有执行:
如果程序包规范(types.ads
)需要主体(types.adb
),而您没有提供它,则当您尝试编译它时,编译器将生成您报告的消息。如果您尝试只是编译 test.adb
,那就可以了。如果您尝试 build test.adb
,它将尝试编译软件包Types
,并且将失败,无论您是尝试构建还是构建并运行。
我不知道这怎么可能第一次起作用!
答案 1 :(得分:0)
您似乎忘记了在测试程序的上下文中包含function Trans
。而且,如果不在上下文中,则不能使用它。
尝试添加:
with Trans;
转到procedure Test
的上下文子句。
答案 2 :(得分:0)
使用强大的Ada枚举功能(以及某些不良的输入处理策略,例如异常)可以避免您的整个问题。您的trans
过程将毫无用处。
如果您对枚举值的顺序关系感兴趣,还可以使用Ada的 'First
* (第一个枚举文字), 'Last
< / strong>(最后一个枚举文字), 'Pos
(在枚举内的位置), 'Succ
(下一个枚举文字), { {1}} (先前的枚举文字)。
如果您对变量执行内存映射,则可以使用 'Pred
来检查变量是否具有有效值,并节省约束错误的异常捕获需求。
请参见以下示例:
'Valid
这给出了以下输出(https://www.tutorialspoint.com/compile_ada_online.php,带有GNATMAKE v7.1.1):
内部版本:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Exceptions; use Ada.Exceptions;
procedure Hello is
-- miwing chars and literal values in enum
-- note that jack is 'J' and not the single source code character J
type My_Awesome_Enum is ('1', '2', '3', 'J', Q, K, Ace);
for My_Awesome_Enum use
('1' => -1,
'2' => 2,
'3' => 3,
-- ...
'J' => 11,
Q => 12,
K => 13,
Ace => 14);
temp : Integer;
prev : My_Awesome_Enum;
succ : My_Awesome_Enum;
temp2 : My_Awesome_Enum;
begin
-- ------------------------------------------
-- Ada enum power
declare
begin
for value in My_Awesome_Enum loop
temp := My_Awesome_Enum'Enum_Rep(value);
Put_Line("Enum litteral value: " & value'Image & " - memory representation: " & Integer'Image(temp));
if value /= My_Awesome_Enum'First then
prev := My_Awesome_Enum'Pred(value);
Put_Line("Previous: " & prev'Image);
else
Put_Line("No previous");
end if;
if value /= My_Awesome_Enum'Last then
succ := My_Awesome_Enum'Succ(value);
Put_Line("Next: " & succ'Image);
else
Put_Line("No next");
end if;
Put_Line("");
end loop;
end;
-- ------------------------------------------
-- conversion from some input source
Put_Line("");
declare
strInput : String := "Unknown user value";
begin
Put_Line("Handling of user input: " & strInput);
temp2 := My_Awesome_Enum'Value (strInput);
exception
when E: others =>
Put_Line("Exception catched: " & Exception_Information (E));
Put_Line("Setting value to Ace instead");
temp2 := Ace;
end;
Put_Line("tmp2 value: " & temp2'Image & " - memory representation: " & Integer'Image(My_Awesome_Enum'Enum_Rep(temp2)));
-- ------------------------------------------
-- mmemory mapping
Put_Line("");
declare
my_int : Integer := -3;
mapped_Enum : My_Awesome_Enum;
for mapped_Enum'Address use my_int'Address;
last_enum : My_Awesome_Enum := (My_Awesome_Enum'Last);
stop_condition : Integer := (last_enum'Enum_Rep) + 2;
begin
while (my_int < stop_condition) loop
if mapped_Enum'Valid then
Put_Line("Enum with value: " & my_int'Image & " is valid.");
else
Put_Line("Memory mapping would result in invalid enum for value: " & my_int'Image);
end if;
my_int := my_int + 1;
end loop;
end;
end Hello;
执行:
$gnatmake -o hello *.adb
gcc -c hello.adb
gnatbind -x hello.ali
gnatlink hello.ali -o hello