From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,c469fdacc2f3302b X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII Path: g2news2.google.com!postnews.google.com!s25g2000prd.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Dynamic Variant Record Creation Date: Tue, 16 Mar 2010 11:57:53 -0700 (PDT) Organization: http://groups.google.com Message-ID: References: NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1268765926 26580 127.0.0.1 (16 Mar 2010 18:58:46 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Tue, 16 Mar 2010 18:58:46 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: s25g2000prd.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618),gzip(gfe),gzip(gfe) Xref: g2news2.google.com comp.lang.ada:10568 Date: 2010-03-16T11:57:53-07:00 List-Id: On Mar 16, 10:11=A0am, Warren wrote: > I am trying to solve a lexer Ada design problem, using a > variant record (Token_Unit) definition: > > =A0 =A0 type Token_Type is ( > =A0 =A0 =A0 =A0 LEX_000, > =A0 =A0 =A0 =A0 LEX_BINARY, > =A0 =A0 =A0 =A0 LEX_SECTION, > =A0 =A0 =A0 =A0 '!', > =A0 =A0 =A0 =A0 '"', > =A0 =A0 =A0 =A0 '#', > =A0 =A0 =A0 =A0 '$', > =A0 =A0 =A0 =A0 ...etc.. > =A0 =A0 =A0 =A0 '^', > =A0 =A0 =A0 =A0 '_', > =A0 =A0 =A0 =A0 '`', > =A0 =A0 =A0 =A0 LEX_SFUN3, > =A0 =A0 =A0 =A0 LEX_SFUN2, > =A0 =A0 =A0 =A0 LEX_SFUN1, > =A0 =A0 =A0 =A0 LEX_SFUNN, > =A0 =A0 =A0 =A0 LEX_FUN3, > =A0 =A0 =A0 =A0 LEX_FUN2, > =A0 =A0 =A0 =A0 LEX_FUN1, > =A0 =A0 =A0 =A0 LEX_FUNN, > =A0 =A0 =A0 =A0 ...etc... > =A0 =A0 =A0 =A0 LEX_EOF > =A0 =A0 ); > > =A0 =A0 type Token_Unit(Token : Token_Type :=3D LEX_EOF) is > =A0 =A0 =A0 =A0 record > =A0 =A0 =A0 =A0 =A0 =A0 case Token is > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 when LEX_SFUN3 | LEX_SFUN2 | LEX_SFUN1 | = LEX_SFUNN > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| LEX_FUN3 =A0| LEX_FUN2 =A0| LEX_= FUN1 =A0| LEX_FUNN =3D> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 Func : =A0 =A0 =A0Func_Type; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 when LEX_IDENT | LEX_SIDENT | LEX_LNUMBER= | LEX_NUMBER > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| LEX_HEX =A0 | LEX_STRLIT | LEX_I= NLREM =A0| LEX_FLOAT > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| LEX_REM =3D> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 ID : =A0 =A0 =A0 =A0String_ID; = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 when others =3D> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 null; > =A0 =A0 =A0 =A0 =A0 =A0 end case; > =A0 =A0 =A0 =A0 end record; > > =A0 =A0 procedure Get_Token(Object : in out Lexer; Token : out Token_Unit= ) is > > =A0 =A0 =A0 =A0 procedure Emit_Token(T : Token_Type) is > =A0 =A0 =A0 =A0 =A0 =A0 T : Token_Type :=3D Token_Type'Val(Character'Pos(= Ch)); > =A0 =A0 =A0 =A0 begin > =A0 =A0 =A0 =A0 =A0 =A0 Token :=3D ( Token =3D> T ); > =A0 =A0 =A0 =A0 end; > > =A0 =A0 =A0 =A0 ... =A0 =A0 =A0 =A0 > > =A0 =A0 end; > > In the above, I need to create a Token_Unit from =A0 =A0 =A0 =A0 =A0 =A0 > a single character (there is no "id" in this case). And how is the compiler supposed to know that there is no "id"? When you use a record aggregate, you need to specify values for every component of the record. If the record has a variant part, then the compiler won't know what components have to be specified unless it knows what the discriminant is going to be; and it doesn't know what the discriminants are going to be unless the value of the discriminant is static. That's why you get the error you're getting: > But the issue is this: =A0 =A0 > > *.adb:339:33: value for discriminant "token" must be static > *.adb:339:33: "T" is not static constant or named number (RM 4.9(5)) You can't get what you want with an aggregate, but Georg's solution will give you some of what you want, at least. However, this will leave all the components (besides the discriminants) uninitialized, and you'll need to assign values into them. By the way, now that Ada 2005 has the <> construct for aggregates, it's just occurred to me that maybe 4.3.1(17) can be relaxed a bit, to make it legal to specify a record aggregate with a nonstatic discriminant for a variant record, *if* the only component associations for aggregates are components that are not in variant parts *and* there is an others=3D><> in the aggregate (or something along those lines). I don't know whether it's worthwhile, though. (It wouldn't help too much in this exact example, since there are no non-variant components, but if it were expanded to include, say, a source file name, line number, and column number for each Token_Unit, then there would be some benefit.) I'll consider making a proposal for this, depending on how loud a groan Randy, Bob, etc., make when they read this idea... :) -- Adam