Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ada: Why exactly is ""A" .. "F"" not discrete?

Program Text

type T is array ("A" .. "F") of Integer;

Compiler Console Output

hello.adb:4:22: discrete type required for range

Question

If my understanding is correct, clause 9 from chapter 3.6 of the Ada reference manual is the reason for the compiler raising an compilation error:

Each index_subtype_definition or discrete_subtype_definition in an array_type_definition defines an index subtype; its type (the index type) shall be discrete.

Hence, why exactly is "A" .. "F" not discrete? What does discrete exactly mean?

Background info

The syntax requirements for array type definitions are quoted below. Source: Ada Reference Manual

array_type_definition ::= unconstrained_array_definition | constrained_array_definition

constrained_array_definition ::= array (discrete_subtype_definition {, discrete_subtype_definition}) of component_definition

discrete_subtype_definition ::= discrete_subtype_indication | range

range ::=  range_attribute_reference | simple_expression .. simple_expression

simple_expression ::= [unary_adding_operator] term {binary_adding_operator term}

term ::= factor {multiplying_operator factor}

factor ::= primary [** primary] | abs primary | not primary

primary ::= numeric_literal | null | string_literal | aggregate | name | qualified_expression | allocator | (expression)
like image 631
Multisync Avatar asked Sep 14 '14 00:09

Multisync


2 Answers

This:

"A" .. "F"

does satisfy the syntax of a range; it consists of a simple_expression, followed by .., followed by another simple_expression. So it's not a syntax error.

It's still invalid; specifically it's a semantic error. The syntax isn't the only thing that determines whether a chunk of code is valid or not. For example, "foo" * 42 is a syntactically valid expression, but it's semantically invalid because there's no * operator for a string and an integer (unless you write your own).

A discrete type is either an integer type or an enumeration type. Integer, Character, and Boolean are examples of discrete types. Floating-point types, array types, pointer types, record types, and so forth are not discrete types, so expressions of those types can't be used in a range for a discrete_subtype_indication.

This:

type T is array ("A" .. "F") of Integer;

is probably supposed to be:

type T is array ('A' .. 'F') of Integer;

String literals are of type String, which is an array type. Character literals are of type Character, which is an enumeration type and therefore a discrete type.

You wrote in a comment on another answer:

Unfortunately I'm unable to replace the string literals by character literals and recompile the code ...

If that's the case, it's quite unfortunate. The code you've posted is simply invalid; it will not compile. Your only options are to modify it or not to use it.

like image 165
Keith Thompson Avatar answered Oct 22 '22 11:10

Keith Thompson


Ermm ... I think it is trying to tell you that you can't use String literals to specify ranges. You probably meant to use a character literal.

Reference:

  • http://archive.adaic.com/standards/83lrm/html/lrm-02-05.html

After all, the clauses quoted above are explicitely requiring string_literal to be used

You have misunderstood the Ada syntax specs. Specifically, you have missed this production:

name ::= simple_name
   | character_literal  | operator_symbol
   | indexed_component  | slice
   | selected_component | attribute 
like image 22
Stephen C Avatar answered Oct 22 '22 12:10

Stephen C