blob: 922f937a2dc67f2f3588ad10aec26921cf08bae7 [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 /* ... */
199%token <a_tag> TOK_tag /* [0] */
200
201
202/*
203 * Types defined herein.
204 */
205%type <a_grammar> ModuleList
206%type <a_module> ModuleSpecification
207%type <a_module> ModuleSpecificationBody
208%type <a_module> ModuleSpecificationElement
209%type <a_module> optModuleSpecificationBody /* Optional */
210%type <a_module_flags> optModuleSpecificationFlags
211%type <a_module_flags> ModuleSpecificationFlags /* Set of FL */
212%type <a_module_flags> ModuleSpecificationFlag /* Single FL */
213%type <a_module> ImportsDefinition
214%type <a_module> ImportsBundleSet
215%type <a_xports> ImportsBundle
216%type <a_xports> ImportsList
217%type <a_xports> ExportsDefinition
218%type <a_xports> ExportsBody
219%type <a_expr> ImportsElement
220%type <a_expr> ExportsElement
Lev Walkinf15320b2004-06-03 03:38:44 +0000221%type <a_expr> ExtensionAndException
Lev Walkin070a52d2004-08-22 03:19:54 +0000222%type <a_expr> TypeDeclaration
Lev Walkinf15320b2004-06-03 03:38:44 +0000223%type <a_ref> ComplexTypeReference
224%type <a_ref> ComplexTypeReferenceAmpList
225%type <a_refcomp> ComplexTypeReferenceElement
226%type <a_refcomp> ClassFieldIdentifier
227%type <a_refcomp> ClassFieldName
228%type <a_expr> ClassFieldList
229%type <a_expr> ClassField
230%type <a_expr> ClassDeclaration
Lev Walkin070a52d2004-08-22 03:19:54 +0000231%type <a_expr> Type
Lev Walkinf15320b2004-06-03 03:38:44 +0000232%type <a_expr> DataTypeReference /* Type1 ::= Type2 */
233%type <a_expr> DefinedTypeRef
234%type <a_expr> ValueSetDefinition /* Val INTEGER ::= {1|2} */
235%type <a_expr> ValueDefinition /* val INTEGER ::= 1*/
Lev Walkinceb20e72004-09-05 10:40:41 +0000236%type <a_expr> optValueSetBody
237%type <a_expr> ValueSetBody
238%type <a_expr> ValueSetElement
Lev Walkin9c974182004-09-15 11:59:51 +0000239%type <a_value> Value
Lev Walkinf15320b2004-06-03 03:38:44 +0000240%type <a_value> DefinedValue
241%type <a_value> SignedNumber
Lev Walkin144db9b2004-10-12 23:26:53 +0000242%type <a_expr> optComponentTypeLists
Lev Walkin070a52d2004-08-22 03:19:54 +0000243%type <a_expr> ComponentTypeLists
244%type <a_expr> ComponentType
245%type <a_expr> AlternativeTypeLists
246%type <a_expr> AlternativeType
Lev Walkinf15320b2004-06-03 03:38:44 +0000247//%type <a_expr> optUniverationDefinition
248%type <a_expr> UniverationDefinition
249%type <a_expr> UniverationList
250%type <a_expr> UniverationElement
251%type <tv_str> TypeRefName
252%type <tv_str> ObjectClassReference
Lev Walkinf15320b2004-06-03 03:38:44 +0000253%type <tv_str> Identifier
Lev Walkin83cac2f2004-09-22 16:03:36 +0000254%type <tv_str> optIdentifier
Lev Walkinf15320b2004-06-03 03:38:44 +0000255%type <a_parg> ParameterArgumentName
256%type <a_plist> ParameterArgumentList
257%type <a_expr> ActualParameter
258%type <a_expr> ActualParameterList
259%type <a_oid> ObjectIdentifier /* OID */
260%type <a_oid> optObjectIdentifier /* Optional OID */
261%type <a_oid> ObjectIdentifierBody
262%type <a_oid_arc> ObjectIdentifierElement
263%type <a_expr> BasicType
264%type <a_type> BasicTypeId
265%type <a_type> BasicTypeId_UniverationCompatible
266%type <a_type> BasicString
267%type <tv_opaque> Opaque
268//%type <tv_opaque> StringValue
269%type <a_tag> Tag /* [UNIVERSAL 0] IMPLICIT */
270%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
285%type <a_value> ConstraintValue
286%type <a_ctype> ConstraintSpec
287%type <a_ctype> ConstraintRangeSpec
288%type <a_wsynt> optWithSyntax
289%type <a_wsynt> WithSyntax
290%type <a_wsynt> WithSyntaxFormat
291%type <a_wchunk> WithSyntaxFormatToken
292%type <a_marker> optMarker Marker
293%type <a_int> optUnique
294%type <a_pres> optPresenceConstraint PresenceConstraint
295%type <tv_str> ComponentIdList
296
297
298%%
299
300
301ParsedGrammar:
302 ModuleList {
303 *(void **)param = $1;
304 }
305 ;
306
307ModuleList:
308 ModuleSpecification {
309 $$ = asn1p_new();
310 checkmem($$);
311 TQ_ADD(&($$->modules), $1, mod_next);
312 }
313 | ModuleList ModuleSpecification {
314 $$ = $1;
315 TQ_ADD(&($$->modules), $2, mod_next);
316 }
317 ;
318
319/*
320 * ASN module definition.
321 * === EXAMPLE ===
322 * MySyntax DEFINITIONS AUTOMATIC TAGS ::=
323 * BEGIN
324 * ...
325 * END
326 * === EOF ===
327 */
328
329ModuleSpecification:
330 TypeRefName optObjectIdentifier TOK_DEFINITIONS
331 optModuleSpecificationFlags
332 TOK_PPEQ TOK_BEGIN
333 optModuleSpecificationBody
334 TOK_END {
335
336 if($7) {
337 $$ = $7;
338 } else {
339 /* There's a chance that a module is just plain empty */
340 $$ = asn1p_module_new();
341 }
342 checkmem($$);
343
344 $$->Identifier = $1;
345 $$->module_oid = $2;
346 $$->module_flags = $4;
347 }
348 ;
349
350/*
351 * Object Identifier Definition
352 * { iso member-body(2) 3 }
353 */
354optObjectIdentifier:
355 { $$ = 0; }
356 | ObjectIdentifier { $$ = $1; }
357 ;
358
359ObjectIdentifier:
360 '{' ObjectIdentifierBody '}' {
361 $$ = $2;
362 }
363 | '{' '}' {
364 $$ = 0;
365 }
366 ;
367
368ObjectIdentifierBody:
369 ObjectIdentifierElement {
370 $$ = asn1p_oid_new();
371 asn1p_oid_add_arc($$, &$1);
372 if($1.name)
373 free($1.name);
374 }
375 | ObjectIdentifierBody ObjectIdentifierElement {
376 $$ = $1;
377 asn1p_oid_add_arc($$, &$2);
378 if($2.name)
379 free($2.name);
380 }
381 ;
382
383ObjectIdentifierElement:
384 Identifier { /* iso */
385 $$.name = $1;
386 $$.number = -1;
387 }
388 | Identifier '(' TOK_number ')' { /* iso(1) */
389 $$.name = $1;
390 $$.number = $3;
391 }
392 | TOK_number { /* 1 */
393 $$.name = 0;
394 $$.number = $1;
395 }
396 ;
397
398/*
399 * Optional module flags.
400 */
401optModuleSpecificationFlags:
402 { $$ = MSF_NOFLAGS; }
403 | ModuleSpecificationFlags {
404 $$ = $1;
405 }
406 ;
407
408/*
409 * Module flags.
410 */
411ModuleSpecificationFlags:
412 ModuleSpecificationFlag {
413 $$ = $1;
414 }
415 | ModuleSpecificationFlags ModuleSpecificationFlag {
416 $$ = $1 | $2;
417 }
418 ;
419
420/*
421 * Single module flag.
422 */
423ModuleSpecificationFlag:
424 TOK_EXPLICIT TOK_TAGS {
425 $$ = MSF_EXPLICIT_TAGS;
426 }
427 | TOK_IMPLICIT TOK_TAGS {
428 $$ = MSF_IMPLICIT_TAGS;
429 }
430 | TOK_AUTOMATIC TOK_TAGS {
431 $$ = MSF_AUTOMATIC_TAGS;
432 }
433 | TOK_EXTENSIBILITY TOK_IMPLIED {
434 $$ = MSF_EXTENSIBILITY_IMPLIED;
435 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000436 /* EncodingReferenceDefault */
437 | TOK_capitalreference TOK_INSTRUCTIONS {
438 /* X.680Amd1 specifies TAG and XER */
439 if(strcmp($1, "TAG") == 0) {
440 $$ = MSF_TAG_INSTRUCTIONS;
441 } else if(strcmp($1, "XER") == 0) {
442 $$ = MSF_XER_INSTRUCTIONS;
443 } else {
444 fprintf(stderr,
445 "WARNING: %s INSTRUCTIONS at line %d: "
446 "Unrecognized encoding reference\n",
447 $1, yylineno);
448 $$ = MSF_unk_INSTRUCTIONS;
449 }
450 free($1);
451 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000452 ;
453
454/*
455 * Optional module body.
456 */
457optModuleSpecificationBody:
458 { $$ = 0; }
459 | ModuleSpecificationBody {
Lev Walkinf15320b2004-06-03 03:38:44 +0000460 $$ = $1;
461 }
462 ;
463
464/*
465 * ASN.1 Module body.
466 */
467ModuleSpecificationBody:
468 ModuleSpecificationElement {
469 $$ = $1;
470 }
471 | ModuleSpecificationBody ModuleSpecificationElement {
472 $$ = $1;
473
Lev Walkinf59d0752004-08-18 04:59:12 +0000474 /* Behave well when one of them is skipped. */
475 if(!($1)) {
476 if($2) $$ = $2;
477 break;
478 }
479
Lev Walkinf15320b2004-06-03 03:38:44 +0000480#ifdef MY_IMPORT
481#error MY_IMPORT DEFINED ELSEWHERE!
482#endif
483#define MY_IMPORT(foo,field) do { \
Lev Walkinbc55d232004-08-13 12:31:09 +0000484 while(TQ_FIRST(&($2->foo))) { \
Lev Walkinf15320b2004-06-03 03:38:44 +0000485 TQ_ADD(&($$->foo), \
486 TQ_REMOVE(&($2->foo), field), \
487 field); \
Lev Walkinbc55d232004-08-13 12:31:09 +0000488 } \
489 assert(TQ_FIRST(&($2->foo)) == 0); \
490 } while(0)
Lev Walkinf15320b2004-06-03 03:38:44 +0000491
492 MY_IMPORT(imports, xp_next);
493 MY_IMPORT(exports, xp_next);
494 MY_IMPORT(members, next);
495#undef MY_IMPORT
496
497 }
498 ;
499
500/*
501 * One of the elements of ASN.1 module specification.
502 */
503ModuleSpecificationElement:
504 ImportsDefinition {
505 $$ = $1;
506 }
507 | ExportsDefinition {
508 $$ = asn1p_module_new();
509 checkmem($$);
510 if($1) {
511 TQ_ADD(&($$->exports), $1, xp_next);
512 } else {
513 /* "EXPORTS ALL;" ? */
514 }
515 }
516 | DataTypeReference {
517 $$ = asn1p_module_new();
518 checkmem($$);
519 assert($1->expr_type != A1TC_INVALID);
520 assert($1->meta_type != AMT_INVALID);
521 TQ_ADD(&($$->members), $1, next);
522 }
523 | ValueDefinition {
524 $$ = asn1p_module_new();
525 checkmem($$);
526 assert($1->expr_type != A1TC_INVALID);
527 assert($1->meta_type != AMT_INVALID);
528 TQ_ADD(&($$->members), $1, next);
529 }
530 /*
531 * Value set definition
532 * === EXAMPLE ===
533 * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 }
534 * === EOF ===
535 */
536 | ValueSetDefinition {
537 $$ = asn1p_module_new();
538 checkmem($$);
539 assert($1->expr_type != A1TC_INVALID);
540 assert($1->meta_type != AMT_INVALID);
541 TQ_ADD(&($$->members), $1, next);
542 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000543 | TOK_ENCODING_CONTROL TOK_capitalreference
544 { asn1p_lexer_hack_push_encoding_control(); }
545 {
546 fprintf(stderr,
547 "WARNING: ENCODING-CONTROL %s "
548 "specification at line %d ignored\n",
549 $2, yylineno);
550 free($2);
551 $$ = 0;
552 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000553
554 /*
555 * Erroneous attemps
556 */
557 | BasicString {
558 return yyerror(
559 "Attempt to redefine a standard basic type, "
560 "use -ftypesXY to switch back "
561 "to older version of ASN.1 standard");
562 }
563 ;
564
565/*
566 * === EXAMPLE ===
567 * IMPORTS Type1, value FROM Module { iso standard(0) } ;
568 * === EOF ===
569 */
570ImportsDefinition:
571 TOK_IMPORTS ImportsBundleSet ';' {
572 $$ = $2;
573 }
574 /*
575 * Some error cases.
576 */
577 | TOK_IMPORTS TOK_FROM /* ... */ {
578 return yyerror("Empty IMPORTS list");
579 }
580 ;
581
582ImportsBundleSet:
583 ImportsBundle {
584 $$ = asn1p_module_new();
585 checkmem($$);
586 TQ_ADD(&($$->imports), $1, xp_next);
587 }
588 | ImportsBundleSet ImportsBundle {
589 $$ = $1;
590 TQ_ADD(&($$->imports), $2, xp_next);
591 }
592 ;
593
594ImportsBundle:
595 ImportsList TOK_FROM TypeRefName optObjectIdentifier {
596 $$ = $1;
597 $$->from = $3;
598 $$->from_oid = $4;
599 checkmem($$);
600 }
601 ;
602
603ImportsList:
604 ImportsElement {
605 $$ = asn1p_xports_new();
606 checkmem($$);
607 TQ_ADD(&($$->members), $1, next);
608 }
609 | ImportsList ',' ImportsElement {
610 $$ = $1;
611 TQ_ADD(&($$->members), $3, next);
612 }
613 ;
614
615ImportsElement:
616 TypeRefName {
617 $$ = asn1p_expr_new(yylineno);
618 checkmem($$);
619 $$->Identifier = $1;
620 $$->expr_type = A1TC_REFERENCE;
621 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000622 | TypeRefName '{' '}' { /* Completely equivalent to above */
623 $$ = asn1p_expr_new(yylineno);
624 checkmem($$);
625 $$->Identifier = $1;
626 $$->expr_type = A1TC_REFERENCE;
627 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000628 | Identifier {
629 $$ = asn1p_expr_new(yylineno);
630 checkmem($$);
631 $$->Identifier = $1;
632 $$->expr_type = A1TC_REFERENCE;
633 }
634 ;
635
636ExportsDefinition:
637 TOK_EXPORTS ExportsBody ';' {
638 $$ = $2;
639 }
640 | TOK_EXPORTS TOK_ALL ';' {
641 $$ = 0;
642 }
643 | TOK_EXPORTS ';' {
644 /* Empty EXPORTS clause effectively prohibits export. */
645 $$ = asn1p_xports_new();
646 checkmem($$);
647 }
648 ;
649
650ExportsBody:
651 ExportsElement {
652 $$ = asn1p_xports_new();
653 assert($$);
654 TQ_ADD(&($$->members), $1, next);
655 }
656 | ExportsBody ',' ExportsElement {
657 $$ = $1;
658 TQ_ADD(&($$->members), $3, next);
659 }
660 ;
661
662ExportsElement:
663 TypeRefName {
664 $$ = asn1p_expr_new(yylineno);
665 checkmem($$);
666 $$->Identifier = $1;
667 $$->expr_type = A1TC_EXPORTVAR;
668 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000669 | TypeRefName '{' '}' {
670 $$ = asn1p_expr_new(yylineno);
671 checkmem($$);
672 $$->Identifier = $1;
673 $$->expr_type = A1TC_EXPORTVAR;
674 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000675 | Identifier {
676 $$ = asn1p_expr_new(yylineno);
677 checkmem($$);
678 $$->Identifier = $1;
679 $$->expr_type = A1TC_EXPORTVAR;
680 }
681 ;
682
683
684ValueSetDefinition:
685 TypeRefName DefinedTypeRef TOK_PPEQ '{' optValueSetBody '}' {
686 $$ = $2;
687 assert($$->Identifier == 0);
688 $$->Identifier = $1;
689 $$->meta_type = AMT_VALUESET;
690 // take care of optValueSetBody
691 }
692 ;
693
694DefinedTypeRef:
695 ComplexTypeReference {
696 $$ = asn1p_expr_new(yylineno);
697 checkmem($$);
698 $$->reference = $1;
699 $$->expr_type = A1TC_REFERENCE;
700 $$->meta_type = AMT_TYPEREF;
701 }
702 | BasicTypeId {
703 $$ = asn1p_expr_new(yylineno);
704 checkmem($$);
705 $$->expr_type = $1;
706 $$->meta_type = AMT_TYPE;
707 }
708 ;
709
710optValueSetBody:
711 { }
Lev Walkinceb20e72004-09-05 10:40:41 +0000712 | ValueSetBody {
713 }
714 ;
715
716/*
717 * X.680 does not permit ElementSetSpecs starting with ellipsis,
718 * i.e. (..., A, B). This is very strange: the ElementSetSpecs is used
719 * inside ValueSet, and ValueSets "in the wild" tend to have the first
720 * ellipsis.
721 */
722ValueSetBody:
723 ValueSetElement {
724 }
725 | ValueSetBody ',' ValueSetElement {
726 }
727 ;
728
729ValueSetElement:
730 TOK_ThreeDots {
731 }
732 | ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +0000733 }
734 ;
735
736
737/*
738 * Data Type Reference.
739 * === EXAMPLE ===
740 * Type3 ::= CHOICE { a Type1, b Type 2 }
741 * === EOF ===
742 */
743
744DataTypeReference:
745 /*
746 * Optionally tagged type definition.
747 */
748 TypeRefName TOK_PPEQ optTag TOK_TYPE_IDENTIFIER {
749 $$ = asn1p_expr_new(yylineno);
750 checkmem($$);
751 $$->Identifier = $1;
752 $$->tag = $3;
753 $$->expr_type = A1TC_TYPEID;
754 $$->meta_type = AMT_TYPE;
755 }
Lev Walkinaf120f72004-09-14 02:36:39 +0000756 | TypeRefName TOK_PPEQ Type {
757 $$ = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000758 $$->Identifier = $1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000759 assert($$->expr_type);
760 assert($$->meta_type);
761 }
762 | TypeRefName TOK_PPEQ ClassDeclaration {
763 $$ = $3;
764 $$->Identifier = $1;
765 assert($$->expr_type == A1TC_CLASSDEF);
766 assert($$->meta_type == AMT_OBJECT);
767 }
768 /*
769 * Parametrized <Type> declaration:
770 * === EXAMPLE ===
771 * SIGNED { ToBeSigned } ::= SEQUENCE {
772 * toBeSigned ToBeSigned,
773 * algorithm AlgorithmIdentifier,
774 * signature BIT STRING
775 * }
776 * === EOF ===
777 */
Lev Walkin070a52d2004-08-22 03:19:54 +0000778 | TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000779 $$ = $6;
780 assert($$->Identifier == 0);
781 $$->Identifier = $1;
782 $$->params = $3;
783 $$->meta_type = AMT_PARAMTYPE;
784 }
785 ;
786
787ParameterArgumentList:
788 ParameterArgumentName {
789 int ret;
790 $$ = asn1p_paramlist_new(yylineno);
791 checkmem($$);
792 ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument);
793 checkmem(ret == 0);
794 if($1.governor) asn1p_ref_free($1.governor);
795 if($1.argument) free($1.argument);
796 }
797 | ParameterArgumentList ',' ParameterArgumentName {
798 int ret;
799 $$ = $1;
800 ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument);
801 checkmem(ret == 0);
802 if($3.governor) asn1p_ref_free($3.governor);
803 if($3.argument) free($3.argument);
804 }
805 ;
806
807ParameterArgumentName:
808 TypeRefName {
809 $$.governor = NULL;
810 $$.argument = $1;
811 }
812 | TypeRefName ':' Identifier {
813 int ret;
814 $$.governor = asn1p_ref_new(yylineno);
815 ret = asn1p_ref_add_component($$.governor, $1, 0);
816 checkmem(ret == 0);
817 $$.argument = $3;
818 }
819 | BasicTypeId ':' Identifier {
820 int ret;
821 $$.governor = asn1p_ref_new(yylineno);
822 ret = asn1p_ref_add_component($$.governor,
823 ASN_EXPR_TYPE2STR($1), 1);
824 checkmem(ret == 0);
825 $$.argument = $3;
826 }
827 ;
828
829ActualParameterList:
830 ActualParameter {
831 $$ = asn1p_expr_new(yylineno);
832 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000833 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000834 }
835 | ActualParameterList ',' ActualParameter {
836 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000837 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000838 }
839 ;
840
841ActualParameter:
Lev Walkin070a52d2004-08-22 03:19:54 +0000842 Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000843 $$ = $1;
844 }
845 | Identifier {
846 $$ = asn1p_expr_new(yylineno);
847 checkmem($$);
848 $$->Identifier = $1;
849 $$->expr_type = A1TC_REFERENCE;
850 $$->meta_type = AMT_VALUE;
851 }
852 ;
853
854/*
855 * A collection of constructed data type members.
856 */
Lev Walkin144db9b2004-10-12 23:26:53 +0000857optComponentTypeLists:
858 { $$ = asn1p_expr_new(yylineno); }
859 | ComponentTypeLists { $$ = $1; };
860
Lev Walkin070a52d2004-08-22 03:19:54 +0000861ComponentTypeLists:
862 ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000863 $$ = asn1p_expr_new(yylineno);
864 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000865 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000866 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000867 | ComponentTypeLists ',' ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000868 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000869 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000870 }
871 ;
872
Lev Walkin070a52d2004-08-22 03:19:54 +0000873ComponentType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000874 Identifier Type optMarker {
Lev Walkin070a52d2004-08-22 03:19:54 +0000875 $$ = $2;
876 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000877 $$->Identifier = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000878 $$->marker = $3;
879 }
880 | TOK_COMPONENTS TOK_OF Type {
881 $$ = asn1p_expr_new(yylineno);
882 checkmem($$);
883 $$->meta_type = $3->meta_type;
884 $$->expr_type = A1TC_COMPONENTS_OF;
Lev Walkin1004aa92004-09-08 00:28:11 +0000885 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000886 }
887 | ExtensionAndException {
888 $$ = $1;
889 }
890 ;
891
892AlternativeTypeLists:
893 AlternativeType {
894 $$ = asn1p_expr_new(yylineno);
895 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000896 asn1p_expr_add($$, $1);
Lev Walkin070a52d2004-08-22 03:19:54 +0000897 }
898 | AlternativeTypeLists ',' AlternativeType {
899 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000900 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000901 }
902 ;
903
904AlternativeType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000905 Identifier Type {
Lev Walkin070a52d2004-08-22 03:19:54 +0000906 $$ = $2;
907 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000908 $$->Identifier = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000909 }
910 | ExtensionAndException {
911 $$ = $1;
912 }
913 ;
914
Lev Walkinf15320b2004-06-03 03:38:44 +0000915ClassDeclaration:
916 TOK_CLASS '{' ClassFieldList '}' optWithSyntax {
917 $$ = $3;
918 checkmem($$);
919 $$->with_syntax = $5;
920 assert($$->expr_type == A1TC_CLASSDEF);
921 assert($$->meta_type == AMT_OBJECT);
922 }
923 ;
924
925optUnique:
926 { $$ = 0; }
927 | TOK_UNIQUE { $$ = 1; }
928 ;
929
930ClassFieldList:
931 ClassField {
932 $$ = asn1p_expr_new(yylineno);
933 checkmem($$);
934 $$->expr_type = A1TC_CLASSDEF;
935 $$->meta_type = AMT_OBJECT;
Lev Walkin1004aa92004-09-08 00:28:11 +0000936 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000937 }
938 | ClassFieldList ',' ClassField {
939 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000940 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000941 }
942 ;
943
944ClassField:
945 ClassFieldIdentifier optMarker {
946 $$ = asn1p_expr_new(yylineno);
947 checkmem($$);
948 $$->Identifier = $1.name;
949 $$->expr_type = A1TC_CLASSFIELD;
950 $$->meta_type = AMT_OBJECTFIELD;
951 $$->marker = $2;
952 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000953 | ClassFieldIdentifier Type optMarker optUnique {
Lev Walkinf15320b2004-06-03 03:38:44 +0000954 $$ = $2;
955 $$->Identifier = $1.name;
Lev Walkin070a52d2004-08-22 03:19:54 +0000956 $$->marker = $3;
957 $$->unique = $4;
Lev Walkinf15320b2004-06-03 03:38:44 +0000958 }
959 | ClassFieldIdentifier ClassFieldIdentifier optMarker optUnique {
960 int ret;
961 $$ = asn1p_expr_new(yylineno);
962 checkmem($$);
963 $$->Identifier = $1.name;
964 $$->reference = asn1p_ref_new(yylineno);
965 checkmem($$->reference);
966 ret = asn1p_ref_add_component($$->reference,
967 $2.name, $2.lex_type);
968 checkmem(ret == 0);
969 $$->expr_type = A1TC_CLASSFIELD;
970 $$->meta_type = AMT_OBJECTFIELD;
971 $$->marker = $3;
972 $$->unique = $4;
973 }
974 ;
975
976optWithSyntax:
977 { $$ = 0; }
978 | WithSyntax {
979 $$ = $1;
980 }
981 ;
982
983WithSyntax:
984 TOK_WITH TOK_SYNTAX '{'
985 { asn1p_lexer_hack_enable_with_syntax(); }
986 WithSyntaxFormat
987 '}' {
988 $$ = $5;
989 }
990 ;
991
992WithSyntaxFormat:
993 WithSyntaxFormatToken {
994 $$ = asn1p_wsyntx_new();
995 TQ_ADD(&($$->chunks), $1, next);
996 }
997 | WithSyntaxFormat WithSyntaxFormatToken {
998 $$ = $1;
999 TQ_ADD(&($$->chunks), $2, next);
1000 }
1001 ;
1002
1003WithSyntaxFormatToken:
1004 TOK_opaque {
1005 $$ = asn1p_wsyntx_chunk_frombuf($1.buf, $1.len, 0);
1006 }
1007 | ClassFieldIdentifier {
1008 asn1p_ref_t *ref;
1009 int ret;
1010 ref = asn1p_ref_new(yylineno);
1011 checkmem(ref);
1012 ret = asn1p_ref_add_component(ref, $1.name, $1.lex_type);
1013 checkmem(ret == 0);
1014 $$ = asn1p_wsyntx_chunk_fromref(ref, 0);
1015 }
1016 ;
1017
Lev Walkinf15320b2004-06-03 03:38:44 +00001018ExtensionAndException:
1019 TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001020 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001021 checkmem($$);
1022 $$->Identifier = strdup("...");
1023 checkmem($$->Identifier);
1024 $$->expr_type = A1TC_EXTENSIBLE;
1025 $$->meta_type = AMT_TYPE;
1026 }
1027 | TOK_ThreeDots '!' DefinedValue {
Lev Walkinceb20e72004-09-05 10:40:41 +00001028 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001029 checkmem($$);
1030 $$->Identifier = strdup("...");
1031 checkmem($$->Identifier);
1032 $$->value = $3;
1033 $$->expr_type = A1TC_EXTENSIBLE;
1034 $$->meta_type = AMT_TYPE;
1035 }
1036 | TOK_ThreeDots '!' SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001037 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001038 checkmem($$);
1039 $$->Identifier = strdup("...");
1040 $$->value = $3;
1041 checkmem($$->Identifier);
1042 $$->expr_type = A1TC_EXTENSIBLE;
1043 $$->meta_type = AMT_TYPE;
1044 }
1045 ;
1046
Lev Walkin070a52d2004-08-22 03:19:54 +00001047Type:
Lev Walkinaf120f72004-09-14 02:36:39 +00001048 optTag TypeDeclaration optConstraints {
1049 $$ = $2;
1050 $$->tag = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +00001051 /*
1052 * Outer constraint for SEQUENCE OF and SET OF applies
1053 * to the inner type.
1054 */
1055 if($$->expr_type == ASN_CONSTR_SEQUENCE_OF
1056 || $$->expr_type == ASN_CONSTR_SET_OF) {
1057 assert(!TQ_FIRST(&($$->members))->constraints);
Lev Walkinaf120f72004-09-14 02:36:39 +00001058 TQ_FIRST(&($$->members))->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001059 } else {
1060 if($$->constraints) {
1061 assert(!$2);
1062 } else {
Lev Walkinaf120f72004-09-14 02:36:39 +00001063 $$->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001064 }
1065 }
1066 }
1067 ;
1068
1069TypeDeclaration:
Lev Walkinf15320b2004-06-03 03:38:44 +00001070 BasicType {
1071 $$ = $1;
1072 }
1073 | BasicString {
1074 $$ = asn1p_expr_new(yylineno);
1075 checkmem($$);
1076 $$->expr_type = $1;
1077 $$->meta_type = AMT_TYPE;
1078 }
Lev Walkin070a52d2004-08-22 03:19:54 +00001079 | TOK_CHOICE '{' AlternativeTypeLists '}' {
1080 $$ = $3;
1081 assert($$->expr_type == A1TC_INVALID);
1082 $$->expr_type = ASN_CONSTR_CHOICE;
1083 $$->meta_type = AMT_TYPE;
Lev Walkinf15320b2004-06-03 03:38:44 +00001084 }
Lev Walkin144db9b2004-10-12 23:26:53 +00001085 | TOK_SEQUENCE '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001086 $$ = $3;
1087 assert($$->expr_type == A1TC_INVALID);
1088 $$->expr_type = ASN_CONSTR_SEQUENCE;
1089 $$->meta_type = AMT_TYPE;
1090 }
Lev Walkin144db9b2004-10-12 23:26:53 +00001091 | TOK_SET '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001092 $$ = $3;
1093 assert($$->expr_type == A1TC_INVALID);
1094 $$->expr_type = ASN_CONSTR_SET;
1095 $$->meta_type = AMT_TYPE;
1096 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001097 | TOK_SEQUENCE optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001098 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001099 checkmem($$);
1100 $$->constraints = $2;
1101 $$->expr_type = ASN_CONSTR_SEQUENCE_OF;
1102 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001103 $6->Identifier = $4;
1104 $6->tag = $5;
1105 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001106 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001107 | TOK_SET optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001108 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001109 checkmem($$);
1110 $$->constraints = $2;
1111 $$->expr_type = ASN_CONSTR_SET_OF;
1112 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001113 $6->Identifier = $4;
1114 $6->tag = $5;
1115 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001116 }
1117 | TOK_ANY {
Lev Walkinceb20e72004-09-05 10:40:41 +00001118 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001119 checkmem($$);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001120 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001121 $$->meta_type = AMT_TYPE;
1122 }
1123 | TOK_ANY TOK_DEFINED TOK_BY Identifier {
1124 int ret;
Lev Walkinceb20e72004-09-05 10:40:41 +00001125 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001126 checkmem($$);
1127 $$->reference = asn1p_ref_new(yylineno);
1128 ret = asn1p_ref_add_component($$->reference,
1129 $4, RLT_lowercase);
1130 checkmem(ret == 0);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001131 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001132 $$->meta_type = AMT_TYPE;
1133 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001134 /*
1135 * A parametrized assignment.
1136 */
1137 | TypeRefName '{' ActualParameterList '}' {
1138 int ret;
1139 $$ = $3;
1140 assert($$->expr_type == 0);
1141 assert($$->meta_type == 0);
1142 assert($$->reference == 0);
1143 $$->reference = asn1p_ref_new(yylineno);
1144 checkmem($$->reference);
1145 ret = asn1p_ref_add_component($$->reference, $1, RLT_UNKNOWN);
1146 checkmem(ret == 0);
1147 free($1);
1148 $$->expr_type = A1TC_PARAMETRIZED;
1149 $$->meta_type = AMT_TYPE;
1150 }
1151 /*
1152 * A DefinedType reference.
1153 * "CLASS1.&id.&id2"
1154 * or
1155 * "Module.Type"
1156 * or
1157 * "Module.identifier"
1158 * or
1159 * "Type"
1160 */
1161 | ComplexTypeReference {
1162 $$ = asn1p_expr_new(yylineno);
1163 checkmem($$);
1164 $$->reference = $1;
1165 $$->expr_type = A1TC_REFERENCE;
1166 $$->meta_type = AMT_TYPEREF;
1167 }
1168 | TOK_INSTANCE TOK_OF ComplexTypeReference {
1169 $$ = asn1p_expr_new(yylineno);
1170 checkmem($$);
1171 $$->reference = $3;
1172 $$->expr_type = A1TC_INSTANCE;
1173 $$->meta_type = AMT_TYPE;
1174 }
1175 ;
1176
1177/*
1178 * A type name consisting of several components.
1179 * === EXAMPLE ===
1180 * === EOF ===
1181 */
1182ComplexTypeReference:
1183 TOK_typereference {
1184 int ret;
1185 $$ = asn1p_ref_new(yylineno);
1186 checkmem($$);
1187 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1188 checkmem(ret == 0);
1189 free($1);
1190 }
1191 | TOK_typereference '.' TypeRefName {
1192 int ret;
1193 $$ = asn1p_ref_new(yylineno);
1194 checkmem($$);
1195 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1196 checkmem(ret == 0);
1197 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1198 checkmem(ret == 0);
1199 free($1);
1200 }
Lev Walkin9c974182004-09-15 11:59:51 +00001201 | ObjectClassReference '.' TypeRefName {
1202 int ret;
1203 $$ = asn1p_ref_new(yylineno);
1204 checkmem($$);
1205 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1206 checkmem(ret == 0);
1207 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1208 checkmem(ret == 0);
1209 free($1);
1210 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001211 | TOK_typereference '.' Identifier {
1212 int ret;
1213 $$ = asn1p_ref_new(yylineno);
1214 checkmem($$);
1215 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1216 checkmem(ret == 0);
1217 ret = asn1p_ref_add_component($$, $3, RLT_lowercase);
1218 checkmem(ret == 0);
1219 free($1);
1220 }
1221 | ObjectClassReference {
1222 int ret;
1223 $$ = asn1p_ref_new(yylineno);
1224 checkmem($$);
1225 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1226 free($1);
1227 checkmem(ret == 0);
1228 }
1229 | ObjectClassReference '.' ComplexTypeReferenceAmpList {
1230 int ret;
1231 $$ = $3;
1232 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1233 free($1);
1234 checkmem(ret == 0);
1235 /*
1236 * Move the last element infront.
1237 */
1238 {
1239 struct asn1p_ref_component_s tmp_comp;
1240 tmp_comp = $$->components[$$->comp_count-1];
1241 memmove(&$$->components[1],
1242 &$$->components[0],
1243 sizeof($$->components[0])
1244 * ($$->comp_count - 1));
1245 $$->components[0] = tmp_comp;
1246 }
1247 }
1248 ;
1249
1250ComplexTypeReferenceAmpList:
1251 ComplexTypeReferenceElement {
1252 int ret;
1253 $$ = asn1p_ref_new(yylineno);
1254 checkmem($$);
1255 ret = asn1p_ref_add_component($$, $1.name, $1.lex_type);
1256 free($1.name);
1257 checkmem(ret == 0);
1258 }
1259 | ComplexTypeReferenceAmpList '.' ComplexTypeReferenceElement {
1260 int ret;
1261 $$ = $1;
1262 ret = asn1p_ref_add_component($$, $3.name, $3.lex_type);
1263 free($3.name);
1264 checkmem(ret == 0);
1265 }
1266 ;
1267
1268ComplexTypeReferenceElement: ClassFieldName;
1269ClassFieldIdentifier: ClassFieldName;
1270
1271ClassFieldName:
1272 /* "&Type1" */
1273 TOK_typefieldreference {
1274 $$.lex_type = RLT_AmpUppercase;
1275 $$.name = $1;
1276 }
1277 /* "&id" */
1278 | TOK_valuefieldreference {
1279 $$.lex_type = RLT_Amplowercase;
1280 $$.name = $1;
1281 }
1282 ;
1283
1284
1285/*
1286 * === EXAMPLE ===
1287 * value INTEGER ::= 1
1288 * === EOF ===
1289 */
1290ValueDefinition:
Lev Walkin9c974182004-09-15 11:59:51 +00001291 Identifier DefinedTypeRef TOK_PPEQ Value {
Lev Walkinf15320b2004-06-03 03:38:44 +00001292 $$ = $2;
1293 assert($$->Identifier == NULL);
1294 $$->Identifier = $1;
1295 $$->meta_type = AMT_VALUE;
1296 $$->value = $4;
1297 }
1298 ;
1299
Lev Walkin9c974182004-09-15 11:59:51 +00001300Value:
1301 Identifier ':' Value {
1302 $$ = asn1p_value_fromint(0);
1303 checkmem($$);
1304 $$->type = ATV_CHOICE_IDENTIFIER;
1305 $$->value.choice_identifier.identifier = $1;
1306 $$->value.choice_identifier.value = $3;
1307 }
1308 | '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
Lev Walkinf15320b2004-06-03 03:38:44 +00001309 $$ = asn1p_value_frombuf($3.buf, $3.len, 0);
1310 checkmem($$);
1311 $$->type = ATV_UNPARSED;
1312 }
Lev Walkin9c974182004-09-15 11:59:51 +00001313 | TOK_NULL {
1314 $$ = asn1p_value_fromint(0);
1315 checkmem($$);
1316 $$->type = ATV_NULL;
1317 }
1318 | TOK_FALSE {
1319 $$ = asn1p_value_fromint(0);
1320 checkmem($$);
1321 $$->type = ATV_FALSE;
1322 }
1323 | TOK_TRUE {
1324 $$ = asn1p_value_fromint(0);
1325 checkmem($$);
1326 $$->type = ATV_TRUE;
1327 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001328 | TOK_bstring {
1329 $$ = _convert_bitstring2binary($1, 'B');
1330 checkmem($$);
1331 }
1332 | TOK_hstring {
1333 $$ = _convert_bitstring2binary($1, 'H');
1334 checkmem($$);
1335 }
1336 | TOK_cstring {
1337 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1338 checkmem($$);
1339 }
1340 | SignedNumber {
1341 $$ = $1;
1342 }
1343 | DefinedValue {
1344 $$ = $1;
1345 }
1346 ;
1347
1348DefinedValue:
1349 Identifier {
1350 asn1p_ref_t *ref;
1351 int ret;
1352 ref = asn1p_ref_new(yylineno);
1353 checkmem(ref);
1354 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1355 checkmem(ret == 0);
1356 $$ = asn1p_value_fromref(ref, 0);
1357 checkmem($$);
1358 free($1);
1359 }
1360 | TypeRefName '.' Identifier {
1361 asn1p_ref_t *ref;
1362 int ret;
1363 ref = asn1p_ref_new(yylineno);
1364 checkmem(ref);
1365 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1366 checkmem(ret == 0);
1367 ret = asn1p_ref_add_component(ref, $3, RLT_lowercase);
1368 checkmem(ret == 0);
1369 $$ = asn1p_value_fromref(ref, 0);
1370 checkmem($$);
1371 free($1);
1372 free($3);
1373 }
1374 ;
1375
1376Opaque:
1377 TOK_opaque {
1378 $$.len = $1.len + 2;
1379 $$.buf = malloc($$.len + 1);
1380 checkmem($$.buf);
1381 $$.buf[0] = '{';
1382 $$.buf[1] = ' ';
1383 memcpy($$.buf + 2, $1.buf, $1.len);
1384 $$.buf[$$.len] = '\0';
1385 free($1.buf);
1386 }
1387 | Opaque TOK_opaque {
1388 int newsize = $1.len + $2.len;
1389 char *p = malloc(newsize + 1);
1390 checkmem(p);
1391 memcpy(p , $1.buf, $1.len);
1392 memcpy(p + $1.len, $2.buf, $2.len);
1393 p[newsize] = '\0';
1394 free($1.buf);
1395 free($2.buf);
1396 $$.buf = p;
1397 $$.len = newsize;
1398 }
1399 ;
1400
1401BasicTypeId:
1402 TOK_BOOLEAN { $$ = ASN_BASIC_BOOLEAN; }
1403 | TOK_NULL { $$ = ASN_BASIC_NULL; }
1404 | TOK_REAL { $$ = ASN_BASIC_REAL; }
1405 | BasicTypeId_UniverationCompatible { $$ = $1; }
1406 | TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; }
1407 | TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; }
1408 | TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; }
1409 | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; }
1410 | TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; }
1411 | TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; }
1412 | TOK_UTCTime { $$ = ASN_BASIC_UTCTime; }
1413 | TOK_GeneralizedTime { $$ = ASN_BASIC_GeneralizedTime; }
1414 ;
1415
1416/*
1417 * A type identifier which may be used with "{ a(1), b(2) }" clause.
1418 */
1419BasicTypeId_UniverationCompatible:
1420 TOK_INTEGER { $$ = ASN_BASIC_INTEGER; }
1421 | TOK_ENUMERATED { $$ = ASN_BASIC_ENUMERATED; }
1422 | TOK_BIT TOK_STRING { $$ = ASN_BASIC_BIT_STRING; }
1423 ;
1424
1425BasicType:
1426 BasicTypeId {
Lev Walkinceb20e72004-09-05 10:40:41 +00001427 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001428 checkmem($$);
1429 $$->expr_type = $1;
1430 $$->meta_type = AMT_TYPE;
1431 }
1432 | BasicTypeId_UniverationCompatible UniverationDefinition {
1433 if($2) {
1434 $$ = $2;
1435 } else {
Lev Walkinceb20e72004-09-05 10:40:41 +00001436 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001437 checkmem($$);
1438 }
1439 $$->expr_type = $1;
1440 $$->meta_type = AMT_TYPE;
1441 }
1442 ;
1443
1444BasicString:
1445 TOK_BMPString { $$ = ASN_STRING_BMPString; }
1446 | TOK_GeneralString {
1447 $$ = ASN_STRING_GeneralString;
Lev Walkin9c974182004-09-15 11:59:51 +00001448 fprintf(stderr, "WARNING: GeneralString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001449 }
1450 | TOK_GraphicString {
1451 $$ = ASN_STRING_GraphicString;
Lev Walkin9c974182004-09-15 11:59:51 +00001452 fprintf(stderr, "WARNING: GraphicString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001453 }
1454 | TOK_IA5String { $$ = ASN_STRING_IA5String; }
1455 | TOK_ISO646String { $$ = ASN_STRING_ISO646String; }
1456 | TOK_NumericString { $$ = ASN_STRING_NumericString; }
1457 | TOK_PrintableString { $$ = ASN_STRING_PrintableString; }
1458 | TOK_T61String {
1459 $$ = ASN_STRING_T61String;
Lev Walkin9c974182004-09-15 11:59:51 +00001460 fprintf(stderr, "WARNING: T61String is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001461 }
1462 | TOK_TeletexString { $$ = ASN_STRING_TeletexString; }
1463 | TOK_UniversalString { $$ = ASN_STRING_UniversalString; }
1464 | TOK_UTF8String { $$ = ASN_STRING_UTF8String; }
1465 | TOK_VideotexString {
1466 $$ = ASN_STRING_VideotexString;
Lev Walkin9c974182004-09-15 11:59:51 +00001467 fprintf(stderr, "WARNING: VideotexString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001468 }
1469 | TOK_VisibleString { $$ = ASN_STRING_VisibleString; }
1470 | TOK_ObjectDescriptor { $$ = ASN_STRING_ObjectDescriptor; }
1471 ;
1472
Lev Walkind2ea1de2004-08-20 13:25:29 +00001473
Lev Walkinf15320b2004-06-03 03:38:44 +00001474/*
1475 * Data type constraints.
1476 */
Lev Walkinf15320b2004-06-03 03:38:44 +00001477Union: '|' | TOK_UNION;
1478Intersection: '^' | TOK_INTERSECTION;
1479Except: TOK_EXCEPT;
1480
Lev Walkinf59d0752004-08-18 04:59:12 +00001481optConstraints:
1482 { $$ = 0; }
Lev Walkind2ea1de2004-08-20 13:25:29 +00001483 | Constraints {
1484 $$ = $1;
1485 }
1486 ;
1487
1488Constraints:
1489 SetOfConstraints {
Lev Walkinf59d0752004-08-18 04:59:12 +00001490 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, 0);
1491 }
1492 | TOK_SIZE '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001493 /*
1494 * This is a special case, for compatibility purposes.
Lev Walkinf59d0752004-08-18 04:59:12 +00001495 * It goes without parentheses.
Lev Walkinf15320b2004-06-03 03:38:44 +00001496 */
Lev Walkind2ea1de2004-08-20 13:25:29 +00001497 CONSTRAINT_INSERT($$, ACT_CT_SIZE, $3, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001498 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001499 ;
1500
Lev Walkinf59d0752004-08-18 04:59:12 +00001501SetOfConstraints:
1502 '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001503 $$ = $2;
1504 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001505 | SetOfConstraints '(' ElementSetSpecs ')' {
1506 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $3);
1507 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001508 ;
1509
Lev Walkinf59d0752004-08-18 04:59:12 +00001510ElementSetSpecs:
1511 ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001512 $$ = $1;
1513 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001514 | ElementSetSpec ',' TOK_ThreeDots {
Lev Walkinf15320b2004-06-03 03:38:44 +00001515 asn1p_constraint_t *ct;
1516 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001517 ct->type = ACT_EL_EXT;
1518 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1519 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001520 | ElementSetSpec ',' TOK_ThreeDots ',' ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001521 asn1p_constraint_t *ct;
1522 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001523 ct->type = ACT_EL_EXT;
1524 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
Lev Walkinb4fcdd22004-08-13 12:35:09 +00001525 ct = $$;
1526 CONSTRAINT_INSERT($$, ACT_CA_CSV, ct, $5);
Lev Walkinf15320b2004-06-03 03:38:44 +00001527 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001528 ;
1529
Lev Walkinf59d0752004-08-18 04:59:12 +00001530ElementSetSpec:
1531 ConstraintSubtypeElement {
1532 $$ = $1;
1533 }
1534 | ElementSetSpec Union ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001535 CONSTRAINT_INSERT($$, ACT_CA_UNI, $1, $3);
1536 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001537 | ElementSetSpec Intersection ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001538 CONSTRAINT_INSERT($$, ACT_CA_INT, $1, $3);
1539 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001540 | ConstraintSubtypeElement Except ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001541 CONSTRAINT_INSERT($$, ACT_CA_EXC, $1, $3);
1542 }
1543 ;
1544
1545ConstraintSubtypeElement:
Lev Walkinf59d0752004-08-18 04:59:12 +00001546 ConstraintSpec '(' ElementSetSpecs ')' {
1547 int ret;
1548 $$ = asn1p_constraint_new(yylineno);
1549 checkmem($$);
1550 $$->type = $1;
1551 ret = asn1p_constraint_insert($$, $3);
1552 checkmem(ret == 0);
1553 }
1554 | '(' ElementSetSpecs ')' {
1555 int ret;
1556 $$ = asn1p_constraint_new(yylineno);
1557 checkmem($$);
1558 $$->type = ACT_CA_SET;
1559 ret = asn1p_constraint_insert($$, $2);
1560 checkmem(ret == 0);
1561 }
1562 | ConstraintValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001563 $$ = asn1p_constraint_new(yylineno);
1564 checkmem($$);
1565 $$->type = ACT_EL_VALUE;
1566 $$->value = $1;
1567 }
1568 | ConstraintValue ConstraintRangeSpec ConstraintValue {
1569 $$ = asn1p_constraint_new(yylineno);
1570 checkmem($$);
1571 $$->type = $2;
1572 $$->range_start = $1;
1573 $$->range_stop = $3;
1574 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001575 | TOK_MIN ConstraintRangeSpec ConstraintValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001576 $$ = asn1p_constraint_new(yylineno);
1577 checkmem($$);
Lev Walkinf59d0752004-08-18 04:59:12 +00001578 $$->type = $2;
1579 $$->range_start = asn1p_value_fromint(-123);
1580 $$->range_stop = $3;
1581 $$->range_start->type = ATV_MIN;
1582 }
1583 | ConstraintValue ConstraintRangeSpec TOK_MAX {
1584 $$ = asn1p_constraint_new(yylineno);
1585 checkmem($$);
1586 $$->type = $2;
1587 $$->range_start = $1;
1588 $$->range_stop = asn1p_value_fromint(321);
1589 $$->range_stop->type = ATV_MAX;
1590 }
1591 | TOK_MIN ConstraintRangeSpec TOK_MAX {
1592 $$ = asn1p_constraint_new(yylineno);
1593 checkmem($$);
1594 $$->type = $2;
1595 $$->range_start = asn1p_value_fromint(-123);
1596 $$->range_stop = asn1p_value_fromint(321);
1597 $$->range_start->type = ATV_MIN;
1598 $$->range_stop->type = ATV_MAX;
Lev Walkinf15320b2004-06-03 03:38:44 +00001599 }
1600 | TableConstraint {
1601 $$ = $1;
1602 }
1603 | WithComponents {
1604 $$ = $1;
1605 }
1606 ;
1607
1608ConstraintRangeSpec:
1609 TOK_TwoDots { $$ = ACT_EL_RANGE; }
1610 | TOK_TwoDots '<' { $$ = ACT_EL_RLRANGE; }
1611 | '<' TOK_TwoDots { $$ = ACT_EL_LLRANGE; }
1612 | '<' TOK_TwoDots '<' { $$ = ACT_EL_ULRANGE; }
1613 ;
1614
1615ConstraintSpec:
1616 TOK_SIZE {
1617 $$ = ACT_CT_SIZE;
1618 }
1619 | TOK_FROM {
1620 $$ = ACT_CT_FROM;
1621 }
1622 ;
1623
1624ConstraintValue:
1625 SignedNumber {
1626 $$ = $1;
1627 }
1628 | Identifier {
1629 asn1p_ref_t *ref;
1630 int ret;
1631 ref = asn1p_ref_new(yylineno);
1632 checkmem(ref);
1633 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1634 checkmem(ret == 0);
1635 $$ = asn1p_value_fromref(ref, 0);
1636 checkmem($$);
1637 free($1);
1638 }
1639 | TOK_cstring {
1640 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1641 checkmem($$);
1642 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001643 | TOK_FALSE {
1644 $$ = asn1p_value_fromint(0);
1645 checkmem($$);
1646 $$->type = ATV_FALSE;
1647 }
1648 | TOK_TRUE {
1649 $$ = asn1p_value_fromint(1);
1650 checkmem($$);
1651 $$->type = ATV_TRUE;
1652 }
1653 ;
1654
1655WithComponents:
1656 TOK_WITH TOK_COMPONENTS '{' WithComponentsList '}' {
1657 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $4, 0);
1658 }
1659 ;
1660
1661WithComponentsList:
1662 WithComponentsElement {
1663 $$ = $1;
1664 }
1665 | WithComponentsList ',' WithComponentsElement {
1666 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $1, $3);
1667 }
1668 ;
1669
1670WithComponentsElement:
1671 TOK_ThreeDots {
1672 $$ = asn1p_constraint_new(yylineno);
1673 checkmem($$);
1674 $$->type = ACT_EL_EXT;
1675 }
1676 | Identifier optConstraints optPresenceConstraint {
1677 $$ = asn1p_constraint_new(yylineno);
1678 checkmem($$);
1679 $$->type = ACT_EL_VALUE;
1680 $$->value = asn1p_value_frombuf($1, strlen($1), 0);
1681 $$->presence = $3;
1682 }
1683 ;
1684
1685/*
1686 * presence constraint for WithComponents
1687 */
1688optPresenceConstraint:
1689 { $$ = ACPRES_DEFAULT; }
1690 | PresenceConstraint { $$ = $1; }
1691 ;
1692
1693PresenceConstraint:
1694 TOK_PRESENT {
1695 $$ = ACPRES_PRESENT;
1696 }
1697 | TOK_ABSENT {
1698 $$ = ACPRES_ABSENT;
1699 }
1700 | TOK_OPTIONAL {
1701 $$ = ACPRES_OPTIONAL;
1702 }
1703 ;
1704
1705TableConstraint:
1706 SimpleTableConstraint {
1707 $$ = $1;
1708 }
1709 | ComponentRelationConstraint {
1710 $$ = $1;
1711 }
1712 ;
1713
1714/*
1715 * "{ExtensionSet}"
1716 */
1717SimpleTableConstraint:
1718 '{' TypeRefName '}' {
1719 asn1p_ref_t *ref = asn1p_ref_new(yylineno);
1720 asn1p_constraint_t *ct;
1721 int ret;
1722 ret = asn1p_ref_add_component(ref, $2, 0);
1723 checkmem(ret == 0);
1724 ct = asn1p_constraint_new(yylineno);
1725 checkmem($$);
1726 ct->type = ACT_EL_VALUE;
1727 ct->value = asn1p_value_fromref(ref, 0);
1728 CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0);
1729 }
1730 ;
1731
1732ComponentRelationConstraint:
1733 SimpleTableConstraint '{' AtNotationList '}' {
1734 CONSTRAINT_INSERT($$, ACT_CA_CRC, $1, $3);
1735 }
1736 ;
1737
1738AtNotationList:
1739 AtNotationElement {
1740 $$ = asn1p_constraint_new(yylineno);
1741 checkmem($$);
1742 $$->type = ACT_EL_VALUE;
1743 $$->value = asn1p_value_fromref($1, 0);
1744 }
1745 | AtNotationList ',' AtNotationElement {
1746 asn1p_constraint_t *ct;
1747 ct = asn1p_constraint_new(yylineno);
1748 checkmem(ct);
1749 ct->type = ACT_EL_VALUE;
1750 ct->value = asn1p_value_fromref($3, 0);
1751 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1752 }
1753 ;
1754
1755/*
1756 * @blah
1757 */
1758AtNotationElement:
1759 '@' ComponentIdList {
1760 char *p = malloc(strlen($2) + 2);
1761 int ret;
1762 *p = '@';
1763 strcpy(p + 1, $2);
1764 $$ = asn1p_ref_new(yylineno);
1765 ret = asn1p_ref_add_component($$, p, 0);
1766 checkmem(ret == 0);
1767 free(p);
1768 free($2);
1769 }
1770 | '@' '.' ComponentIdList {
1771 char *p = malloc(strlen($3) + 3);
1772 int ret;
1773 p[0] = '@';
1774 p[1] = '.';
1775 strcpy(p + 2, $3);
1776 $$ = asn1p_ref_new(yylineno);
1777 ret = asn1p_ref_add_component($$, p, 0);
1778 checkmem(ret == 0);
1779 free(p);
1780 free($3);
1781 }
1782 ;
1783
1784/* identifier "." ... */
1785ComponentIdList:
1786 Identifier {
1787 $$ = $1;
1788 }
1789 | ComponentIdList '.' Identifier {
1790 int l1 = strlen($1);
1791 int l3 = strlen($3);
1792 $$ = malloc(l1 + 1 + l3 + 1);
1793 memcpy($$, $1, l1);
1794 $$[l1] = '.';
1795 memcpy($$ + l1 + 1, $3, l3);
1796 $$[l1 + 1 + l3] = '\0';
1797 }
1798 ;
1799
1800
1801
1802/*
1803 * MARKERS
1804 */
1805
1806optMarker:
Lev Walkin9c974182004-09-15 11:59:51 +00001807 {
1808 $$.flags = EM_NOMARK;
1809 $$.default_value = 0;
1810 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001811 | Marker { $$ = $1; }
1812 ;
1813
1814Marker:
1815 TOK_OPTIONAL {
Lev Walkin9c974182004-09-15 11:59:51 +00001816 $$.flags = EM_OPTIONAL;
1817 $$.default_value = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +00001818 }
Lev Walkin9c974182004-09-15 11:59:51 +00001819 | TOK_DEFAULT Value {
1820 $$.flags = EM_DEFAULT;
1821 $$.default_value = $2;
Lev Walkinf15320b2004-06-03 03:38:44 +00001822 }
1823 ;
1824
1825/*
1826 * Universal enumeration definition to use in INTEGER and ENUMERATED.
1827 * === EXAMPLE ===
1828 * Gender ::= ENUMERATED { unknown(0), male(1), female(2) }
1829 * Temperature ::= INTEGER { absolute-zero(-273), freezing(0), boiling(100) }
1830 * === EOF ===
1831 */
1832/*
1833optUniverationDefinition:
1834 { $$ = 0; }
1835 | UniverationDefinition {
1836 $$ = $1;
1837 }
1838 ;
1839*/
1840
1841UniverationDefinition:
1842 '{' '}' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001843 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001844 checkmem($$);
1845 }
1846 | '{' UniverationList '}' {
1847 $$ = $2;
1848 }
1849 ;
1850
1851UniverationList:
1852 UniverationElement {
Lev Walkinceb20e72004-09-05 10:40:41 +00001853 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001854 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +00001855 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +00001856 }
1857 | UniverationList ',' UniverationElement {
1858 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +00001859 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00001860 }
1861 ;
1862
1863UniverationElement:
1864 Identifier {
Lev Walkinceb20e72004-09-05 10:40:41 +00001865 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001866 checkmem($$);
1867 $$->expr_type = A1TC_UNIVERVAL;
1868 $$->meta_type = AMT_VALUE;
1869 $$->Identifier = $1;
1870 }
1871 | Identifier '(' SignedNumber ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001872 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001873 checkmem($$);
1874 $$->expr_type = A1TC_UNIVERVAL;
1875 $$->meta_type = AMT_VALUE;
1876 $$->Identifier = $1;
1877 $$->value = $3;
1878 }
1879 | Identifier '(' DefinedValue ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001880 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001881 checkmem($$);
1882 $$->expr_type = A1TC_UNIVERVAL;
1883 $$->meta_type = AMT_VALUE;
1884 $$->Identifier = $1;
1885 $$->value = $3;
1886 }
1887 | SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001888 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001889 checkmem($$);
1890 $$->expr_type = A1TC_UNIVERVAL;
1891 $$->meta_type = AMT_VALUE;
1892 $$->value = $1;
1893 }
1894 | TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001895 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001896 checkmem($$);
1897 $$->Identifier = strdup("...");
1898 checkmem($$->Identifier);
1899 $$->expr_type = A1TC_EXTENSIBLE;
1900 $$->meta_type = AMT_VALUE;
1901 }
1902 ;
1903
1904SignedNumber:
1905 TOK_number {
1906 $$ = asn1p_value_fromint($1);
1907 checkmem($$);
1908 }
1909 | TOK_number_negative {
1910 $$ = asn1p_value_fromint($1);
1911 checkmem($$);
1912 }
1913 ;
1914
1915/*
1916 * SEQUENCE definition.
1917 * === EXAMPLE ===
1918 * Struct1 ::= SEQUENCE {
1919 * memb1 Struct2,
1920 * memb2 SEQUENCE OF {
1921 * memb2-1 Struct 3
1922 * }
1923 * }
1924 * === EOF ===
1925 */
1926
1927
1928
1929/*
1930 * SET definition.
1931 * === EXAMPLE ===
1932 * Person ::= SET {
1933 * name [0] PrintableString (SIZE(1..20)),
1934 * country [1] PrintableString (SIZE(1..20)) DEFAULT default-country,
1935 * }
1936 * === EOF ===
1937 */
1938
1939optTag:
1940 { memset(&$$, 0, sizeof($$)); }
1941 | Tag { $$ = $1; }
1942 ;
1943
1944Tag:
1945 TOK_tag {
1946 $$ = $1;
1947 $$.tag_mode = TM_DEFAULT;
1948 }
1949 | TOK_tag TOK_IMPLICIT {
1950 $$ = $1;
1951 $$.tag_mode = TM_IMPLICIT;
1952 }
1953 | TOK_tag TOK_EXPLICIT {
1954 $$ = $1;
1955 $$.tag_mode = TM_EXPLICIT;
1956 }
1957 ;
1958
1959TypeRefName:
1960 TOK_typereference {
1961 checkmem($1);
1962 $$ = $1;
1963 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001964 | TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00001965 checkmem($1);
1966 $$ = $1;
1967 }
1968 ;
1969
Lev Walkinf59d0752004-08-18 04:59:12 +00001970
Lev Walkinf15320b2004-06-03 03:38:44 +00001971ObjectClassReference:
Lev Walkinf59d0752004-08-18 04:59:12 +00001972 TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00001973 checkmem($1);
1974 $$ = $1;
1975 }
1976 ;
1977
Lev Walkin83cac2f2004-09-22 16:03:36 +00001978optIdentifier:
1979 { $$ = 0; }
1980 | Identifier {
1981 $$ = $1;
1982 }
1983
Lev Walkinf15320b2004-06-03 03:38:44 +00001984Identifier:
1985 TOK_identifier {
1986 checkmem($1);
1987 $$ = $1;
1988 }
1989 ;
1990
Lev Walkinf15320b2004-06-03 03:38:44 +00001991%%
1992
1993
1994/*
1995 * Convert Xstring ('0101'B or '5'H) to the binary vector.
1996 */
1997static asn1p_value_t *
1998_convert_bitstring2binary(char *str, int base) {
1999 asn1p_value_t *val;
2000 int slen;
2001 int memlen;
2002 int baselen;
2003 int bits;
2004 uint8_t *binary_vector;
2005 uint8_t *bv_ptr;
2006 uint8_t cur_val;
2007
2008 assert(str);
2009 assert(str[0] == '\'');
2010
2011 switch(base) {
2012 case 'B':
2013 baselen = 1;
2014 break;
2015 case 'H':
2016 baselen = 4;
2017 break;
2018 default:
2019 assert(base == 'B' || base == 'H');
2020 errno = EINVAL;
2021 return NULL;
2022 }
2023
2024 slen = strlen(str);
2025 assert(str[slen - 1] == base);
2026 assert(str[slen - 2] == '\'');
2027
2028 memlen = slen / (8 / baselen); /* Conservative estimate */
2029
2030 bv_ptr = binary_vector = malloc(memlen + 1);
2031 if(bv_ptr == NULL)
2032 /* ENOMEM */
2033 return NULL;
2034
2035 cur_val = 0;
2036 bits = 0;
2037 while(*(++str) != '\'') {
2038 switch(baselen) {
2039 case 1:
2040 switch(*str) {
2041 case '1':
2042 cur_val |= 1 << (7 - (bits % 8));
2043 case '0':
2044 break;
2045 default:
2046 assert(!"_y UNREACH1");
2047 case ' ': case '\r': case '\n':
2048 continue;
2049 }
2050 break;
2051 case 4:
2052 switch(*str) {
2053 case '0': case '1': case '2': case '3': case '4':
2054 case '5': case '6': case '7': case '8': case '9':
2055 cur_val |= (*str - '0') << (4 - (bits % 8));
2056 break;
2057 case 'A': case 'B': case 'C':
2058 case 'D': case 'E': case 'F':
2059 cur_val |= ((*str - 'A') + 10)
2060 << (4 - (bits % 8));
2061 break;
2062 default:
2063 assert(!"_y UNREACH2");
2064 case ' ': case '\r': case '\n':
2065 continue;
2066 }
2067 break;
2068 }
2069
2070 bits += baselen;
2071 if((bits % 8) == 0) {
2072 *bv_ptr++ = cur_val;
2073 cur_val = 0;
2074 }
2075 }
2076
2077 *bv_ptr = cur_val;
2078 assert((bv_ptr - binary_vector) <= memlen);
2079
2080 val = asn1p_value_frombits(binary_vector, bits, 0);
2081 if(val == NULL) {
2082 free(binary_vector);
2083 }
2084
2085 return val;
2086}
2087
2088extern char *asn1p_text;
2089
2090int
2091yyerror(const char *msg) {
2092 fprintf(stderr,
2093 "ASN.1 grammar parse error "
2094 "near line %d (token \"%s\"): %s\n",
Lev Walkinceb20e72004-09-05 10:40:41 +00002095 yylineno, asn1p_text, msg);
Lev Walkinf15320b2004-06-03 03:38:44 +00002096 return -1;
2097}
2098
2099