]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - crypto/heimdal/lib/asn1/parse.y
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / crypto / heimdal / lib / asn1 / parse.y
1 /*
2  * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan
3  * (Royal Institute of Technology, Stockholm, Sweden). 
4  * All rights reserved. 
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met: 
9  *
10  * 1. Redistributions of source code must retain the above copyright 
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright 
14  *    notice, this list of conditions and the following disclaimer in the 
15  *    documentation and/or other materials provided with the distribution. 
16  *
17  * 3. Neither the name of the Institute nor the names of its contributors 
18  *    may be used to endorse or promote products derived from this software 
19  *    without specific prior written permission. 
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
31  * SUCH DAMAGE. 
32  */
33
34 /* $Id: parse.y 21597 2007-07-16 18:48:58Z lha $ */
35
36 %{
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include "symbol.h"
44 #include "lex.h"
45 #include "gen_locl.h"
46 #include "der.h"
47
48 RCSID("$Id: parse.y 21597 2007-07-16 18:48:58Z lha $");
49
50 static Type *new_type (Typetype t);
51 static struct constraint_spec *new_constraint_spec(enum ctype);
52 static Type *new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype);
53 void yyerror (const char *);
54 static struct objid *new_objid(const char *label, int value);
55 static void add_oid_to_tail(struct objid *, struct objid *);
56 static void fix_labels(Symbol *s);
57
58 struct string_list {
59     char *string;
60     struct string_list *next;
61 };
62
63 %}
64
65 %union {
66     int constant;
67     struct value *value;
68     struct range *range;
69     char *name;
70     Type *type;
71     Member *member;
72     struct objid *objid;
73     char *defval;
74     struct string_list *sl;
75     struct tagtype tag;
76     struct memhead *members;
77     struct constraint_spec *constraint_spec;
78 }
79
80 %token kw_ABSENT
81 %token kw_ABSTRACT_SYNTAX
82 %token kw_ALL
83 %token kw_APPLICATION
84 %token kw_AUTOMATIC
85 %token kw_BEGIN
86 %token kw_BIT
87 %token kw_BMPString
88 %token kw_BOOLEAN
89 %token kw_BY
90 %token kw_CHARACTER
91 %token kw_CHOICE
92 %token kw_CLASS
93 %token kw_COMPONENT
94 %token kw_COMPONENTS
95 %token kw_CONSTRAINED
96 %token kw_CONTAINING
97 %token kw_DEFAULT
98 %token kw_DEFINITIONS
99 %token kw_EMBEDDED
100 %token kw_ENCODED
101 %token kw_END
102 %token kw_ENUMERATED
103 %token kw_EXCEPT
104 %token kw_EXPLICIT
105 %token kw_EXPORTS
106 %token kw_EXTENSIBILITY
107 %token kw_EXTERNAL
108 %token kw_FALSE
109 %token kw_FROM
110 %token kw_GeneralString
111 %token kw_GeneralizedTime
112 %token kw_GraphicString
113 %token kw_IA5String
114 %token kw_IDENTIFIER
115 %token kw_IMPLICIT
116 %token kw_IMPLIED
117 %token kw_IMPORTS
118 %token kw_INCLUDES
119 %token kw_INSTANCE
120 %token kw_INTEGER
121 %token kw_INTERSECTION
122 %token kw_ISO646String
123 %token kw_MAX
124 %token kw_MIN
125 %token kw_MINUS_INFINITY
126 %token kw_NULL
127 %token kw_NumericString
128 %token kw_OBJECT
129 %token kw_OCTET
130 %token kw_OF
131 %token kw_OPTIONAL
132 %token kw_ObjectDescriptor
133 %token kw_PATTERN
134 %token kw_PDV
135 %token kw_PLUS_INFINITY
136 %token kw_PRESENT
137 %token kw_PRIVATE
138 %token kw_PrintableString
139 %token kw_REAL
140 %token kw_RELATIVE_OID
141 %token kw_SEQUENCE
142 %token kw_SET
143 %token kw_SIZE
144 %token kw_STRING
145 %token kw_SYNTAX
146 %token kw_T61String
147 %token kw_TAGS
148 %token kw_TRUE
149 %token kw_TYPE_IDENTIFIER
150 %token kw_TeletexString
151 %token kw_UNION
152 %token kw_UNIQUE
153 %token kw_UNIVERSAL
154 %token kw_UTCTime
155 %token kw_UTF8String
156 %token kw_UniversalString
157 %token kw_VideotexString
158 %token kw_VisibleString
159 %token kw_WITH
160
161 %token RANGE
162 %token EEQUAL
163 %token ELLIPSIS
164
165 %token <name> IDENTIFIER  referencename
166 %token <name> STRING
167
168 %token <constant> NUMBER
169 %type <constant> SignedNumber
170 %type <constant> Class tagenv
171
172 %type <value> Value
173 %type <value> BuiltinValue
174 %type <value> IntegerValue
175 %type <value> BooleanValue
176 %type <value> ObjectIdentifierValue
177 %type <value> CharacterStringValue
178 %type <value> NullValue
179 %type <value> DefinedValue
180 %type <value> ReferencedValue
181 %type <value> Valuereference
182
183 %type <type> Type
184 %type <type> BuiltinType
185 %type <type> BitStringType
186 %type <type> BooleanType
187 %type <type> ChoiceType
188 %type <type> ConstrainedType
189 %type <type> EnumeratedType
190 %type <type> IntegerType
191 %type <type> NullType
192 %type <type> OctetStringType
193 %type <type> SequenceType
194 %type <type> SequenceOfType
195 %type <type> SetType
196 %type <type> SetOfType
197 %type <type> TaggedType
198 %type <type> ReferencedType
199 %type <type> DefinedType
200 %type <type> UsefulType
201 %type <type> ObjectIdentifierType
202 %type <type> CharacterStringType
203 %type <type> RestrictedCharactedStringType
204
205 %type <tag> Tag
206
207 %type <member> ComponentType
208 %type <member> NamedBit
209 %type <member> NamedNumber
210 %type <member> NamedType
211 %type <members> ComponentTypeList 
212 %type <members> Enumerations
213 %type <members> NamedBitList
214 %type <members> NamedNumberList
215
216 %type <objid> objid objid_list objid_element objid_opt
217 %type <range> range size
218
219 %type <sl> referencenames
220
221 %type <constraint_spec> Constraint
222 %type <constraint_spec> ConstraintSpec
223 %type <constraint_spec> GeneralConstraint
224 %type <constraint_spec> ContentsConstraint
225 %type <constraint_spec> UserDefinedConstraint
226
227
228
229 %start ModuleDefinition
230
231 %%
232
233 ModuleDefinition: IDENTIFIER objid_opt kw_DEFINITIONS TagDefault ExtensionDefault
234                         EEQUAL kw_BEGIN ModuleBody kw_END
235                 {
236                         checkundefined();
237                 }
238                 ;
239
240 TagDefault      : kw_EXPLICIT kw_TAGS
241                 | kw_IMPLICIT kw_TAGS
242                       { error_message("implicit tagging is not supported"); }
243                 | kw_AUTOMATIC kw_TAGS
244                       { error_message("automatic tagging is not supported"); }
245                 | /* empty */
246                 ;
247
248 ExtensionDefault: kw_EXTENSIBILITY kw_IMPLIED
249                       { error_message("no extensibility options supported"); }
250                 | /* empty */
251                 ;
252
253 ModuleBody      : /* Exports */ Imports AssignmentList
254                 | /* empty */
255                 ;
256
257 Imports         : kw_IMPORTS SymbolsImported ';'
258                 | /* empty */
259                 ;
260
261 SymbolsImported : SymbolsFromModuleList
262                 | /* empty */
263                 ;
264
265 SymbolsFromModuleList: SymbolsFromModule
266                 | SymbolsFromModuleList SymbolsFromModule
267                 ;
268
269 SymbolsFromModule: referencenames kw_FROM IDENTIFIER objid_opt
270                 { 
271                     struct string_list *sl;
272                     for(sl = $1; sl != NULL; sl = sl->next) {
273                         Symbol *s = addsym(sl->string);
274                         s->stype = Stype;
275                     }
276                     add_import($3);
277                 }
278                 ;
279
280 AssignmentList  : Assignment
281                 | Assignment AssignmentList
282                 ;
283
284 Assignment      : TypeAssignment
285                 | ValueAssignment
286                 ;
287
288 referencenames  : IDENTIFIER ',' referencenames
289                 {
290                     $$ = emalloc(sizeof(*$$));
291                     $$->string = $1;
292                     $$->next = $3;
293                 }
294                 | IDENTIFIER
295                 {
296                     $$ = emalloc(sizeof(*$$));
297                     $$->string = $1;
298                     $$->next = NULL;
299                 }
300                 ;
301
302 TypeAssignment  : IDENTIFIER EEQUAL Type
303                 {
304                     Symbol *s = addsym ($1);
305                     s->stype = Stype;
306                     s->type = $3;
307                     fix_labels(s);
308                     generate_type (s);
309                 }
310                 ;
311
312 Type            : BuiltinType
313                 | ReferencedType
314                 | ConstrainedType
315                 ;
316
317 BuiltinType     : BitStringType
318                 | BooleanType
319                 | CharacterStringType
320                 | ChoiceType
321                 | EnumeratedType
322                 | IntegerType
323                 | NullType
324                 | ObjectIdentifierType
325                 | OctetStringType
326                 | SequenceType
327                 | SequenceOfType
328                 | SetType
329                 | SetOfType
330                 | TaggedType
331                 ;
332
333 BooleanType     : kw_BOOLEAN
334                 {
335                         $$ = new_tag(ASN1_C_UNIV, UT_Boolean, 
336                                      TE_EXPLICIT, new_type(TBoolean));
337                 }
338                 ;
339
340 range           : '(' Value RANGE Value ')'
341                 {
342                     if($2->type != integervalue)
343                         error_message("Non-integer used in first part of range");
344                     if($2->type != integervalue)
345                         error_message("Non-integer in second part of range");
346                     $$ = ecalloc(1, sizeof(*$$));
347                     $$->min = $2->u.integervalue;
348                     $$->max = $4->u.integervalue;
349                 }
350                 | '(' Value RANGE kw_MAX ')'
351                 {               
352                     if($2->type != integervalue)
353                         error_message("Non-integer in first part of range");
354                     $$ = ecalloc(1, sizeof(*$$));
355                     $$->min = $2->u.integervalue;
356                     $$->max = $2->u.integervalue - 1;
357                 }
358                 | '(' kw_MIN RANGE Value ')'
359                 {               
360                     if($4->type != integervalue)
361                         error_message("Non-integer in second part of range");
362                     $$ = ecalloc(1, sizeof(*$$));
363                     $$->min = $4->u.integervalue + 2;
364                     $$->max = $4->u.integervalue;
365                 }
366                 | '(' Value ')'
367                 {
368                     if($2->type != integervalue)
369                         error_message("Non-integer used in limit");
370                     $$ = ecalloc(1, sizeof(*$$));
371                     $$->min = $2->u.integervalue;
372                     $$->max = $2->u.integervalue;
373                 }
374                 ;
375
376
377 IntegerType     : kw_INTEGER
378                 {
379                         $$ = new_tag(ASN1_C_UNIV, UT_Integer, 
380                                      TE_EXPLICIT, new_type(TInteger));
381                 }
382                 | kw_INTEGER range
383                 {
384                         $$ = new_type(TInteger);
385                         $$->range = $2;
386                         $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
387                 }
388                 | kw_INTEGER '{' NamedNumberList '}'
389                 {
390                   $$ = new_type(TInteger);
391                   $$->members = $3;
392                   $$ = new_tag(ASN1_C_UNIV, UT_Integer, TE_EXPLICIT, $$);
393                 }
394                 ;
395
396 NamedNumberList : NamedNumber
397                 {
398                         $$ = emalloc(sizeof(*$$));
399                         ASN1_TAILQ_INIT($$);
400                         ASN1_TAILQ_INSERT_HEAD($$, $1, members);
401                 }
402                 | NamedNumberList ',' NamedNumber
403                 {
404                         ASN1_TAILQ_INSERT_TAIL($1, $3, members);
405                         $$ = $1;
406                 }
407                 | NamedNumberList ',' ELLIPSIS
408                         { $$ = $1; } /* XXX used for Enumerations */
409                 ;
410
411 NamedNumber     : IDENTIFIER '(' SignedNumber ')'
412                 {
413                         $$ = emalloc(sizeof(*$$));
414                         $$->name = $1;
415                         $$->gen_name = estrdup($1);
416                         output_name ($$->gen_name);
417                         $$->val = $3;
418                         $$->optional = 0;
419                         $$->ellipsis = 0;
420                         $$->type = NULL;
421                 }
422                 ;
423
424 EnumeratedType  : kw_ENUMERATED '{' Enumerations '}'
425                 {
426                   $$ = new_type(TInteger);
427                   $$->members = $3;
428                   $$ = new_tag(ASN1_C_UNIV, UT_Enumerated, TE_EXPLICIT, $$);
429                 }
430                 ;
431
432 Enumerations    : NamedNumberList /* XXX */
433                 ;
434
435 BitStringType   : kw_BIT kw_STRING
436                 {
437                   $$ = new_type(TBitString);
438                   $$->members = emalloc(sizeof(*$$->members));
439                   ASN1_TAILQ_INIT($$->members);
440                   $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
441                 }
442                 | kw_BIT kw_STRING '{' NamedBitList '}'
443                 {
444                   $$ = new_type(TBitString);
445                   $$->members = $4;
446                   $$ = new_tag(ASN1_C_UNIV, UT_BitString, TE_EXPLICIT, $$);
447                 }
448                 ;
449
450 ObjectIdentifierType: kw_OBJECT kw_IDENTIFIER
451                 {
452                         $$ = new_tag(ASN1_C_UNIV, UT_OID, 
453                                      TE_EXPLICIT, new_type(TOID));
454                 }
455                 ;
456 OctetStringType : kw_OCTET kw_STRING size
457                 {
458                     Type *t = new_type(TOctetString);
459                     t->range = $3;
460                     $$ = new_tag(ASN1_C_UNIV, UT_OctetString, 
461                                  TE_EXPLICIT, t);
462                 }
463                 ;
464
465 NullType        : kw_NULL
466                 {
467                         $$ = new_tag(ASN1_C_UNIV, UT_Null, 
468                                      TE_EXPLICIT, new_type(TNull));
469                 }
470                 ;
471
472 size            :
473                 { $$ = NULL; }
474                 | kw_SIZE range
475                 { $$ = $2; }
476                 ;
477
478
479 SequenceType    : kw_SEQUENCE '{' /* ComponentTypeLists */ ComponentTypeList '}'
480                 {
481                   $$ = new_type(TSequence);
482                   $$->members = $3;
483                   $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
484                 }
485                 | kw_SEQUENCE '{' '}'
486                 {
487                   $$ = new_type(TSequence);
488                   $$->members = NULL;
489                   $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
490                 }
491                 ;
492
493 SequenceOfType  : kw_SEQUENCE size kw_OF Type
494                 {
495                   $$ = new_type(TSequenceOf);
496                   $$->range = $2;
497                   $$->subtype = $4;
498                   $$ = new_tag(ASN1_C_UNIV, UT_Sequence, TE_EXPLICIT, $$);
499                 }
500                 ;
501
502 SetType         : kw_SET '{' /* ComponentTypeLists */ ComponentTypeList '}'
503                 {
504                   $$ = new_type(TSet);
505                   $$->members = $3;
506                   $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
507                 }
508                 | kw_SET '{' '}'
509                 {
510                   $$ = new_type(TSet);
511                   $$->members = NULL;
512                   $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
513                 }
514                 ;
515
516 SetOfType       : kw_SET kw_OF Type
517                 {
518                   $$ = new_type(TSetOf);
519                   $$->subtype = $3;
520                   $$ = new_tag(ASN1_C_UNIV, UT_Set, TE_EXPLICIT, $$);
521                 }
522                 ;
523
524 ChoiceType      : kw_CHOICE '{' /* AlternativeTypeLists */ ComponentTypeList '}'
525                 {
526                   $$ = new_type(TChoice);
527                   $$->members = $3;
528                 }
529                 ;
530
531 ReferencedType  : DefinedType
532                 | UsefulType
533                 ;
534
535 DefinedType     : IDENTIFIER
536                 {
537                   Symbol *s = addsym($1);
538                   $$ = new_type(TType);
539                   if(s->stype != Stype && s->stype != SUndefined)
540                     error_message ("%s is not a type\n", $1);
541                   else
542                     $$->symbol = s;
543                 }
544                 ;
545
546 UsefulType      : kw_GeneralizedTime
547                 {
548                         $$ = new_tag(ASN1_C_UNIV, UT_GeneralizedTime, 
549                                      TE_EXPLICIT, new_type(TGeneralizedTime));
550                 }
551                 | kw_UTCTime
552                 {
553                         $$ = new_tag(ASN1_C_UNIV, UT_UTCTime, 
554                                      TE_EXPLICIT, new_type(TUTCTime));
555                 }
556                 ;
557
558 ConstrainedType : Type Constraint
559                 {
560                     /* if (Constraint.type == contentConstrant) {
561                        assert(Constraint.u.constraint.type == octetstring|bitstring-w/o-NamedBitList); // remember to check type reference too
562                        if (Constraint.u.constraint.type) {
563                          assert((Constraint.u.constraint.type.length % 8) == 0);
564                        }
565                       }
566                       if (Constraint.u.constraint.encoding) {
567                         type == der-oid|ber-oid
568                       }
569                     */
570                 }
571                 ;
572
573
574 Constraint      : '(' ConstraintSpec ')'
575                 {
576                     $$ = $2;
577                 }
578                 ;
579
580 ConstraintSpec  : GeneralConstraint
581                 ;
582
583 GeneralConstraint: ContentsConstraint
584                 | UserDefinedConstraint
585                 ;
586
587 ContentsConstraint: kw_CONTAINING Type
588                 {
589                     $$ = new_constraint_spec(CT_CONTENTS);
590                     $$->u.content.type = $2;
591                     $$->u.content.encoding = NULL;
592                 }
593                 | kw_ENCODED kw_BY Value
594                 {
595                     if ($3->type != objectidentifiervalue)
596                         error_message("Non-OID used in ENCODED BY constraint");
597                     $$ = new_constraint_spec(CT_CONTENTS);
598                     $$->u.content.type = NULL;
599                     $$->u.content.encoding = $3;
600                 }
601                 | kw_CONTAINING Type kw_ENCODED kw_BY Value
602                 {
603                     if ($5->type != objectidentifiervalue)
604                         error_message("Non-OID used in ENCODED BY constraint");
605                     $$ = new_constraint_spec(CT_CONTENTS);
606                     $$->u.content.type = $2;
607                     $$->u.content.encoding = $5;
608                 }
609                 ;
610
611 UserDefinedConstraint: kw_CONSTRAINED kw_BY '{' '}'
612                 {
613                     $$ = new_constraint_spec(CT_USER);
614                 }
615                 ;
616
617 TaggedType      : Tag tagenv Type
618                 {
619                         $$ = new_type(TTag);
620                         $$->tag = $1;
621                         $$->tag.tagenv = $2;
622                         if($3->type == TTag && $2 == TE_IMPLICIT) {
623                                 $$->subtype = $3->subtype;
624                                 free($3);
625                         } else
626                                 $$->subtype = $3;
627                 }
628                 ;
629
630 Tag             : '[' Class NUMBER ']'
631                 {
632                         $$.tagclass = $2;
633                         $$.tagvalue = $3;
634                         $$.tagenv = TE_EXPLICIT;
635                 }
636                 ;
637
638 Class           : /* */
639                 {
640                         $$ = ASN1_C_CONTEXT;
641                 }
642                 | kw_UNIVERSAL
643                 {
644                         $$ = ASN1_C_UNIV;
645                 }
646                 | kw_APPLICATION
647                 {
648                         $$ = ASN1_C_APPL;
649                 }
650                 | kw_PRIVATE
651                 {
652                         $$ = ASN1_C_PRIVATE;
653                 }
654                 ;
655
656 tagenv          : /* */
657                 {
658                         $$ = TE_EXPLICIT;
659                 }
660                 | kw_EXPLICIT
661                 {
662                         $$ = TE_EXPLICIT;
663                 }
664                 | kw_IMPLICIT
665                 {
666                         $$ = TE_IMPLICIT;
667                 }
668                 ;
669
670
671 ValueAssignment : IDENTIFIER Type EEQUAL Value
672                 {
673                         Symbol *s;
674                         s = addsym ($1);
675
676                         s->stype = SValue;
677                         s->value = $4;
678                         generate_constant (s);
679                 }
680                 ;
681
682 CharacterStringType: RestrictedCharactedStringType
683                 ;
684
685 RestrictedCharactedStringType: kw_GeneralString
686                 {
687                         $$ = new_tag(ASN1_C_UNIV, UT_GeneralString, 
688                                      TE_EXPLICIT, new_type(TGeneralString));
689                 }
690                 | kw_UTF8String
691                 {
692                         $$ = new_tag(ASN1_C_UNIV, UT_UTF8String, 
693                                      TE_EXPLICIT, new_type(TUTF8String));
694                 }
695                 | kw_PrintableString
696                 {
697                         $$ = new_tag(ASN1_C_UNIV, UT_PrintableString, 
698                                      TE_EXPLICIT, new_type(TPrintableString));
699                 }
700                 | kw_VisibleString
701                 {
702                         $$ = new_tag(ASN1_C_UNIV, UT_VisibleString, 
703                                      TE_EXPLICIT, new_type(TVisibleString));
704                 }
705                 | kw_IA5String
706                 {
707                         $$ = new_tag(ASN1_C_UNIV, UT_IA5String, 
708                                      TE_EXPLICIT, new_type(TIA5String));
709                 }
710                 | kw_BMPString
711                 {
712                         $$ = new_tag(ASN1_C_UNIV, UT_BMPString, 
713                                      TE_EXPLICIT, new_type(TBMPString));
714                 }
715                 | kw_UniversalString
716                 {
717                         $$ = new_tag(ASN1_C_UNIV, UT_UniversalString, 
718                                      TE_EXPLICIT, new_type(TUniversalString));
719                 }
720
721                 ;
722
723 ComponentTypeList: ComponentType
724                 {
725                         $$ = emalloc(sizeof(*$$));
726                         ASN1_TAILQ_INIT($$);
727                         ASN1_TAILQ_INSERT_HEAD($$, $1, members);
728                 }
729                 | ComponentTypeList ',' ComponentType
730                 {
731                         ASN1_TAILQ_INSERT_TAIL($1, $3, members);
732                         $$ = $1;
733                 }
734                 | ComponentTypeList ',' ELLIPSIS
735                 {
736                         struct member *m = ecalloc(1, sizeof(*m));
737                         m->name = estrdup("...");
738                         m->gen_name = estrdup("asn1_ellipsis");
739                         m->ellipsis = 1;
740                         ASN1_TAILQ_INSERT_TAIL($1, m, members);
741                         $$ = $1;
742                 }
743                 ;
744
745 NamedType       : IDENTIFIER Type
746                 {
747                   $$ = emalloc(sizeof(*$$));
748                   $$->name = $1;
749                   $$->gen_name = estrdup($1);
750                   output_name ($$->gen_name);
751                   $$->type = $2;
752                   $$->ellipsis = 0;
753                 }
754                 ;
755
756 ComponentType   : NamedType
757                 {
758                         $$ = $1;
759                         $$->optional = 0;
760                         $$->defval = NULL;
761                 }
762                 | NamedType kw_OPTIONAL
763                 {
764                         $$ = $1;
765                         $$->optional = 1;
766                         $$->defval = NULL;
767                 }
768                 | NamedType kw_DEFAULT Value
769                 {
770                         $$ = $1;
771                         $$->optional = 0;
772                         $$->defval = $3;
773                 }
774                 ;
775
776 NamedBitList    : NamedBit
777                 {
778                         $$ = emalloc(sizeof(*$$));
779                         ASN1_TAILQ_INIT($$);
780                         ASN1_TAILQ_INSERT_HEAD($$, $1, members);
781                 }
782                 | NamedBitList ',' NamedBit
783                 {
784                         ASN1_TAILQ_INSERT_TAIL($1, $3, members);
785                         $$ = $1;
786                 }
787                 ;
788
789 NamedBit        : IDENTIFIER '(' NUMBER ')'
790                 {
791                   $$ = emalloc(sizeof(*$$));
792                   $$->name = $1;
793                   $$->gen_name = estrdup($1);
794                   output_name ($$->gen_name);
795                   $$->val = $3;
796                   $$->optional = 0;
797                   $$->ellipsis = 0;
798                   $$->type = NULL;
799                 }
800                 ;
801
802 objid_opt       : objid
803                 | /* empty */ { $$ = NULL; }
804                 ;
805
806 objid           : '{' objid_list '}'
807                 {
808                         $$ = $2;
809                 }
810                 ;
811
812 objid_list      :  /* empty */
813                 {
814                         $$ = NULL;
815                 }
816                 | objid_element objid_list
817                 {
818                         if ($2) {
819                                 $$ = $2;
820                                 add_oid_to_tail($2, $1);
821                         } else {
822                                 $$ = $1;
823                         }
824                 }
825                 ;
826
827 objid_element   : IDENTIFIER '(' NUMBER ')'
828                 {
829                         $$ = new_objid($1, $3);
830                 }
831                 | IDENTIFIER
832                 {
833                     Symbol *s = addsym($1);
834                     if(s->stype != SValue ||
835                        s->value->type != objectidentifiervalue) {
836                         error_message("%s is not an object identifier\n", 
837                                       s->name);
838                         exit(1);
839                     }
840                     $$ = s->value->u.objectidentifiervalue;
841                 }
842                 | NUMBER
843                 {
844                     $$ = new_objid(NULL, $1);
845                 }
846                 ;
847
848 Value           : BuiltinValue
849                 | ReferencedValue
850                 ;
851
852 BuiltinValue    : BooleanValue
853                 | CharacterStringValue
854                 | IntegerValue
855                 | ObjectIdentifierValue
856                 | NullValue
857                 ;
858
859 ReferencedValue : DefinedValue
860                 ;
861
862 DefinedValue    : Valuereference
863                 ;
864
865 Valuereference  : IDENTIFIER
866                 {
867                         Symbol *s = addsym($1);
868                         if(s->stype != SValue)
869                                 error_message ("%s is not a value\n",
870                                                 s->name);
871                         else
872                                 $$ = s->value;
873                 }
874                 ;
875
876 CharacterStringValue: STRING
877                 {
878                         $$ = emalloc(sizeof(*$$));
879                         $$->type = stringvalue;
880                         $$->u.stringvalue = $1;
881                 }
882                 ;
883
884 BooleanValue    : kw_TRUE
885                 {
886                         $$ = emalloc(sizeof(*$$));
887                         $$->type = booleanvalue;
888                         $$->u.booleanvalue = 0;
889                 }
890                 | kw_FALSE
891                 {
892                         $$ = emalloc(sizeof(*$$));
893                         $$->type = booleanvalue;
894                         $$->u.booleanvalue = 0;
895                 }
896                 ;
897
898 IntegerValue    : SignedNumber
899                 {
900                         $$ = emalloc(sizeof(*$$));
901                         $$->type = integervalue;
902                         $$->u.integervalue = $1;
903                 }
904                 ;
905
906 SignedNumber    : NUMBER
907                 ;
908
909 NullValue       : kw_NULL
910                 {
911                 }
912                 ;
913
914 ObjectIdentifierValue: objid
915                 {
916                         $$ = emalloc(sizeof(*$$));
917                         $$->type = objectidentifiervalue;
918                         $$->u.objectidentifiervalue = $1;
919                 }
920                 ;
921
922 %%
923
924 void
925 yyerror (const char *s)
926 {
927      error_message ("%s\n", s);
928 }
929
930 static Type *
931 new_tag(int tagclass, int tagvalue, int tagenv, Type *oldtype)
932 {
933     Type *t;
934     if(oldtype->type == TTag && oldtype->tag.tagenv == TE_IMPLICIT) {
935         t = oldtype;
936         oldtype = oldtype->subtype; /* XXX */
937     } else
938         t = new_type (TTag);
939     
940     t->tag.tagclass = tagclass;
941     t->tag.tagvalue = tagvalue;
942     t->tag.tagenv = tagenv;
943     t->subtype = oldtype;
944     return t;
945 }
946
947 static struct objid *
948 new_objid(const char *label, int value)
949 {
950     struct objid *s;
951     s = emalloc(sizeof(*s));
952     s->label = label;
953     s->value = value;
954     s->next = NULL;
955     return s;
956 }
957
958 static void
959 add_oid_to_tail(struct objid *head, struct objid *tail)
960 {
961     struct objid *o;
962     o = head;
963     while (o->next)
964         o = o->next;
965     o->next = tail;
966 }
967
968 static Type *
969 new_type (Typetype tt)
970 {
971     Type *t = ecalloc(1, sizeof(*t));
972     t->type = tt;
973     return t;
974 }
975
976 static struct constraint_spec *
977 new_constraint_spec(enum ctype ct)
978 {
979     struct constraint_spec *c = ecalloc(1, sizeof(*c));
980     c->ctype = ct;
981     return c;
982 }
983
984 static void fix_labels2(Type *t, const char *prefix);
985 static void fix_labels1(struct memhead *members, const char *prefix)
986 {
987     Member *m;
988
989     if(members == NULL)
990         return;
991     ASN1_TAILQ_FOREACH(m, members, members) {
992         asprintf(&m->label, "%s_%s", prefix, m->gen_name);
993         if (m->label == NULL)
994             errx(1, "malloc");
995         if(m->type != NULL)
996             fix_labels2(m->type, m->label);
997     }
998 }
999
1000 static void fix_labels2(Type *t, const char *prefix)
1001 {
1002     for(; t; t = t->subtype)
1003         fix_labels1(t->members, prefix);
1004 }
1005
1006 static void
1007 fix_labels(Symbol *s)
1008 {
1009     char *p;
1010     asprintf(&p, "choice_%s", s->gen_name);
1011     if (p == NULL)
1012         errx(1, "malloc");
1013     fix_labels2(s->type, p);
1014     free(p);
1015 }