comp.lang.ada
 help / color / mirror / Atom feed
* How does Ada.Text_IO.Enumeration_IO work?
@ 2011-11-03  8:52 Jerry
  2011-11-03  9:27 ` AdaMagica
  2011-11-03 14:52 ` Adam Beneschan
  0 siblings, 2 replies; 8+ messages in thread
From: Jerry @ 2011-11-03  8:52 UTC (permalink / raw)


I don't understand how the following program works, specifically, how
instances of Ada.Text_IO.Enumeration_IO read input. I understand that
it will skip leading white space, leave anything after finding a
proper element including line terminator, that apostophe ' is a valid
character, and that it can raise an exception (quoting ARM):

"The exception Data_Error is propagated if the sequence input does not
have the required syntax, or if the identifier or character literal
does not correspond to a value of the subtype Enum."

I want the program to read input until a valid element is found, then
quit.


with Ada.Text_IO; use Ada.Text_IO;
with Ada.IO_Exceptions; use Ada.IO_Exceptions;
procedure Day_Proc is
    type Day_Type is (Sunday, Monday, Tuesday);
    Day : Day_Type;
    package Day_Type_IO is new Ada.Text_IO.Enumeration_IO(Day_Type);
    Have_Good_Value : Boolean;
begin
    Put("Enter a day: ");
    loop
        Have_Good_Value := True;
        begin
            Day_Type_IO.Get(Day);
            --Skip_Line; -- Doesn't matter if present or not.
        exception
        when Ada.IO_Exceptions.Data_Error =>
            Have_Good_Value := False;
            Put_Line("Exception raised");
        end;
        Put_Line(Boolean'image(Have_Good_Value));
        exit when Have_Good_Value;
    end loop;
    Put_Line("Your day is " & Day_Type'image(Day));
end Day_Proc;


This works as I expect for inputs such as

   Monday
Monday Friday
Friday Monday
Fri7day Monday
Friday ' Monday
Monday.
 etc.

but anytime the input contains a non-apostrophe punctuation mark
before a valid element, or an otherwise inproperly syntaxed element,
it loops endlessly, outputting Exception raised and FALSE for each
passage through the loop. For instance, these lines cause infinite
looping:

Friday. Monday
Friday.Monday
Friday ? Monday
Fri?day Monday
Friday 7Thursday Monday
This is (or is not) a comment
 etc.

It is correctly raising the exception upon encountering the bad input,
but why does it keep looping and not proceed past the bad input to
find the following correct element?

Jerry



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

* Re: How does Ada.Text_IO.Enumeration_IO work?
  2011-11-03  8:52 How does Ada.Text_IO.Enumeration_IO work? Jerry
@ 2011-11-03  9:27 ` AdaMagica
  2011-11-03 10:18   ` Jerry
  2011-11-03 14:52 ` Adam Beneschan
  1 sibling, 1 reply; 8+ messages in thread
From: AdaMagica @ 2011-11-03  9:27 UTC (permalink / raw)



A.10.10(8) ...reads an identifier according to the syntax of this
lexical element...

This means that reading stops as soon as a character is met that does
not belong to the syntax of enumerations. This means that reading must
use a look ahead. Otherwise it could not successfully read an input
string like
   Monday,
Here, reading stops after the character y, leaving the comma in the
input stream. Thus in your loop, after having read and output Monday,
reading begins with the comma and immediately stops again, raising the
exception, ad infinitum...



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

* Re: How does Ada.Text_IO.Enumeration_IO work?
  2011-11-03  9:27 ` AdaMagica
@ 2011-11-03 10:18   ` Jerry
  0 siblings, 0 replies; 8+ messages in thread
From: Jerry @ 2011-11-03 10:18 UTC (permalink / raw)


On Nov 3, 2:27 am, AdaMagica <christ-usch.gr...@t-online.de> wrote:
> A.10.10(8) ...reads an identifier according to the syntax of this
> lexical element...
>
> This means that reading stops as soon as a character is met that does
> not belong to the syntax of enumerations. This means that reading must
> use a look ahead. Otherwise it could not successfully read an input
> string like
>    Monday,
> Here, reading stops after the character y, leaving the comma in the
> input stream. Thus in your loop, after having read and output Monday,
> reading begins with the comma and immediately stops again, raising the
> exception, ad infinitum...

Actually, the input
  Monday,
is read correctly and the program terminates normally, apparently
because it found a correct element before having to deal with the
comma.

Jerry



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

* Re: How does Ada.Text_IO.Enumeration_IO work?
  2011-11-03  8:52 How does Ada.Text_IO.Enumeration_IO work? Jerry
  2011-11-03  9:27 ` AdaMagica
@ 2011-11-03 14:52 ` Adam Beneschan
  2011-11-04 22:46   ` Jerry
  1 sibling, 1 reply; 8+ messages in thread
From: Adam Beneschan @ 2011-11-03 14:52 UTC (permalink / raw)


On Nov 3, 1:52 am, Jerry <lancebo...@qwest.net> wrote:
> I don't understand how the following program works, specifically, how
> instances of Ada.Text_IO.Enumeration_IO read input. I understand that
> it will skip leading white space, leave anything after finding a
> proper element including line terminator, that apostophe ' is a valid
> character, and that it can raise an exception (quoting ARM):
>
> "The exception Data_Error is propagated if the sequence input does not
> have the required syntax, or if the identifier or character literal
> does not correspond to a value of the subtype Enum."
>
> I want the program to read input until a valid element is found, then
> quit.
>
> with Ada.Text_IO; use Ada.Text_IO;
> with Ada.IO_Exceptions; use Ada.IO_Exceptions;
> procedure Day_Proc is
>     type Day_Type is (Sunday, Monday, Tuesday);
>     Day : Day_Type;
>     package Day_Type_IO is new Ada.Text_IO.Enumeration_IO(Day_Type);
>     Have_Good_Value : Boolean;
> begin
>     Put("Enter a day: ");
>     loop
>         Have_Good_Value := True;
>         begin
>             Day_Type_IO.Get(Day);
>             --Skip_Line; -- Doesn't matter if present or not.
>         exception
>         when Ada.IO_Exceptions.Data_Error =>
>             Have_Good_Value := False;
>             Put_Line("Exception raised");
>         end;
>         Put_Line(Boolean'image(Have_Good_Value));
>         exit when Have_Good_Value;
>     end loop;
>     Put_Line("Your day is " & Day_Type'image(Day));
> end Day_Proc;
>
> This works as I expect for inputs such as
>
>    Monday
> Monday Friday
> Friday Monday
> Fri7day Monday
> Friday ' Monday
> Monday.
>  etc.
>
> but anytime the input contains a non-apostrophe punctuation mark
> before a valid element, or an otherwise inproperly syntaxed element,
> it loops endlessly, outputting Exception raised and FALSE for each
> passage through the loop. For instance, these lines cause infinite
> looping:
>
> Friday. Monday
> Friday.Monday
> Friday ? Monday
> Fri?day Monday
> Friday 7Thursday Monday
> This is (or is not) a comment
>  etc.
>
> It is correctly raising the exception upon encountering the bad input,
> but why does it keep looping and not proceed past the bad input to
> find the following correct element?

'Cuz the rules say so.  A.10.6(5) is the important one here: "Next,
characters are input only so long as the sequence input is an initial
sequence of an identifier or of a character literal (in particular,
input ceases when a line terminator is encountered). The character or
line terminator that causes input to cease remains available for
subsequent input."  A.10.6(10): "The exception Data_Error is
propagated by a Get procedure if the sequence finally input is not a
lexical element corresponding to the type, in particular if no
characters were input ...".  That's the case when your input (skipping
leading blanks) starts with an invalid character like a comma.  Since
the comma can't be the first character of an enumeration literal, the
comma "remains available for subsequent input", and thus "no
characters are input" and Data_Error is raised.

By the way, apostrophes are "allowed" but they have to be in the
correct syntax.  So if your line begins with

'ABCDE'

I believe the characters 'A will be input, but since 'AB cannot be the
start of an enumeration literal, input stops at that point, and B will
be the next character available for input.

                         -- Adam




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

* Re: How does Ada.Text_IO.Enumeration_IO work?
  2011-11-03 14:52 ` Adam Beneschan
@ 2011-11-04 22:46   ` Jerry
  2011-11-04 23:31     ` Adam Beneschan
  0 siblings, 1 reply; 8+ messages in thread
From: Jerry @ 2011-11-04 22:46 UTC (permalink / raw)


On Nov 3, 7:52 am, Adam Beneschan <a...@irvine.com> wrote:
> On Nov 3, 1:52 am, Jerry <lancebo...@qwest.net> wrote:
>
>
>
>
>
> > I don't understand how the following program works, specifically, how
> > instances of Ada.Text_IO.Enumeration_IO read input. I understand that
> > it will skip leading white space, leave anything after finding a
> > proper element including line terminator, that apostophe ' is a valid
> > character, and that it can raise an exception (quoting ARM):
>
> > "The exception Data_Error is propagated if the sequence input does not
> > have the required syntax, or if the identifier or character literal
> > does not correspond to a value of the subtype Enum."
>
> > I want the program to read input until a valid element is found, then
> > quit.
>
> > with Ada.Text_IO; use Ada.Text_IO;
> > with Ada.IO_Exceptions; use Ada.IO_Exceptions;
> > procedure Day_Proc is
> >     type Day_Type is (Sunday, Monday, Tuesday);
> >     Day : Day_Type;
> >     package Day_Type_IO is new Ada.Text_IO.Enumeration_IO(Day_Type);
> >     Have_Good_Value : Boolean;
> > begin
> >     Put("Enter a day: ");
> >     loop
> >         Have_Good_Value := True;
> >         begin
> >             Day_Type_IO.Get(Day);
> >             --Skip_Line; -- Doesn't matter if present or not.
> >         exception
> >         when Ada.IO_Exceptions.Data_Error =>
> >             Have_Good_Value := False;
> >             Put_Line("Exception raised");
> >         end;
> >         Put_Line(Boolean'image(Have_Good_Value));
> >         exit when Have_Good_Value;
> >     end loop;
> >     Put_Line("Your day is " & Day_Type'image(Day));
> > end Day_Proc;
>
> > This works as I expect for inputs such as
>
> >    Monday
> > Monday Friday
> > Friday Monday
> > Fri7day Monday
> > Friday ' Monday
> > Monday.
> >  etc.
>
> > but anytime the input contains a non-apostrophe punctuation mark
> > before a valid element, or an otherwise inproperly syntaxed element,
> > it loops endlessly, outputting Exception raised and FALSE for each
> > passage through the loop. For instance, these lines cause infinite
> > looping:
>
> > Friday. Monday
> > Friday.Monday
> > Friday ? Monday
> > Fri?day Monday
> > Friday 7Thursday Monday
> > This is (or is not) a comment
> >  etc.
>
> > It is correctly raising the exception upon encountering the bad input,
> > but why does it keep looping and not proceed past the bad input to
> > find the following correct element?
>
> 'Cuz the rules say so.  A.10.6(5) is the important one here: "Next,
> characters are input only so long as the sequence input is an initial
> sequence of an identifier or of a character literal (in particular,
> input ceases when a line terminator is encountered). The character or
> line terminator that causes input to cease remains available for
> subsequent input."  A.10.6(10): "The exception Data_Error is
> propagated by a Get procedure if the sequence finally input is not a
> lexical element corresponding to the type, in particular if no
> characters were input ...".  That's the case when your input (skipping
> leading blanks) starts with an invalid character like a comma.  Since
> the comma can't be the first character of an enumeration literal, the
> comma "remains available for subsequent input", and thus "no
> characters are input" and Data_Error is raised.
>
> By the way, apostrophes are "allowed" but they have to be in the
> correct syntax.  So if your line begins with
>
> 'ABCDE'
>
> I believe the characters 'A will be input, but since 'AB cannot be the
> start of an enumeration literal, input stops at that point, and B will
> be the next character available for input.
>
>                          -- Adam

[Not sure why my earlier reply didn't make it but here is a
reconstruction of it.]

Thanks, Adam. I believe that the clue for me is that "remains
available for subsequent input" means that it is available only to non-
enumeration input, characters excepted.

Jerry



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

* Re: How does Ada.Text_IO.Enumeration_IO work?
  2011-11-04 22:46   ` Jerry
@ 2011-11-04 23:31     ` Adam Beneschan
  2011-11-05  9:32       ` Dmitry A. Kazakov
  2011-11-06 22:42       ` Jerry
  0 siblings, 2 replies; 8+ messages in thread
From: Adam Beneschan @ 2011-11-04 23:31 UTC (permalink / raw)


On Nov 4, 3:46 pm, Jerry <lancebo...@qwest.net> wrote:

> > 'Cuz the rules say so.  A.10.6(5) is the important one here: "Next,
> > characters are input only so long as the sequence input is an initial
> > sequence of an identifier or of a character literal (in particular,
> > input ceases when a line terminator is encountered). The character or
> > line terminator that causes input to cease remains available for
> > subsequent input."  A.10.6(10): "The exception Data_Error is
> > propagated by a Get procedure if the sequence finally input is not a
> > lexical element corresponding to the type, in particular if no
> > characters were input ...".  That's the case when your input (skipping
> > leading blanks) starts with an invalid character like a comma.  Since
> > the comma can't be the first character of an enumeration literal, the
> > comma "remains available for subsequent input", and thus "no
> > characters are input" and Data_Error is raised.
>
> Thanks, Adam. I believe that the clue for me is that "remains
> available for subsequent input" means that it is available only to non-
> enumeration input, characters excepted.

I'm not sure what you mean by this.  If the first character in the
input (other than space) cannot be the start of an enumeration
literal, the input will stop right there; and that character remains
available in the input.  If you then try to perform input using
Enumeration_IO (without any other input routines in between), that
same character is "available" in the input but causes Enumeration_IO
to fail again for the same reason.  Perhaps there's some confusion
about what the RM means by "available".  "The character remains
available for subsequent input" means that *any* input routine will
see that character first (and could raise an exception if that
character is not legal).  It doesn't mean that the input routine will
succeed.  But you could suck the character up with Text_IO.Get (to get
one character), and then the character isn't available for input any
more.  I hope this doesn't confuse you more, but I couldn't tell from
your comment whether things were clear to you; and if not, I was
hoping to try to make it clearer.

                            -- Adam




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

* Re: How does Ada.Text_IO.Enumeration_IO work?
  2011-11-04 23:31     ` Adam Beneschan
@ 2011-11-05  9:32       ` Dmitry A. Kazakov
  2011-11-06 22:42       ` Jerry
  1 sibling, 0 replies; 8+ messages in thread
From: Dmitry A. Kazakov @ 2011-11-05  9:32 UTC (permalink / raw)


On Fri, 4 Nov 2011 16:31:33 -0700 (PDT), Adam Beneschan wrote:

> On Nov 4, 3:46�pm, Jerry <lancebo...@qwest.net> wrote:
> 
>>> 'Cuz the rules say so. �A.10.6(5) is the important one here: "Next,
>>> characters are input only so long as the sequence input is an initial
>>> sequence of an identifier or of a character literal (in particular,
>>> input ceases when a line terminator is encountered). The character or
>>> line terminator that causes input to cease remains available for
>>> subsequent input." �A.10.6(10): "The exception Data_Error is
>>> propagated by a Get procedure if the sequence finally input is not a
>>> lexical element corresponding to the type, in particular if no
>>> characters were input ...". �That's the case when your input (skipping
>>> leading blanks) starts with an invalid character like a comma. �Since
>>> the comma can't be the first character of an enumeration literal, the
>>> comma "remains available for subsequent input", and thus "no
>>> characters are input" and Data_Error is raised.
>>
>> Thanks, Adam. I believe that the clue for me is that "remains
>> available for subsequent input" means that it is available only to non-
>> enumeration input, characters excepted.
> 
> I'm not sure what you mean by this.  If the first character in the
> input (other than space) cannot be the start of an enumeration
> literal, the input will stop right there; and that character remains
> available in the input.  If you then try to perform input using
> Enumeration_IO (without any other input routines in between), that
> same character is "available" in the input but causes Enumeration_IO
> to fail again for the same reason.  Perhaps there's some confusion
> about what the RM means by "available".  "The character remains
> available for subsequent input" means that *any* input routine will
> see that character first (and could raise an exception if that
> character is not legal).  It doesn't mean that the input routine will
> succeed.  But you could suck the character up with Text_IO.Get (to get
> one character), and then the character isn't available for input any
> more.  I hope this doesn't confuse you more, but I couldn't tell from
> your comment whether things were clear to you; and if not, I was
> hoping to try to make it clearer.

For what it is worth. Any scanner when detects an error has only two
options:

1. Consume input and then raise an exception
2. Leave input as is and raise

As a side note, it is unfortunate that Enumeration_IO uses the same
exception (Data_Error) in both cases. The behavior 1 means: input
recognized but illegal. The behavior 2 means: nothing there, repeat.

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



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

* Re: How does Ada.Text_IO.Enumeration_IO work?
  2011-11-04 23:31     ` Adam Beneschan
  2011-11-05  9:32       ` Dmitry A. Kazakov
@ 2011-11-06 22:42       ` Jerry
  1 sibling, 0 replies; 8+ messages in thread
From: Jerry @ 2011-11-06 22:42 UTC (permalink / raw)


On Nov 4, 4:31 pm, Adam Beneschan <a...@irvine.com> wrote:
> On Nov 4, 3:46 pm, Jerry <lancebo...@qwest.net> wrote:
>
>
>
>
>
> > > 'Cuz the rules say so.  A.10.6(5) is the important one here: "Next,
> > > characters are input only so long as the sequence input is an initial
> > > sequence of an identifier or of a character literal (in particular,
> > > input ceases when a line terminator is encountered). The character or
> > > line terminator that causes input to cease remains available for
> > > subsequent input."  A.10.6(10): "The exception Data_Error is
> > > propagated by a Get procedure if the sequence finally input is not a
> > > lexical element corresponding to the type, in particular if no
> > > characters were input ...".  That's the case when your input (skipping
> > > leading blanks) starts with an invalid character like a comma.  Since
> > > the comma can't be the first character of an enumeration literal, the
> > > comma "remains available for subsequent input", and thus "no
> > > characters are input" and Data_Error is raised.
>
> > Thanks, Adam. I believe that the clue for me is that "remains
> > available for subsequent input" means that it is available only to non-
> > enumeration input, characters excepted.
>
> I'm not sure what you mean by this.  If the first character in the
> input (other than space) cannot be the start of an enumeration
> literal, the input will stop right there; and that character remains
> available in the input.  If you then try to perform input using
> Enumeration_IO (without any other input routines in between), that
> same character is "available" in the input but causes Enumeration_IO
> to fail again for the same reason.  Perhaps there's some confusion
> about what the RM means by "available".  "The character remains
> available for subsequent input" means that *any* input routine will
> see that character first (and could raise an exception if that
> character is not legal).  It doesn't mean that the input routine will
> succeed.  But you could suck the character up with Text_IO.Get (to get
> one character), and then the character isn't available for input any
> more.  I hope this doesn't confuse you more, but I couldn't tell from
> your comment whether things were clear to you; and if not, I was
> hoping to try to make it clearer.
>
>                             -- Adam

The source of confusion here is my poorly worded reply. What I meant
to say (he said, sounding like a politician) is that the character
will be "gotten" only by non-enumeration input attempts, character
types excepted. Both RM and you are clear.

Jerry



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

end of thread, other threads:[~2011-11-06 22:48 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-03  8:52 How does Ada.Text_IO.Enumeration_IO work? Jerry
2011-11-03  9:27 ` AdaMagica
2011-11-03 10:18   ` Jerry
2011-11-03 14:52 ` Adam Beneschan
2011-11-04 22:46   ` Jerry
2011-11-04 23:31     ` Adam Beneschan
2011-11-05  9:32       ` Dmitry A. Kazakov
2011-11-06 22:42       ` Jerry

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