运行.adb程序时“无法为文件random.ads生成代码”

时间:2018-12-02 01:04:34

标签: gps ada

在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文件,所以我不明白。 您知道为什么它不起作用吗?

谢谢大家!

3 个答案:

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