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