comp.lang.ada
 help / color / mirror / Atom feed
* Question about Ada.Unchecked_Conversion
@ 2004-10-29 12:46 Eric Jacoboni
  2004-10-29 14:22 ` Dmitry A. Kazakov
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Eric Jacoboni @ 2004-10-29 12:46 UTC (permalink / raw)


Hi

There is something i've probably not understood about
Ada.Unchecked_Conversion behavior, despite readings of Barnes and
RM95.

To illustrate my pb, let a String in which i want to count
various separators :

subtype T_Phrase is String(1..Lg_Max);
   
type T_S�parateur is (' ', Ht, Lf, ',' ,';', ':', '.', '?', '!');
for T_S�parateur'Size use Character'Size;

function Char_To_S�parateur is 
      new Ada.Unchecked_Conversion(Character, T_S�parateur);

Ma_Phrase : T_Phrase;

What i want to do is simply a test like this, in order to find
characters that are also separators:

if Char_To_S�parateur(Ma_Phrase(I)) in T_S�parateur then 
  ...
end if;

But this test always fails and i don't understand why. The logic seems
correct so i suppose it's a misunderstanding of Unchecked_Conversion?

Any clue?
-- 
�ric Jacoboni, n� il y a 1402497600 secondes



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about Ada.Unchecked_Conversion
  2004-10-29 12:46 Question about Ada.Unchecked_Conversion Eric Jacoboni
@ 2004-10-29 14:22 ` Dmitry A. Kazakov
  2004-10-29 14:26 ` Jean-Pierre Rosen
  2004-10-29 15:15 ` Nick Roberts
  2 siblings, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2004-10-29 14:22 UTC (permalink / raw)


On Fri, 29 Oct 2004 14:46:54 +0200, Eric Jacoboni wrote:

> There is something i've probably not understood about
> Ada.Unchecked_Conversion behavior, despite readings of Barnes and
> RM95.
> 
> To illustrate my pb, let a String in which i want to count
> various separators :
> 
> subtype T_Phrase is String(1..Lg_Max);
>    
> type T_S�parateur is (' ', Ht, Lf, ',' ,';', ':', '.', '?', '!');
> for T_S�parateur'Size use Character'Size;
> 
> function Char_To_S�parateur is 
>       new Ada.Unchecked_Conversion(Character, T_S�parateur);
> 
> Ma_Phrase : T_Phrase;
> 
> What i want to do is simply a test like this, in order to find
> characters that are also separators:
> 
> if Char_To_S�parateur(Ma_Phrase(I)) in T_S�parateur then 
>   ...
> end if;
> 
> But this test always fails and i don't understand why. The logic seems
> correct so i suppose it's a misunderstanding of Unchecked_Conversion?

The semantics of Unchecked_conversion differs from what you seem to imply.
What you want is probably just:

with Ada.Strings.Maps;        use Ada.Strings.Maps;
with Ada.Characters.Latin_1;  use Ada.Characters.Latin_1;
...
Separators : constant Character_Set := To_Set (" .,:!?" & HT & LF);
...
if Is_In (Ma_Phrase (I), Separators) then
   ...
