NativeEnumerated.c vars NULL init and check
[com/asn1c.git] / libasn1parser / asn1p_y.y
1 %{
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <stdarg.h>
7 #include <errno.h>
8 #include <assert.h>
9
10 #include "asn1parser.h"
11
12 #define YYPARSE_PARAM   param
13 #define YYPARSE_PARAM_TYPE      void **
14 #define YYERROR_VERBOSE
15 #define YYDEBUG 1
16 #define YYFPRINTF   prefixed_fprintf
17
18 /*
19  * Prefix parser debug with "PARSER: " for easier human eye scanning.
20  */
21 static int
22 __attribute__((format(printf, 2, 3)))
23 prefixed_fprintf(FILE *f, const char *fmt, ...) {
24     static int line_ended = 1;
25     va_list ap;
26     va_start(ap, fmt);
27     if(line_ended) {
28         fprintf(f, "PARSER: ");
29         line_ended = 0;
30     }
31     size_t len = strlen(fmt);
32     if(len && fmt[len-1] == '\n') {
33         line_ended = 1;
34     }
35     int ret = vfprintf(f, fmt, ap);
36     va_end(ap);
37     return ret;
38 }
39
40 int yylex(void);
41 static int yyerror(const char *msg);
42
43 #ifdef  YYBYACC
44 int yyparse(void **param);      /* byacc does not produce a prototype */
45 #endif
46 void asn1p_lexer_hack_push_opaque_state(void);
47 void asn1p_lexer_hack_enable_with_syntax(void);
48 void asn1p_lexer_hack_push_encoding_control(void);
49 #define yylineno        asn1p_lineno
50 extern int asn1p_lineno;
51 const char *asn1p_parse_debug_filename;
52 #define ASN_FILENAME asn1p_parse_debug_filename
53
54 /*
55  * Process directives as <ASN1C:RepresentAsPointer>
56  */
57 extern int asn1p_as_pointer;
58
59 /*
60  * This temporary variable is used to solve the shortcomings of 1-lookahead
61  * parser.
62  */
63 static struct AssignedIdentifier *saved_aid;
64
65 static asn1p_value_t *_convert_bitstring2binary(char *str, int base);
66 static void _fixup_anonymous_identifier(asn1p_expr_t *expr);
67
68 static asn1p_module_t *currentModule;
69 #define NEW_EXPR()      (asn1p_expr_new(yylineno, currentModule))
70
71 #define checkmem(ptr)   do {                                            \
72                 if(!(ptr))                                              \
73                 return yyerror("Memory failure");                       \
74         } while(0)
75
76 #define CONSTRAINT_INSERT(root, constr_type, arg1, arg2) do {           \
77                 if(arg1->type != constr_type) {                         \
78                         int __ret;                                      \
79                         root = asn1p_constraint_new(yylineno, currentModule);   \
80                         checkmem(root);                                 \
81                         root->type = constr_type;                       \
82                         __ret = asn1p_constraint_insert(root,           \
83                                 arg1);                                  \
84                         checkmem(__ret == 0);                           \
85                 } else {                                                \
86                         root = arg1;                                    \
87                 }                                                       \
88                 if(arg2) {                                              \
89                         int __ret                                       \
90                         = asn1p_constraint_insert(root, arg2);          \
91                         checkmem(__ret == 0);                           \
92                 }                                                       \
93         } while(0)
94
95 #ifdef  AL_IMPORT
96 #error  AL_IMPORT DEFINED ELSEWHERE!
97 #endif
98 #define AL_IMPORT(to, where, from, field)                                      \
99     do {                                                                       \
100         if(!(from)) break;                                                     \
101         while(TQ_FIRST(&((from)->where))) {                                    \
102             TQ_ADD(&((to)->where), TQ_REMOVE(&((from)->where), field), field); \
103         }                                                                      \
104         assert(TQ_FIRST(&((from)->where)) == 0);                               \
105     } while(0)
106
107 %}
108
109
110 /*
111  * Token value definition.
112  * a_*:   ASN-specific types.
113  * tv_*:  Locally meaningful types.
114  */
115 %union {
116         asn1p_t                 *a_grammar;
117         asn1p_module_flags_e     a_module_flags;
118         asn1p_module_t          *a_module;
119         asn1p_expr_type_e        a_type;        /* ASN.1 Type */
120         asn1p_expr_t            *a_expr;        /* Constructed collection */
121         asn1p_constraint_t      *a_constr;      /* Constraint */
122         enum asn1p_constraint_type_e    a_ctype;/* Constraint type */
123         asn1p_xports_t          *a_xports;      /* IMports/EXports */
124         struct AssignedIdentifier a_aid;        /* Assigned Identifier */
125         asn1p_oid_t             *a_oid;         /* Object Identifier */
126         asn1p_oid_arc_t          a_oid_arc;     /* Single OID's arc */
127         struct asn1p_type_tag_s  a_tag;         /* A tag */
128         asn1p_ref_t             *a_ref;         /* Reference to custom type */
129         asn1p_wsyntx_t          *a_wsynt;       /* WITH SYNTAX contents */
130         asn1p_wsyntx_chunk_t    *a_wchunk;      /* WITH SYNTAX chunk */
131         struct asn1p_ref_component_s a_refcomp; /* Component of a reference */
132         asn1p_value_t           *a_value;       /* Number, DefinedValue, etc */
133         struct asn1p_param_s     a_parg;        /* A parameter argument */
134         asn1p_paramlist_t       *a_plist;       /* A pargs list */
135         struct asn1p_expr_marker_s a_marker;    /* OPTIONAL/DEFAULT */
136         enum asn1p_constr_pres_e a_pres;        /* PRESENT/ABSENT/OPTIONAL */
137         asn1c_integer_t          a_int;
138         double                   a_dbl;
139         char    *tv_str;
140         struct {
141                 char *buf;
142                 int len;
143         }       tv_opaque;
144         struct {
145                 char *name;
146                 struct asn1p_type_tag_s tag;
147         } tv_nametag;
148 };
149
150 /*
151  * Token types returned by scanner.
152  */
153 %token                  TOK_PPEQ        /* "::=", Pseudo Pascal EQuality */
154 %token                  TOK_VBracketLeft TOK_VBracketRight      /* "[[", "]]" */
155 %token  <tv_opaque>     TOK_whitespace  /* A span of whitespace */
156 %token  <tv_opaque>     TOK_opaque      /* opaque data (driven from .y) */
157 %token  <tv_str>        TOK_bstring
158 %token  <tv_opaque>     TOK_cstring
159 %token  <tv_str>        TOK_hstring
160 %token  <tv_str>        TOK_identifier "identifier"
161 %token  <a_int>         TOK_number "number"
162 %token  <a_int>         TOK_number_negative "negative number"
163 %token  <a_dbl>         TOK_realnumber
164 %token  <a_int>         TOK_tuple
165 %token  <a_int>         TOK_quadruple
166 %token  <tv_str>        TOK_typereference
167 %token  <tv_str>        TOK_capitalreference            /* "CLASS1" */
168 %token  <tv_str>        TOK_typefieldreference          /* "&Pork" */
169 %token  <tv_str>        TOK_valuefieldreference         /* "&id" */
170 %token  <tv_str>        TOK_Literal                     /* "BY" */
171
172 /*
173  * Tokens available with asn1p_lexer_hack_push_extended_values().
174  */
175 %token              TOK_ExtValue_BIT_STRING
176
177 /*
178  * Token types representing ASN.1 standard keywords.
179  */
180 %token                  TOK_ABSENT
181 %token                  TOK_ABSTRACT_SYNTAX
182 %token                  TOK_ALL
183 %token                  TOK_ANY
184 %token                  TOK_APPLICATION
185 %token                  TOK_AUTOMATIC
186 %token                  TOK_BEGIN
187 %token                  TOK_BIT
188 %token                  TOK_BMPString
189 %token                  TOK_BOOLEAN
190 %token                  TOK_BY
191 %token                  TOK_CHARACTER
192 %token                  TOK_CHOICE
193 %token                  TOK_CLASS
194 %token                  TOK_COMPONENT
195 %token                  TOK_COMPONENTS
196 %token                  TOK_CONSTRAINED
197 %token                  TOK_CONTAINING
198 %token                  TOK_DEFAULT
199 %token                  TOK_DEFINITIONS
200 %token                  TOK_DEFINED
201 %token                  TOK_EMBEDDED
202 %token                  TOK_ENCODED
203 %token                  TOK_ENCODING_CONTROL
204 %token                  TOK_END
205 %token                  TOK_ENUMERATED
206 %token                  TOK_EXPLICIT
207 %token                  TOK_EXPORTS
208 %token                  TOK_EXTENSIBILITY
209 %token                  TOK_EXTERNAL
210 %token                  TOK_FALSE
211 %token                  TOK_FROM
212 %token                  TOK_GeneralizedTime
213 %token                  TOK_GeneralString
214 %token                  TOK_GraphicString
215 %token                  TOK_IA5String
216 %token                  TOK_IDENTIFIER
217 %token                  TOK_IMPLICIT
218 %token                  TOK_IMPLIED
219 %token                  TOK_IMPORTS
220 %token                  TOK_INCLUDES
221 %token                  TOK_INSTANCE
222 %token                  TOK_INSTRUCTIONS
223 %token                  TOK_INTEGER
224 %token                  TOK_ISO646String
225 %token                  TOK_MAX
226 %token                  TOK_MIN
227 %token                  TOK_MINUS_INFINITY
228 %token                  TOK_NULL
229 %token                  TOK_NumericString
230 %token                  TOK_OBJECT
231 %token                  TOK_ObjectDescriptor
232 %token                  TOK_OCTET
233 %token                  TOK_OF
234 %token                  TOK_OPTIONAL
235 %token                  TOK_PATTERN
236 %token                  TOK_PDV
237 %token                  TOK_PLUS_INFINITY
238 %token                  TOK_PRESENT
239 %token                  TOK_PrintableString
240 %token                  TOK_PRIVATE
241 %token                  TOK_REAL
242 %token                  TOK_RELATIVE_OID
243 %token                  TOK_SEQUENCE
244 %token                  TOK_SET
245 %token                  TOK_SIZE
246 %token                  TOK_STRING
247 %token                  TOK_SYNTAX
248 %token                  TOK_T61String
249 %token                  TOK_TAGS
250 %token                  TOK_TeletexString
251 %token                  TOK_TRUE
252 %token                  TOK_TYPE_IDENTIFIER
253 %token                  TOK_UNIQUE
254 %token                  TOK_UNIVERSAL
255 %token                  TOK_UniversalString
256 %token                  TOK_UTCTime
257 %token                  TOK_UTF8String
258 %token                  TOK_VideotexString
259 %token                  TOK_VisibleString
260 %token                  TOK_WITH
261 %token                  UTF8_BOM    "UTF-8 byte order mark"
262
263 %nonassoc               TOK_EXCEPT
264 %left                   '^' TOK_INTERSECTION
265 %left                   '|' TOK_UNION
266
267 /* Misc tags */
268 %token                  TOK_TwoDots             ".."
269 %token                  TOK_ThreeDots   "..."
270
271
272 /*
273  * Types defined herein.
274  */
275 %type   <a_grammar>             ModuleList
276 %type   <a_module>              ModuleDefinition
277 %type   <a_module>              ModuleBody
278 %type   <a_module>              AssignmentList
279 %type   <a_module>              Assignment
280 %type   <a_module>              optModuleBody   /* Optional */
281 %type   <a_module_flags>        optModuleDefinitionFlags
282 %type   <a_module_flags>        ModuleDefinitionFlags   /* Set of FL */
283 %type   <a_module_flags>        ModuleDefinitionFlag            /* Single FL */
284 %type   <a_module>              optImports
285 %type   <a_module>              optExports
286 %type   <a_module>              ImportsDefinition
287 %type   <a_module>              optImportsBundleSet
288 %type   <a_module>              ImportsBundleSet
289 %type   <a_xports>              ImportsBundle
290 %type   <a_xports>              ImportsList
291 %type   <a_xports>              ExportsDefinition
292 %type   <a_xports>              ExportsBody
293 %type   <a_expr>                ImportsElement
294 %type   <a_expr>                ExportsElement
295 %type   <a_expr>                ExtensionAndException
296 %type   <a_expr>                Type
297 %type   <a_expr>                TaggedType
298 %type   <a_expr>                MaybeIndirectTaggedType
299 %type   <a_expr>                UntaggedType
300 %type   <a_expr>                DefinedUntaggedType
301 %type   <a_expr>                ConcreteTypeDeclaration "concrete TypeDeclaration"
302 %type   <a_expr>                TypeDeclaration
303 %type   <a_expr>                MaybeIndirectTypeDeclaration
304 %type   <a_ref>                 ComplexTypeReference
305 %type   <a_ref>                 ComplexTypeReferenceAmpList
306 %type   <a_refcomp>             ComplexTypeReferenceElement
307 %type   <a_refcomp>             PrimitiveFieldReference
308 %type   <a_expr>                FieldSpec
309 %type   <a_ref>                 FieldName
310 %type   <a_ref>                 DefinedObjectClass
311 %type   <a_expr>                ClassField
312 %type   <a_expr>                ObjectClass
313 %type   <a_expr>                DataTypeReference       /* Type1 ::= Type2 */
314 %type   <a_expr>                DefinedType
315 %type   <a_constr>              ValueSet                /* {a|b|c}*/
316 %type   <a_expr>                ValueSetTypeAssignment  /* Val INTEGER ::= {1|2} */
317 %type   <a_expr>                ValueAssignment         /* val INTEGER ::= 1*/
318 %type   <a_value>               Value
319 %type   <a_value>               SimpleValue
320 %type   <a_value>               DefinedValue
321 %type   <a_value>               SignedNumber
322 %type   <a_value>               RealValue
323 %type   <a_value>               BitStringValue
324 %type   <a_expr>                optComponentTypeLists
325 %type   <a_expr>                ComponentTypeLists
326 %type   <a_expr>                ComponentType
327 %type   <a_expr>                AlternativeTypeLists
328 %type   <a_expr>                AlternativeType
329 %type   <a_expr>                UniverationList
330 %type   <a_expr>                Enumerations
331 %type   <a_expr>                NamedBitList
332 %type   <a_expr>                NamedBit
333 %type   <a_expr>                NamedNumberList
334 %type   <a_expr>                NamedNumber
335 %type   <a_expr>                IdentifierList
336 %type   <a_expr>                IdentifierElement
337 %type   <a_expr>                UniverationElement
338 %type   <tv_str>                TypeRefName
339 %type   <tv_str>                Identifier
340 %type   <a_ref>             IdentifierAsReference
341 %type   <a_value>               IdentifierAsValue
342 %type   <tv_str>                optIdentifier
343 %type   <a_parg>                ParameterArgumentName
344 %type   <a_plist>               ParameterArgumentList
345 %type   <a_expr>                ActualParameter
346 %type   <a_expr>                ActualParameterList
347 %type   <a_aid>                 AssignedIdentifier      /* OID/DefinedValue */
348 %type   <a_oid>                 ObjectIdentifier        /* OID */
349 %type   <a_oid>                 optObjectIdentifier     /* Optional OID */
350 %type   <a_oid>                 ObjectIdentifierBody
351 %type   <a_oid_arc>             ObjectIdentifierElement
352 %type   <a_expr>                BuiltinType
353 %type   <a_type>                BasicTypeId
354 %type   <a_type>                BasicTypeId_UniverationCompatible
355 %type   <a_type>                BasicString
356 %type   <tv_opaque>             Opaque
357 %type   <tv_opaque>             OpaqueFirstToken
358 %type   <a_tag>                 Tag             /* [UNIVERSAL 0] IMPLICIT */
359 %type   <a_tag>                 TagClass TagTypeValue TagPlicit
360 %type   <a_tag>                 optTag          /* [UNIVERSAL 0] IMPLICIT */
361 %type   <a_constr>              optConstraint
362 %type   <a_constr>              optManyConstraints  /* Only for Type */
363 %type   <a_constr>              ManyConstraints
364 %type   <a_constr>              optSizeOrConstraint
365 %type   <a_constr>              Constraint
366 %type   <a_constr>              PermittedAlphabet
367 %type   <a_constr>              SizeConstraint
368 %type   <a_constr>              SingleTypeConstraint
369 %type   <a_constr>              MultipleTypeConstraints
370 %type   <a_constr>              NamedConstraint
371 %type   <a_constr>              FullSpecification
372 %type   <a_constr>              PartialSpecification
373 %type   <a_constr>              TypeConstraints
374 %type   <a_constr>              ConstraintSpec
375 %type   <a_constr>              SubtypeConstraint
376 %type   <a_constr>              GeneralConstraint
377 %type   <a_constr>              ElementSetSpecs         /* 1..2,...,3 */
378 %type   <a_constr>              ElementSetSpec          /* 1..2 */
379 %type   <a_constr>              Unions
380 %type   <a_constr>              Intersections
381 %type   <a_constr>              IntersectionElements
382 %type   <a_constr>              Elements
383 %type   <a_constr>              SubtypeElements /* 1..2 */
384 %type   <a_constr>              SimpleTableConstraint
385 %type   <a_constr>              UserDefinedConstraint
386 %type   <a_constr>              TableConstraint
387 %type   <a_constr>              ContentsConstraint
388 %type   <a_constr>              PatternConstraint
389 %type   <a_constr>              InnerTypeConstraints
390 %type   <a_constr>              ValueRange
391 %type   <a_constr>              ComponentRelationConstraint
392 %type   <a_constr>              AtNotationList
393 %type   <a_ref>                 AtNotationElement
394 %type   <a_value>               SingleValue
395 %type   <a_value>               LowerEndValue
396 %type   <a_value>               UpperEndValue
397 %type   <a_value>               ContainedSubtype
398 %type   <a_ctype>               ConstraintRangeSpec
399 %type   <a_value>               RestrictedCharacterStringValue
400 %type   <a_wsynt>               optWithSyntax
401 %type   <a_wsynt>               WithSyntax
402 %type   <a_wsynt>               WithSyntaxList
403 %type   <a_wchunk>              WithSyntaxToken
404 %type   <a_marker>              optMarker Marker
405 %type   <a_int>                 optUNIQUE
406 %type   <a_pres>                optPresenceConstraint PresenceConstraint
407 %type   <tv_str>                ComponentIdList
408 %type   <a_int>                 NSTD_IndirectMarker
409
410 %%
411
412
413 ParsedGrammar:
414         UTF8_BOM ModuleList {
415                 *(void **)param = $2;
416         }
417         | ModuleList {
418                 *(void **)param = $1;
419         }
420         ;
421
422 ModuleList:
423         ModuleDefinition {
424                 $$ = asn1p_new();
425                 checkmem($$);
426                 TQ_ADD(&($$->modules), $1, mod_next);
427         }
428         | ModuleList ModuleDefinition {
429                 $$ = $1;
430                 TQ_ADD(&($$->modules), $2, mod_next);
431         }
432         ;
433
434 /*
435  * ASN module definition.
436  * === EXAMPLE ===
437  * MySyntax DEFINITIONS AUTOMATIC TAGS ::=
438  * BEGIN
439  * ...
440  * END 
441  * === EOF ===
442  */
443
444 ModuleDefinition:
445         TypeRefName { currentModule = asn1p_module_new(); }
446         optObjectIdentifier TOK_DEFINITIONS
447                 optModuleDefinitionFlags
448                 TOK_PPEQ TOK_BEGIN
449                 optModuleBody
450                 TOK_END {
451
452                 $$ = currentModule;
453
454                 if($8) {
455                         asn1p_module_t tmp = *($$);
456                         *($$) = *($8);
457                         *($8) = tmp;
458                         asn1p_module_free($8);
459                 } else {
460                         /* There's a chance that a module is just plain empty */
461                 }
462
463                 $$->ModuleName = $1;
464                 $$->module_oid = $3;
465                 $$->module_flags = $5;
466         }
467         ;
468
469 /*
470  * Object Identifier Definition
471  * { iso member-body(2) 3 }
472  */
473 optObjectIdentifier:
474         { $$ = 0; }
475         | ObjectIdentifier { $$ = $1; }
476         ;
477         
478 ObjectIdentifier:
479         '{' ObjectIdentifierBody '}' {
480                 $$ = $2;
481         }
482         | '{' '}' {
483                 $$ = 0;
484         }
485         ;
486
487 ObjectIdentifierBody:
488         ObjectIdentifierElement {
489                 $$ = asn1p_oid_new();
490                 asn1p_oid_add_arc($$, &$1);
491                 if($1.name)
492                         free($1.name);
493         }
494         | ObjectIdentifierBody ObjectIdentifierElement {
495                 $$ = $1;
496                 asn1p_oid_add_arc($$, &$2);
497                 if($2.name)
498                         free($2.name);
499         }
500         ;
501
502 ObjectIdentifierElement:
503         Identifier {                                    /* iso */
504                 $$.name = $1;
505                 $$.number = -1;
506         }
507         | Identifier '(' TOK_number ')' {               /* iso(1) */
508                 $$.name = $1;
509                 $$.number = $3;
510         }
511         | TOK_number {                                  /* 1 */
512                 $$.name = 0;
513                 $$.number = $1;
514         }
515         ;
516         
517 /*
518  * Optional module flags.
519  */
520 optModuleDefinitionFlags:
521         { $$ = MSF_NOFLAGS; }
522         | ModuleDefinitionFlags {
523                 $$ = $1;
524         }
525         ;
526
527 /*
528  * Module flags.
529  */
530 ModuleDefinitionFlags:
531         ModuleDefinitionFlag {
532                 $$ = $1;
533         }
534         | ModuleDefinitionFlags ModuleDefinitionFlag {
535                 $$ = $1 | $2;
536         }
537         ;
538
539 /*
540  * Single module flag.
541  */
542 ModuleDefinitionFlag:
543         TOK_EXPLICIT TOK_TAGS {
544                 $$ = MSF_EXPLICIT_TAGS;
545         }
546         | TOK_IMPLICIT TOK_TAGS {
547                 $$ = MSF_IMPLICIT_TAGS;
548         }
549         | TOK_AUTOMATIC TOK_TAGS {
550                 $$ = MSF_AUTOMATIC_TAGS;
551         }
552         | TOK_EXTENSIBILITY TOK_IMPLIED {
553                 $$ = MSF_EXTENSIBILITY_IMPLIED;
554         }
555         /* EncodingReferenceDefault */
556         | TOK_capitalreference TOK_INSTRUCTIONS {
557                 /* X.680Amd1 specifies TAG and XER */
558                 if(strcmp($1, "TAG") == 0) {
559                         $$ = MSF_TAG_INSTRUCTIONS;
560                 } else if(strcmp($1, "XER") == 0) {
561                         $$ = MSF_XER_INSTRUCTIONS;
562                 } else {
563                         fprintf(stderr,
564                                 "WARNING: %s INSTRUCTIONS at %s:%d: "
565                                 "Unrecognized encoding reference\n",
566                                 $1, ASN_FILENAME, yylineno);
567                         $$ = MSF_unk_INSTRUCTIONS;
568                 }
569                 free($1);
570         }
571         ;
572
573 /*
574  * Optional module body.
575  */
576 optModuleBody:
577         { $$ = 0; }
578         | ModuleBody {
579                 $$ = $1;
580         }
581         ;
582
583 /*
584  * ASN.1 Module body.
585  */
586 ModuleBody:
587         optExports optImports AssignmentList {
588                 $$ = asn1p_module_new();
589                 AL_IMPORT($$, exports, $1, xp_next);
590                 AL_IMPORT($$, imports, $2, xp_next);
591                 asn1p_module_move_members($$, $3);
592
593                 asn1p_module_free($1);
594                 asn1p_module_free($2);
595                 asn1p_module_free($3);
596         }
597         ;
598
599 AssignmentList:
600         Assignment {
601                 $$ = $1;
602         }
603         | AssignmentList Assignment {
604                 if($1) {
605                         $$ = $1;
606                 } else {
607                         $$ = $2;
608                         break;
609                 }
610         asn1p_module_move_members($$, $2);
611                 asn1p_module_free($2);
612         }
613         ;
614
615
616 /*
617  * One of the elements of ASN.1 module specification.
618  */
619 Assignment:
620         DataTypeReference {
621                 $$ = asn1p_module_new();
622                 checkmem($$);
623                 assert($1->expr_type != A1TC_INVALID);
624                 assert($1->meta_type != AMT_INVALID);
625                 asn1p_module_member_add($$, $1);
626         }
627         | ValueAssignment {
628                 $$ = asn1p_module_new();
629                 checkmem($$);
630                 assert($1->expr_type != A1TC_INVALID);
631                 assert($1->meta_type != AMT_INVALID);
632                 asn1p_module_member_add($$, $1);
633         }
634         /*
635          * Value set definition
636          * === EXAMPLE ===
637          * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 }
638          * === EOF ===
639          * Also ObjectClassSet.
640          */
641         | ValueSetTypeAssignment {
642                 $$ = asn1p_module_new();
643                 checkmem($$);
644                 assert($1->expr_type != A1TC_INVALID);
645                 assert($1->meta_type != AMT_INVALID);
646                 asn1p_module_member_add($$, $1);
647         }
648         | TOK_ENCODING_CONTROL TOK_capitalreference 
649                 { asn1p_lexer_hack_push_encoding_control(); }
650                         {
651                 fprintf(stderr,
652                         "WARNING: ENCODING-CONTROL %s "
653                         "specification at %s:%d ignored\n",
654                         $2, ASN_FILENAME, yylineno);
655                 free($2);
656                 $$ = 0;
657         }
658
659         /*
660          * Erroneous attemps
661          */
662         | BasicString {
663                 return yyerror(
664                         "Attempt to redefine a standard basic string type, "
665                         "please comment out or remove this type redefinition.");
666         }
667         ;
668
669 /*
670  * === EXAMPLE ===
671  * IMPORTS Type1, value FROM Module { iso standard(0) } ;
672  * === EOF ===
673  */
674 optImports:
675         { $$ = 0; }
676         | ImportsDefinition;
677
678 ImportsDefinition:
679         TOK_IMPORTS optImportsBundleSet ';' {
680                 if(!saved_aid && 0)
681                         return yyerror("Unterminated IMPORTS FROM, "
682                                         "expected semicolon ';'");
683                 saved_aid = 0;
684                 $$ = $2;
685         }
686         /*
687          * Some error cases.
688          */
689         | TOK_IMPORTS TOK_FROM /* ... */ {
690                 return yyerror("Empty IMPORTS list");
691         }
692         ;
693
694 optImportsBundleSet:
695         { $$ = asn1p_module_new(); }
696         | ImportsBundleSet;
697
698 ImportsBundleSet:
699         ImportsBundle {
700                 $$ = asn1p_module_new();
701                 checkmem($$);
702                 TQ_ADD(&($$->imports), $1, xp_next);
703         }
704         | ImportsBundleSet ImportsBundle {
705                 $$ = $1;
706                 TQ_ADD(&($$->imports), $2, xp_next);
707         }
708         ;
709
710 AssignedIdentifier:
711         { memset(&$$, 0, sizeof($$)); }
712         | ObjectIdentifier { $$.oid = $1; };
713         /* | DefinedValue { $$.value = $1; }; // Handled through saved_aid */
714
715 ImportsBundle:
716         ImportsList TOK_FROM TypeRefName AssignedIdentifier {
717                 $$ = $1;
718                 $$->fromModuleName = $3;
719                 $$->identifier = $4;
720                 /* This stupid thing is used for look-back hack. */
721                 saved_aid = $$->identifier.oid ? 0 : &($$->identifier);
722                 checkmem($$);
723         }
724         ;
725
726 ImportsList:
727         ImportsElement {
728                 $$ = asn1p_xports_new();
729                 checkmem($$);
730                 TQ_ADD(&($$->xp_members), $1, next);
731         }
732         | ImportsList ',' ImportsElement {
733                 $$ = $1;
734                 TQ_ADD(&($$->xp_members), $3, next);
735         }
736         ;
737
738 ImportsElement:
739         TypeRefName {
740                 $$ = NEW_EXPR();
741                 checkmem($$);
742                 $$->Identifier = $1;
743                 $$->expr_type = A1TC_REFERENCE;
744         }
745         | TypeRefName '{' '}' {         /* Completely equivalent to above */
746                 $$ = NEW_EXPR();
747                 checkmem($$);
748                 $$->Identifier = $1;
749                 $$->expr_type = A1TC_REFERENCE;
750         }
751         | Identifier {
752                 $$ = NEW_EXPR();
753                 checkmem($$);
754                 $$->Identifier = $1;
755                 $$->expr_type = A1TC_REFERENCE;
756         }
757         ;
758
759
760 optExports:
761         { $$ = 0; }
762         | ExportsDefinition {
763                 $$ = asn1p_module_new();
764                 checkmem($$);
765                 if($1) {
766                         TQ_ADD(&($$->exports), $1, xp_next);
767                 } else {
768                         /* "EXPORTS ALL;" */
769                 }
770         }
771         ;
772
773 ExportsDefinition:
774         TOK_EXPORTS ExportsBody ';' {
775                 $$ = $2;
776         }
777         | TOK_EXPORTS TOK_ALL ';' {
778                 $$ = 0;
779         }
780         | TOK_EXPORTS ';' {
781                 /* Empty EXPORTS clause effectively prohibits export. */
782                 $$ = asn1p_xports_new();
783                 checkmem($$);
784         }
785         ;
786
787 ExportsBody:
788         ExportsElement {
789                 $$ = asn1p_xports_new();
790                 assert($$);
791                 TQ_ADD(&($$->xp_members), $1, next);
792         }
793         | ExportsBody ',' ExportsElement {
794                 $$ = $1;
795                 TQ_ADD(&($$->xp_members), $3, next);
796         }
797         ;
798
799 ExportsElement:
800         TypeRefName {
801                 $$ = NEW_EXPR();
802                 checkmem($$);
803                 $$->Identifier = $1;
804                 $$->expr_type = A1TC_EXPORTVAR;
805         }
806         | TypeRefName '{' '}' {
807                 $$ = NEW_EXPR();
808                 checkmem($$);
809                 $$->Identifier = $1;
810                 $$->expr_type = A1TC_EXPORTVAR;
811         }
812         | Identifier {
813                 $$ = NEW_EXPR();
814                 checkmem($$);
815                 $$->Identifier = $1;
816                 $$->expr_type = A1TC_EXPORTVAR;
817         }
818         ;
819
820
821 ValueSet: '{' ElementSetSpecs '}' { $$ = $2; };
822
823 ValueSetTypeAssignment:
824         TypeRefName Type TOK_PPEQ ValueSet {
825                 $$ = $2;
826                 assert($$->Identifier == 0);
827                 $$->Identifier = $1;
828                 $$->meta_type = AMT_VALUESET;
829                 $$->constraints = $4;
830         }
831         ;
832
833 DefinedType:
834         /*
835          * A DefinedType reference.
836          * "CLASS1.&id.&id2"
837          * or
838          * "Module.Type"
839          * or
840          * "Module.identifier"
841          * or
842          * "Type"
843          */
844         ComplexTypeReference {
845                 $$ = NEW_EXPR();
846                 checkmem($$);
847                 $$->reference = $1;
848                 $$->expr_type = A1TC_REFERENCE;
849                 $$->meta_type = AMT_TYPEREF;
850         }
851         /*
852          * A parameterized assignment.
853          */
854         | ComplexTypeReference '{' ActualParameterList '}' {
855                 $$ = NEW_EXPR();
856                 checkmem($$);
857                 $$->reference = $1;
858                 $$->rhs_pspecs = $3;
859                 $$->expr_type = A1TC_REFERENCE;
860                 $$->meta_type = AMT_TYPEREF;
861         }
862         ;
863
864 /*
865  * Data Type Reference.
866  * === EXAMPLE ===
867  * Type3 ::= CHOICE { a Type1,  b Type 2 }
868  * === EOF ===
869  */
870 DataTypeReference:
871         /*
872          * Optionally tagged type definition.
873          */
874         TypeRefName TOK_PPEQ Type {
875                 $$ = $3;
876                 $$->Identifier = $1;
877                 assert($$->expr_type);
878                 assert($$->meta_type);
879         }
880         | TypeRefName TOK_PPEQ ObjectClass {
881                 $$ = $3;
882                 $$->Identifier = $1;
883                 assert($$->expr_type == A1TC_CLASSDEF);
884                 assert($$->meta_type == AMT_OBJECTCLASS);
885         }
886         /*
887          * Parameterized <Type> declaration:
888          * === EXAMPLE ===
889          *   SIGNED { ToBeSigned } ::= SEQUENCE {
890          *      toBeSigned  ToBeSigned,
891          *      algorithm   AlgorithmIdentifier,
892          *      signature   BIT STRING
893          *   }
894          * === EOF ===
895          */
896         | TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ Type {
897                 $$ = $6;
898                 $$->Identifier = $1;
899                 $$->lhs_params = $3;
900         }
901         /* Parameterized CLASS declaration */
902         | TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ ObjectClass {
903                 $$ = $6;
904                 $$->Identifier = $1;
905                 $$->lhs_params = $3;
906         }
907         ;
908
909 ParameterArgumentList:
910         ParameterArgumentName {
911                 int ret;
912                 $$ = asn1p_paramlist_new(yylineno);
913                 checkmem($$);
914                 ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument);
915                 checkmem(ret == 0);
916                 asn1p_ref_free($1.governor);
917                 free($1.argument);
918         }
919         | ParameterArgumentList ',' ParameterArgumentName {
920                 int ret;
921                 $$ = $1;
922                 ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument);
923                 checkmem(ret == 0);
924                 asn1p_ref_free($3.governor);
925                 free($3.argument);
926         }
927         ;
928         
929 ParameterArgumentName:
930         TypeRefName {
931                 $$.governor = NULL;
932                 $$.argument = $1;
933         }
934         | TypeRefName ':' Identifier {
935                 int ret;
936                 $$.governor = asn1p_ref_new(yylineno, currentModule);
937                 ret = asn1p_ref_add_component($$.governor, $1, 0);
938                 checkmem(ret == 0);
939                 $$.argument = $3;
940                 free($1);
941         }
942         | TypeRefName ':' TypeRefName {
943                 int ret;
944                 $$.governor = asn1p_ref_new(yylineno, currentModule);
945                 ret = asn1p_ref_add_component($$.governor, $1, 0);
946                 checkmem(ret == 0);
947                 $$.argument = $3;
948                 free($1);
949         }
950         | BasicTypeId ':' Identifier {
951                 int ret;
952                 $$.governor = asn1p_ref_new(yylineno, currentModule);
953                 ret = asn1p_ref_add_component($$.governor,
954                         ASN_EXPR_TYPE2STR($1), 1);
955                 checkmem(ret == 0);
956                 $$.argument = $3;
957         }
958         | BasicTypeId ':' TypeRefName {
959                 int ret;
960                 $$.governor = asn1p_ref_new(yylineno, currentModule);
961                 ret = asn1p_ref_add_component($$.governor,
962                         ASN_EXPR_TYPE2STR($1), 1);
963                 checkmem(ret == 0);
964                 $$.argument = $3;
965         }
966         ;
967
968 ActualParameterList:
969         ActualParameter {
970                 $$ = NEW_EXPR();
971                 checkmem($$);
972                 asn1p_expr_add($$, $1);
973         }
974         | ActualParameterList ',' ActualParameter {
975                 $$ = $1;
976                 asn1p_expr_add($$, $3);
977         }
978         ;
979
980 ActualParameter:
981         UntaggedType    /* act. Type */
982         | SimpleValue {
983                 $$ = NEW_EXPR();
984                 checkmem($$);
985                 $$->Identifier = strdup("?");
986                 $$->expr_type = A1TC_REFERENCE;
987                 $$->meta_type = AMT_VALUE;
988                 $$->value = $1;
989         }
990         | DefinedValue {
991                 $$ = NEW_EXPR();
992                 checkmem($$);
993                 $$->Identifier = strdup("?");
994                 $$->expr_type = A1TC_REFERENCE;
995                 $$->meta_type = AMT_VALUE;
996                 $$->value = $1;
997         }
998         | ValueSet {
999                 $$ = NEW_EXPR();
1000                 $$->expr_type = A1TC_VALUESET;
1001                 $$->meta_type = AMT_VALUESET;
1002                 $$->constraints = $1;
1003         }
1004         ;
1005
1006 /*
1007         | '{' ActualParameter '}' {
1008                 $$ = NEW_EXPR();
1009                 checkmem($$);
1010                 asn1p_expr_add($$, $2);
1011                 $$->expr_type = A1TC_PARAMETRIZED;
1012                 $$->meta_type = AMT_TYPE;
1013         }
1014         ;
1015 */
1016
1017 /*
1018  * A collection of constructed data type members.
1019  */
1020 optComponentTypeLists:
1021         { $$ = NEW_EXPR(); }
1022         | ComponentTypeLists { $$ = $1; };
1023
1024 ComponentTypeLists:
1025         ComponentType {
1026                 $$ = NEW_EXPR();
1027                 checkmem($$);
1028                 asn1p_expr_add($$, $1);
1029         }
1030         | ComponentTypeLists ',' ComponentType {
1031                 $$ = $1;
1032                 asn1p_expr_add($$, $3);
1033         }
1034         | ComponentTypeLists ',' TOK_VBracketLeft ComponentTypeLists TOK_VBracketRight {
1035                 $$ = $1;
1036                 $4->meta_type = AMT_TYPE;
1037                 $4->expr_type = ASN_CONSTR_SEQUENCE;
1038                 $4->marker.flags |= EM_OPTIONAL;
1039                 asn1p_expr_add($$, $4);
1040         }
1041         ;
1042
1043 ComponentType:
1044         Identifier MaybeIndirectTaggedType optMarker {
1045                 $$ = $2;
1046                 assert($$->Identifier == 0);
1047                 $$->Identifier = $1;
1048                 $3.flags |= $$->marker.flags;
1049                 $$->marker = $3;
1050         }
1051         | MaybeIndirectTaggedType optMarker {
1052                 $$ = $1;
1053                 $2.flags |= $$->marker.flags;
1054                 $$->marker = $2;
1055                 _fixup_anonymous_identifier($$);
1056         }
1057         | TOK_COMPONENTS TOK_OF MaybeIndirectTaggedType {
1058                 $$ = NEW_EXPR();
1059                 checkmem($$);
1060                 $$->meta_type = $3->meta_type;
1061                 $$->expr_type = A1TC_COMPONENTS_OF;
1062                 asn1p_expr_add($$, $3);
1063         }
1064         | ExtensionAndException {
1065                 $$ = $1;
1066         }
1067         ;
1068
1069 AlternativeTypeLists:
1070         AlternativeType {
1071                 $$ = NEW_EXPR();
1072                 checkmem($$);
1073                 asn1p_expr_add($$, $1);
1074         }
1075         | AlternativeTypeLists ',' AlternativeType {
1076                 $$ = $1;
1077                 asn1p_expr_add($$, $3);
1078         }
1079         ;
1080
1081 AlternativeType:
1082         Identifier MaybeIndirectTaggedType {
1083                 $$ = $2;
1084                 assert($$->Identifier == 0);
1085                 $$->Identifier = $1;
1086         }
1087         | ExtensionAndException {
1088                 $$ = $1;
1089         }
1090         | MaybeIndirectTaggedType {
1091                 $$ = $1;
1092                 _fixup_anonymous_identifier($$);
1093         }
1094         ;
1095
1096 ObjectClass:
1097         TOK_CLASS '{' FieldSpec '}' optWithSyntax {
1098                 $$ = $3;
1099                 checkmem($$);
1100                 $$->with_syntax = $5;
1101                 assert($$->expr_type == A1TC_CLASSDEF);
1102                 assert($$->meta_type == AMT_OBJECTCLASS);
1103         }
1104         ;
1105
1106 optUNIQUE:
1107         { $$ = 0; }
1108         | TOK_UNIQUE { $$ = 1; }
1109         ;
1110
1111 FieldSpec:
1112         ClassField {
1113                 $$ = NEW_EXPR();
1114                 checkmem($$);
1115                 $$->expr_type = A1TC_CLASSDEF;
1116                 $$->meta_type = AMT_OBJECTCLASS;
1117                 asn1p_expr_add($$, $1);
1118         }
1119         | FieldSpec ',' ClassField {
1120                 $$ = $1;
1121                 asn1p_expr_add($$, $3);
1122         }
1123         ;
1124
1125         /* X.681 */
1126 ClassField:
1127
1128         /* TypeFieldSpec ::= typefieldreference TypeOptionalitySpec? */
1129         TOK_typefieldreference optMarker {
1130                 $$ = NEW_EXPR();
1131                 checkmem($$);
1132                 $$->Identifier = $1;
1133                 $$->meta_type = AMT_OBJECTFIELD;
1134                 $$->expr_type = A1TC_CLASSFIELD_TFS;    /* TypeFieldSpec */
1135                 $$->marker = $2;
1136         }
1137
1138         /* FixedTypeValueFieldSpec ::= valuefieldreference Type UNIQUE ? ValueOptionalitySpec ? */
1139         | TOK_valuefieldreference Type optUNIQUE optMarker {
1140                 $$ = NEW_EXPR();
1141                 $$->Identifier = $1;
1142                 $$->meta_type = AMT_OBJECTFIELD;
1143                 $$->expr_type = A1TC_CLASSFIELD_FTVFS;  /* FixedTypeValueFieldSpec */
1144                 $$->unique = $3;
1145                 $$->marker = $4;
1146                 asn1p_expr_add($$, $2);
1147         }
1148
1149         /* VariableTypeValueFieldSpec ::= valuefieldreference FieldName ValueOptionalitySpec ? */
1150         | TOK_valuefieldreference FieldName optMarker {
1151                 $$ = NEW_EXPR();
1152                 $$->Identifier = $1;
1153                 $$->meta_type = AMT_OBJECTFIELD;
1154                 $$->expr_type = A1TC_CLASSFIELD_VTVFS;
1155                 $$->reference = $2;
1156                 $$->marker = $3;
1157         }
1158
1159         /*  ObjectFieldSpec ::= objectfieldreference DefinedObjectClass ObjectOptionalitySpec ? */
1160         | TOK_valuefieldreference DefinedObjectClass optMarker {
1161                 $$ = NEW_EXPR();
1162                 checkmem($$);
1163                 $$->Identifier = $1;
1164                 $$->reference = $2;
1165                 $$->meta_type = AMT_OBJECTFIELD;
1166                 $$->expr_type = A1TC_CLASSFIELD_OFS;
1167                 $$->marker = $3;
1168         }
1169
1170         /* VariableTypeValueSetFieldSpec ::= valuesetfieldreference FieldName ValueOptionalitySpec ? */
1171         | TOK_typefieldreference FieldName optMarker {
1172                 $$ = NEW_EXPR();
1173                 $$->Identifier = $1;
1174                 $$->meta_type = AMT_OBJECTFIELD;
1175                 $$->expr_type = A1TC_CLASSFIELD_VTVSFS;
1176                 $$->reference = $2;
1177                 $$->marker = $3;
1178         }
1179
1180         /* FixedTypeValueSetFieldSpec ::= valuesetfieldreference Type ValueSetOptionalitySpec ? */
1181         | TOK_typefieldreference Type optMarker {
1182                 $$ = NEW_EXPR();
1183                 checkmem($$);
1184                 $$->Identifier = $1;
1185                 $$->meta_type = AMT_OBJECTFIELD;
1186                 $$->expr_type = A1TC_CLASSFIELD_FTVSFS;
1187                 asn1p_expr_add($$, $2);
1188                 $$->marker = $3;
1189         }
1190
1191         /*  ObjectSetFieldSpec ::= objectsetfieldreference DefinedObjectClass ObjectOptionalitySpec ? */
1192         | TOK_typefieldreference DefinedObjectClass optMarker {
1193                 $$ = NEW_EXPR();
1194                 checkmem($$);
1195                 $$->Identifier = $1;
1196                 $$->reference = $2;
1197                 $$->meta_type = AMT_OBJECTFIELD;
1198                 $$->expr_type = A1TC_CLASSFIELD_OSFS;
1199                 $$->marker = $3;
1200         }
1201         ;
1202
1203 optWithSyntax:
1204         { $$ = 0; }
1205         | WithSyntax {
1206                 $$ = $1;
1207         }
1208         ;
1209
1210 WithSyntax:
1211         TOK_WITH TOK_SYNTAX '{'
1212                 { asn1p_lexer_hack_enable_with_syntax(); }
1213                 WithSyntaxList
1214                 '}' {
1215                 $$ = $5;
1216         }
1217         ;
1218
1219 WithSyntaxList:
1220         WithSyntaxToken {
1221                 $$ = asn1p_wsyntx_new();
1222                 TQ_ADD(&($$->chunks), $1, next);
1223         }
1224         | WithSyntaxList WithSyntaxToken {
1225                 $$ = $1;
1226                 TQ_ADD(&($$->chunks), $2, next);
1227         }
1228         ;
1229
1230 WithSyntaxToken:
1231         TOK_whitespace {
1232                 $$ = asn1p_wsyntx_chunk_fromstring($1.buf, 0);
1233                 $$->type = WC_WHITESPACE;
1234         }
1235         | TOK_Literal {
1236                 $$ = asn1p_wsyntx_chunk_fromstring($1, 0);
1237         }
1238         | PrimitiveFieldReference {
1239                 $$ = asn1p_wsyntx_chunk_fromstring($1.name, 0);
1240                 $$->type = WC_FIELD;
1241         }
1242         | '[' WithSyntaxList ']' {
1243                 $$ = asn1p_wsyntx_chunk_fromsyntax($2);
1244         }
1245         ;
1246
1247 ExtensionAndException:
1248         TOK_ThreeDots {
1249                 $$ = NEW_EXPR();
1250                 checkmem($$);
1251                 $$->Identifier = strdup("...");
1252                 checkmem($$->Identifier);
1253                 $$->expr_type = A1TC_EXTENSIBLE;
1254                 $$->meta_type = AMT_TYPE;
1255         }
1256         | TOK_ThreeDots '!' DefinedValue {
1257                 $$ = NEW_EXPR();
1258                 checkmem($$);
1259                 $$->Identifier = strdup("...");
1260                 checkmem($$->Identifier);
1261                 $$->value = $3;
1262                 $$->expr_type = A1TC_EXTENSIBLE;
1263                 $$->meta_type = AMT_TYPE;
1264         }
1265         | TOK_ThreeDots '!' SignedNumber {
1266                 $$ = NEW_EXPR();
1267                 checkmem($$);
1268                 $$->Identifier = strdup("...");
1269                 $$->value = $3;
1270                 checkmem($$->Identifier);
1271                 $$->expr_type = A1TC_EXTENSIBLE;
1272                 $$->meta_type = AMT_TYPE;
1273         }
1274         ;
1275
1276 Type: TaggedType;
1277
1278 TaggedType:
1279     optTag UntaggedType {
1280         $$ = $2;
1281         $$->tag = $1;
1282     }
1283     ;
1284
1285 DefinedUntaggedType:
1286         DefinedType optManyConstraints {
1287                 $$ = $1;
1288                 /*
1289                  * Outer constraint for SEQUENCE OF and SET OF applies
1290                  * to the inner type.
1291                  */
1292                 if($$->expr_type == ASN_CONSTR_SEQUENCE_OF
1293                 || $$->expr_type == ASN_CONSTR_SET_OF) {
1294                         assert(!TQ_FIRST(&($$->members))->constraints);
1295                         TQ_FIRST(&($$->members))->constraints = $2;
1296                 } else {
1297                         if($$->constraints) {
1298                                 assert(!$2);
1299                                 /* Check this : optManyConstraints is not used ?! */
1300                                 asn1p_constraint_free($2);
1301                         } else {
1302                                 $$->constraints = $2;
1303                         }
1304                 }
1305         }
1306         ;
1307
1308 UntaggedType:
1309         TypeDeclaration optManyConstraints {
1310                 $$ = $1;
1311                 /*
1312                  * Outer constraint for SEQUENCE OF and SET OF applies
1313                  * to the inner type.
1314                  */
1315                 if($$->expr_type == ASN_CONSTR_SEQUENCE_OF
1316                 || $$->expr_type == ASN_CONSTR_SET_OF) {
1317                         assert(!TQ_FIRST(&($$->members))->constraints);
1318                         TQ_FIRST(&($$->members))->constraints = $2;
1319                 } else {
1320                         if($$->constraints) {
1321                                 assert(!$2);
1322                                 /* Check this : optManyConstraints is not used ?! */
1323                                 asn1p_constraint_free($2);
1324                         } else {
1325                                 $$->constraints = $2;
1326                         }
1327                 }
1328         }
1329         ;
1330
1331 MaybeIndirectTaggedType:
1332     optTag MaybeIndirectTypeDeclaration optManyConstraints {
1333                 $$ = $2;
1334                 $$->tag = $1;
1335                 /*
1336                  * Outer constraint for SEQUENCE OF and SET OF applies
1337                  * to the inner type.
1338                  */
1339                 if($$->expr_type == ASN_CONSTR_SEQUENCE_OF
1340                 || $$->expr_type == ASN_CONSTR_SET_OF) {
1341                         assert(!TQ_FIRST(&($$->members))->constraints);
1342                         TQ_FIRST(&($$->members))->constraints = $3;
1343                 } else {
1344                         if($$->constraints) {
1345                                 assert(!$2);
1346                                 /* Check this : optManyConstraints is not used ?! */
1347                                 asn1p_constraint_free($3);
1348                         } else {
1349                                 $$->constraints = $3;
1350                         }
1351                 }
1352         }
1353     ;
1354
1355 NSTD_IndirectMarker:
1356         {
1357                 $$ = asn1p_as_pointer ? EM_INDIRECT : 0;
1358                 asn1p_as_pointer = 0;
1359         }
1360         ;
1361
1362 MaybeIndirectTypeDeclaration:
1363     NSTD_IndirectMarker TypeDeclaration {
1364         $$ = $2;
1365                 $$->marker.flags |= $1;
1366
1367                 if(($$->marker.flags & EM_INDIRECT)
1368                 && ($$->marker.flags & EM_OPTIONAL) != EM_OPTIONAL) {
1369                         fprintf(stderr,
1370                                 "INFO: Directive <ASN1C:RepresentAsPointer> "
1371                                 "applied to %s at %s:%d\n",
1372                                 ASN_EXPR_TYPE2STR($$->expr_type)
1373                                         ?  ASN_EXPR_TYPE2STR($$->expr_type)
1374                                         : "member",
1375                                 ASN_FILENAME, $$->_lineno
1376                         );
1377                 }
1378     }
1379     ;
1380
1381 TypeDeclaration:
1382     ConcreteTypeDeclaration
1383     | DefinedType;
1384
1385 ConcreteTypeDeclaration:
1386         BuiltinType
1387         | TOK_CHOICE '{' AlternativeTypeLists '}' {
1388                 $$ = $3;
1389                 assert($$->expr_type == A1TC_INVALID);
1390                 $$->expr_type = ASN_CONSTR_CHOICE;
1391                 $$->meta_type = AMT_TYPE;
1392         }
1393         | TOK_SEQUENCE '{' optComponentTypeLists '}' {
1394                 $$ = $3;
1395                 assert($$->expr_type == A1TC_INVALID);
1396                 $$->expr_type = ASN_CONSTR_SEQUENCE;
1397                 $$->meta_type = AMT_TYPE;
1398         }
1399         | TOK_SET '{' optComponentTypeLists '}' {
1400                 $$ = $3;
1401                 assert($$->expr_type == A1TC_INVALID);
1402                 $$->expr_type = ASN_CONSTR_SET;
1403                 $$->meta_type = AMT_TYPE;
1404         }
1405         | TOK_SEQUENCE optSizeOrConstraint TOK_OF optIdentifier optTag MaybeIndirectTypeDeclaration {
1406                 $$ = NEW_EXPR();
1407                 checkmem($$);
1408                 $$->constraints = $2;
1409                 $$->expr_type = ASN_CONSTR_SEQUENCE_OF;
1410                 $$->meta_type = AMT_TYPE;
1411                 $6->Identifier = $4;
1412                 $6->tag = $5;
1413                 asn1p_expr_add($$, $6);
1414         }
1415         | TOK_SET optSizeOrConstraint TOK_OF optIdentifier optTag MaybeIndirectTypeDeclaration {
1416                 $$ = NEW_EXPR();
1417                 checkmem($$);
1418                 $$->constraints = $2;
1419                 $$->expr_type = ASN_CONSTR_SET_OF;
1420                 $$->meta_type = AMT_TYPE;
1421                 $6->Identifier = $4;
1422                 $6->tag = $5;
1423                 asn1p_expr_add($$, $6);
1424         }
1425         | TOK_ANY                                       {
1426                 $$ = NEW_EXPR();
1427                 checkmem($$);
1428                 $$->expr_type = ASN_TYPE_ANY;
1429                 $$->meta_type = AMT_TYPE;
1430         }
1431         | TOK_ANY TOK_DEFINED TOK_BY Identifier         {
1432                 int ret;
1433                 $$ = NEW_EXPR();
1434                 checkmem($$);
1435                 $$->reference = asn1p_ref_new(yylineno, currentModule);
1436                 ret = asn1p_ref_add_component($$->reference,
1437                         $4, RLT_lowercase);
1438                 checkmem(ret == 0);
1439                 $$->expr_type = ASN_TYPE_ANY;
1440                 $$->meta_type = AMT_TYPE;
1441                 free($4);
1442         }
1443         | TOK_INSTANCE TOK_OF ComplexTypeReference {
1444                 $$ = NEW_EXPR();
1445                 checkmem($$);
1446                 $$->reference = $3;
1447                 $$->expr_type = A1TC_INSTANCE;
1448                 $$->meta_type = AMT_TYPE;
1449         }
1450         ;
1451
1452 /*
1453  * A type name consisting of several components.
1454  * === EXAMPLE ===
1455  * === EOF ===
1456  */
1457 ComplexTypeReference:
1458         TOK_typereference {
1459                 int ret;
1460                 $$ = asn1p_ref_new(yylineno, currentModule);
1461                 checkmem($$);
1462                 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1463                 checkmem(ret == 0);
1464                 free($1);
1465         }
1466         | TOK_capitalreference {
1467                 int ret;
1468                 $$ = asn1p_ref_new(yylineno, currentModule);
1469                 checkmem($$);
1470                 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1471                 free($1);
1472                 checkmem(ret == 0);
1473         }
1474         | TOK_typereference '.' TypeRefName {
1475                 int ret;
1476                 $$ = asn1p_ref_new(yylineno, currentModule);
1477                 checkmem($$);
1478                 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1479                 checkmem(ret == 0);
1480                 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1481                 checkmem(ret == 0);
1482                 free($1);
1483                 free($3);
1484         }
1485         | TOK_capitalreference '.' TypeRefName {
1486                 int ret;
1487                 $$ = asn1p_ref_new(yylineno, currentModule);
1488                 checkmem($$);
1489                 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1490                 checkmem(ret == 0);
1491                 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1492                 checkmem(ret == 0);
1493                 free($1);
1494                 free($3);
1495         }
1496         | TOK_capitalreference '.' ComplexTypeReferenceAmpList {
1497                 int ret;
1498                 $$ = $3;
1499                 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1500                 free($1);
1501                 checkmem(ret == 0);
1502                 /*
1503                  * Move the last element infront.
1504                  */
1505                 {
1506                         struct asn1p_ref_component_s tmp_comp;
1507                         tmp_comp = $$->components[$$->comp_count-1];
1508                         memmove(&$$->components[1],
1509                                 &$$->components[0],
1510                                 sizeof($$->components[0])
1511                                 * ($$->comp_count - 1));
1512                         $$->components[0] = tmp_comp;
1513                 }
1514         }
1515         ;
1516
1517 ComplexTypeReferenceAmpList:
1518         ComplexTypeReferenceElement {
1519                 int ret;
1520                 $$ = asn1p_ref_new(yylineno, currentModule);
1521                 checkmem($$);
1522                 ret = asn1p_ref_add_component($$, $1.name, $1.lex_type);
1523                 free($1.name);
1524                 checkmem(ret == 0);
1525         }
1526         | ComplexTypeReferenceAmpList '.' ComplexTypeReferenceElement {
1527                 int ret;
1528                 $$ = $1;
1529                 ret = asn1p_ref_add_component($$, $3.name, $3.lex_type);
1530                 free($3.name);
1531                 checkmem(ret == 0);
1532         }
1533         ;
1534
1535 ComplexTypeReferenceElement:    PrimitiveFieldReference;
1536
1537 PrimitiveFieldReference:
1538         /* "&Type1" */
1539         TOK_typefieldreference {
1540                 $$.lex_type = RLT_AmpUppercase;
1541                 $$.name = $1;
1542         }
1543         /* "&id" */
1544         | TOK_valuefieldreference {
1545                 $$.lex_type = RLT_Amplowercase;
1546                 $$.name = $1;
1547         }
1548         ;
1549
1550
1551 FieldName:
1552         /* "&Type1" */
1553         TOK_typefieldreference {
1554                 $$ = asn1p_ref_new(yylineno, currentModule);
1555                 asn1p_ref_add_component($$, $1, RLT_AmpUppercase);
1556                 free($1);
1557         }
1558         | FieldName '.' TOK_typefieldreference {
1559                 $$ = $$;
1560                 asn1p_ref_add_component($$, $3, RLT_AmpUppercase);
1561                 free($3);
1562         }
1563         | FieldName '.' TOK_valuefieldreference {
1564                 $$ = $$;
1565                 asn1p_ref_add_component($$, $3, RLT_Amplowercase);
1566                 free($3);
1567         }
1568         ;
1569
1570 DefinedObjectClass:
1571         TOK_capitalreference {
1572                 $$ = asn1p_ref_new(yylineno, currentModule);
1573                 asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1574                 free($1);
1575         }
1576 /*
1577         | TypeRefName '.' TOK_capitalreference {
1578                 $$ = asn1p_ref_new(yylineno, currentModule);
1579                 asn1p_ref_add_component($$, $1, RLT_AmpUppercase);
1580                 asn1p_ref_add_component($$, $3, RLT_CAPITALS);
1581                 free($1);
1582                 free($3);
1583         }
1584 */
1585         ;
1586
1587
1588 /*
1589  * === EXAMPLE ===
1590  * value INTEGER ::= 1
1591  * === EOF ===
1592  */
1593 ValueAssignment:
1594         Identifier Type TOK_PPEQ Value {
1595                 $$ = $2;
1596                 assert($$->Identifier == NULL);
1597                 $$->Identifier = $1;
1598                 $$->meta_type = AMT_VALUE;
1599                 $$->value = $4;
1600         }
1601         ;
1602
1603 Value:
1604         SimpleValue
1605         | DefinedValue
1606         | '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque {
1607                 $$ = asn1p_value_frombuf($3.buf, $3.len, 0);
1608                 checkmem($$);
1609                 $$->type = ATV_UNPARSED;
1610         }
1611     ;
1612
1613 SimpleValue:
1614         TOK_NULL {
1615                 $$ = asn1p_value_fromint(0);
1616                 checkmem($$);
1617                 $$->type = ATV_NULL;
1618         }
1619         | TOK_FALSE {
1620                 $$ = asn1p_value_fromint(0);
1621                 checkmem($$);
1622                 $$->type = ATV_FALSE;
1623         }
1624         | TOK_TRUE {
1625                 $$ = asn1p_value_fromint(1);
1626                 checkmem($$);
1627                 $$->type = ATV_TRUE;
1628         }
1629         | SignedNumber
1630         | RealValue
1631         | RestrictedCharacterStringValue
1632         | BitStringValue
1633         ;
1634
1635 DefinedValue:
1636         IdentifierAsValue
1637         | TypeRefName '.' Identifier {
1638                 asn1p_ref_t *ref;
1639                 int ret;
1640                 ref = asn1p_ref_new(yylineno, currentModule);
1641                 checkmem(ref);
1642                 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1643                 checkmem(ret == 0);
1644                 ret = asn1p_ref_add_component(ref, $3, RLT_lowercase);
1645                 checkmem(ret == 0);
1646                 $$ = asn1p_value_fromref(ref, 0);
1647                 checkmem($$);
1648                 free($1);
1649                 free($3);
1650         }
1651         ;
1652
1653
1654 RestrictedCharacterStringValue:
1655         TOK_cstring {
1656                 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1657                 checkmem($$);
1658         }
1659         | TOK_tuple {
1660                 $$ = asn1p_value_fromint($1);
1661                 checkmem($$);
1662                 $$->type = ATV_TUPLE;
1663         }
1664         | TOK_quadruple {
1665                 $$ = asn1p_value_fromint($1);
1666                 checkmem($$);
1667                 $$->type = ATV_QUADRUPLE;
1668         }
1669         ;
1670
1671 Opaque:
1672     OpaqueFirstToken {
1673                 $$.len = $1.len + 1;
1674                 $$.buf = malloc(1 + $$.len + 1);
1675                 checkmem($$.buf);
1676                 $$.buf[0] = '{';
1677                 memcpy($$.buf + 1, $1.buf, $1.len);
1678                 $$.buf[$$.len] = '\0';
1679                 free($1.buf);
1680     }
1681         | Opaque TOK_opaque {
1682                 int newsize = $1.len + $2.len;
1683                 char *p = malloc(newsize + 1);
1684                 checkmem(p);
1685                 memcpy(p         , $1.buf, $1.len);
1686                 memcpy(p + $1.len, $2.buf, $2.len);
1687                 p[newsize] = '\0';
1688                 free($1.buf);
1689                 free($2.buf);
1690                 $$.buf = p;
1691                 $$.len = newsize;
1692         }
1693         ;
1694
1695 OpaqueFirstToken:
1696     TOK_opaque
1697     | Identifier {
1698         $$.len = strlen($1);
1699         $$.buf = $1;
1700     };
1701
1702 BasicTypeId:
1703         TOK_BOOLEAN { $$ = ASN_BASIC_BOOLEAN; }
1704         | TOK_NULL { $$ = ASN_BASIC_NULL; }
1705         | TOK_REAL { $$ = ASN_BASIC_REAL; }
1706         | TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; }
1707         | TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; }
1708         | TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; }
1709         | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; }
1710         | TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; }
1711         | TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; }
1712         | TOK_UTCTime { $$ = ASN_BASIC_UTCTime; }
1713         | TOK_GeneralizedTime { $$ = ASN_BASIC_GeneralizedTime; }
1714         | BasicString
1715         | BasicTypeId_UniverationCompatible
1716         ;
1717
1718 /*
1719  * A type identifier which may be used with "{ a(1), b(2) }" clause.
1720  */
1721 BasicTypeId_UniverationCompatible:
1722         TOK_INTEGER { $$ = ASN_BASIC_INTEGER; }
1723         | TOK_ENUMERATED { $$ = ASN_BASIC_ENUMERATED; }
1724         | TOK_BIT TOK_STRING { $$ = ASN_BASIC_BIT_STRING; }
1725         ;
1726
1727 BuiltinType:
1728         BasicTypeId {
1729                 $$ = NEW_EXPR();
1730                 checkmem($$);
1731                 $$->expr_type = $1;
1732                 $$->meta_type = AMT_TYPE;
1733         }
1734     | TOK_INTEGER '{' NamedNumberList '}' {
1735         $$ = $3;
1736         $$->expr_type = ASN_BASIC_INTEGER;
1737         $$->meta_type = AMT_TYPE;
1738     }
1739     | TOK_ENUMERATED '{' Enumerations '}' {
1740         $$ = $3;
1741         $$->expr_type = ASN_BASIC_ENUMERATED;
1742         $$->meta_type = AMT_TYPE;
1743     }
1744     | TOK_BIT TOK_STRING '{' NamedBitList '}' {
1745         $$ = $4;
1746         $$->expr_type = ASN_BASIC_BIT_STRING;
1747         $$->meta_type = AMT_TYPE;
1748     }
1749     | TOK_ExtValue_BIT_STRING '{' IdentifierList '}' {
1750         $$ = $3;
1751         $$->expr_type = ASN_BASIC_BIT_STRING;
1752         $$->meta_type = AMT_TYPE;
1753     }
1754     | TOK_ExtValue_BIT_STRING '{' '}' {
1755                 $$ = NEW_EXPR();
1756                 checkmem($$);
1757         $$->expr_type = ASN_BASIC_BIT_STRING;
1758         $$->meta_type = AMT_TYPE;
1759     }
1760         ;
1761
1762 BasicString:
1763         TOK_BMPString { $$ = ASN_STRING_BMPString; }
1764         | TOK_GeneralString {
1765                 $$ = ASN_STRING_GeneralString;
1766                 fprintf(stderr, "WARNING: GeneralString is not fully supported\n");
1767         }
1768         | TOK_GraphicString {
1769                 $$ = ASN_STRING_GraphicString;
1770                 fprintf(stderr, "WARNING: GraphicString is not fully supported\n");
1771         }
1772         | TOK_IA5String { $$ = ASN_STRING_IA5String; }
1773         | TOK_ISO646String { $$ = ASN_STRING_ISO646String; }
1774         | TOK_NumericString { $$ = ASN_STRING_NumericString; }
1775         | TOK_PrintableString { $$ = ASN_STRING_PrintableString; }
1776         | TOK_T61String {
1777                 $$ = ASN_STRING_T61String;
1778                 fprintf(stderr, "WARNING: T61String is not fully supported\n");
1779         }
1780         | TOK_TeletexString { $$ = ASN_STRING_TeletexString; }
1781         | TOK_UniversalString { $$ = ASN_STRING_UniversalString; }
1782         | TOK_UTF8String { $$ = ASN_STRING_UTF8String; }
1783         | TOK_VideotexString {
1784                 $$ = ASN_STRING_VideotexString;
1785                 fprintf(stderr, "WARNING: VideotexString is not fully supported\n");
1786         }
1787         | TOK_VisibleString { $$ = ASN_STRING_VisibleString; }
1788         | TOK_ObjectDescriptor { $$ = ASN_STRING_ObjectDescriptor; }
1789         ;
1790
1791
1792 /*
1793  * Data type constraints.
1794  */
1795 UnionMark:              '|' | TOK_UNION;
1796 IntersectionMark:       '^' | TOK_INTERSECTION;
1797
1798 /* empty | Constraint */
1799 optConstraint:
1800         { $$ = 0; }
1801         | Constraint;
1802
1803 /* empty | Constraint... */
1804 optManyConstraints:
1805         { $$ = 0; }
1806         | ManyConstraints;
1807
1808 /* empty | Constraint | SIZE(...) */
1809 optSizeOrConstraint:
1810         { $$ = 0; }
1811         | Constraint
1812         | SizeConstraint
1813         ;
1814
1815 Constraint:
1816     '(' ConstraintSpec ')' {
1817                 CONSTRAINT_INSERT($$, ACT_CA_SET, $2, 0);
1818     }
1819     ;
1820
1821 ManyConstraints:
1822     Constraint
1823         | ManyConstraints Constraint {
1824         if($2->type == ACT_CA_SET && $2->el_count == 1) {
1825             CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $2->elements[0]);
1826         } else {
1827             CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $2);
1828         }
1829         }
1830         ;
1831
1832 ConstraintSpec: SubtypeConstraint | GeneralConstraint;
1833
1834 SubtypeConstraint: ElementSetSpecs;
1835
1836 ElementSetSpecs:
1837         TOK_ThreeDots  {
1838                 $$ = asn1p_constraint_new(yylineno, currentModule);
1839                 $$->type = ACT_EL_EXT;
1840         }
1841    | ElementSetSpec
1842    | ElementSetSpec ',' TOK_ThreeDots {
1843        asn1p_constraint_t *ct;
1844        ct = asn1p_constraint_new(yylineno, currentModule);
1845        ct->type = ACT_EL_EXT;
1846        CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1847    }
1848    | ElementSetSpec ',' TOK_ThreeDots ',' ElementSetSpec {
1849        asn1p_constraint_t *ct;
1850        ct = asn1p_constraint_new(yylineno, currentModule);
1851        ct->type = ACT_EL_EXT;
1852        CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1853        ct = $$;
1854        CONSTRAINT_INSERT($$, ACT_CA_CSV, ct, $5);
1855    }
1856 ;
1857
1858 ElementSetSpec:
1859         Unions
1860         | TOK_ALL TOK_EXCEPT Elements {
1861                 CONSTRAINT_INSERT($$, ACT_CA_AEX, $3, 0);
1862         }
1863         ;
1864
1865 Unions:
1866         Intersections
1867         | Unions UnionMark Intersections {
1868                 CONSTRAINT_INSERT($$, ACT_CA_UNI, $1, $3);
1869         }
1870         ;
1871
1872 Intersections:
1873         IntersectionElements
1874         |  Intersections IntersectionMark IntersectionElements {
1875                 CONSTRAINT_INSERT($$, ACT_CA_INT, $1, $3);
1876         }
1877         ;
1878
1879
1880 IntersectionElements:
1881         Elements
1882         | Elements TOK_EXCEPT Elements {
1883                 CONSTRAINT_INSERT($$, ACT_CA_EXC, $1, $3);
1884         }
1885         ;
1886
1887 Elements:
1888     SubtypeElements
1889     | '(' ElementSetSpec ')' {
1890         int ret;
1891         $$ = asn1p_constraint_new(yylineno, currentModule);
1892         checkmem($$);
1893         $$->type = ACT_CA_SET;
1894         ret = asn1p_constraint_insert($$, $2);
1895         checkmem(ret == 0);
1896     }
1897     ;
1898
1899 SubtypeElements:
1900         SingleValue {
1901                 $$ = asn1p_constraint_new(yylineno, currentModule);
1902                 checkmem($$);
1903                 $$->type = ACT_EL_VALUE;
1904                 $$->value = $1;
1905         }
1906         | ContainedSubtype {
1907                 $$ = asn1p_constraint_new(yylineno, currentModule);
1908                 checkmem($$);
1909                 $$->type = ACT_EL_TYPE;
1910                 $$->containedSubtype = $1;
1911         }
1912     | PermittedAlphabet /* FROM ... */
1913     | SizeConstraint    /* SIZE ... */
1914     /* | TypeConstraint is via ContainedSubtype */
1915         | InnerTypeConstraints  /* WITH COMPONENT[S] ... */
1916         | PatternConstraint     /* PATTERN ... */
1917         | ValueRange
1918         ;
1919
1920
1921 PermittedAlphabet:
1922         TOK_FROM Constraint {
1923                 CONSTRAINT_INSERT($$, ACT_CT_FROM, $2, 0);
1924         };
1925
1926 SizeConstraint:
1927         TOK_SIZE Constraint {
1928                 CONSTRAINT_INSERT($$, ACT_CT_SIZE, $2, 0);
1929         };
1930
1931 PatternConstraint:
1932         TOK_PATTERN TOK_cstring {
1933                 $$ = asn1p_constraint_new(yylineno, currentModule);
1934                 $$->type = ACT_CT_PATTERN;
1935                 $$->value = asn1p_value_frombuf($2.buf, $2.len, 0);
1936         }
1937         | TOK_PATTERN Identifier {
1938                 asn1p_ref_t *ref;
1939                 $$ = asn1p_constraint_new(yylineno, currentModule);
1940                 $$->type = ACT_CT_PATTERN;
1941                 ref = asn1p_ref_new(yylineno, currentModule);
1942                 asn1p_ref_add_component(ref, $2, RLT_lowercase);
1943                 $$->value = asn1p_value_fromref(ref, 0);
1944                 free($2);
1945         }
1946         ;
1947
1948 ValueRange:
1949     LowerEndValue ConstraintRangeSpec UpperEndValue {
1950                 $$ = asn1p_constraint_new(yylineno, currentModule);
1951                 checkmem($$);
1952                 $$->type = $2;
1953                 $$->range_start = $1;
1954                 $$->range_stop = $3;
1955     };
1956
1957 LowerEndValue:
1958     SingleValue
1959     | TOK_MIN {
1960                 $$ = asn1p_value_fromint(-123);
1961                 $$->type = ATV_MIN;
1962     };
1963
1964 UpperEndValue:
1965     SingleValue
1966     | TOK_MAX {
1967                 $$ = asn1p_value_fromint(321);
1968                 $$->type = ATV_MAX;
1969     };
1970
1971 SingleValue: Value;
1972
1973 BitStringValue:
1974         TOK_bstring {
1975                 $$ = _convert_bitstring2binary($1, 'B');
1976                 checkmem($$);
1977                 free($1);
1978         }
1979         | TOK_hstring {
1980                 $$ = _convert_bitstring2binary($1, 'H');
1981                 checkmem($$);
1982                 free($1);
1983         }
1984         ;
1985
1986 ContainedSubtype:
1987     TOK_INCLUDES Type {
1988                 $$ = asn1p_value_fromtype($2);
1989                 checkmem($$);
1990                 asn1p_expr_free($2);
1991     }
1992     /* Can't put Type here because of conflicts. Simplified subset */
1993     | DefinedUntaggedType {
1994                 $$ = asn1p_value_fromtype($1);
1995                 checkmem($$);
1996                 asn1p_expr_free($1);
1997     }
1998         ;
1999
2000 /*
2001  * X.680 08/2015
2002  * #51.8.5
2003  */
2004 InnerTypeConstraints:
2005         TOK_WITH TOK_COMPONENT SingleTypeConstraint {
2006                 CONSTRAINT_INSERT($$, ACT_CT_WCOMP, $3, 0);
2007         }
2008         | TOK_WITH TOK_COMPONENTS MultipleTypeConstraints {
2009         assert($3->type == ACT_CA_CSV);
2010         $3->type = ACT_CT_WCOMPS;
2011         $$ = $3;
2012         }
2013         ;
2014 SingleTypeConstraint: Constraint;
2015 MultipleTypeConstraints: FullSpecification | PartialSpecification;
2016 FullSpecification: '{' TypeConstraints '}' { $$ = $2; };
2017 PartialSpecification:
2018     '{' TOK_ThreeDots ',' TypeConstraints '}' {
2019         assert($4->type == ACT_CA_CSV);
2020                 $$ = asn1p_constraint_new(yylineno, currentModule);
2021         $$->type = ACT_CA_CSV;
2022                 asn1p_constraint_t *ct = asn1p_constraint_new(yylineno, currentModule);
2023                 checkmem($$);
2024                 ct->type = ACT_EL_EXT;
2025         asn1p_constraint_insert($$, ct);
2026         for(unsigned i = 0; i < $4->el_count; i++) {
2027             asn1p_constraint_insert($$, $4->elements[i]);
2028         }
2029     };
2030 TypeConstraints:
2031     NamedConstraint {
2032         $$ = asn1p_constraint_new(yylineno, currentModule);
2033         $$->type = ACT_CA_CSV;
2034         asn1p_constraint_insert($$, $1);
2035     }
2036     | TypeConstraints ',' NamedConstraint {
2037         $$ = $1;
2038         asn1p_constraint_insert($$, $3);
2039         }
2040         ;
2041 NamedConstraint:
2042         IdentifierAsValue optConstraint optPresenceConstraint {
2043         $$ = asn1p_constraint_new(yylineno, currentModule);
2044         checkmem($$);
2045         $$->type = ACT_EL_VALUE;
2046         $$->value = $1;
2047         if($2) asn1p_constraint_insert($$, $2);
2048         $$->presence = $3;
2049     }
2050     ;
2051
2052 /*
2053  * presence constraint for NamedConstraint
2054  */
2055 optPresenceConstraint:
2056         { $$ = ACPRES_DEFAULT; }
2057         | PresenceConstraint { $$ = $1; }
2058         ;
2059
2060 PresenceConstraint:
2061         TOK_PRESENT {
2062                 $$ = ACPRES_PRESENT;
2063         }
2064         | TOK_ABSENT {
2065                 $$ = ACPRES_ABSENT;
2066         }
2067         | TOK_OPTIONAL {
2068                 $$ = ACPRES_OPTIONAL;
2069         }
2070         ;
2071
2072
2073 /* X.682 */
2074 GeneralConstraint:
2075         UserDefinedConstraint
2076         | TableConstraint
2077         | ContentsConstraint
2078         ;
2079
2080 UserDefinedConstraint:
2081         TOK_CONSTRAINED TOK_BY '{'
2082                 { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
2083                 $$ = asn1p_constraint_new(yylineno, currentModule);
2084                 checkmem($$);
2085                 $$->type = ACT_CT_CTDBY;
2086                 $$->value = asn1p_value_frombuf($5.buf, $5.len, 0);
2087                 checkmem($$->value);
2088                 $$->value->type = ATV_UNPARSED;
2089         }
2090         ;
2091
2092 ContentsConstraint:
2093         TOK_CONTAINING Type {
2094                 $$ = asn1p_constraint_new(yylineno, currentModule);
2095                 $$->type = ACT_CT_CTNG;
2096                 $$->value = asn1p_value_fromtype($2);
2097                 asn1p_expr_free($2);
2098         }
2099         ;
2100
2101 ConstraintRangeSpec:
2102         TOK_TwoDots             { $$ = ACT_EL_RANGE; }
2103         | TOK_TwoDots '<'       { $$ = ACT_EL_RLRANGE; }
2104         | '<' TOK_TwoDots       { $$ = ACT_EL_LLRANGE; }
2105         | '<' TOK_TwoDots '<'   { $$ = ACT_EL_ULRANGE; }
2106         ;
2107 TableConstraint:
2108         SimpleTableConstraint {
2109                 $$ = $1;
2110         }
2111         | ComponentRelationConstraint {
2112                 $$ = $1;
2113         }
2114         ;
2115
2116 /*
2117  * "{ExtensionSet}"
2118  */
2119 SimpleTableConstraint:
2120         '{' TypeRefName '}' {
2121                 asn1p_ref_t *ref = asn1p_ref_new(yylineno, currentModule);
2122                 asn1p_constraint_t *ct;
2123                 int ret;
2124                 ret = asn1p_ref_add_component(ref, $2, 0);
2125                 checkmem(ret == 0);
2126                 ct = asn1p_constraint_new(yylineno, currentModule);
2127                 checkmem($$);
2128                 ct->type = ACT_EL_VALUE;
2129                 ct->value = asn1p_value_fromref(ref, 0);
2130                 CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0);
2131                 free($2);
2132         }
2133         ;
2134
2135 ComponentRelationConstraint:
2136         SimpleTableConstraint '{' AtNotationList '}' {
2137                 CONSTRAINT_INSERT($$, ACT_CA_CRC, $1, $3);
2138         }
2139         ;
2140
2141 AtNotationList:
2142         AtNotationElement {
2143                 $$ = asn1p_constraint_new(yylineno, currentModule);
2144                 checkmem($$);
2145                 $$->type = ACT_EL_VALUE;
2146                 $$->value = asn1p_value_fromref($1, 0);
2147         }
2148         | AtNotationList ',' AtNotationElement {
2149                 asn1p_constraint_t *ct;
2150                 ct = asn1p_constraint_new(yylineno, currentModule);
2151                 checkmem(ct);
2152                 ct->type = ACT_EL_VALUE;
2153                 ct->value = asn1p_value_fromref($3, 0);
2154                 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
2155         }
2156         ;
2157
2158 /*
2159  * @blah
2160  */
2161 AtNotationElement:
2162         '@' ComponentIdList {
2163                 char *p = malloc(strlen($2) + 2);
2164                 int ret;
2165                 *p = '@';
2166                 strcpy(p + 1, $2);
2167                 $$ = asn1p_ref_new(yylineno, currentModule);
2168                 ret = asn1p_ref_add_component($$, p, 0);
2169                 checkmem(ret == 0);
2170                 free(p);
2171                 free($2);
2172         }
2173         | '@' '.' ComponentIdList {
2174                 char *p = malloc(strlen($3) + 3);
2175                 int ret;
2176                 p[0] = '@';
2177                 p[1] = '.';
2178                 strcpy(p + 2, $3);
2179                 $$ = asn1p_ref_new(yylineno, currentModule);
2180                 ret = asn1p_ref_add_component($$, p, 0);
2181                 checkmem(ret == 0);
2182                 free(p);
2183                 free($3);
2184         }
2185         ;
2186
2187 /* identifier "." ... */
2188 ComponentIdList:
2189         Identifier {
2190                 $$ = $1;
2191         }
2192         | ComponentIdList '.' Identifier {
2193                 int l1 = strlen($1);
2194                 int l3 = strlen($3);
2195                 $$ = malloc(l1 + 1 + l3 + 1);
2196                 memcpy($$, $1, l1);
2197                 $$[l1] = '.';
2198                 memcpy($$ + l1 + 1, $3, l3);
2199                 $$[l1 + 1 + l3] = '\0';
2200                 free($1);
2201                 free($3);
2202         }
2203         ;
2204
2205
2206
2207 /*
2208  * MARKERS
2209  */
2210
2211 optMarker:
2212         {
2213                 $$.flags = EM_NOMARK;
2214                 $$.default_value = 0;
2215         }
2216         | Marker { $$ = $1; }
2217         ;
2218
2219 Marker:
2220         TOK_OPTIONAL {
2221                 $$.flags = EM_OPTIONAL | EM_INDIRECT;
2222                 $$.default_value = 0;
2223         }
2224         | TOK_DEFAULT Value {
2225                 $$.flags = EM_DEFAULT;
2226                 $$.default_value = $2;
2227         }
2228         ;
2229
2230 IdentifierList:
2231     IdentifierElement {
2232                 $$ = NEW_EXPR();
2233                 checkmem($$);
2234                 asn1p_expr_add($$, $1);
2235     }
2236     | IdentifierList ',' IdentifierElement {
2237                 $$ = $1;
2238                 asn1p_expr_add($$, $3);
2239     };
2240
2241 IdentifierElement:
2242     Identifier {
2243                 $$ = NEW_EXPR();
2244                 checkmem($$);
2245                 $$->expr_type = A1TC_UNIVERVAL;
2246                 $$->meta_type = AMT_VALUE;
2247                 $$->Identifier = $1;
2248     }
2249
2250 NamedNumberList:
2251         NamedNumber {
2252                 $$ = NEW_EXPR();
2253                 checkmem($$);
2254                 asn1p_expr_add($$, $1);
2255         }
2256         | NamedNumberList ',' NamedNumber {
2257                 $$ = $1;
2258                 asn1p_expr_add($$, $3);
2259         }
2260         ;
2261
2262 NamedNumber:
2263         Identifier '(' SignedNumber ')' {
2264                 $$ = NEW_EXPR();
2265                 checkmem($$);
2266                 $$->expr_type = A1TC_UNIVERVAL;
2267                 $$->meta_type = AMT_VALUE;
2268                 $$->Identifier = $1;
2269                 $$->value = $3;
2270         }
2271         | Identifier '(' DefinedValue ')' {
2272                 $$ = NEW_EXPR();
2273                 checkmem($$);
2274                 $$->expr_type = A1TC_UNIVERVAL;
2275                 $$->meta_type = AMT_VALUE;
2276                 $$->Identifier = $1;
2277                 $$->value = $3;
2278         };
2279
2280 NamedBitList:
2281         NamedBit {
2282                 $$ = NEW_EXPR();
2283                 checkmem($$);
2284                 asn1p_expr_add($$, $1);
2285         }
2286         | NamedBitList ',' NamedBit {
2287                 $$ = $1;
2288                 asn1p_expr_add($$, $3);
2289         }
2290         ;
2291
2292 NamedBit:
2293         Identifier '(' TOK_number ')' {
2294                 $$ = NEW_EXPR();
2295                 checkmem($$);
2296                 $$->expr_type = A1TC_UNIVERVAL;
2297                 $$->meta_type = AMT_VALUE;
2298                 $$->Identifier = $1;
2299                 $$->value = asn1p_value_fromint($3);
2300         }
2301         | Identifier '(' DefinedValue ')' {
2302                 $$ = NEW_EXPR();
2303                 checkmem($$);
2304                 $$->expr_type = A1TC_UNIVERVAL;
2305                 $$->meta_type = AMT_VALUE;
2306                 $$->Identifier = $1;
2307                 $$->value = $3;
2308         };
2309
2310 Enumerations:
2311     UniverationList {
2312                 $$ = $1;
2313         asn1p_expr_t *first_memb = TQ_FIRST(&($$->members));
2314         if(first_memb) {
2315             if(first_memb->expr_type == A1TC_EXTENSIBLE) {
2316                 return yyerror(
2317                     "The ENUMERATION cannot start with extension (...).");
2318             }
2319         } else {
2320             return yyerror(
2321                 "The ENUMERATION list cannot be empty.");
2322         }
2323     }
2324
2325 UniverationList:
2326         UniverationElement {
2327                 $$ = NEW_EXPR();
2328                 checkmem($$);
2329                 asn1p_expr_add($$, $1);
2330         }
2331         | UniverationList ',' UniverationElement {
2332                 $$ = $1;
2333                 asn1p_expr_add($$, $3);
2334         }
2335         ;
2336
2337 UniverationElement:
2338         Identifier {
2339                 $$ = NEW_EXPR();
2340                 checkmem($$);
2341                 $$->expr_type = A1TC_UNIVERVAL;
2342                 $$->meta_type = AMT_VALUE;
2343                 $$->Identifier = $1;
2344         }
2345         | Identifier '(' SignedNumber ')' {
2346                 $$ = NEW_EXPR();
2347                 checkmem($$);
2348                 $$->expr_type = A1TC_UNIVERVAL;
2349                 $$->meta_type = AMT_VALUE;
2350                 $$->Identifier = $1;
2351                 $$->value = $3;
2352         }
2353         | Identifier '(' DefinedValue ')' {
2354                 $$ = NEW_EXPR();
2355                 checkmem($$);
2356                 $$->expr_type = A1TC_UNIVERVAL;
2357                 $$->meta_type = AMT_VALUE;
2358                 $$->Identifier = $1;
2359                 $$->value = $3;
2360         }
2361         | SignedNumber {
2362                 $$ = NEW_EXPR();
2363                 checkmem($$);
2364                 $$->expr_type = A1TC_UNIVERVAL;
2365                 $$->meta_type = AMT_VALUE;
2366                 $$->value = $1;
2367         }
2368         | TOK_ThreeDots {
2369                 $$ = NEW_EXPR();
2370                 checkmem($$);
2371                 $$->Identifier = strdup("...");
2372                 checkmem($$->Identifier);
2373                 $$->expr_type = A1TC_EXTENSIBLE;
2374                 $$->meta_type = AMT_VALUE;
2375         }
2376         ;
2377
2378 SignedNumber:
2379         TOK_number {
2380                 $$ = asn1p_value_fromint($1);
2381                 checkmem($$);
2382         }
2383         | TOK_number_negative {
2384                 $$ = asn1p_value_fromint($1);
2385                 checkmem($$);
2386         }
2387         ;
2388
2389 RealValue:
2390         TOK_realnumber {
2391                 $$ = asn1p_value_fromdouble($1);
2392                 checkmem($$);
2393         }
2394         ;
2395
2396 /*
2397  * SEQUENCE definition.
2398  * === EXAMPLE ===
2399  * Struct1 ::= SEQUENCE {
2400  *      memb1 Struct2,
2401  *      memb2 SEQUENCE OF {
2402  *              memb2-1 Struct 3
2403  *      }
2404  * }
2405  * === EOF ===
2406  */
2407
2408
2409
2410 /*
2411  * SET definition.
2412  * === EXAMPLE ===
2413  * Person ::= SET {
2414  *      name [0] PrintableString (SIZE(1..20)),
2415  *      country [1] PrintableString (SIZE(1..20)) DEFAULT default-country,
2416  * }
2417  * === EOF ===
2418  */
2419
2420 optTag:
2421         { memset(&$$, 0, sizeof($$)); }
2422         | Tag { $$ = $1; }
2423         ;
2424
2425 Tag:
2426         TagTypeValue TagPlicit {
2427                 $$ = $1;
2428                 $$.tag_mode = $2.tag_mode;
2429         }
2430         ;
2431
2432 TagTypeValue:
2433         '[' TagClass TOK_number ']' {
2434                 $$ = $2;
2435                 $$.tag_value = $3;
2436         };
2437
2438 TagClass:
2439         { $$.tag_class = TC_CONTEXT_SPECIFIC; }
2440         | TOK_UNIVERSAL { $$.tag_class = TC_UNIVERSAL; }
2441         | TOK_APPLICATION { $$.tag_class = TC_APPLICATION; }
2442         | TOK_PRIVATE { $$.tag_class = TC_PRIVATE; }
2443         ;
2444
2445 TagPlicit:
2446         { $$.tag_mode = TM_DEFAULT; }
2447         | TOK_IMPLICIT { $$.tag_mode = TM_IMPLICIT; }
2448         | TOK_EXPLICIT { $$.tag_mode = TM_EXPLICIT; }
2449         ;
2450
2451 TypeRefName:
2452         TOK_typereference {
2453                 checkmem($1);
2454                 $$ = $1;
2455         }
2456         | TOK_capitalreference {
2457                 checkmem($1);
2458                 $$ = $1;
2459         }
2460         ;
2461
2462
2463 optIdentifier:
2464         { $$ = 0; }
2465         | Identifier {
2466                 $$ = $1;
2467         }
2468         ;
2469
2470 Identifier:
2471         TOK_identifier {
2472                 checkmem($1);
2473                 $$ = $1;
2474         }
2475         ;
2476
2477 IdentifierAsReference:
2478     Identifier {
2479                 $$ = asn1p_ref_new(yylineno, currentModule);
2480                 asn1p_ref_add_component($$, $1, RLT_lowercase);
2481                 free($1);
2482     };
2483
2484 IdentifierAsValue:
2485     IdentifierAsReference {
2486                 $$ = asn1p_value_fromref($1, 0);
2487     };
2488
2489 %%
2490
2491
2492 /*
2493  * Convert Xstring ('0101'B or '5'H) to the binary vector.
2494  */
2495 static asn1p_value_t *
2496 _convert_bitstring2binary(char *str, int base) {
2497         asn1p_value_t *val;
2498         int slen;
2499         int memlen;
2500         int baselen;
2501         int bits;
2502         uint8_t *binary_vector;
2503         uint8_t *bv_ptr;
2504         uint8_t cur_val;
2505
2506         assert(str);
2507         assert(str[0] == '\'');
2508
2509         switch(base) {
2510         case 'B':
2511                 baselen = 1;
2512                 break;
2513         case 'H':
2514                 baselen = 4;
2515                 break;
2516         default:
2517                 assert(base == 'B' || base == 'H');
2518                 errno = EINVAL;
2519                 return NULL;
2520         }
2521
2522         slen = strlen(str);
2523         assert(str[slen - 1] == base);
2524         assert(str[slen - 2] == '\'');
2525
2526         memlen = slen / (8 / baselen);  /* Conservative estimate */
2527
2528         bv_ptr = binary_vector = malloc(memlen + 1);
2529         if(bv_ptr == NULL)
2530                 /* ENOMEM */
2531                 return NULL;
2532
2533         cur_val = 0;
2534         bits = 0;
2535         while(*(++str) != '\'') {
2536                 switch(baselen) {
2537                 case 1:
2538                         switch(*str) {
2539                         case '1':
2540                                 cur_val |= 1 << (7 - (bits % 8));
2541                         case '0':
2542                                 break;
2543                         default:
2544                                 assert(!"_y UNREACH1");
2545                         case ' ': case '\r': case '\n':
2546                                 continue;
2547                         }
2548                         break;
2549                 case 4:
2550                         switch(*str) {
2551                         case '0': case '1': case '2': case '3': case '4':
2552                         case '5': case '6': case '7': case '8': case '9':
2553                                 cur_val |= (*str - '0') << (4 - (bits % 8));
2554                                 break;
2555                         case 'A': case 'B': case 'C':
2556                         case 'D': case 'E': case 'F':
2557                                 cur_val |= ((*str - 'A') + 10)
2558                                         << (4 - (bits % 8));
2559                                 break;
2560                         default:
2561                                 assert(!"_y UNREACH2");
2562                         case ' ': case '\r': case '\n':
2563                                 continue;
2564                         }
2565                         break;
2566                 }
2567
2568                 bits += baselen;
2569                 if((bits % 8) == 0) {
2570                         *bv_ptr++ = cur_val;
2571                         cur_val = 0;
2572                 }
2573         }
2574
2575         *bv_ptr = cur_val;
2576         assert((bv_ptr - binary_vector) <= memlen);
2577
2578         val = asn1p_value_frombits(binary_vector, bits, 0);
2579         if(val == NULL) {
2580                 free(binary_vector);
2581         }
2582
2583         return val;
2584 }
2585
2586 /*
2587  * For unnamed types (used in old X.208 compliant modules)
2588  * generate some sort of interim names, to not to force human being to fix
2589  * the specification's compliance to modern ASN.1 standards.
2590  */
2591 static void
2592 _fixup_anonymous_identifier(asn1p_expr_t *expr) {
2593         char *p;
2594         assert(expr->Identifier == 0);
2595
2596         /*
2597          * Try to figure out the type name
2598          * without going too much into details
2599          */
2600         expr->Identifier = ASN_EXPR_TYPE2STR(expr->expr_type);
2601         if(expr->reference && expr->reference->comp_count > 0)
2602                 expr->Identifier = expr->reference->components[0].name;
2603
2604         fprintf(stderr,
2605                 "WARNING: Line %d: expected lower-case member identifier, "
2606                 "found an unnamed %s.\n"
2607                 "WARNING: Obsolete X.208 syntax detected, "
2608                 "please give the member a name.\n",
2609                 yylineno, expr->Identifier ? expr->Identifier : "type");
2610
2611         if(!expr->Identifier)
2612                 expr->Identifier = "unnamed";
2613         expr->Identifier = strdup(expr->Identifier);
2614         assert(expr->Identifier);
2615         /* Make a lowercase identifier from the type name */
2616         for(p = expr->Identifier; *p; p++) {
2617                 switch(*p) {
2618                 case 'A' ... 'Z': *p += 32; break;
2619                 case ' ': *p = '_'; break;
2620                 case '-': *p = '_'; break;
2621                 }
2622         }
2623         fprintf(stderr, "NOTE: Assigning temporary identifier \"%s\". "
2624                         "Name clash may occur later.\n",
2625                 expr->Identifier);
2626 }
2627
2628 static int
2629 yyerror(const char *msg) {
2630         extern char *asn1p_text;
2631         fprintf(stderr,
2632                 "ASN.1 grammar parse error "
2633                 "near %s:%d (token \"%s\"): %s\n",
2634                 ASN_FILENAME, yylineno, asn1p_text, msg);
2635         return -1;
2636 }
2637