blob: f9c7ed4fbfe9c7a6feb17613d0ff5c540a5e3bea [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001%{
2
3#include <stdlib.h>
4#include <stdio.h>
5#include <string.h>
6#include <errno.h>
7#include <assert.h>
8
9#include "asn1parser.h"
10
11#define YYPARSE_PARAM param
12#define YYERROR_VERBOSE
13
14int yylex(void);
15int yyerror(const char *msg);
16void asn1p_lexer_hack_push_opaque_state(void);
17void asn1p_lexer_hack_enable_with_syntax(void);
Lev Walkinf59d0752004-08-18 04:59:12 +000018void asn1p_lexer_hack_push_encoding_control(void);
Lev Walkinf15320b2004-06-03 03:38:44 +000019#define yylineno asn1p_lineno
20extern int asn1p_lineno;
21
22
23static asn1p_value_t *
24 _convert_bitstring2binary(char *str, int base);
25
Lev Walkin1004aa92004-09-08 00:28:11 +000026#define checkmem(ptr) do { \
27 if(!(ptr)) \
28 return yyerror("Memory failure"); \
Lev Walkinf15320b2004-06-03 03:38:44 +000029 } while(0)
30
31#define CONSTRAINT_INSERT(root, constr_type, arg1, arg2) do { \
32 if(arg1->type != constr_type) { \
33 int __ret; \
34 root = asn1p_constraint_new(yylineno); \
35 checkmem(root); \
36 root->type = constr_type; \
37 __ret = asn1p_constraint_insert(root, \
38 arg1); \
39 checkmem(__ret == 0); \
40 } else { \
41 root = arg1; \
42 } \
43 if(arg2) { \
44 int __ret \
45 = asn1p_constraint_insert(root, arg2); \
46 checkmem(__ret == 0); \
47 } \
48 } while(0)
49
50%}
51
52
53/*
54 * Token value definition.
55 * a_*: ASN-specific types.
56 * tv_*: Locally meaningful types.
57 */
58%union {
59 asn1p_t *a_grammar;
60 asn1p_module_flags_e a_module_flags;
61 asn1p_module_t *a_module;
62 asn1p_expr_type_e a_type; /* ASN.1 Type */
63 asn1p_expr_t *a_expr; /* Constructed collection */
64 asn1p_constraint_t *a_constr; /* Constraint */
65 enum asn1p_constraint_type_e a_ctype;/* Constraint type */
66 asn1p_xports_t *a_xports; /* IMports/EXports */
67 asn1p_oid_t *a_oid; /* Object Identifier */
68 asn1p_oid_arc_t a_oid_arc; /* Single OID's arc */
69 struct asn1p_type_tag_s a_tag; /* A tag */
70 asn1p_ref_t *a_ref; /* Reference to custom type */
71 asn1p_wsyntx_t *a_wsynt; /* WITH SYNTAX contents */
72 asn1p_wsyntx_chunk_t *a_wchunk; /* WITH SYNTAX chunk */
73 struct asn1p_ref_component_s a_refcomp; /* Component of a reference */
74 asn1p_value_t *a_value; /* Number, DefinedValue, etc */
75 struct asn1p_param_s a_parg; /* A parameter argument */
76 asn1p_paramlist_t *a_plist; /* A pargs list */
Lev Walkin9c974182004-09-15 11:59:51 +000077 struct asn1p_expr_marker_s a_marker; /* OPTIONAL/DEFAULT */
Lev Walkinf15320b2004-06-03 03:38:44 +000078 enum asn1p_constr_pres_e a_pres; /* PRESENT/ABSENT/OPTIONAL */
Lev Walkin144db9b2004-10-12 23:26:53 +000079 asn1c_integer_t a_int;
Lev Walkinf15320b2004-06-03 03:38:44 +000080 char *tv_str;
81 struct {
82 char *buf;
83 int len;
84 } tv_opaque;
85 struct {
86 char *name;
87 struct asn1p_type_tag_s tag;
88 } tv_nametag;
89};
90
91/*
92 * Token types returned by scanner.
93 */
94%token TOK_PPEQ /* "::=", Pseudo Pascal EQuality */
95%token <tv_opaque> TOK_opaque /* opaque data (driven from .y) */
96%token <tv_str> TOK_bstring
97%token <tv_opaque> TOK_cstring
98%token <tv_str> TOK_hstring
99%token <tv_str> TOK_identifier
100%token <a_int> TOK_number
101%token <a_int> TOK_number_negative
102%token <tv_str> TOK_typereference
Lev Walkinf59d0752004-08-18 04:59:12 +0000103%token <tv_str> TOK_capitalreference /* "CLASS1" */
Lev Walkinf15320b2004-06-03 03:38:44 +0000104%token <tv_str> TOK_typefieldreference /* "&Pork" */
105%token <tv_str> TOK_valuefieldreference /* "&id" */
106
107/*
108 * Token types representing ASN.1 standard keywords.
109 */
110%token TOK_ABSENT
111%token TOK_ABSTRACT_SYNTAX
112%token TOK_ALL
113%token TOK_ANY
114%token TOK_APPLICATION
115%token TOK_AUTOMATIC
116%token TOK_BEGIN
117%token TOK_BIT
118%token TOK_BMPString
119%token TOK_BOOLEAN
120%token TOK_BY
121%token TOK_CHARACTER
122%token TOK_CHOICE
123%token TOK_CLASS
124%token TOK_COMPONENT
125%token TOK_COMPONENTS
126%token TOK_CONSTRAINED
127%token TOK_CONTAINING
128%token TOK_DEFAULT
129%token TOK_DEFINITIONS
130%token TOK_DEFINED
131%token TOK_EMBEDDED
132%token TOK_ENCODED
Lev Walkinf59d0752004-08-18 04:59:12 +0000133%token TOK_ENCODING_CONTROL
Lev Walkinf15320b2004-06-03 03:38:44 +0000134%token TOK_END
135%token TOK_ENUMERATED
136%token TOK_EXPLICIT
137%token TOK_EXPORTS
138%token TOK_EXTENSIBILITY
139%token TOK_EXTERNAL
140%token TOK_FALSE
141%token TOK_FROM
142%token TOK_GeneralizedTime
143%token TOK_GeneralString
144%token TOK_GraphicString
145%token TOK_IA5String
146%token TOK_IDENTIFIER
147%token TOK_IMPLICIT
148%token TOK_IMPLIED
149%token TOK_IMPORTS
150%token TOK_INCLUDES
151%token TOK_INSTANCE
Lev Walkinf59d0752004-08-18 04:59:12 +0000152%token TOK_INSTRUCTIONS
Lev Walkinf15320b2004-06-03 03:38:44 +0000153%token TOK_INTEGER
154%token TOK_ISO646String
155%token TOK_MAX
156%token TOK_MIN
157%token TOK_MINUS_INFINITY
158%token TOK_NULL
159%token TOK_NumericString
160%token TOK_OBJECT
161%token TOK_ObjectDescriptor
162%token TOK_OCTET
163%token TOK_OF
164%token TOK_OPTIONAL
165%token TOK_PATTERN
166%token TOK_PDV
167%token TOK_PLUS_INFINITY
168%token TOK_PRESENT
169%token TOK_PrintableString
170%token TOK_PRIVATE
171%token TOK_REAL
172%token TOK_RELATIVE_OID
173%token TOK_SEQUENCE
174%token TOK_SET
175%token TOK_SIZE
176%token TOK_STRING
177%token TOK_SYNTAX
178%token TOK_T61String
179%token TOK_TAGS
180%token TOK_TeletexString
181%token TOK_TRUE
182%token TOK_TYPE_IDENTIFIER
183%token TOK_UNIQUE
184%token TOK_UNIVERSAL
185%token TOK_UniversalString
186%token TOK_UTCTime
187%token TOK_UTF8String
188%token TOK_VideotexString
189%token TOK_VisibleString
190%token TOK_WITH
191
Lev Walkinf15320b2004-06-03 03:38:44 +0000192%left TOK_EXCEPT
Lev Walkinf59d0752004-08-18 04:59:12 +0000193%left '^' TOK_INTERSECTION
194%left '|' TOK_UNION
Lev Walkinf15320b2004-06-03 03:38:44 +0000195
196/* Misc tags */
197%token TOK_TwoDots /* .. */
198%token TOK_ThreeDots /* ... */
Lev Walkinf15320b2004-06-03 03:38:44 +0000199
200
201/*
202 * Types defined herein.
203 */
204%type <a_grammar> ModuleList
205%type <a_module> ModuleSpecification
206%type <a_module> ModuleSpecificationBody
207%type <a_module> ModuleSpecificationElement
208%type <a_module> optModuleSpecificationBody /* Optional */
209%type <a_module_flags> optModuleSpecificationFlags
210%type <a_module_flags> ModuleSpecificationFlags /* Set of FL */
211%type <a_module_flags> ModuleSpecificationFlag /* Single FL */
212%type <a_module> ImportsDefinition
213%type <a_module> ImportsBundleSet
214%type <a_xports> ImportsBundle
215%type <a_xports> ImportsList
216%type <a_xports> ExportsDefinition
217%type <a_xports> ExportsBody
218%type <a_expr> ImportsElement
219%type <a_expr> ExportsElement
Lev Walkinf15320b2004-06-03 03:38:44 +0000220%type <a_expr> ExtensionAndException
Lev Walkin070a52d2004-08-22 03:19:54 +0000221%type <a_expr> TypeDeclaration
Lev Walkinf15320b2004-06-03 03:38:44 +0000222%type <a_ref> ComplexTypeReference
223%type <a_ref> ComplexTypeReferenceAmpList
224%type <a_refcomp> ComplexTypeReferenceElement
225%type <a_refcomp> ClassFieldIdentifier
226%type <a_refcomp> ClassFieldName
227%type <a_expr> ClassFieldList
228%type <a_expr> ClassField
229%type <a_expr> ClassDeclaration
Lev Walkin070a52d2004-08-22 03:19:54 +0000230%type <a_expr> Type
Lev Walkinf15320b2004-06-03 03:38:44 +0000231%type <a_expr> DataTypeReference /* Type1 ::= Type2 */
232%type <a_expr> DefinedTypeRef
233%type <a_expr> ValueSetDefinition /* Val INTEGER ::= {1|2} */
234%type <a_expr> ValueDefinition /* val INTEGER ::= 1*/
Lev Walkinceb20e72004-09-05 10:40:41 +0000235%type <a_expr> optValueSetBody
236%type <a_expr> ValueSetBody
237%type <a_expr> ValueSetElement
Lev Walkin9c974182004-09-15 11:59:51 +0000238%type <a_value> Value
Lev Walkinf15320b2004-06-03 03:38:44 +0000239%type <a_value> DefinedValue
240%type <a_value> SignedNumber
Lev Walkin144db9b2004-10-12 23:26:53 +0000241%type <a_expr> optComponentTypeLists
Lev Walkin070a52d2004-08-22 03:19:54 +0000242%type <a_expr> ComponentTypeLists
243%type <a_expr> ComponentType
244%type <a_expr> AlternativeTypeLists
245%type <a_expr> AlternativeType
Lev Walkinf15320b2004-06-03 03:38:44 +0000246//%type <a_expr> optUniverationDefinition
247%type <a_expr> UniverationDefinition
248%type <a_expr> UniverationList
249%type <a_expr> UniverationElement
250%type <tv_str> TypeRefName
251%type <tv_str> ObjectClassReference
Lev Walkinf15320b2004-06-03 03:38:44 +0000252%type <tv_str> Identifier
Lev Walkin83cac2f2004-09-22 16:03:36 +0000253%type <tv_str> optIdentifier
Lev Walkinf15320b2004-06-03 03:38:44 +0000254%type <a_parg> ParameterArgumentName
255%type <a_plist> ParameterArgumentList
256%type <a_expr> ActualParameter
257%type <a_expr> ActualParameterList
258%type <a_oid> ObjectIdentifier /* OID */
259%type <a_oid> optObjectIdentifier /* Optional OID */
260%type <a_oid> ObjectIdentifierBody
261%type <a_oid_arc> ObjectIdentifierElement
262%type <a_expr> BasicType
263%type <a_type> BasicTypeId
264%type <a_type> BasicTypeId_UniverationCompatible
265%type <a_type> BasicString
266%type <tv_opaque> Opaque
267//%type <tv_opaque> StringValue
Lev Walkinc603f102005-01-23 09:51:44 +0000268%type <a_tag> Tag /* [UNIVERSAL 0] IMPLICIT */
269%type <a_tag> TagClass TagTypeValue TagPlicit
Lev Walkinf15320b2004-06-03 03:38:44 +0000270%type <a_tag> optTag /* [UNIVERSAL 0] IMPLICIT */
271%type <a_constr> optConstraints
Lev Walkind2ea1de2004-08-20 13:25:29 +0000272%type <a_constr> Constraints
Lev Walkinf59d0752004-08-18 04:59:12 +0000273%type <a_constr> SetOfConstraints
274%type <a_constr> ElementSetSpecs /* 1..2,...,3 */
275%type <a_constr> ElementSetSpec /* 1..2,...,3 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000276%type <a_constr> ConstraintSubtypeElement /* 1..2 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000277%type <a_constr> SimpleTableConstraint
278%type <a_constr> TableConstraint
279%type <a_constr> WithComponents
280%type <a_constr> WithComponentsList
281%type <a_constr> WithComponentsElement
282%type <a_constr> ComponentRelationConstraint
283%type <a_constr> AtNotationList
284%type <a_ref> AtNotationElement
Lev Walkinff7dd142005-03-20 12:58:00 +0000285%type <a_value> SingleValue
286%type <a_value> ContainedSubtype
Lev Walkinf15320b2004-06-03 03:38:44 +0000287%type <a_ctype> ConstraintSpec
288%type <a_ctype> ConstraintRangeSpec
289%type <a_wsynt> optWithSyntax
290%type <a_wsynt> WithSyntax
291%type <a_wsynt> WithSyntaxFormat
292%type <a_wchunk> WithSyntaxFormatToken
293%type <a_marker> optMarker Marker
294%type <a_int> optUnique
295%type <a_pres> optPresenceConstraint PresenceConstraint
296%type <tv_str> ComponentIdList
297
298
299%%
300
301
302ParsedGrammar:
303 ModuleList {
304 *(void **)param = $1;
305 }
306 ;
307
308ModuleList:
309 ModuleSpecification {
310 $$ = asn1p_new();
311 checkmem($$);
312 TQ_ADD(&($$->modules), $1, mod_next);
313 }
314 | ModuleList ModuleSpecification {
315 $$ = $1;
316 TQ_ADD(&($$->modules), $2, mod_next);
317 }
318 ;
319
320/*
321 * ASN module definition.
322 * === EXAMPLE ===
323 * MySyntax DEFINITIONS AUTOMATIC TAGS ::=
324 * BEGIN
325 * ...
326 * END
327 * === EOF ===
328 */
329
330ModuleSpecification:
331 TypeRefName optObjectIdentifier TOK_DEFINITIONS
332 optModuleSpecificationFlags
333 TOK_PPEQ TOK_BEGIN
334 optModuleSpecificationBody
335 TOK_END {
336
337 if($7) {
338 $$ = $7;
339 } else {
340 /* There's a chance that a module is just plain empty */
341 $$ = asn1p_module_new();
342 }
343 checkmem($$);
344
345 $$->Identifier = $1;
346 $$->module_oid = $2;
347 $$->module_flags = $4;
348 }
349 ;
350
351/*
352 * Object Identifier Definition
353 * { iso member-body(2) 3 }
354 */
355optObjectIdentifier:
356 { $$ = 0; }
357 | ObjectIdentifier { $$ = $1; }
358 ;
359
360ObjectIdentifier:
361 '{' ObjectIdentifierBody '}' {
362 $$ = $2;
363 }
364 | '{' '}' {
365 $$ = 0;
366 }
367 ;
368
369ObjectIdentifierBody:
370 ObjectIdentifierElement {
371 $$ = asn1p_oid_new();
372 asn1p_oid_add_arc($$, &$1);
373 if($1.name)
374 free($1.name);
375 }
376 | ObjectIdentifierBody ObjectIdentifierElement {
377 $$ = $1;
378 asn1p_oid_add_arc($$, &$2);
379 if($2.name)
380 free($2.name);
381 }
382 ;
383
384ObjectIdentifierElement:
385 Identifier { /* iso */
386 $$.name = $1;
387 $$.number = -1;
388 }
389 | Identifier '(' TOK_number ')' { /* iso(1) */
390 $$.name = $1;
391 $$.number = $3;
392 }
393 | TOK_number { /* 1 */
394 $$.name = 0;
395 $$.number = $1;
396 }
397 ;
398
399/*
400 * Optional module flags.
401 */
402optModuleSpecificationFlags:
403 { $$ = MSF_NOFLAGS; }
404 | ModuleSpecificationFlags {
405 $$ = $1;
406 }
407 ;
408
409/*
410 * Module flags.
411 */
412ModuleSpecificationFlags:
413 ModuleSpecificationFlag {
414 $$ = $1;
415 }
416 | ModuleSpecificationFlags ModuleSpecificationFlag {
417 $$ = $1 | $2;
418 }
419 ;
420
421/*
422 * Single module flag.
423 */
424ModuleSpecificationFlag:
425 TOK_EXPLICIT TOK_TAGS {
426 $$ = MSF_EXPLICIT_TAGS;
427 }
428 | TOK_IMPLICIT TOK_TAGS {
429 $$ = MSF_IMPLICIT_TAGS;
430 }
431 | TOK_AUTOMATIC TOK_TAGS {
432 $$ = MSF_AUTOMATIC_TAGS;
433 }
434 | TOK_EXTENSIBILITY TOK_IMPLIED {
435 $$ = MSF_EXTENSIBILITY_IMPLIED;
436 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000437 /* EncodingReferenceDefault */
438 | TOK_capitalreference TOK_INSTRUCTIONS {
439 /* X.680Amd1 specifies TAG and XER */
440 if(strcmp($1, "TAG") == 0) {
441 $$ = MSF_TAG_INSTRUCTIONS;
442 } else if(strcmp($1, "XER") == 0) {
443 $$ = MSF_XER_INSTRUCTIONS;
444 } else {
445 fprintf(stderr,
446 "WARNING: %s INSTRUCTIONS at line %d: "
447 "Unrecognized encoding reference\n",
448 $1, yylineno);
449 $$ = MSF_unk_INSTRUCTIONS;
450 }
451 free($1);
452 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000453 ;
454
455/*
456 * Optional module body.
457 */
458optModuleSpecificationBody:
459 { $$ = 0; }
460 | ModuleSpecificationBody {
Lev Walkinf15320b2004-06-03 03:38:44 +0000461 $$ = $1;
462 }
463 ;
464
465/*
466 * ASN.1 Module body.
467 */
468ModuleSpecificationBody:
469 ModuleSpecificationElement {
470 $$ = $1;
471 }
472 | ModuleSpecificationBody ModuleSpecificationElement {
473 $$ = $1;
474
Lev Walkinf59d0752004-08-18 04:59:12 +0000475 /* Behave well when one of them is skipped. */
476 if(!($1)) {
477 if($2) $$ = $2;
478 break;
479 }
480
Lev Walkinf15320b2004-06-03 03:38:44 +0000481#ifdef MY_IMPORT
482#error MY_IMPORT DEFINED ELSEWHERE!
483#endif
484#define MY_IMPORT(foo,field) do { \
Lev Walkinbc55d232004-08-13 12:31:09 +0000485 while(TQ_FIRST(&($2->foo))) { \
Lev Walkinf15320b2004-06-03 03:38:44 +0000486 TQ_ADD(&($$->foo), \
487 TQ_REMOVE(&($2->foo), field), \
488 field); \
Lev Walkinbc55d232004-08-13 12:31:09 +0000489 } \
490 assert(TQ_FIRST(&($2->foo)) == 0); \
491 } while(0)
Lev Walkinf15320b2004-06-03 03:38:44 +0000492
493 MY_IMPORT(imports, xp_next);
494 MY_IMPORT(exports, xp_next);
495 MY_IMPORT(members, next);
496#undef MY_IMPORT
497
498 }
499 ;
500
501/*
502 * One of the elements of ASN.1 module specification.
503 */
504ModuleSpecificationElement:
505 ImportsDefinition {
506 $$ = $1;
507 }
508 | ExportsDefinition {
509 $$ = asn1p_module_new();
510 checkmem($$);
511 if($1) {
512 TQ_ADD(&($$->exports), $1, xp_next);
513 } else {
514 /* "EXPORTS ALL;" ? */
515 }
516 }
517 | DataTypeReference {
518 $$ = asn1p_module_new();
519 checkmem($$);
520 assert($1->expr_type != A1TC_INVALID);
521 assert($1->meta_type != AMT_INVALID);
522 TQ_ADD(&($$->members), $1, next);
523 }
524 | ValueDefinition {
525 $$ = asn1p_module_new();
526 checkmem($$);
527 assert($1->expr_type != A1TC_INVALID);
528 assert($1->meta_type != AMT_INVALID);
529 TQ_ADD(&($$->members), $1, next);
530 }
531 /*
532 * Value set definition
533 * === EXAMPLE ===
534 * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 }
535 * === EOF ===
536 */
537 | ValueSetDefinition {
538 $$ = asn1p_module_new();
539 checkmem($$);
540 assert($1->expr_type != A1TC_INVALID);
541 assert($1->meta_type != AMT_INVALID);
542 TQ_ADD(&($$->members), $1, next);
543 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000544 | TOK_ENCODING_CONTROL TOK_capitalreference
545 { asn1p_lexer_hack_push_encoding_control(); }
546 {
547 fprintf(stderr,
548 "WARNING: ENCODING-CONTROL %s "
549 "specification at line %d ignored\n",
550 $2, yylineno);
551 free($2);
552 $$ = 0;
553 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000554
555 /*
556 * Erroneous attemps
557 */
558 | BasicString {
559 return yyerror(
560 "Attempt to redefine a standard basic type, "
561 "use -ftypesXY to switch back "
562 "to older version of ASN.1 standard");
563 }
564 ;
565
566/*
567 * === EXAMPLE ===
568 * IMPORTS Type1, value FROM Module { iso standard(0) } ;
569 * === EOF ===
570 */
571ImportsDefinition:
572 TOK_IMPORTS ImportsBundleSet ';' {
573 $$ = $2;
574 }
575 /*
576 * Some error cases.
577 */
578 | TOK_IMPORTS TOK_FROM /* ... */ {
579 return yyerror("Empty IMPORTS list");
580 }
581 ;
582
583ImportsBundleSet:
584 ImportsBundle {
585 $$ = asn1p_module_new();
586 checkmem($$);
587 TQ_ADD(&($$->imports), $1, xp_next);
588 }
589 | ImportsBundleSet ImportsBundle {
590 $$ = $1;
591 TQ_ADD(&($$->imports), $2, xp_next);
592 }
593 ;
594
595ImportsBundle:
596 ImportsList TOK_FROM TypeRefName optObjectIdentifier {
597 $$ = $1;
598 $$->from = $3;
599 $$->from_oid = $4;
600 checkmem($$);
601 }
602 ;
603
604ImportsList:
605 ImportsElement {
606 $$ = asn1p_xports_new();
607 checkmem($$);
608 TQ_ADD(&($$->members), $1, next);
609 }
610 | ImportsList ',' ImportsElement {
611 $$ = $1;
612 TQ_ADD(&($$->members), $3, next);
613 }
614 ;
615
616ImportsElement:
617 TypeRefName {
618 $$ = asn1p_expr_new(yylineno);
619 checkmem($$);
620 $$->Identifier = $1;
621 $$->expr_type = A1TC_REFERENCE;
622 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000623 | TypeRefName '{' '}' { /* Completely equivalent to above */
624 $$ = asn1p_expr_new(yylineno);
625 checkmem($$);
626 $$->Identifier = $1;
627 $$->expr_type = A1TC_REFERENCE;
628 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000629 | Identifier {
630 $$ = asn1p_expr_new(yylineno);
631 checkmem($$);
632 $$->Identifier = $1;
633 $$->expr_type = A1TC_REFERENCE;
634 }
635 ;
636
637ExportsDefinition:
638 TOK_EXPORTS ExportsBody ';' {
639 $$ = $2;
640 }
641 | TOK_EXPORTS TOK_ALL ';' {
642 $$ = 0;
643 }
644 | TOK_EXPORTS ';' {
645 /* Empty EXPORTS clause effectively prohibits export. */
646 $$ = asn1p_xports_new();
647 checkmem($$);
648 }
649 ;
650
651ExportsBody:
652 ExportsElement {
653 $$ = asn1p_xports_new();
654 assert($$);
655 TQ_ADD(&($$->members), $1, next);
656 }
657 | ExportsBody ',' ExportsElement {
658 $$ = $1;
659 TQ_ADD(&($$->members), $3, next);
660 }
661 ;
662
663ExportsElement:
664 TypeRefName {
665 $$ = asn1p_expr_new(yylineno);
666 checkmem($$);
667 $$->Identifier = $1;
668 $$->expr_type = A1TC_EXPORTVAR;
669 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000670 | TypeRefName '{' '}' {
671 $$ = asn1p_expr_new(yylineno);
672 checkmem($$);
673 $$->Identifier = $1;
674 $$->expr_type = A1TC_EXPORTVAR;
675 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000676 | Identifier {
677 $$ = asn1p_expr_new(yylineno);
678 checkmem($$);
679 $$->Identifier = $1;
680 $$->expr_type = A1TC_EXPORTVAR;
681 }
682 ;
683
684
685ValueSetDefinition:
686 TypeRefName DefinedTypeRef TOK_PPEQ '{' optValueSetBody '}' {
687 $$ = $2;
688 assert($$->Identifier == 0);
689 $$->Identifier = $1;
690 $$->meta_type = AMT_VALUESET;
691 // take care of optValueSetBody
692 }
693 ;
694
695DefinedTypeRef:
696 ComplexTypeReference {
697 $$ = asn1p_expr_new(yylineno);
698 checkmem($$);
699 $$->reference = $1;
700 $$->expr_type = A1TC_REFERENCE;
701 $$->meta_type = AMT_TYPEREF;
702 }
703 | BasicTypeId {
704 $$ = asn1p_expr_new(yylineno);
705 checkmem($$);
706 $$->expr_type = $1;
707 $$->meta_type = AMT_TYPE;
708 }
709 ;
710
711optValueSetBody:
712 { }
Lev Walkinceb20e72004-09-05 10:40:41 +0000713 | ValueSetBody {
714 }
715 ;
716
717/*
718 * X.680 does not permit ElementSetSpecs starting with ellipsis,
719 * i.e. (..., A, B). This is very strange: the ElementSetSpecs is used
720 * inside ValueSet, and ValueSets "in the wild" tend to have the first
721 * ellipsis.
722 */
723ValueSetBody:
724 ValueSetElement {
725 }
726 | ValueSetBody ',' ValueSetElement {
727 }
728 ;
729
730ValueSetElement:
731 TOK_ThreeDots {
732 }
733 | ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +0000734 }
735 ;
736
737
738/*
739 * Data Type Reference.
740 * === EXAMPLE ===
741 * Type3 ::= CHOICE { a Type1, b Type 2 }
742 * === EOF ===
743 */
744
745DataTypeReference:
746 /*
747 * Optionally tagged type definition.
748 */
749 TypeRefName TOK_PPEQ optTag TOK_TYPE_IDENTIFIER {
750 $$ = asn1p_expr_new(yylineno);
751 checkmem($$);
752 $$->Identifier = $1;
753 $$->tag = $3;
754 $$->expr_type = A1TC_TYPEID;
755 $$->meta_type = AMT_TYPE;
756 }
Lev Walkinaf120f72004-09-14 02:36:39 +0000757 | TypeRefName TOK_PPEQ Type {
758 $$ = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000759 $$->Identifier = $1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000760 assert($$->expr_type);
761 assert($$->meta_type);
762 }
763 | TypeRefName TOK_PPEQ ClassDeclaration {
764 $$ = $3;
765 $$->Identifier = $1;
766 assert($$->expr_type == A1TC_CLASSDEF);
767 assert($$->meta_type == AMT_OBJECT);
768 }
769 /*
770 * Parametrized <Type> declaration:
771 * === EXAMPLE ===
772 * SIGNED { ToBeSigned } ::= SEQUENCE {
773 * toBeSigned ToBeSigned,
774 * algorithm AlgorithmIdentifier,
775 * signature BIT STRING
776 * }
777 * === EOF ===
778 */
Lev Walkin070a52d2004-08-22 03:19:54 +0000779 | TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000780 $$ = $6;
781 assert($$->Identifier == 0);
782 $$->Identifier = $1;
783 $$->params = $3;
784 $$->meta_type = AMT_PARAMTYPE;
785 }
786 ;
787
788ParameterArgumentList:
789 ParameterArgumentName {
790 int ret;
791 $$ = asn1p_paramlist_new(yylineno);
792 checkmem($$);
793 ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument);
794 checkmem(ret == 0);
795 if($1.governor) asn1p_ref_free($1.governor);
796 if($1.argument) free($1.argument);
797 }
798 | ParameterArgumentList ',' ParameterArgumentName {
799 int ret;
800 $$ = $1;
801 ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument);
802 checkmem(ret == 0);
803 if($3.governor) asn1p_ref_free($3.governor);
804 if($3.argument) free($3.argument);
805 }
806 ;
807
808ParameterArgumentName:
809 TypeRefName {
810 $$.governor = NULL;
811 $$.argument = $1;
812 }
813 | TypeRefName ':' Identifier {
814 int ret;
815 $$.governor = asn1p_ref_new(yylineno);
816 ret = asn1p_ref_add_component($$.governor, $1, 0);
817 checkmem(ret == 0);
818 $$.argument = $3;
819 }
Lev Walkinc8092cb2005-02-18 16:34:21 +0000820 | TypeRefName ':' TypeRefName {
821 int ret;
822 $$.governor = asn1p_ref_new(yylineno);
823 ret = asn1p_ref_add_component($$.governor, $1, 0);
824 checkmem(ret == 0);
825 $$.argument = $3;
826 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000827 | BasicTypeId ':' Identifier {
828 int ret;
829 $$.governor = asn1p_ref_new(yylineno);
830 ret = asn1p_ref_add_component($$.governor,
831 ASN_EXPR_TYPE2STR($1), 1);
832 checkmem(ret == 0);
833 $$.argument = $3;
834 }
835 ;
836
837ActualParameterList:
838 ActualParameter {
839 $$ = asn1p_expr_new(yylineno);
840 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000841 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000842 }
843 | ActualParameterList ',' ActualParameter {
844 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000845 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000846 }
847 ;
848
849ActualParameter:
Lev Walkin070a52d2004-08-22 03:19:54 +0000850 Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000851 $$ = $1;
852 }
853 | Identifier {
854 $$ = asn1p_expr_new(yylineno);
855 checkmem($$);
856 $$->Identifier = $1;
857 $$->expr_type = A1TC_REFERENCE;
858 $$->meta_type = AMT_VALUE;
859 }
860 ;
861
862/*
Lev Walkinc8092cb2005-02-18 16:34:21 +0000863 | '{' ActualParameter '}' {
864 $$ = asn1p_expr_new(yylineno);
865 checkmem($$);
866 asn1p_expr_add($$, $2);
867 $$->expr_type = A1TC_PARAMETRIZED;
868 $$->meta_type = AMT_TYPE;
869 }
870 ;
871*/
872
873/*
Lev Walkinf15320b2004-06-03 03:38:44 +0000874 * A collection of constructed data type members.
875 */
Lev Walkin144db9b2004-10-12 23:26:53 +0000876optComponentTypeLists:
877 { $$ = asn1p_expr_new(yylineno); }
878 | ComponentTypeLists { $$ = $1; };
879
Lev Walkin070a52d2004-08-22 03:19:54 +0000880ComponentTypeLists:
881 ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000882 $$ = asn1p_expr_new(yylineno);
883 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000884 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000885 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000886 | ComponentTypeLists ',' ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000887 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000888 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000889 }
890 ;
891
Lev Walkin070a52d2004-08-22 03:19:54 +0000892ComponentType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000893 Identifier Type optMarker {
Lev Walkin070a52d2004-08-22 03:19:54 +0000894 $$ = $2;
895 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000896 $$->Identifier = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000897 $$->marker = $3;
898 }
899 | TOK_COMPONENTS TOK_OF Type {
900 $$ = asn1p_expr_new(yylineno);
901 checkmem($$);
902 $$->meta_type = $3->meta_type;
903 $$->expr_type = A1TC_COMPONENTS_OF;
Lev Walkin1004aa92004-09-08 00:28:11 +0000904 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000905 }
906 | ExtensionAndException {
907 $$ = $1;
908 }
909 ;
910
911AlternativeTypeLists:
912 AlternativeType {
913 $$ = asn1p_expr_new(yylineno);
914 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000915 asn1p_expr_add($$, $1);
Lev Walkin070a52d2004-08-22 03:19:54 +0000916 }
917 | AlternativeTypeLists ',' AlternativeType {
918 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000919 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000920 }
921 ;
922
923AlternativeType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000924 Identifier Type {
Lev Walkin070a52d2004-08-22 03:19:54 +0000925 $$ = $2;
926 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000927 $$->Identifier = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000928 }
929 | ExtensionAndException {
930 $$ = $1;
931 }
932 ;
933
Lev Walkinf15320b2004-06-03 03:38:44 +0000934ClassDeclaration:
935 TOK_CLASS '{' ClassFieldList '}' optWithSyntax {
936 $$ = $3;
937 checkmem($$);
938 $$->with_syntax = $5;
939 assert($$->expr_type == A1TC_CLASSDEF);
940 assert($$->meta_type == AMT_OBJECT);
941 }
942 ;
943
944optUnique:
945 { $$ = 0; }
946 | TOK_UNIQUE { $$ = 1; }
947 ;
948
949ClassFieldList:
950 ClassField {
951 $$ = asn1p_expr_new(yylineno);
952 checkmem($$);
953 $$->expr_type = A1TC_CLASSDEF;
954 $$->meta_type = AMT_OBJECT;
Lev Walkin1004aa92004-09-08 00:28:11 +0000955 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000956 }
957 | ClassFieldList ',' ClassField {
958 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000959 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000960 }
961 ;
962
963ClassField:
964 ClassFieldIdentifier optMarker {
965 $$ = asn1p_expr_new(yylineno);
966 checkmem($$);
967 $$->Identifier = $1.name;
968 $$->expr_type = A1TC_CLASSFIELD;
969 $$->meta_type = AMT_OBJECTFIELD;
970 $$->marker = $2;
971 }
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000972 | ClassFieldIdentifier Type optUnique optMarker {
Lev Walkinf15320b2004-06-03 03:38:44 +0000973 $$ = $2;
974 $$->Identifier = $1.name;
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000975 $$->marker = $4;
976 $$->unique = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000977 }
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000978 | ClassFieldIdentifier ClassFieldIdentifier optUnique optMarker {
Lev Walkinf15320b2004-06-03 03:38:44 +0000979 int ret;
980 $$ = asn1p_expr_new(yylineno);
981 checkmem($$);
982 $$->Identifier = $1.name;
983 $$->reference = asn1p_ref_new(yylineno);
984 checkmem($$->reference);
985 ret = asn1p_ref_add_component($$->reference,
986 $2.name, $2.lex_type);
987 checkmem(ret == 0);
988 $$->expr_type = A1TC_CLASSFIELD;
989 $$->meta_type = AMT_OBJECTFIELD;
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000990 $$->marker = $4;
991 $$->unique = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000992 }
993 ;
994
995optWithSyntax:
996 { $$ = 0; }
997 | WithSyntax {
998 $$ = $1;
999 }
1000 ;
1001
1002WithSyntax:
1003 TOK_WITH TOK_SYNTAX '{'
1004 { asn1p_lexer_hack_enable_with_syntax(); }
1005 WithSyntaxFormat
1006 '}' {
1007 $$ = $5;
1008 }
1009 ;
1010
1011WithSyntaxFormat:
1012 WithSyntaxFormatToken {
1013 $$ = asn1p_wsyntx_new();
1014 TQ_ADD(&($$->chunks), $1, next);
1015 }
1016 | WithSyntaxFormat WithSyntaxFormatToken {
1017 $$ = $1;
1018 TQ_ADD(&($$->chunks), $2, next);
1019 }
1020 ;
1021
1022WithSyntaxFormatToken:
1023 TOK_opaque {
1024 $$ = asn1p_wsyntx_chunk_frombuf($1.buf, $1.len, 0);
1025 }
1026 | ClassFieldIdentifier {
1027 asn1p_ref_t *ref;
1028 int ret;
1029 ref = asn1p_ref_new(yylineno);
1030 checkmem(ref);
1031 ret = asn1p_ref_add_component(ref, $1.name, $1.lex_type);
1032 checkmem(ret == 0);
1033 $$ = asn1p_wsyntx_chunk_fromref(ref, 0);
1034 }
1035 ;
1036
Lev Walkinf15320b2004-06-03 03:38:44 +00001037ExtensionAndException:
1038 TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001039 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001040 checkmem($$);
1041 $$->Identifier = strdup("...");
1042 checkmem($$->Identifier);
1043 $$->expr_type = A1TC_EXTENSIBLE;
1044 $$->meta_type = AMT_TYPE;
1045 }
1046 | TOK_ThreeDots '!' DefinedValue {
Lev Walkinceb20e72004-09-05 10:40:41 +00001047 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001048 checkmem($$);
1049 $$->Identifier = strdup("...");
1050 checkmem($$->Identifier);
1051 $$->value = $3;
1052 $$->expr_type = A1TC_EXTENSIBLE;
1053 $$->meta_type = AMT_TYPE;
1054 }
1055 | TOK_ThreeDots '!' SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001056 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001057 checkmem($$);
1058 $$->Identifier = strdup("...");
1059 $$->value = $3;
1060 checkmem($$->Identifier);
1061 $$->expr_type = A1TC_EXTENSIBLE;
1062 $$->meta_type = AMT_TYPE;
1063 }
1064 ;
1065
Lev Walkin070a52d2004-08-22 03:19:54 +00001066Type:
Lev Walkinaf120f72004-09-14 02:36:39 +00001067 optTag TypeDeclaration optConstraints {
1068 $$ = $2;
1069 $$->tag = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +00001070 /*
1071 * Outer constraint for SEQUENCE OF and SET OF applies
1072 * to the inner type.
1073 */
1074 if($$->expr_type == ASN_CONSTR_SEQUENCE_OF
1075 || $$->expr_type == ASN_CONSTR_SET_OF) {
1076 assert(!TQ_FIRST(&($$->members))->constraints);
Lev Walkinaf120f72004-09-14 02:36:39 +00001077 TQ_FIRST(&($$->members))->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001078 } else {
1079 if($$->constraints) {
1080 assert(!$2);
1081 } else {
Lev Walkinaf120f72004-09-14 02:36:39 +00001082 $$->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001083 }
1084 }
1085 }
1086 ;
1087
1088TypeDeclaration:
Lev Walkinf15320b2004-06-03 03:38:44 +00001089 BasicType {
1090 $$ = $1;
1091 }
Lev Walkin070a52d2004-08-22 03:19:54 +00001092 | TOK_CHOICE '{' AlternativeTypeLists '}' {
1093 $$ = $3;
1094 assert($$->expr_type == A1TC_INVALID);
1095 $$->expr_type = ASN_CONSTR_CHOICE;
1096 $$->meta_type = AMT_TYPE;
Lev Walkinf15320b2004-06-03 03:38:44 +00001097 }
Lev Walkin144db9b2004-10-12 23:26:53 +00001098 | TOK_SEQUENCE '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001099 $$ = $3;
1100 assert($$->expr_type == A1TC_INVALID);
1101 $$->expr_type = ASN_CONSTR_SEQUENCE;
1102 $$->meta_type = AMT_TYPE;
1103 }
Lev Walkin144db9b2004-10-12 23:26:53 +00001104 | TOK_SET '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001105 $$ = $3;
1106 assert($$->expr_type == A1TC_INVALID);
1107 $$->expr_type = ASN_CONSTR_SET;
1108 $$->meta_type = AMT_TYPE;
1109 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001110 | TOK_SEQUENCE optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001111 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001112 checkmem($$);
1113 $$->constraints = $2;
1114 $$->expr_type = ASN_CONSTR_SEQUENCE_OF;
1115 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001116 $6->Identifier = $4;
1117 $6->tag = $5;
1118 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001119 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001120 | TOK_SET optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001121 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001122 checkmem($$);
1123 $$->constraints = $2;
1124 $$->expr_type = ASN_CONSTR_SET_OF;
1125 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001126 $6->Identifier = $4;
1127 $6->tag = $5;
1128 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001129 }
1130 | TOK_ANY {
Lev Walkinceb20e72004-09-05 10:40:41 +00001131 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001132 checkmem($$);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001133 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001134 $$->meta_type = AMT_TYPE;
1135 }
1136 | TOK_ANY TOK_DEFINED TOK_BY Identifier {
1137 int ret;
Lev Walkinceb20e72004-09-05 10:40:41 +00001138 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001139 checkmem($$);
1140 $$->reference = asn1p_ref_new(yylineno);
1141 ret = asn1p_ref_add_component($$->reference,
1142 $4, RLT_lowercase);
1143 checkmem(ret == 0);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001144 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001145 $$->meta_type = AMT_TYPE;
1146 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001147 /*
1148 * A parametrized assignment.
1149 */
1150 | TypeRefName '{' ActualParameterList '}' {
1151 int ret;
1152 $$ = $3;
1153 assert($$->expr_type == 0);
1154 assert($$->meta_type == 0);
1155 assert($$->reference == 0);
1156 $$->reference = asn1p_ref_new(yylineno);
1157 checkmem($$->reference);
1158 ret = asn1p_ref_add_component($$->reference, $1, RLT_UNKNOWN);
1159 checkmem(ret == 0);
1160 free($1);
1161 $$->expr_type = A1TC_PARAMETRIZED;
1162 $$->meta_type = AMT_TYPE;
1163 }
1164 /*
1165 * A DefinedType reference.
1166 * "CLASS1.&id.&id2"
1167 * or
1168 * "Module.Type"
1169 * or
1170 * "Module.identifier"
1171 * or
1172 * "Type"
1173 */
1174 | ComplexTypeReference {
1175 $$ = asn1p_expr_new(yylineno);
1176 checkmem($$);
1177 $$->reference = $1;
1178 $$->expr_type = A1TC_REFERENCE;
1179 $$->meta_type = AMT_TYPEREF;
1180 }
1181 | TOK_INSTANCE TOK_OF ComplexTypeReference {
1182 $$ = asn1p_expr_new(yylineno);
1183 checkmem($$);
1184 $$->reference = $3;
1185 $$->expr_type = A1TC_INSTANCE;
1186 $$->meta_type = AMT_TYPE;
1187 }
1188 ;
1189
1190/*
1191 * A type name consisting of several components.
1192 * === EXAMPLE ===
1193 * === EOF ===
1194 */
1195ComplexTypeReference:
1196 TOK_typereference {
1197 int ret;
1198 $$ = asn1p_ref_new(yylineno);
1199 checkmem($$);
1200 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1201 checkmem(ret == 0);
1202 free($1);
1203 }
1204 | TOK_typereference '.' TypeRefName {
1205 int ret;
1206 $$ = asn1p_ref_new(yylineno);
1207 checkmem($$);
1208 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1209 checkmem(ret == 0);
1210 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1211 checkmem(ret == 0);
1212 free($1);
1213 }
Lev Walkin9c974182004-09-15 11:59:51 +00001214 | ObjectClassReference '.' TypeRefName {
1215 int ret;
1216 $$ = asn1p_ref_new(yylineno);
1217 checkmem($$);
1218 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1219 checkmem(ret == 0);
1220 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1221 checkmem(ret == 0);
1222 free($1);
1223 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001224 | TOK_typereference '.' Identifier {
1225 int ret;
1226 $$ = asn1p_ref_new(yylineno);
1227 checkmem($$);
1228 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1229 checkmem(ret == 0);
1230 ret = asn1p_ref_add_component($$, $3, RLT_lowercase);
1231 checkmem(ret == 0);
1232 free($1);
1233 }
1234 | ObjectClassReference {
1235 int ret;
1236 $$ = asn1p_ref_new(yylineno);
1237 checkmem($$);
1238 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1239 free($1);
1240 checkmem(ret == 0);
1241 }
1242 | ObjectClassReference '.' ComplexTypeReferenceAmpList {
1243 int ret;
1244 $$ = $3;
1245 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1246 free($1);
1247 checkmem(ret == 0);
1248 /*
1249 * Move the last element infront.
1250 */
1251 {
1252 struct asn1p_ref_component_s tmp_comp;
1253 tmp_comp = $$->components[$$->comp_count-1];
1254 memmove(&$$->components[1],
1255 &$$->components[0],
1256 sizeof($$->components[0])
1257 * ($$->comp_count - 1));
1258 $$->components[0] = tmp_comp;
1259 }
1260 }
1261 ;
1262
1263ComplexTypeReferenceAmpList:
1264 ComplexTypeReferenceElement {
1265 int ret;
1266 $$ = asn1p_ref_new(yylineno);
1267 checkmem($$);
1268 ret = asn1p_ref_add_component($$, $1.name, $1.lex_type);
1269 free($1.name);
1270 checkmem(ret == 0);
1271 }
1272 | ComplexTypeReferenceAmpList '.' ComplexTypeReferenceElement {
1273 int ret;
1274 $$ = $1;
1275 ret = asn1p_ref_add_component($$, $3.name, $3.lex_type);
1276 free($3.name);
1277 checkmem(ret == 0);
1278 }
1279 ;
1280
1281ComplexTypeReferenceElement: ClassFieldName;
1282ClassFieldIdentifier: ClassFieldName;
1283
1284ClassFieldName:
1285 /* "&Type1" */
1286 TOK_typefieldreference {
1287 $$.lex_type = RLT_AmpUppercase;
1288 $$.name = $1;
1289 }
1290 /* "&id" */
1291 | TOK_valuefieldreference {
1292 $$.lex_type = RLT_Amplowercase;
1293 $$.name = $1;
1294 }
1295 ;
1296
1297
1298/*
1299 * === EXAMPLE ===
1300 * value INTEGER ::= 1
1301 * === EOF ===
1302 */
1303ValueDefinition:
Lev Walkin9c974182004-09-15 11:59:51 +00001304 Identifier DefinedTypeRef TOK_PPEQ Value {
Lev Walkinf15320b2004-06-03 03:38:44 +00001305 $$ = $2;
1306 assert($$->Identifier == NULL);
1307 $$->Identifier = $1;
1308 $$->meta_type = AMT_VALUE;
1309 $$->value = $4;
1310 }
1311 ;
1312
Lev Walkin9c974182004-09-15 11:59:51 +00001313Value:
1314 Identifier ':' Value {
1315 $$ = asn1p_value_fromint(0);
1316 checkmem($$);
1317 $$->type = ATV_CHOICE_IDENTIFIER;
1318 $$->value.choice_identifier.identifier = $1;
1319 $$->value.choice_identifier.value = $3;
1320 }
1321 | '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
Lev Walkinf15320b2004-06-03 03:38:44 +00001322 $$ = asn1p_value_frombuf($3.buf, $3.len, 0);
1323 checkmem($$);
1324 $$->type = ATV_UNPARSED;
1325 }
Lev Walkin9c974182004-09-15 11:59:51 +00001326 | TOK_NULL {
1327 $$ = asn1p_value_fromint(0);
1328 checkmem($$);
1329 $$->type = ATV_NULL;
1330 }
1331 | TOK_FALSE {
1332 $$ = asn1p_value_fromint(0);
1333 checkmem($$);
1334 $$->type = ATV_FALSE;
1335 }
1336 | TOK_TRUE {
1337 $$ = asn1p_value_fromint(0);
1338 checkmem($$);
1339 $$->type = ATV_TRUE;
1340 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001341 | TOK_bstring {
1342 $$ = _convert_bitstring2binary($1, 'B');
1343 checkmem($$);
1344 }
1345 | TOK_hstring {
1346 $$ = _convert_bitstring2binary($1, 'H');
1347 checkmem($$);
1348 }
1349 | TOK_cstring {
1350 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1351 checkmem($$);
1352 }
1353 | SignedNumber {
1354 $$ = $1;
1355 }
1356 | DefinedValue {
1357 $$ = $1;
1358 }
1359 ;
1360
1361DefinedValue:
1362 Identifier {
1363 asn1p_ref_t *ref;
1364 int ret;
1365 ref = asn1p_ref_new(yylineno);
1366 checkmem(ref);
1367 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1368 checkmem(ret == 0);
1369 $$ = asn1p_value_fromref(ref, 0);
1370 checkmem($$);
1371 free($1);
1372 }
1373 | TypeRefName '.' Identifier {
1374 asn1p_ref_t *ref;
1375 int ret;
1376 ref = asn1p_ref_new(yylineno);
1377 checkmem(ref);
1378 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1379 checkmem(ret == 0);
1380 ret = asn1p_ref_add_component(ref, $3, RLT_lowercase);
1381 checkmem(ret == 0);
1382 $$ = asn1p_value_fromref(ref, 0);
1383 checkmem($$);
1384 free($1);
1385 free($3);
1386 }
1387 ;
1388
1389Opaque:
1390 TOK_opaque {
Lev Walkin1893ddf2005-03-20 14:28:32 +00001391 $$.len = $1.len + 1;
Lev Walkinf15320b2004-06-03 03:38:44 +00001392 $$.buf = malloc($$.len + 1);
1393 checkmem($$.buf);
1394 $$.buf[0] = '{';
Lev Walkin1893ddf2005-03-20 14:28:32 +00001395 memcpy($$.buf + 1, $1.buf, $1.len);
Lev Walkinf15320b2004-06-03 03:38:44 +00001396 $$.buf[$$.len] = '\0';
1397 free($1.buf);
1398 }
1399 | Opaque TOK_opaque {
1400 int newsize = $1.len + $2.len;
1401 char *p = malloc(newsize + 1);
1402 checkmem(p);
1403 memcpy(p , $1.buf, $1.len);
1404 memcpy(p + $1.len, $2.buf, $2.len);
1405 p[newsize] = '\0';
1406 free($1.buf);
1407 free($2.buf);
1408 $$.buf = p;
1409 $$.len = newsize;
1410 }
1411 ;
1412
1413BasicTypeId:
1414 TOK_BOOLEAN { $$ = ASN_BASIC_BOOLEAN; }
1415 | TOK_NULL { $$ = ASN_BASIC_NULL; }
1416 | TOK_REAL { $$ = ASN_BASIC_REAL; }
1417 | BasicTypeId_UniverationCompatible { $$ = $1; }
1418 | TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; }
1419 | TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; }
1420 | TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; }
1421 | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; }
1422 | TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; }
1423 | TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; }
1424 | TOK_UTCTime { $$ = ASN_BASIC_UTCTime; }
1425 | TOK_GeneralizedTime { $$ = ASN_BASIC_GeneralizedTime; }
Lev Walkinc7d939d2005-03-20 11:12:40 +00001426 | BasicString { $$ = $1; }
Lev Walkinf15320b2004-06-03 03:38:44 +00001427 ;
1428
1429/*
1430 * A type identifier which may be used with "{ a(1), b(2) }" clause.
1431 */
1432BasicTypeId_UniverationCompatible:
1433 TOK_INTEGER { $$ = ASN_BASIC_INTEGER; }
1434 | TOK_ENUMERATED { $$ = ASN_BASIC_ENUMERATED; }
1435 | TOK_BIT TOK_STRING { $$ = ASN_BASIC_BIT_STRING; }
1436 ;
1437
1438BasicType:
1439 BasicTypeId {
Lev Walkinceb20e72004-09-05 10:40:41 +00001440 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001441 checkmem($$);
1442 $$->expr_type = $1;
1443 $$->meta_type = AMT_TYPE;
1444 }
1445 | BasicTypeId_UniverationCompatible UniverationDefinition {
1446 if($2) {
1447 $$ = $2;
1448 } else {
Lev Walkinceb20e72004-09-05 10:40:41 +00001449 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001450 checkmem($$);
1451 }
1452 $$->expr_type = $1;
1453 $$->meta_type = AMT_TYPE;
1454 }
1455 ;
1456
1457BasicString:
1458 TOK_BMPString { $$ = ASN_STRING_BMPString; }
1459 | TOK_GeneralString {
1460 $$ = ASN_STRING_GeneralString;
Lev Walkin9c974182004-09-15 11:59:51 +00001461 fprintf(stderr, "WARNING: GeneralString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001462 }
1463 | TOK_GraphicString {
1464 $$ = ASN_STRING_GraphicString;
Lev Walkin9c974182004-09-15 11:59:51 +00001465 fprintf(stderr, "WARNING: GraphicString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001466 }
1467 | TOK_IA5String { $$ = ASN_STRING_IA5String; }
1468 | TOK_ISO646String { $$ = ASN_STRING_ISO646String; }
1469 | TOK_NumericString { $$ = ASN_STRING_NumericString; }
1470 | TOK_PrintableString { $$ = ASN_STRING_PrintableString; }
1471 | TOK_T61String {
1472 $$ = ASN_STRING_T61String;
Lev Walkin9c974182004-09-15 11:59:51 +00001473 fprintf(stderr, "WARNING: T61String is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001474 }
1475 | TOK_TeletexString { $$ = ASN_STRING_TeletexString; }
1476 | TOK_UniversalString { $$ = ASN_STRING_UniversalString; }
1477 | TOK_UTF8String { $$ = ASN_STRING_UTF8String; }
1478 | TOK_VideotexString {
1479 $$ = ASN_STRING_VideotexString;
Lev Walkin9c974182004-09-15 11:59:51 +00001480 fprintf(stderr, "WARNING: VideotexString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001481 }
1482 | TOK_VisibleString { $$ = ASN_STRING_VisibleString; }
1483 | TOK_ObjectDescriptor { $$ = ASN_STRING_ObjectDescriptor; }
1484 ;
1485
Lev Walkind2ea1de2004-08-20 13:25:29 +00001486
Lev Walkinf15320b2004-06-03 03:38:44 +00001487/*
1488 * Data type constraints.
1489 */
Lev Walkinf15320b2004-06-03 03:38:44 +00001490Union: '|' | TOK_UNION;
1491Intersection: '^' | TOK_INTERSECTION;
1492Except: TOK_EXCEPT;
1493
Lev Walkinf59d0752004-08-18 04:59:12 +00001494optConstraints:
1495 { $$ = 0; }
Lev Walkind2ea1de2004-08-20 13:25:29 +00001496 | Constraints {
1497 $$ = $1;
1498 }
1499 ;
1500
1501Constraints:
1502 SetOfConstraints {
Lev Walkinf59d0752004-08-18 04:59:12 +00001503 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, 0);
1504 }
1505 | TOK_SIZE '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001506 /*
1507 * This is a special case, for compatibility purposes.
Lev Walkinf59d0752004-08-18 04:59:12 +00001508 * It goes without parentheses.
Lev Walkinf15320b2004-06-03 03:38:44 +00001509 */
Lev Walkind2ea1de2004-08-20 13:25:29 +00001510 CONSTRAINT_INSERT($$, ACT_CT_SIZE, $3, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001511 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001512 ;
1513
Lev Walkinf59d0752004-08-18 04:59:12 +00001514SetOfConstraints:
1515 '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001516 $$ = $2;
1517 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001518 | SetOfConstraints '(' ElementSetSpecs ')' {
1519 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $3);
1520 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001521 ;
1522
Lev Walkinf59d0752004-08-18 04:59:12 +00001523ElementSetSpecs:
1524 ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001525 $$ = $1;
1526 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001527 | ElementSetSpec ',' TOK_ThreeDots {
Lev Walkinf15320b2004-06-03 03:38:44 +00001528 asn1p_constraint_t *ct;
1529 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001530 ct->type = ACT_EL_EXT;
1531 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1532 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001533 | ElementSetSpec ',' TOK_ThreeDots ',' ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001534 asn1p_constraint_t *ct;
1535 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001536 ct->type = ACT_EL_EXT;
1537 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
Lev Walkinb4fcdd22004-08-13 12:35:09 +00001538 ct = $$;
1539 CONSTRAINT_INSERT($$, ACT_CA_CSV, ct, $5);
Lev Walkinf15320b2004-06-03 03:38:44 +00001540 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001541 ;
1542
Lev Walkinf59d0752004-08-18 04:59:12 +00001543ElementSetSpec:
1544 ConstraintSubtypeElement {
1545 $$ = $1;
1546 }
1547 | ElementSetSpec Union ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001548 CONSTRAINT_INSERT($$, ACT_CA_UNI, $1, $3);
1549 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001550 | ElementSetSpec Intersection ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001551 CONSTRAINT_INSERT($$, ACT_CA_INT, $1, $3);
1552 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001553 | ConstraintSubtypeElement Except ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001554 CONSTRAINT_INSERT($$, ACT_CA_EXC, $1, $3);
1555 }
1556 ;
1557
1558ConstraintSubtypeElement:
Lev Walkinf59d0752004-08-18 04:59:12 +00001559 ConstraintSpec '(' ElementSetSpecs ')' {
1560 int ret;
1561 $$ = asn1p_constraint_new(yylineno);
1562 checkmem($$);
1563 $$->type = $1;
1564 ret = asn1p_constraint_insert($$, $3);
1565 checkmem(ret == 0);
1566 }
1567 | '(' ElementSetSpecs ')' {
1568 int ret;
1569 $$ = asn1p_constraint_new(yylineno);
1570 checkmem($$);
1571 $$->type = ACT_CA_SET;
1572 ret = asn1p_constraint_insert($$, $2);
1573 checkmem(ret == 0);
1574 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001575 | SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001576 $$ = asn1p_constraint_new(yylineno);
1577 checkmem($$);
1578 $$->type = ACT_EL_VALUE;
1579 $$->value = $1;
1580 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001581 | ContainedSubtype {
1582 $$ = asn1p_constraint_new(yylineno);
1583 checkmem($$);
1584 $$->type = ACT_EL_TYPE;
1585 $$->containedSubtype = $1;
1586 }
1587 | SingleValue ConstraintRangeSpec SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001588 $$ = asn1p_constraint_new(yylineno);
1589 checkmem($$);
1590 $$->type = $2;
1591 $$->range_start = $1;
1592 $$->range_stop = $3;
1593 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001594 | TOK_MIN ConstraintRangeSpec SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001595 $$ = asn1p_constraint_new(yylineno);
1596 checkmem($$);
Lev Walkinf59d0752004-08-18 04:59:12 +00001597 $$->type = $2;
1598 $$->range_start = asn1p_value_fromint(-123);
1599 $$->range_stop = $3;
1600 $$->range_start->type = ATV_MIN;
1601 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001602 | SingleValue ConstraintRangeSpec TOK_MAX {
Lev Walkinf59d0752004-08-18 04:59:12 +00001603 $$ = asn1p_constraint_new(yylineno);
1604 checkmem($$);
1605 $$->type = $2;
1606 $$->range_start = $1;
1607 $$->range_stop = asn1p_value_fromint(321);
1608 $$->range_stop->type = ATV_MAX;
1609 }
1610 | TOK_MIN ConstraintRangeSpec TOK_MAX {
1611 $$ = asn1p_constraint_new(yylineno);
1612 checkmem($$);
1613 $$->type = $2;
1614 $$->range_start = asn1p_value_fromint(-123);
1615 $$->range_stop = asn1p_value_fromint(321);
1616 $$->range_start->type = ATV_MIN;
1617 $$->range_stop->type = ATV_MAX;
Lev Walkinf15320b2004-06-03 03:38:44 +00001618 }
1619 | TableConstraint {
1620 $$ = $1;
1621 }
1622 | WithComponents {
1623 $$ = $1;
1624 }
Lev Walkin1893ddf2005-03-20 14:28:32 +00001625 | TOK_CONSTRAINED TOK_BY '{'
1626 { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
1627 $$ = asn1p_constraint_new(yylineno);
1628 checkmem($$);
1629 $$->type = ACT_CT_CTDBY;
1630 $$->value = asn1p_value_frombuf($5.buf, $5.len, 0);
1631 checkmem($$->value);
1632 $$->value->type = ATV_UNPARSED;
1633 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001634 ;
1635
1636ConstraintRangeSpec:
1637 TOK_TwoDots { $$ = ACT_EL_RANGE; }
1638 | TOK_TwoDots '<' { $$ = ACT_EL_RLRANGE; }
1639 | '<' TOK_TwoDots { $$ = ACT_EL_LLRANGE; }
1640 | '<' TOK_TwoDots '<' { $$ = ACT_EL_ULRANGE; }
1641 ;
1642
1643ConstraintSpec:
1644 TOK_SIZE {
1645 $$ = ACT_CT_SIZE;
1646 }
1647 | TOK_FROM {
1648 $$ = ACT_CT_FROM;
1649 }
1650 ;
1651
Lev Walkinff7dd142005-03-20 12:58:00 +00001652SingleValue:
Lev Walkinc8092cb2005-02-18 16:34:21 +00001653 TOK_FALSE {
1654 $$ = asn1p_value_fromint(0);
1655 checkmem($$);
1656 $$->type = ATV_FALSE;
1657 }
1658 | TOK_TRUE {
1659 $$ = asn1p_value_fromint(1);
1660 checkmem($$);
1661 $$->type = ATV_TRUE;
1662 }
1663 | SignedNumber {
Lev Walkinf15320b2004-06-03 03:38:44 +00001664 $$ = $1;
1665 }
Lev Walkinc8092cb2005-02-18 16:34:21 +00001666 | TOK_cstring {
1667 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1668 checkmem($$);
1669 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001670 | Identifier {
1671 asn1p_ref_t *ref;
1672 int ret;
1673 ref = asn1p_ref_new(yylineno);
1674 checkmem(ref);
1675 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1676 checkmem(ret == 0);
1677 $$ = asn1p_value_fromref(ref, 0);
1678 checkmem($$);
1679 free($1);
1680 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001681 ;
1682
1683ContainedSubtype:
1684 TypeRefName {
Lev Walkinc8092cb2005-02-18 16:34:21 +00001685 asn1p_ref_t *ref;
1686 int ret;
1687 ref = asn1p_ref_new(yylineno);
1688 checkmem(ref);
1689 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1690 checkmem(ret == 0);
1691 $$ = asn1p_value_fromref(ref, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001692 checkmem($$);
Lev Walkinc8092cb2005-02-18 16:34:21 +00001693 free($1);
Lev Walkinf15320b2004-06-03 03:38:44 +00001694 }
1695 ;
1696
1697WithComponents:
1698 TOK_WITH TOK_COMPONENTS '{' WithComponentsList '}' {
1699 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $4, 0);
1700 }
1701 ;
1702
1703WithComponentsList:
1704 WithComponentsElement {
1705 $$ = $1;
1706 }
1707 | WithComponentsList ',' WithComponentsElement {
1708 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $1, $3);
1709 }
1710 ;
1711
1712WithComponentsElement:
1713 TOK_ThreeDots {
1714 $$ = asn1p_constraint_new(yylineno);
1715 checkmem($$);
1716 $$->type = ACT_EL_EXT;
1717 }
1718 | Identifier optConstraints optPresenceConstraint {
1719 $$ = asn1p_constraint_new(yylineno);
1720 checkmem($$);
1721 $$->type = ACT_EL_VALUE;
1722 $$->value = asn1p_value_frombuf($1, strlen($1), 0);
1723 $$->presence = $3;
1724 }
1725 ;
1726
1727/*
1728 * presence constraint for WithComponents
1729 */
1730optPresenceConstraint:
1731 { $$ = ACPRES_DEFAULT; }
1732 | PresenceConstraint { $$ = $1; }
1733 ;
1734
1735PresenceConstraint:
1736 TOK_PRESENT {
1737 $$ = ACPRES_PRESENT;
1738 }
1739 | TOK_ABSENT {
1740 $$ = ACPRES_ABSENT;
1741 }
1742 | TOK_OPTIONAL {
1743 $$ = ACPRES_OPTIONAL;
1744 }
1745 ;
1746
1747TableConstraint:
1748 SimpleTableConstraint {
1749 $$ = $1;
1750 }
1751 | ComponentRelationConstraint {
1752 $$ = $1;
1753 }
1754 ;
1755
1756/*
1757 * "{ExtensionSet}"
1758 */
1759SimpleTableConstraint:
1760 '{' TypeRefName '}' {
1761 asn1p_ref_t *ref = asn1p_ref_new(yylineno);
1762 asn1p_constraint_t *ct;
1763 int ret;
1764 ret = asn1p_ref_add_component(ref, $2, 0);
1765 checkmem(ret == 0);
1766 ct = asn1p_constraint_new(yylineno);
1767 checkmem($$);
1768 ct->type = ACT_EL_VALUE;
1769 ct->value = asn1p_value_fromref(ref, 0);
1770 CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0);
1771 }
1772 ;
1773
1774ComponentRelationConstraint:
1775 SimpleTableConstraint '{' AtNotationList '}' {
1776 CONSTRAINT_INSERT($$, ACT_CA_CRC, $1, $3);
1777 }
1778 ;
1779
1780AtNotationList:
1781 AtNotationElement {
1782 $$ = asn1p_constraint_new(yylineno);
1783 checkmem($$);
1784 $$->type = ACT_EL_VALUE;
1785 $$->value = asn1p_value_fromref($1, 0);
1786 }
1787 | AtNotationList ',' AtNotationElement {
1788 asn1p_constraint_t *ct;
1789 ct = asn1p_constraint_new(yylineno);
1790 checkmem(ct);
1791 ct->type = ACT_EL_VALUE;
1792 ct->value = asn1p_value_fromref($3, 0);
1793 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1794 }
1795 ;
1796
1797/*
1798 * @blah
1799 */
1800AtNotationElement:
1801 '@' ComponentIdList {
1802 char *p = malloc(strlen($2) + 2);
1803 int ret;
1804 *p = '@';
1805 strcpy(p + 1, $2);
1806 $$ = asn1p_ref_new(yylineno);
1807 ret = asn1p_ref_add_component($$, p, 0);
1808 checkmem(ret == 0);
1809 free(p);
1810 free($2);
1811 }
1812 | '@' '.' ComponentIdList {
1813 char *p = malloc(strlen($3) + 3);
1814 int ret;
1815 p[0] = '@';
1816 p[1] = '.';
1817 strcpy(p + 2, $3);
1818 $$ = asn1p_ref_new(yylineno);
1819 ret = asn1p_ref_add_component($$, p, 0);
1820 checkmem(ret == 0);
1821 free(p);
1822 free($3);
1823 }
1824 ;
1825
1826/* identifier "." ... */
1827ComponentIdList:
1828 Identifier {
1829 $$ = $1;
1830 }
1831 | ComponentIdList '.' Identifier {
1832 int l1 = strlen($1);
1833 int l3 = strlen($3);
1834 $$ = malloc(l1 + 1 + l3 + 1);
1835 memcpy($$, $1, l1);
1836 $$[l1] = '.';
1837 memcpy($$ + l1 + 1, $3, l3);
1838 $$[l1 + 1 + l3] = '\0';
1839 }
1840 ;
1841
1842
1843
1844/*
1845 * MARKERS
1846 */
1847
1848optMarker:
Lev Walkin9c974182004-09-15 11:59:51 +00001849 {
1850 $$.flags = EM_NOMARK;
1851 $$.default_value = 0;
1852 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001853 | Marker { $$ = $1; }
1854 ;
1855
1856Marker:
1857 TOK_OPTIONAL {
Lev Walkin9c974182004-09-15 11:59:51 +00001858 $$.flags = EM_OPTIONAL;
1859 $$.default_value = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +00001860 }
Lev Walkin9c974182004-09-15 11:59:51 +00001861 | TOK_DEFAULT Value {
1862 $$.flags = EM_DEFAULT;
1863 $$.default_value = $2;
Lev Walkinf15320b2004-06-03 03:38:44 +00001864 }
1865 ;
1866
1867/*
1868 * Universal enumeration definition to use in INTEGER and ENUMERATED.
1869 * === EXAMPLE ===
1870 * Gender ::= ENUMERATED { unknown(0), male(1), female(2) }
1871 * Temperature ::= INTEGER { absolute-zero(-273), freezing(0), boiling(100) }
1872 * === EOF ===
1873 */
1874/*
1875optUniverationDefinition:
1876 { $$ = 0; }
1877 | UniverationDefinition {
1878 $$ = $1;
1879 }
1880 ;
1881*/
1882
1883UniverationDefinition:
1884 '{' '}' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001885 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001886 checkmem($$);
1887 }
1888 | '{' UniverationList '}' {
1889 $$ = $2;
1890 }
1891 ;
1892
1893UniverationList:
1894 UniverationElement {
Lev Walkinceb20e72004-09-05 10:40:41 +00001895 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001896 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +00001897 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +00001898 }
1899 | UniverationList ',' UniverationElement {
1900 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +00001901 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00001902 }
1903 ;
1904
1905UniverationElement:
1906 Identifier {
Lev Walkinceb20e72004-09-05 10:40:41 +00001907 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001908 checkmem($$);
1909 $$->expr_type = A1TC_UNIVERVAL;
1910 $$->meta_type = AMT_VALUE;
1911 $$->Identifier = $1;
1912 }
1913 | Identifier '(' SignedNumber ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001914 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001915 checkmem($$);
1916 $$->expr_type = A1TC_UNIVERVAL;
1917 $$->meta_type = AMT_VALUE;
1918 $$->Identifier = $1;
1919 $$->value = $3;
1920 }
1921 | Identifier '(' DefinedValue ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001922 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001923 checkmem($$);
1924 $$->expr_type = A1TC_UNIVERVAL;
1925 $$->meta_type = AMT_VALUE;
1926 $$->Identifier = $1;
1927 $$->value = $3;
1928 }
1929 | SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001930 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001931 checkmem($$);
1932 $$->expr_type = A1TC_UNIVERVAL;
1933 $$->meta_type = AMT_VALUE;
1934 $$->value = $1;
1935 }
1936 | TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001937 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001938 checkmem($$);
1939 $$->Identifier = strdup("...");
1940 checkmem($$->Identifier);
1941 $$->expr_type = A1TC_EXTENSIBLE;
1942 $$->meta_type = AMT_VALUE;
1943 }
1944 ;
1945
1946SignedNumber:
1947 TOK_number {
1948 $$ = asn1p_value_fromint($1);
1949 checkmem($$);
1950 }
1951 | TOK_number_negative {
1952 $$ = asn1p_value_fromint($1);
1953 checkmem($$);
1954 }
1955 ;
1956
1957/*
1958 * SEQUENCE definition.
1959 * === EXAMPLE ===
1960 * Struct1 ::= SEQUENCE {
1961 * memb1 Struct2,
1962 * memb2 SEQUENCE OF {
1963 * memb2-1 Struct 3
1964 * }
1965 * }
1966 * === EOF ===
1967 */
1968
1969
1970
1971/*
1972 * SET definition.
1973 * === EXAMPLE ===
1974 * Person ::= SET {
1975 * name [0] PrintableString (SIZE(1..20)),
1976 * country [1] PrintableString (SIZE(1..20)) DEFAULT default-country,
1977 * }
1978 * === EOF ===
1979 */
1980
1981optTag:
1982 { memset(&$$, 0, sizeof($$)); }
1983 | Tag { $$ = $1; }
1984 ;
1985
1986Tag:
Lev Walkinc603f102005-01-23 09:51:44 +00001987 TagTypeValue TagPlicit {
Lev Walkinf15320b2004-06-03 03:38:44 +00001988 $$ = $1;
Lev Walkinc603f102005-01-23 09:51:44 +00001989 $$.tag_mode = $2.tag_mode;
Lev Walkinf15320b2004-06-03 03:38:44 +00001990 }
Lev Walkinc603f102005-01-23 09:51:44 +00001991 ;
1992
1993TagTypeValue:
1994 '[' TagClass TOK_number ']' {
1995 $$ = $2;
1996 $$.tag_value = $3;
1997 };
1998
1999TagClass:
2000 { $$.tag_class = TC_CONTEXT_SPECIFIC; }
2001 | TOK_UNIVERSAL { $$.tag_class = TC_UNIVERSAL; }
2002 | TOK_APPLICATION { $$.tag_class = TC_APPLICATION; }
2003 | TOK_PRIVATE { $$.tag_class = TC_PRIVATE; }
2004 ;
2005
2006TagPlicit:
2007 { $$.tag_mode = TM_DEFAULT; }
2008 | TOK_IMPLICIT { $$.tag_mode = TM_IMPLICIT; }
2009 | TOK_EXPLICIT { $$.tag_mode = TM_EXPLICIT; }
Lev Walkinf15320b2004-06-03 03:38:44 +00002010 ;
2011
2012TypeRefName:
2013 TOK_typereference {
2014 checkmem($1);
2015 $$ = $1;
2016 }
Lev Walkinf59d0752004-08-18 04:59:12 +00002017 | TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00002018 checkmem($1);
2019 $$ = $1;
2020 }
2021 ;
2022
Lev Walkinf59d0752004-08-18 04:59:12 +00002023
Lev Walkinf15320b2004-06-03 03:38:44 +00002024ObjectClassReference:
Lev Walkinf59d0752004-08-18 04:59:12 +00002025 TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00002026 checkmem($1);
2027 $$ = $1;
2028 }
2029 ;
2030
Lev Walkin83cac2f2004-09-22 16:03:36 +00002031optIdentifier:
2032 { $$ = 0; }
2033 | Identifier {
2034 $$ = $1;
2035 }
2036
Lev Walkinf15320b2004-06-03 03:38:44 +00002037Identifier:
2038 TOK_identifier {
2039 checkmem($1);
2040 $$ = $1;
2041 }
2042 ;
2043
Lev Walkinf15320b2004-06-03 03:38:44 +00002044%%
2045
2046
2047/*
2048 * Convert Xstring ('0101'B or '5'H) to the binary vector.
2049 */
2050static asn1p_value_t *
2051_convert_bitstring2binary(char *str, int base) {
2052 asn1p_value_t *val;
2053 int slen;
2054 int memlen;
2055 int baselen;
2056 int bits;
2057 uint8_t *binary_vector;
2058 uint8_t *bv_ptr;
2059 uint8_t cur_val;
2060
2061 assert(str);
2062 assert(str[0] == '\'');
2063
2064 switch(base) {
2065 case 'B':
2066 baselen = 1;
2067 break;
2068 case 'H':
2069 baselen = 4;
2070 break;
2071 default:
2072 assert(base == 'B' || base == 'H');
2073 errno = EINVAL;
2074 return NULL;
2075 }
2076
2077 slen = strlen(str);
2078 assert(str[slen - 1] == base);
2079 assert(str[slen - 2] == '\'');
2080
2081 memlen = slen / (8 / baselen); /* Conservative estimate */
2082
2083 bv_ptr = binary_vector = malloc(memlen + 1);
2084 if(bv_ptr == NULL)
2085 /* ENOMEM */
2086 return NULL;
2087
2088 cur_val = 0;
2089 bits = 0;
2090 while(*(++str) != '\'') {
2091 switch(baselen) {
2092 case 1:
2093 switch(*str) {
2094 case '1':
2095 cur_val |= 1 << (7 - (bits % 8));
2096 case '0':
2097 break;
2098 default:
2099 assert(!"_y UNREACH1");
2100 case ' ': case '\r': case '\n':
2101 continue;
2102 }
2103 break;
2104 case 4:
2105 switch(*str) {
2106 case '0': case '1': case '2': case '3': case '4':
2107 case '5': case '6': case '7': case '8': case '9':
2108 cur_val |= (*str - '0') << (4 - (bits % 8));
2109 break;
2110 case 'A': case 'B': case 'C':
2111 case 'D': case 'E': case 'F':
2112 cur_val |= ((*str - 'A') + 10)
2113 << (4 - (bits % 8));
2114 break;
2115 default:
2116 assert(!"_y UNREACH2");
2117 case ' ': case '\r': case '\n':
2118 continue;
2119 }
2120 break;
2121 }
2122
2123 bits += baselen;
2124 if((bits % 8) == 0) {
2125 *bv_ptr++ = cur_val;
2126 cur_val = 0;
2127 }
2128 }
2129
2130 *bv_ptr = cur_val;
2131 assert((bv_ptr - binary_vector) <= memlen);
2132
2133 val = asn1p_value_frombits(binary_vector, bits, 0);
2134 if(val == NULL) {
2135 free(binary_vector);
2136 }
2137
2138 return val;
2139}
2140
2141extern char *asn1p_text;
2142
2143int
2144yyerror(const char *msg) {
2145 fprintf(stderr,
2146 "ASN.1 grammar parse error "
2147 "near line %d (token \"%s\"): %s\n",
Lev Walkinceb20e72004-09-05 10:40:41 +00002148 yylineno, asn1p_text, msg);
Lev Walkinf15320b2004-06-03 03:38:44 +00002149 return -1;
2150}
2151
2152