end if;

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about Ada.Unchecked_Conversion
  2004-10-29 12:46 Question about Ada.Unchecked_Conversion Eric Jacoboni
  2004-10-29 14:22 ` Dmitry A. Kazakov
@ 2004-10-29 14:26 ` Jean-Pierre Rosen
  2004-10-29 15:15 ` Nick Roberts
  2 siblings, 0 replies; 8+ messages in thread
From: Jean-Pierre Rosen @ 2004-10-29 14:26 UTC (permalink / raw)


Eric Jacoboni a écrit :

> type T_Séparateur is (' ', Ht, Lf, ',' ,';', ':', '.', '?', '!');
Beware! This defines a new character type, not related in any way to 
Standard.Character. The default representation for enumeration type 
applies, therefore ' ' will be coded as 0, Ht as 1, etc.

-- 
---------------------------------------------------------
            J-P. Rosen (rosen@adalog.fr)
Visit Adalog's web site at http://www.adalog.fr



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about Ada.Unchecked_Conversion
  2004-10-29 12:46 Question about Ada.Unchecked_Conversion Eric Jacoboni
  2004-10-29 14:22 ` Dmitry A. Kazakov
  2004-10-29 14:26 ` Jean-Pierre Rosen
@ 2004-10-29 15:15 ` Nick Roberts
  2004-10-29 15:47   ` Eric Jacoboni
  2 siblings, 1 reply; 8+ messages in thread
From: Nick Roberts @ 2004-10-29 15:15 UTC (permalink / raw)


Eric Jacoboni wrote:

> subtype T_Phrase is String(1..Lg_Max);
>    
> type T_S�parateur is (' ', Ht, Lf, ',' ,';', ':', '.', '?', '!');
> for T_S�parateur'Size use Character'Size;
> 
> function Char_To_S�parateur is 
>       new Ada.Unchecked_Conversion(Character, T_S�parateur);
> 
> Ma_Phrase : T_Phrase;
> 
> What i want to do is simply a test like this, in order to find
> characters that are also separators:
> 
> if Char_To_S�parateur(Ma_Phrase(I)) in T_S�parateur then 
>   ...
> end if;
> 
> But this test always fails and i don't understand why. The logic seems
> correct so i suppose it's a misunderstanding of Unchecked_Conversion?

It certainly is a misunderstanding!

Unchecked_Conversion should be used only when you know for sure that
the bit representation of one type will have the meaning you intend
when interpreted as another type. In this case, the bit representation
for type T_S�parateur is likely to be totally different to that of
Standard.Character.

You don't need to use Unchecked_Conversion to convert between one
character type (T_S�parateur) and another (Standard.Character), and
you should not. You need only (and should) use predefined conversion
for this purpose.

However, in order to do the membership test, you do not want to
perform any conversion, because if a value of type Standard.Character
cannot be converted to T_S�parateur, Constraint_Error will be raised.

Instead, for this job, I recommend you use the facilities of the
standard package Ada.Strings.Maps. In this package, there is a type
Character_Set, with the operations you would expect, including
functions which make it easy (usually) to construct a set.

   with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
   with Ada.Strings.Maps; use Ada.Strings.Maps;
   ...
      S�parateurs: constant Character_Set := 
         To_Set( HT & LF & Space & ",;:.?!" );
   ...
      for i in Ma_Phrase'Range loop
         if Is_In( Ma_Phrase(i), S�parateurs ) then
            ...

There is another possible method, using an array that maps from
characters to a category (indicating some significance to each
character, in this case, whether it is a separator).

   with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
   ...
      Est_S�parateur: constant array (Character) of Boolean :=
         ( Space | HT | LF |
              ',' | ';' | ':' | '.' | '?' | '!' => True,
           others => False );
   ...
      for i in Ma_Phrase'Range loop
         if Est_S�parateur( Ma_Phrase(i) ) then
            ...

This method might be difficult for testing Wide_Characters, because
of the size of the array, and the type Character_Set can provide more
sophisticated functionality sometimes.

-- 
Nick Roberts



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about Ada.Unchecked_Conversion
  2004-10-29 15:15 ` Nick Roberts
@ 2004-10-29 15:47   ` Eric Jacoboni
  2004-10-30 10:23     ` skidmarks
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Jacoboni @ 2004-10-29 15:47 UTC (permalink / raw)


Nick Roberts <nick.roberts@acm.org> writes:

> It certainly is a misunderstanding!

Yes, i've understood now ;)

> There is another possible method, using an array that maps from
> characters to a category (indicating some significance to each
> character, in this case, whether it is a separator).

Before various answers, i wrote a Is_Separator(C : in Character)
return Boolean, which use a case construct to return true or false.

But i think i'm gonna use Maps as they are more flexible.

Thanks to you, to Jean-Pierre and Dmitry.

-- 
�ric Jacoboni, n� il y a 1402508624 secondes



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about Ada.Unchecked_Conversion
  2004-10-29 15:47   ` Eric Jacoboni
@ 2004-10-30 10:23     ` skidmarks
  2004-10-30 16:30       ` Nick Roberts
  0 siblings, 1 reply; 8+ messages in thread
From: skidmarks @ 2004-10-30 10:23 UTC (permalink / raw)


I don't have the full picture of what you're trying to do so my answer
may be off the mark.

When I build a custom lexor I include a (usually) 256 cell array. The
cell is mapped one-to-one with (any) 256 representation of the
character set in use, and 256 has the property of guaranteeing nor
constraint errors. The contents of each cell is a enumeration
representing the purpose of the mapped character. My lexer is built
around this.

For example:

  type enum { ign, sep, op, sym, num, hex, ... );

  type enum_Map is array ( Integer range 1 .. 256 ) of enum;

  Map : constant enum_Map := ( ign, ... sep, ... );

begin -- 

   if ( enum_Map( Character'Pos(char) ) = <> ) then <> end if;


or

   case enum_Map( Character'Pos(char) ) is
   when ign => <>
   when sep => <>
   when op  => <>
   when sym => <>
   when num => <>
  
 and so on.

I use a Moore Machine for my finite state machine, the arcs
representing the transition states (ign, sep, ...) and actions
associated with taking the transition.

Hope this helps.

art



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about Ada.Unchecked_Conversion
  2004-10-30 10:23     ` skidmarks
