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