AI22-0144-1
!standard A.10.8(8) 26-03-20 AI22-0144-1/05
!standard A.10.9(13)
!class Binding Interpretation
!status Revision-202Y 25-12-16
!status ARG Approved 9-0-0 25-12-11
!status work item 25-11-24
!status received 25-04-03
!assigned author Tucker Taft
!submitter Tucker Taft
!priority Low
!difficulty Easy
!qualifier Clarification
!subject Clarify Data_Error condition in Text_IO.Get
The description of when Data_Error is raised by Text_IO.Get is clarified.
A.10.8(17), describing Integer_IO.Get, says:
The exception Data_Error is propagated if the sequence input does not have the required syntax or if the value obtained is not of the subtype Num.
A.10.9(29) describing the Get routines of Float_IO, Fixed_IO, and Decimal_IO, says the same thing.
It is somewhat ambiguous exactly when, or whether the exception is raised, which affects the number of characters that have been read from the input. Is input consumed as long as it might have the legal syntax for a number, or does it somehow look ahead, and stop at the longest sequence that represents the legal syntax of a number?
For example, given "16#ABC<end-of-file>" should it return "16" or should it consume all of the input and then give Data_Error because there is a missing '#' terminator?
This AI confirms that it should continue reading as long as it might be legal.
We propose some small wording changes which should clarify that it continues consuming input as long as the sequence might be the prefix of a syntactically legal literal.
Modify A.10.8(8):
If the value of the parameter Width is zero, skips any leading blanks, line terminators, or page terminators, then reads a plus sign if present or (for a signed type only) a minus sign if present, then reads the longest possible sequence of characters matching the syntax of a numeric literal without a point{, or a prefix of such syntax}. If a nonzero value of Width is supplied, then exactly Width characters are input, or the characters (possibly none) up to a line terminator, whichever comes first; any skipped leading blanks are included in the count.
{AARM Ramification: When Width = 0, this means that you read the text so long as the input might have the syntax of a numeric literal without a point. For instance, if the input is "2#10101T", reading stops before the 'T' and Data_Error is raised. There is no backtracking to the '#', even though the fragment "2#10101" itself does not have the syntax of a numeric literal. The fragment is potentially the first part of a numeric literal (it would be fine if the T had been a '#'), so it is all read.}
Modify A.10.9(13):
If the value of the parameter Width is zero, skips any leading blanks, line terminators, or page terminators, then reads the longest possible sequence of characters matching the syntax of any of the following (see 2.4){, or a prefix of one of the following}:
Add after A.10.9(18):
AARM Ramification: When Width = 0, this means that you read the text so long as the input might have one of the given syntaxes. For instance, if the input is "2#1.Z", reading stops before the 'Z' and Data_Error is raised. There is no backtracking to the '#', even though the fragment "2#1." itself does not have one of the given syntaxes. The fragment is potentially the first part of several of the syntaxes (it would be fine if the Z had been a '#'), so it is all read.
The existing ACATS tests confirm the proposed interpretation, as do considerations of ease of implementation. It might be preferable to use the term "might" in the revised wording, but ISO is picky about that, and prefers the use of the term "can".
Here are examples that illustrate where Data_Error is raised, if at all
|
16#ABC<eof> => raises Data_Error after consuming the entire string 8#777ABC# => raises Data_Error after consuming the entire string 8#777XYZ# => raises Data_Error upon encountering the 'X' 2## => raises Data_Error after the first '#', that is, upon encountering the second '#[a][b]' |
Note that the syntax of a based numeric literal allows any extended hex digit independent of the base. It is a legality rule that the value of each digit must be less than the base, and the legality rule is checked after consuming the input, which is consumed while checking only the syntax.
@drepl
If the value of the parameter Width is zero, skips any leading blanks, line terminators, or page terminators, then reads a plus sign if present or (for a signed type only) a minus sign if present, then reads the longest possible sequence of characters matching the syntax of a numeric literal without a point. If a nonzero value of Width is supplied, then exactly Width characters are input, or the characters (possibly none) up to a line terminator, whichever comes first; any skipped leading blanks are included in the count.
@dby
If the value of the parameter Width is zero, skips any leading blanks, line terminators, or page terminators, then reads a plus sign if present or (for a signed type only) a minus sign if present, then reads the longest possible sequence of characters matching the syntax of a numeric literal without a point, or a prefix of such syntax. If a nonzero value of Width is supplied, then exactly Width characters are input, or the characters (possibly none) up to a line terminator, whichever comes first; any skipped leading blanks are included in the count.
@drepl
If the value of the parameter Width is zero, skips any leading blanks, line terminators, or page terminators, then reads the longest possible sequence of characters matching the syntax of any of the following (see @ref{2.4}):
@dby
If the value of the parameter Width is zero, skips any leading blanks, line terminators, or page terminators, then reads the longest possible sequence of characters matching the syntax of any of the following (see @ref{2.4}), or a prefix of one of the following:
These require C tests to check the number of characters consumed and whether Data_Error is raised. Existing C-Tests (from Ada 83!) test many of these cases.
This addresses ARG GitHub issue #133.
AI12-0066-1 (“issues we don’t intend to fix”) includes mail relevant to this AI.
[a]GNAT consumes the entire string contrary to the rule "the character raising the exception because it violates the syntax stays in the input stream".
[b]Interesting. I am not surprised that the syntax error isn't detected at the right moment in this case, so GNAT has at least this bug to fix in this area.