!standard 4.4(3/3) 12-11-29 AI12-0039-1/01
!standard 4.4(3.2/3)
!class binding interpretation 12-11-29
!status work item 12-11-29
!status received 12-10-09
!priority High
!difficulty Easy
!subject Syntax for membership expressions is ambiguous
!summary
The choices of a membership are syntactically simple_expressions, not
choice_expressions.
!question
It appears that the Ada 2012 syntax for membership expressions introduces
ambiguities.
Assume A, B, C, and D are all objects of type Boolean.
Consider
A in B and C
This could be interpreted as equivalent to either of these valid Ada
expressions:
(A in B) and C --or as
A in (B and C)
Similarly:
A in B in C | D can be interpreted as
A in (B in C) | D --or as
A in (B in C | D)
And:
A in B | C and D can be interpreted as
(A in B | C) and D --or as
A in B | (C and D)
Should the syntax be corrected to eliminate these ambiguities? (Yes.)
!recommendation
(See summary.)
!wording
Replace the last line of 4.4(3) with:
| *tested_*simple_expression [not] in membership_choice_list
Replace 4.4(3.2/3) with:
membership_choice ::= *choice_*simple_expression | range | subtype_mark
[Note: The change here is to replace "choice_expression" with
"simple_expression"; it would be ambiguous to use the usual insertion
and deletion marks in syntax, so this was not done here.]
In 4.5.2, paragraphs 3.1/3 [only the first use], 3.b/2, 4, 27/3, 27.1/3, 28.1/3,
28.2/3, 29/3, 30/3, 30.a, 30.1/2, 30.2/2, 30.3/2, and 32.a/3, in 4.9(11/3),
in 3.2.4(17/3), and in 8.6(27.1/3):
replace "simple_expression" with "*tested_*simple_expression".
In 4.5.2, paragraphs 3.1/3, 4.1/3, 28.1/3, in 4.9(11/3), and in 4.9(32.6/3):
replace "choice_expression" with "*choice_*simple_expression".
[Editor's note: There are a few cases where we don't have use the new prefixes,
especially for the latter cases (where we often say "of a membership_choice")
but it's going to be clearer to just them globally.]
In AARM 3.9.2(9.a/2), "expression" probably should be "*tested_*simple_expression",
although this isn't absolutely required.
[Editor's note: I searched for "membership", "choice_expression", and "simple_expression"
everywhere in the Standard (and AARM), and above are the changes that I found. There
seem to be enough. :-)]
!discussion
The basic intent was that the choice of a membership was syntactically
equivalent to the other uses of a choice (such as in a case statement).
Choice_expression was introduced to minimize the incompatibility with
existing choices in case statements. Unfortunately, we failed to notice
that doing so made the grammar ambiguous.
Clearly, the constituents of a membership choice either have to have higher
precedence than a membership or have to be enclosed in parentheses. If
a membership or logical operator is used in a membership choice, it has
to be parenthesized.
This is most easily accomplished by making a membership choice a
simple expression; this gives the proper precedence.
It is annoying that choices for memberships and case statements are subtly
different. Had this been a concern in 1994, probably choices would never
have been changed from simple_expression (in Ada 83) to expression (in Ada 95)
to choice_expression (in Ada 2012). But today, minimizing compatibility issues
with Ada 95 has to be more important than having everything exactly the same.
Note that this change has no effect the interpretation of on any syntax or
construct that existed in Ada 2005 or before; it only could change the
interpretation of new Ada 2012 expressions (of which there are hopefully
very few taking advantage of this ambiguity).
Unfortunately, changing the syntax this way makes all of the rules that
talk about "the simple_expression" and "a choice_expression" in 4.5.2 ambiguous.
As such, we have to give these syntax items prefixes to eliminate any confusion.
Thus we talk about "tested_simple_expression" and "choice_simple_expression".
!ACATS test
An ACATS B-Test could be created to test these rules, but we generally don't
test syntax rules (and the rules given in the Ada 2012 cannot be usefully
implemented).
!appendix
!topic Ambiguous grammar related to new membership test
!reference 4.4(2-3.2/3)
!from Adam Beneschan 12-10-09
!discussion
It appears to me that the new syntax for membership choice lists
(AI05-158) has introduced some ambiguities into the grammar. I found
this out while looking into a comp.lang.ada post from Maxim Reznik
(https://groups.google.com/forum/?hl=en&fromgroups=#!topic/comp.lang.ada/UYjxb612B_s).
Assume A, B, C, and D are all objects of type Boolean. Here are some
cases that I believe are ambiguous:
A in B and C [Maxim's original example] can be interpreted as
equivalent to either of these valid Ada expressions:
(A in B) and C --or as
A in (B and C)
The problem is that in the second interpretation, the
membership_choice_list can be one or more membership_choices, and a
membership_choice can be a choice_expression, and a choice_expression
can be two choice_relations connected by a logical operator ("and").
A couple other examples:
A in B in C | D can be interpreted as
A in (B in C) | D --or as
A in (B in C | D)
A in B | C and D can be interpreted as
(A in B | C) and D --or as
A in B | (C and D)
(Note: Although I cannot imagine ever writing a membership test with a
Boolean as the left-hand value, except in a simple case such as A in
Arr'Range where Arr is an array (Boolean range <>) of something, I
think it needs to be fixed since it's not good to have an ambiguous
grammar.)
I think the solution is probably to change
membership_choice ::= choice_expression | range | subtype_mark
to
membership_choice ::= simple_expression | range | subtype_mark
which means that in the new multiple-choice membership test, the
choices on the right side could not use logical or relational
operators except in parentheses. This wouldn't introduce any
incompatibilities except with the new form of membership test; in
particular, since discrete_choice_lists would still use
choice_expressions, rather than simple_expressions, CASE statements,
variant parts, and array aggregates wouldn't be affected.
If this change is made, then it might no longer make sense for
choice_expression and choice_relation to be defined in 4.4 since they
wouldn't be used in an expression; maybe it could be moved to 3.8.1.
But that's a less important issue. Also, if this change is made,
some wording changes would be needed in 4.5.2, and maybe elsewhere (I
haven't checked).
****************************************************************
From: Tucker Taft
Sent: Wednesday, October 10, 2012 7:47 AM
...
> I think the solution is probably to change
>
> membership_choice ::= choice_expression | range | subtype_mark
>
> to
>
> membership_choice ::= simple_expression | range | subtype_mark
I agree with your analysis.
> which means that in the new multiple-choice membership test, the
> choices on the right side could not use logical or relational
> operators except in parentheses. This wouldn't introduce any
> incompatibilities except with the new form of membership test; in
> particular, since discrete_choice_lists would still use
> choice_expressions, rather than simple_expressions, CASE statements,
> variant parts, and array aggregates wouldn't be affected.
>
> If this change is made, then it might no longer make sense for
> choice_expression and choice_relation to be defined in 4.4 since they
> wouldn't be used in an expression; maybe it could be moved to 3.8.1.
> But that's a less important issue. Also, if this change is made, some
> wording changes would be needed in 4.5.2, and maybe elsewhere (I
> haven't checked).
Yes, I agree it might make sense to move choice_expression, but that is a bigger
change which at this stage is probably not worth it.
****************************************************************