@ 2004-10-30 16:30       ` Nick Roberts
  2004-10-30 17:18         ` Eric Jacoboni
  0 siblings, 1 reply; 8+ messages in thread
From: Nick Roberts @ 2004-10-30 16:30 UTC (permalink / raw)


skidmarks wrote:

> I don't have the full picture of what you're trying to do so my answer
> may be off the mark.

I think you're dead right in principle, and slightly off only in a few
minor details.

> When I build a custom lexor I include a (usually) 256 cell array. The
> cell is mapped one-to-one with (any) 256 representation of the
> character set in use, and 256 has the property of guaranteeing nor
> constraint errors. The contents of each cell is a enumeration
> representing the purpose of the mapped character. My lexer is built
> around this.

Exactly how I do it. Which is not to say that it is necessarily the best
possible way, but I have used it with success in the past.

> For example:
> 
>   type enum { ign, sep, op, sym, num, hex, ... );

   type Character_Category is
      ( Ignore, Separator, Operator, Symbolic, [and so on] );

>   type enum_Map is array ( Integer range 1 .. 256 ) of enum;
> 
>   Map : constant enum_Map := ( ign, ... sep, ... );

   Cat_Of: constant array (Character) of Character_Category :=
      ( ',' | ';' | ':' | '(' | ')' => Separator,
        '+' | '-' | '*' | '/'       => Operator,
        [and so on],
        others                      => Ignore );

> begin -- 
> 
>    if ( enum_Map( Character'Pos(char) ) = <> ) then <> end if;

   if Cat_Of(Char) = Separator then
      ...

> or
> 
>    case enum_Map( Character'Pos(char) ) is
>    when ign => <>
>    when sep => <>
>    when op  => <>
>    when sym => <>
>    when num => <>

   case Cat_Of(Char) is
      when Ignore =>
         null;
      when Separator => 
         if Char = ')' then
            End_of_List := True;
         elsif Char /= ',' then
            raise Syntax_Error;
         end if;
         if Id = "" then
            raise Syntax_Error;
         end if;
         Append( Id_List, Id );
         Clear( Id );
         Get_Next_Character;
      [and so on]

>  and so on.
> 
> I use a Moore Machine for my finite state machine, the arcs
> representing the transition states (ign, sep, ...) and actions
> associated with taking the transition.

-- 
Nick Roberts



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Question about Ada.Unchecked_Conversion
  2004-10-30 16:30       ` Nick Roberts
@ 2004-10-30 17:18         ` Eric Jacoboni
  0 siblings, 0 replies; 8+ messages in thread
From: Eric Jacoboni @ 2004-10-30 17:18 UTC (permalink / raw)


Nick Roberts <nick.roberts@acm.org> writes:

>   type Character_Category is
>      ( Ignore, Separator, Operator, Symbolic, [and so on] );
>

>   Cat_Of: constant array (Character) of Character_Category :=
>      ( ',' | ';' | ':' | '(' | ')' => Separator,
>        '+' | '-' | '*' | '/'       => Operator,
>        [and so on],
>        others                      => Ignore );
>

>   if Cat_Of(Char) = Separator then


Oh yes, that's a fine trick, too.

Thanks.
-- 
�ric Jacoboni, n� il y a 1402600607 secondes



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2004-10-30 17:18 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-29 12:46 Question about Ada.Unchecked_Conversion Eric Jacoboni
2004-10-29 14:22 ` Dmitry A. Kazakov
2004-10-29 14:26 ` Jean-Pierre Rosen
2004-10-29 15:15 ` Nick Roberts
2004-10-29 15:47   ` Eric Jacoboni
2004-10-30 10:23     ` skidmarks
2004-10-30 16:30       ` Nick Roberts
2004-10-30 17:18         ` Eric Jacoboni

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox