Hello!
Компилятор не может подставить соответсвующую процедуру GET. Вместо
procedure Get
(From : String;
Item : out Num;
Last : out Positive);
из Ada.Text_IO.Decimal_IO или Ada.Text_IO.Integer_IO пытается подставить
procedure Get
(Item : out Num;
Width : Field := 0);
, т.е. не видит процедуры ввода из строки и пытается пользоваться вводом из файла, что, естественно, вызывает ошибку:
200:16 expected private type "Ada.Text_Io.File_Type"
200:16 found type "Standard.String"
200:10 no candidate interpretations match the actuals:
200:10 too many arguments in call to "GET"
197:13 expected private type "Ada.Text_Io.File_Type"
197:38 expected type "RECORD_TIMES" defined at line 40
200:68 expected type "RECORD_TIMES" defined at line 40
197:13 found type "Standard.String"
197:7 no candidate interpretations match the actuals:
197:7 too many arguments in call to "GET"
Фрагмент текста ( звёздочкой помечена строка 197 из протокола ):
type RECORD_TIMES is delta 0.001 digits 13 ;
package IIO is new TEXT_IO.INTEGER_IO ( INTEGER ) ;
use IIO ;
package DIO is new TEXT_IO.DECIMAL_IO ( RECORD_TIMES ) ;
use DIO ;
generic
type COMPONENTS is private ;
procedure GET_PAIR_G
( DATA : in STRING ;
SEPARATOR : in STRING ;
START , DURATION : in out COMPONENTS ) ;
procedure GET_PAIR_G
( DATA : in STRING ;
SEPARATOR : in STRING ;
START , DURATION : in out COMPONENTS ) is
-- Tries to split the input string into two parts separated by SEPARATOR -- If there is no first part propagates the exception raised by the GET -- If there is no second part raises TRUNCATED_DATA_ERROR
LAST_POS : INTEGER := INDEX ( DATA , SEPARATOR , 1 ) ;
begin -- GET_PAIR_G
* GET ( DATA ( 1 .. LAST_POS ) , START , LAST_POS ) ;
begin
GET ( DATA ( LAST_POS + SEPARATOR'LENGTH .. DATA'LAST ) , DURATION , LAST_POS ) ;
exception
when Ada.IO_EXCEPTIONS.END_ERROR => raise TRUNCATED_DATA_ERROR ; end ;
end GET_PAIR_G ;
Компилятор не может подставить соответсвующую процедуру GET.
Потому что ее - соответствующей - не существует. Вам непонятно что - где ошибка (а вернее - ошибкИ), или почему такая диагностика? Тот факт, что ваша программа неверна, вам понятен, или нет?
Как это не существует? А в пакете Ada.Text_IO.Fixed_IO в строке 73 что ( помечена звёздочкой )? Аналоги есть и в Ada.Text_IO.INTEGER_IO, и в Ada.Text_IO.DECIMAL_IO.
Или при объявлении GENERIC'ов нельзя использовать другие GENERIC-модули ( пакеты, процедуры )? Или нужно их как-то по-другому описывать?
------------------------------------------------------------------------------ -- -- -- GNAT RUN-TIME COMPONENTS -- -- -- -- A D A . T E X T _ I O . F I X E D _ I O -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- -- apply solely to the contents of the part following the private keyword. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- <http://www.gnu.org/licenses/>. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------
-- In Ada 95, the package Ada.Text_IO.Fixed_IO is a subpackage of Text_IO. -- This is for compatibility with Ada 83. In GNAT we make it a child package -- to avoid loading the necessary code if Fixed_IO is not instantiated. See -- routine Rtsfind.Text_IO_Kludge for a description of how we patch up the -- difference in semantics so that it is invisible to the Ada programmer.
private generic
type Num is delta <>;
package Ada.Text_IO.Fixed_IO is
Default_Fore : Field := Num'Fore;
Default_Aft : Field := Num'Aft;
Default_Exp : Field := 0;
procedure Get
(File : File_Type;
Item : out Num;
Width : Field := 0);
procedure Get
(Item : out Num;
Width : Field := 0);
procedure Put
(File : File_Type;
Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
Exp : Field := Default_Exp);
procedure Put
(Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
Exp : Field := Default_Exp);
* procedure Get
(From : String;
Item : out Num;
Last : out Positive);
procedure Put
(To : out String;
Item : Num;
Aft : Field := Default_Aft;
Exp : Field := Default_Exp);
private
pragma Inline (Get);
pragma Inline (Put);
end Ada.Text_IO.Fixed_IO;
А в пакете ADA.TEXT_IO.FIXED _ IO в строке 73 что ( помечена звёздочкой )?
Мне непонятно, почему компилятор не видит именно эту процедуру. В чём ошибочность моей программы? При объявлении GENERIC'ов нельзя использовать другие GENERIC-пакеты? Или надо на них как-то по-другому ссылаться?
------------------------------------------------------------------------------ -- -- -- GNAT RUN-TIME COMPONENTS -- -- -- -- A D A . T E X T _ I O . F I X E D _ I O -- -- -- -- S p e c -- -- -- -- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- -- apply solely to the contents of the part following the private keyword. -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- -- ware Foundation; either version 3, or (at your option) any later ver- -- -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- -- or FITNESS FOR A PARTICULAR PURPOSE. -- -- -- -- -- -- -- -- -- -- -- -- You should have received a copy of the GNU General Public License and -- -- a copy of the GCC Runtime Library Exception along with this program; -- -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- -- <http://www.gnu.org/licenses/>. -- -- -- -- GNAT was originally developed by the GNAT team at New York University. -- -- Extensive contributions were provided by Ada Core Technologies Inc. -- -- -- ------------------------------------------------------------------------------
-- In Ada 95, the package Ada.Text_IO.Fixed_IO is a subpackage of Text_IO. -- This is for compatibility with Ada 83. In GNAT we make it a child package -- to avoid loading the necessary code if Fixed_IO is not instantiated. See -- routine Rtsfind.Text_IO_Kludge for a description of how we patch up the -- difference in semantics so that it is invisible to the Ada programmer.
private generic
type Num is delta <>;
package Ada.Text_IO.Fixed_IO is
Default_Fore : Field := Num'Fore;
Default_Aft : Field := Num'Aft;
Default_Exp : Field := 0;
procedure Get
(File : File_Type;
Item : out Num;
Width : Field := 0);
procedure Get
(Item : out Num;
Width : Field := 0);
procedure Put
(File : File_Type;
Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
Exp : Field := Default_Exp);
procedure Put
(Item : Num;
Fore : Field := Default_Fore;
Aft : Field := Default_Aft;
Exp : Field := Default_Exp);
* procedure Get
(From : String;
Item : out Num;
Last : out Positive);
procedure Put
(To : out String;
Item : Num;
Aft : Field := Default_Aft;
Exp : Field := Default_Exp);
private
pragma Inline (Get);
pragma Inline (Put);
end Ada.Text_IO.Fixed_IO;
Гм. Из вашего вопроса я заключаю, что вам непонятно, почему ваша программа неверна :)
Как это не существует? А в пакете Ada.Text_IO.Fixed_IO в строке 73 что ( помечена звёздочкой )? Аналоги есть и в Ada.Text_IO.INTEGER_IO, и в Ada.Text_IO.DECIMAL_IO.
Ну вот, всего этого и не существует :) Настраиваемые пакеты - это не реальный код, это просто шаблоны. Чтобы в реальности появились соответствующие процедуры - их вначале надо настроить.
Или при объявлении GENERIC'ов нельзя использовать другие GENERIC-модули ( пакеты, процедуры )? Или нужно их как-то по-другому описывать?
Напрямую - нельзя разумеется. Просто задумайтесь, как будет выглядеть конечный результат? Что мы будем вызывать в итоге? Ближайшее к искомому, что язык предоставляет - это т.наз. формальные пакеты. См. руководство языка, глава 12.7. Вот что-то такого рода:
with Ada.Containers.Ordered_Maps;
generic
with package Mapping_1 is new Ada.Containers.Ordered_Maps(<>); package Ordered_Join is
... и т.д.
Но это просто объявление обязательств программиста, настраивать пакет нужно будет все равно. Например то объявление, что выше, подразумевает, что вы где-то в программе настроите пакет Ada.Containers.Ordered_Maps, и передадите его в качестве параметра.
Не знаю - тот ли это механизм, что вы ищете, или нет?
Что это шаблоны и их надо настраивать я знаю. И в моей программе они настроены и даже работают. !-)
type RECORD_TIMES is delta 0.001 digits 13 ;
package IIO is new TEXT_IO.INTEGER_IO ( INTEGER ) ;
use IIO ;
package DIO is new TEXT_IO.DECIMAL_IO ( RECORD_TIMES ) ;
use DIO ;
Это хорошо, но это только полдела :)
Так при соотвествующей настройке моей процедуры должен выбираться соответствующий настроенный пакет ввода/вывода и подставляться.
Ну а с какой стати компилятор отождествит профиль
GET (STRING, INTEGER, COMPONENTS)
с профилем
GET (STRING, INTEGER, INTEGER) ?
Во-первых вы объявили COMPONENTS как тип PRIVATE, то есть иными словами никакой совместимости с целочисленным типом не предусматривается (и вообще не предусматривается никаких знаний о внутренней структуре типа). Если совместимость нужна - необходимо объявить формальный параметр целочисленного типа -
type COMPONENTS is range <>;
Во-вторых, даже и в этом случае не стоит забывать о строгой типизации языка Ада. С точки зрения языка тип COMPONENTS это одно, а INTEGER это другое, два несовместимых типа. Требуется явное преобразование:
GET ( DATA ( 1 .. LAST_POS ) , START , INTEGER (LAST_POS) ) ;
Вот тогда должно начать компилироваться... :)
Или я слишком много хочу от компилятора?
Ну вобщем да - вы хотите, чтобы компилятор компилировал неправильные программы ;)
В любом случае компилятор ( вернее, уже сборщик ) ведёт себя странно.
Если просто откомпилировать ( без сборки ) программу, то ошибок нет. Ошибки возникают при сборке.
По-хорошему должено было бы выдаваться сообщение о невозможности именно _подстановки типов_, а не о несоответствии профиля вызова. Поскольку, исходя из диагностики, считается возможной подстановка типа в _другую_ процедуру GET и в качестве ошибки выдаётся несоответсвие количества аргументов.
С другой стороны, может, я, конечно, и здесь ошибаюсь, GENERIC'и по своей сути есть макросредство, порождающее копии кода с указанными подстановками. Соответственно, при рекурсивной подстановке корректность описания может ( и должна ) быть проверена так сказать "задом наперёд", т.е. от более конкретных модулей к более абстрактным, от того, что я описываю в своей программе к описаным ранее. При имеющихся описаниях на этапе настройки моей процедуры GET_PAIR все типы определены и профили вызова полностью определены. Следовательно, корректная подстановка возможна.
Но, похоже, работаёт это не так, что и вызвало недоумение.
В любом случае компилятор ( вернее, уже сборщик ) ведёт себя странно.
Если просто откомпилировать ( без сборки ) программу, то ошибок нет. Ошибки возникают при сборке.
Нет, ничего подобного. Сообщения
...
200:16 expected private type "Ada.Text_Io.File_Type"
200:16 found type "Standard.String"
...
и т.п. - это сообщения периода компиляции, а не периода сборки.
По-хорошему должено было бы выдаваться сообщение
Такого рода пожелания существуют столько же времени, сколько существуют синтаксические ошибки в программах. На самом деле компилятор может на каждую ошибку просто говорить "syntax error", всё что дополнительно - это не более чем бонус. Восстановление после синтаксической ошибки - это совсем не простое дело, и не всегда возможно. А уж тем более не всегда возможно догадаться, что хотел программист. Я лично при невозможности статического связывания на догадки компилятора относительно того, "что бы это могло быть" вообще почти никогда не смотрю, поскольку в отличие от компилятора, точно знаю, что там ДОЛЖНО быть, и этого знания (и знания языка) мне достаточно, чтобы исправить ошибку ;)
Но, похоже, работаёт это не так, что и вызвало недоумение.
Да, работает это не так. Домысливать не стоит, лучше писать программы в соответствии с требованиями Руководства на язык :)
Если просто откомпилировать ( без сборки ) программу, то ошибок нет. Ошибки возникают при сборке.
> Нет, ничего подобного. Сообщения
Да, действительно. В GPS "Check synax" и "Compile file" разные действия. !-)
Но, похоже, работает это не так, что и вызвало недоумение.
Да, работает это не так. Домысливать не стоит, лучше писать программы в соответствии с требованиями Руководства на язык :)
Из LRM это не очень очевидно ( то есть надо внимательно поползать по нему, чем я давно не занимался ). Собственно, от шаблона я ждал немного другого.
Что нужно было получить? Единообразную обработку для пар целых чисел ( INTEGER ) и чисел с фиксированной точкой ( decimal fixed point ), ну и принципе для любых типов чисел. ( В процессе уточнения задачи оказалось, что обработка всё-таки не единообразна, но это к обсуждению уже не отностится )
Моя задача решается немного по-другому. И это тоже не работает:
Ближайшее к искомому, что язык предоставляет - это т.наз. формальные пакеты. См. руководство языка, глава 12.7.
В данном случае не поможет точно по той же причине, по которой не проходит изначально предложенный мной вариант -- нельзя подствить впрямую _любой_ тип или пакет в качестве формального параметра настройки GENERIC'а, которые будут реально сопоставлены друг другу в теле создаваемого пакета. Но это сопставление ( в моём случае ) можно сделать в окружении пакета.
LRM в этой части ещё внимательно почитаю и поэкспериментирую с этим. Может, найду ещё какой-нибудь путь.
Спасибо.
Привожу работающий модельный фрагмент программы для нужного мне случая.
type BYTE is new INTEGER range 0 .. 255 ;
for BYTE'SIZE use 8 ;
type RECORD_TIMES is delta 0.001 digits 13 ;
package IIO is new TEXT_IO.INTEGER_IO ( INTEGER ) ;
use IIO ;
package BIO is new TEXT_IO.INTEGER_IO ( BYTE ) ;
use BIO ;
package DIO is new TEXT_IO.DECIMAL_IO ( RECORD_TIMES ) ;
use DIO ;
A : INTEGER := 0 ;
B : BYTE := 0 ;
C : RECORD_TIMES := 0.0 ;
generic
type COMPONENTS is private ;
with procedure GET
( SRC : in STRING ;
DST : out COMPONENTS ;
POS : out POSITIVE ) ;
procedure GET_ITEM_G
( DATA : in STRING ;
ITEM : out COMPONENTS ) ;
procedure GET_ITEM_G
( DATA : in STRING ;
ITEM : out COMPONENTS ) is
LAST_POS : POSITIVE := 1 ;
begin -- GET_ITEM_G
GET ( DATA , ITEM , LAST_POS ) ;
end GET_ITEM_G ;
procedure GET_ITEM is new GET_ITEM_G ( INTEGER , IIO.GET ) ; procedure GET_ITEM is new GET_ITEM_G ( BYTE , BIO.GET ) ;
procedure GET_ITEM is new GET_ITEM_G ( RECORD_TIMES , DIO.GET ) ;
Да, действительно. В GPS "Check synax" и "Compile file" разные действия. !-)
Это и логично: синтактический анализ не подразумевает генерации объектного кода. Соответственно, с одной стороны, возможна обработка исходных текстов, для которых невозможно сгенерировать объектный код (generic, spec, separate), с другой - отсутствует анализ ошибок, связанных с отображением типов данных на целевую машину и т.п.
Из LRM это не очень очевидно (
Мне трудновато судить, поскольку я по нему практически обучался грамоте, но верю :) В любом случае, рад слышать что вам удалось отыскать подходящее решение.
Чтобы оставить новое сообщение необходимо Зарегистрироваться и Войти