blob: 452086f56e0b77779295fa1b2f76931e95ab83c6 [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
26#define checkmem(ptr) do { \
27 if(!(ptr)) \
28 return yyerror("Memory failure"); \
29 } 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 */
77 enum asn1p_expr_marker_e a_marker; /* OPTIONAL/DEFAULT */
78 enum asn1p_constr_pres_e a_pres; /* PRESENT/ABSENT/OPTIONAL */
79 asn1_integer_t a_int;
80 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
221%type <a_expr> DataTypeMember
222%type <a_expr> ExtensionAndException
223%type <a_expr> TypeDeclaration
224%type <a_ref> ComplexTypeReference
225%type <a_ref> ComplexTypeReferenceAmpList
226%type <a_refcomp> ComplexTypeReferenceElement
227%type <a_refcomp> ClassFieldIdentifier
228%type <a_refcomp> ClassFieldName
229%type <a_expr> ClassFieldList
230%type <a_expr> ClassField
231%type <a_expr> ClassDeclaration
232%type <a_expr> ConstrainedTypeDeclaration
233%type <a_expr> DataTypeReference /* Type1 ::= Type2 */
234%type <a_expr> DefinedTypeRef
235%type <a_expr> ValueSetDefinition /* Val INTEGER ::= {1|2} */
236%type <a_expr> ValueDefinition /* val INTEGER ::= 1*/
237%type <a_value> optValueSetBody
238%type <a_value> InlineOrDefinedValue
239%type <a_value> DefinedValue
240%type <a_value> SignedNumber
241%type <a_expr> ConstructedType
242%type <a_expr> ConstructedDataTypeDefinition
243//%type <a_expr> optUniverationDefinition
244%type <a_expr> UniverationDefinition
245%type <a_expr> UniverationList
246%type <a_expr> UniverationElement
247%type <tv_str> TypeRefName
248%type <tv_str> ObjectClassReference
249%type <tv_nametag> TaggedIdentifier
250%type <tv_str> Identifier
251%type <a_parg> ParameterArgumentName
252%type <a_plist> ParameterArgumentList
253%type <a_expr> ActualParameter
254%type <a_expr> ActualParameterList
255%type <a_oid> ObjectIdentifier /* OID */
256%type <a_oid> optObjectIdentifier /* Optional OID */
257%type <a_oid> ObjectIdentifierBody
258%type <a_oid_arc> ObjectIdentifierElement
259%type <a_expr> BasicType
260%type <a_type> BasicTypeId
261%type <a_type> BasicTypeId_UniverationCompatible
262%type <a_type> BasicString
263%type <tv_opaque> Opaque
264//%type <tv_opaque> StringValue
265%type <a_tag> Tag /* [UNIVERSAL 0] IMPLICIT */
266%type <a_tag> optTag /* [UNIVERSAL 0] IMPLICIT */
267%type <a_constr> optConstraints
Lev Walkinf59d0752004-08-18 04:59:12 +0000268%type <a_constr> SetOfConstraints
269%type <a_constr> ElementSetSpecs /* 1..2,...,3 */
270%type <a_constr> ElementSetSpec /* 1..2,...,3 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000271%type <a_constr> ConstraintSubtypeElement /* 1..2 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000272%type <a_constr> SimpleTableConstraint
273%type <a_constr> TableConstraint
274%type <a_constr> WithComponents
275%type <a_constr> WithComponentsList
276%type <a_constr> WithComponentsElement
277%type <a_constr> ComponentRelationConstraint
278%type <a_constr> AtNotationList
279%type <a_ref> AtNotationElement
280%type <a_value> ConstraintValue
281%type <a_ctype> ConstraintSpec
282%type <a_ctype> ConstraintRangeSpec
283%type <a_wsynt> optWithSyntax
284%type <a_wsynt> WithSyntax
285%type <a_wsynt> WithSyntaxFormat
286%type <a_wchunk> WithSyntaxFormatToken
287%type <a_marker> optMarker Marker
288%type <a_int> optUnique
289%type <a_pres> optPresenceConstraint PresenceConstraint
290%type <tv_str> ComponentIdList
291
292
293%%
294
295
296ParsedGrammar:
297 ModuleList {
298 *(void **)param = $1;
299 }
300 ;
301
302ModuleList:
303 ModuleSpecification {
304 $$ = asn1p_new();
305 checkmem($$);
306 TQ_ADD(&($$->modules), $1, mod_next);
307 }
308 | ModuleList ModuleSpecification {
309 $$ = $1;
310 TQ_ADD(&($$->modules), $2, mod_next);
311 }
312 ;
313
314/*
315 * ASN module definition.
316 * === EXAMPLE ===
317 * MySyntax DEFINITIONS AUTOMATIC TAGS ::=
318 * BEGIN
319 * ...
320 * END
321 * === EOF ===
322 */
323
324ModuleSpecification:
325 TypeRefName optObjectIdentifier TOK_DEFINITIONS
326 optModuleSpecificationFlags
327 TOK_PPEQ TOK_BEGIN
328 optModuleSpecificationBody
329 TOK_END {
330
331 if($7) {
332 $$ = $7;
333 } else {
334 /* There's a chance that a module is just plain empty */
335 $$ = asn1p_module_new();
336 }
337 checkmem($$);
338
339 $$->Identifier = $1;
340 $$->module_oid = $2;
341 $$->module_flags = $4;
342 }
343 ;
344
345/*
346 * Object Identifier Definition
347 * { iso member-body(2) 3 }
348 */
349optObjectIdentifier:
350 { $$ = 0; }
351 | ObjectIdentifier { $$ = $1; }
352 ;
353
354ObjectIdentifier:
355 '{' ObjectIdentifierBody '}' {
356 $$ = $2;
357 }
358 | '{' '}' {
359 $$ = 0;
360 }
361 ;
362
363ObjectIdentifierBody:
364 ObjectIdentifierElement {
365 $$ = asn1p_oid_new();
366 asn1p_oid_add_arc($$, &$1);
367 if($1.name)
368 free($1.name);
369 }
370 | ObjectIdentifierBody ObjectIdentifierElement {
371 $$ = $1;
372 asn1p_oid_add_arc($$, &$2);
373 if($2.name)
374 free($2.name);
375 }
376 ;
377
378ObjectIdentifierElement:
379 Identifier { /* iso */
380 $$.name = $1;
381 $$.number = -1;
382 }
383 | Identifier '(' TOK_number ')' { /* iso(1) */
384 $$.name = $1;
385 $$.number = $3;
386 }
387 | TOK_number { /* 1 */
388 $$.name = 0;
389 $$.number = $1;
390 }
391 ;
392
393/*
394 * Optional module flags.
395 */
396optModuleSpecificationFlags:
397 { $$ = MSF_NOFLAGS; }
398 | ModuleSpecificationFlags {
399 $$ = $1;
400 }
401 ;
402
403/*
404 * Module flags.
405 */
406ModuleSpecificationFlags:
407 ModuleSpecificationFlag {
408 $$ = $1;
409 }
410 | ModuleSpecificationFlags ModuleSpecificationFlag {
411 $$ = $1 | $2;
412 }
413 ;
414
415/*
416 * Single module flag.
417 */
418ModuleSpecificationFlag:
419 TOK_EXPLICIT TOK_TAGS {
420 $$ = MSF_EXPLICIT_TAGS;
421 }
422 | TOK_IMPLICIT TOK_TAGS {
423 $$ = MSF_IMPLICIT_TAGS;
424 }
425 | TOK_AUTOMATIC TOK_TAGS {
426 $$ = MSF_AUTOMATIC_TAGS;
427 }
428 | TOK_EXTENSIBILITY TOK_IMPLIED {
429 $$ = MSF_EXTENSIBILITY_IMPLIED;
430 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000431 /* EncodingReferenceDefault */
432 | TOK_capitalreference TOK_INSTRUCTIONS {
433 /* X.680Amd1 specifies TAG and XER */
434 if(strcmp($1, "TAG") == 0) {
435 $$ = MSF_TAG_INSTRUCTIONS;
436 } else if(strcmp($1, "XER") == 0) {
437 $$ = MSF_XER_INSTRUCTIONS;
438 } else {
439 fprintf(stderr,
440 "WARNING: %s INSTRUCTIONS at line %d: "
441 "Unrecognized encoding reference\n",
442 $1, yylineno);
443 $$ = MSF_unk_INSTRUCTIONS;
444 }
445 free($1);
446 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000447 ;
448
449/*
450 * Optional module body.
451 */
452optModuleSpecificationBody:
453 { $$ = 0; }
454 | ModuleSpecificationBody {
Lev Walkinf15320b2004-06-03 03:38:44 +0000455 $$ = $1;
456 }
457 ;
458
459/*
460 * ASN.1 Module body.
461 */
462ModuleSpecificationBody:
463 ModuleSpecificationElement {
464 $$ = $1;
465 }
466 | ModuleSpecificationBody ModuleSpecificationElement {
467 $$ = $1;
468
Lev Walkinf59d0752004-08-18 04:59:12 +0000469 /* Behave well when one of them is skipped. */
470 if(!($1)) {
471 if($2) $$ = $2;
472 break;
473 }
474
Lev Walkinf15320b2004-06-03 03:38:44 +0000475#ifdef MY_IMPORT
476#error MY_IMPORT DEFINED ELSEWHERE!
477#endif
478#define MY_IMPORT(foo,field) do { \
Lev Walkinbc55d232004-08-13 12:31:09 +0000479 while(TQ_FIRST(&($2->foo))) { \
Lev Walkinf15320b2004-06-03 03:38:44 +0000480 TQ_ADD(&($$->foo), \
481 TQ_REMOVE(&($2->foo), field), \
482 field); \
Lev Walkinbc55d232004-08-13 12:31:09 +0000483 } \
484 assert(TQ_FIRST(&($2->foo)) == 0); \
485 } while(0)
Lev Walkinf15320b2004-06-03 03:38:44 +0000486
487 MY_IMPORT(imports, xp_next);
488 MY_IMPORT(exports, xp_next);
489 MY_IMPORT(members, next);
490#undef MY_IMPORT
491
492 }
493 ;
494
495/*
496 * One of the elements of ASN.1 module specification.
497 */
498ModuleSpecificationElement:
499 ImportsDefinition {
500 $$ = $1;
501 }
502 | ExportsDefinition {
503 $$ = asn1p_module_new();
504 checkmem($$);
505 if($1) {
506 TQ_ADD(&($$->exports), $1, xp_next);
507 } else {
508 /* "EXPORTS ALL;" ? */
509 }
510 }
511 | DataTypeReference {
512 $$ = asn1p_module_new();
513 checkmem($$);
514 assert($1->expr_type != A1TC_INVALID);
515 assert($1->meta_type != AMT_INVALID);
516 TQ_ADD(&($$->members), $1, next);
517 }
518 | ValueDefinition {
519 $$ = asn1p_module_new();
520 checkmem($$);
521 assert($1->expr_type != A1TC_INVALID);
522 assert($1->meta_type != AMT_INVALID);
523 TQ_ADD(&($$->members), $1, next);
524 }
525 /*
526 * Value set definition
527 * === EXAMPLE ===
528 * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 }
529 * === EOF ===
530 */
531 | ValueSetDefinition {
532 $$ = asn1p_module_new();
533 checkmem($$);
534 assert($1->expr_type != A1TC_INVALID);
535 assert($1->meta_type != AMT_INVALID);
536 TQ_ADD(&($$->members), $1, next);
537 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000538 | TOK_ENCODING_CONTROL TOK_capitalreference
539 { asn1p_lexer_hack_push_encoding_control(); }
540 {
541 fprintf(stderr,
542 "WARNING: ENCODING-CONTROL %s "
543 "specification at line %d ignored\n",
544 $2, yylineno);
545 free($2);
546 $$ = 0;
547 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000548
549 /*
550 * Erroneous attemps
551 */
552 | BasicString {
553 return yyerror(
554 "Attempt to redefine a standard basic type, "
555 "use -ftypesXY to switch back "
556 "to older version of ASN.1 standard");
557 }
558 ;
559
560/*
561 * === EXAMPLE ===
562 * IMPORTS Type1, value FROM Module { iso standard(0) } ;
563 * === EOF ===
564 */
565ImportsDefinition:
566 TOK_IMPORTS ImportsBundleSet ';' {
567 $$ = $2;
568 }
569 /*
570 * Some error cases.
571 */
572 | TOK_IMPORTS TOK_FROM /* ... */ {
573 return yyerror("Empty IMPORTS list");
574 }
575 ;
576
577ImportsBundleSet:
578 ImportsBundle {
579 $$ = asn1p_module_new();
580 checkmem($$);
581 TQ_ADD(&($$->imports), $1, xp_next);
582 }
583 | ImportsBundleSet ImportsBundle {
584 $$ = $1;
585 TQ_ADD(&($$->imports), $2, xp_next);
586 }
587 ;
588
589ImportsBundle:
590 ImportsList TOK_FROM TypeRefName optObjectIdentifier {
591 $$ = $1;
592 $$->from = $3;
593 $$->from_oid = $4;
594 checkmem($$);
595 }
596 ;
597
598ImportsList:
599 ImportsElement {
600 $$ = asn1p_xports_new();
601 checkmem($$);
602 TQ_ADD(&($$->members), $1, next);
603 }
604 | ImportsList ',' ImportsElement {
605 $$ = $1;
606 TQ_ADD(&($$->members), $3, next);
607 }
608 ;
609
610ImportsElement:
611 TypeRefName {
612 $$ = asn1p_expr_new(yylineno);
613 checkmem($$);
614 $$->Identifier = $1;
615 $$->expr_type = A1TC_REFERENCE;
616 }
617 | Identifier {
618 $$ = asn1p_expr_new(yylineno);
619 checkmem($$);
620 $$->Identifier = $1;
621 $$->expr_type = A1TC_REFERENCE;
622 }
623 ;
624
625ExportsDefinition:
626 TOK_EXPORTS ExportsBody ';' {
627 $$ = $2;
628 }
629 | TOK_EXPORTS TOK_ALL ';' {
630 $$ = 0;
631 }
632 | TOK_EXPORTS ';' {
633 /* Empty EXPORTS clause effectively prohibits export. */
634 $$ = asn1p_xports_new();
635 checkmem($$);
636 }
637 ;
638
639ExportsBody:
640 ExportsElement {
641 $$ = asn1p_xports_new();
642 assert($$);
643 TQ_ADD(&($$->members), $1, next);
644 }
645 | ExportsBody ',' ExportsElement {
646 $$ = $1;
647 TQ_ADD(&($$->members), $3, next);
648 }
649 ;
650
651ExportsElement:
652 TypeRefName {
653 $$ = asn1p_expr_new(yylineno);
654 checkmem($$);
655 $$->Identifier = $1;
656 $$->expr_type = A1TC_EXPORTVAR;
657 }
658 | Identifier {
659 $$ = asn1p_expr_new(yylineno);
660 checkmem($$);
661 $$->Identifier = $1;
662 $$->expr_type = A1TC_EXPORTVAR;
663 }
664 ;
665
666
667ValueSetDefinition:
668 TypeRefName DefinedTypeRef TOK_PPEQ '{' optValueSetBody '}' {
669 $$ = $2;
670 assert($$->Identifier == 0);
671 $$->Identifier = $1;
672 $$->meta_type = AMT_VALUESET;
673 // take care of optValueSetBody
674 }
675 ;
676
677DefinedTypeRef:
678 ComplexTypeReference {
679 $$ = asn1p_expr_new(yylineno);
680 checkmem($$);
681 $$->reference = $1;
682 $$->expr_type = A1TC_REFERENCE;
683 $$->meta_type = AMT_TYPEREF;
684 }
685 | BasicTypeId {
686 $$ = asn1p_expr_new(yylineno);
687 checkmem($$);
688 $$->expr_type = $1;
689 $$->meta_type = AMT_TYPE;
690 }
691 ;
692
693optValueSetBody:
694 { }
Lev Walkinf59d0752004-08-18 04:59:12 +0000695 | ElementSetSpecs {
Lev Walkinf15320b2004-06-03 03:38:44 +0000696 }
697 ;
698
699
700/*
701 * Data Type Reference.
702 * === EXAMPLE ===
703 * Type3 ::= CHOICE { a Type1, b Type 2 }
704 * === EOF ===
705 */
706
707DataTypeReference:
708 /*
709 * Optionally tagged type definition.
710 */
711 TypeRefName TOK_PPEQ optTag TOK_TYPE_IDENTIFIER {
712 $$ = asn1p_expr_new(yylineno);
713 checkmem($$);
714 $$->Identifier = $1;
715 $$->tag = $3;
716 $$->expr_type = A1TC_TYPEID;
717 $$->meta_type = AMT_TYPE;
718 }
719 | TypeRefName TOK_PPEQ optTag ConstrainedTypeDeclaration {
720 $$ = $4;
721 $$->Identifier = $1;
722 $$->tag = $3;
723 assert($$->expr_type);
724 assert($$->meta_type);
725 }
726 | TypeRefName TOK_PPEQ ClassDeclaration {
727 $$ = $3;
728 $$->Identifier = $1;
729 assert($$->expr_type == A1TC_CLASSDEF);
730 assert($$->meta_type == AMT_OBJECT);
731 }
732 /*
733 * Parametrized <Type> declaration:
734 * === EXAMPLE ===
735 * SIGNED { ToBeSigned } ::= SEQUENCE {
736 * toBeSigned ToBeSigned,
737 * algorithm AlgorithmIdentifier,
738 * signature BIT STRING
739 * }
740 * === EOF ===
741 */
742 | TypeRefName '{' ParameterArgumentList '}'
743 TOK_PPEQ ConstrainedTypeDeclaration {
744 $$ = $6;
745 assert($$->Identifier == 0);
746 $$->Identifier = $1;
747 $$->params = $3;
748 $$->meta_type = AMT_PARAMTYPE;
749 }
750 ;
751
752ParameterArgumentList:
753 ParameterArgumentName {
754 int ret;
755 $$ = asn1p_paramlist_new(yylineno);
756 checkmem($$);
757 ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument);
758 checkmem(ret == 0);
759 if($1.governor) asn1p_ref_free($1.governor);
760 if($1.argument) free($1.argument);
761 }
762 | ParameterArgumentList ',' ParameterArgumentName {
763 int ret;
764 $$ = $1;
765 ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument);
766 checkmem(ret == 0);
767 if($3.governor) asn1p_ref_free($3.governor);
768 if($3.argument) free($3.argument);
769 }
770 ;
771
772ParameterArgumentName:
773 TypeRefName {
774 $$.governor = NULL;
775 $$.argument = $1;
776 }
777 | TypeRefName ':' Identifier {
778 int ret;
779 $$.governor = asn1p_ref_new(yylineno);
780 ret = asn1p_ref_add_component($$.governor, $1, 0);
781 checkmem(ret == 0);
782 $$.argument = $3;
783 }
784 | BasicTypeId ':' Identifier {
785 int ret;
786 $$.governor = asn1p_ref_new(yylineno);
787 ret = asn1p_ref_add_component($$.governor,
788 ASN_EXPR_TYPE2STR($1), 1);
789 checkmem(ret == 0);
790 $$.argument = $3;
791 }
792 ;
793
794ActualParameterList:
795 ActualParameter {
796 $$ = asn1p_expr_new(yylineno);
797 checkmem($$);
798 TQ_ADD(&($$->members), $1, next);
799 }
800 | ActualParameterList ',' ActualParameter {
801 $$ = $1;
802 TQ_ADD(&($$->members), $3, next);
803 }
804 ;
805
806ActualParameter:
807 TypeDeclaration {
808 $$ = $1;
809 }
810 | Identifier {
811 $$ = asn1p_expr_new(yylineno);
812 checkmem($$);
813 $$->Identifier = $1;
814 $$->expr_type = A1TC_REFERENCE;
815 $$->meta_type = AMT_VALUE;
816 }
817 ;
818
819/*
820 * A collection of constructed data type members.
821 */
822ConstructedDataTypeDefinition:
823 DataTypeMember {
824 $$ = asn1p_expr_new(yylineno);
825 checkmem($$);
826 TQ_ADD(&($$->members), $1, next);
827 }
828 | ConstructedDataTypeDefinition ',' DataTypeMember {
829 $$ = $1;
830 TQ_ADD(&($$->members), $3, next);
831 }
832 ;
833
834ClassDeclaration:
835 TOK_CLASS '{' ClassFieldList '}' optWithSyntax {
836 $$ = $3;
837 checkmem($$);
838 $$->with_syntax = $5;
839 assert($$->expr_type == A1TC_CLASSDEF);
840 assert($$->meta_type == AMT_OBJECT);
841 }
842 ;
843
844optUnique:
845 { $$ = 0; }
846 | TOK_UNIQUE { $$ = 1; }
847 ;
848
849ClassFieldList:
850 ClassField {
851 $$ = asn1p_expr_new(yylineno);
852 checkmem($$);
853 $$->expr_type = A1TC_CLASSDEF;
854 $$->meta_type = AMT_OBJECT;
855 TQ_ADD(&($$->members), $1, next);
856 }
857 | ClassFieldList ',' ClassField {
858 $$ = $1;
859 TQ_ADD(&($$->members), $3, next);
860 }
861 ;
862
863ClassField:
864 ClassFieldIdentifier optMarker {
865 $$ = asn1p_expr_new(yylineno);
866 checkmem($$);
867 $$->Identifier = $1.name;
868 $$->expr_type = A1TC_CLASSFIELD;
869 $$->meta_type = AMT_OBJECTFIELD;
870 $$->marker = $2;
871 }
872 | ClassFieldIdentifier ConstrainedTypeDeclaration optUnique {
873 $$ = $2;
874 $$->Identifier = $1.name;
875 $$->unique = $3;
876 }
877 | ClassFieldIdentifier ClassFieldIdentifier optMarker optUnique {
878 int ret;
879 $$ = asn1p_expr_new(yylineno);
880 checkmem($$);
881 $$->Identifier = $1.name;
882 $$->reference = asn1p_ref_new(yylineno);
883 checkmem($$->reference);
884 ret = asn1p_ref_add_component($$->reference,
885 $2.name, $2.lex_type);
886 checkmem(ret == 0);
887 $$->expr_type = A1TC_CLASSFIELD;
888 $$->meta_type = AMT_OBJECTFIELD;
889 $$->marker = $3;
890 $$->unique = $4;
891 }
892 ;
893
894optWithSyntax:
895 { $$ = 0; }
896 | WithSyntax {
897 $$ = $1;
898 }
899 ;
900
901WithSyntax:
902 TOK_WITH TOK_SYNTAX '{'
903 { asn1p_lexer_hack_enable_with_syntax(); }
904 WithSyntaxFormat
905 '}' {
906 $$ = $5;
907 }
908 ;
909
910WithSyntaxFormat:
911 WithSyntaxFormatToken {
912 $$ = asn1p_wsyntx_new();
913 TQ_ADD(&($$->chunks), $1, next);
914 }
915 | WithSyntaxFormat WithSyntaxFormatToken {
916 $$ = $1;
917 TQ_ADD(&($$->chunks), $2, next);
918 }
919 ;
920
921WithSyntaxFormatToken:
922 TOK_opaque {
923 $$ = asn1p_wsyntx_chunk_frombuf($1.buf, $1.len, 0);
924 }
925 | ClassFieldIdentifier {
926 asn1p_ref_t *ref;
927 int ret;
928 ref = asn1p_ref_new(yylineno);
929 checkmem(ref);
930 ret = asn1p_ref_add_component(ref, $1.name, $1.lex_type);
931 checkmem(ret == 0);
932 $$ = asn1p_wsyntx_chunk_fromref(ref, 0);
933 }
934 ;
935
936/*
937 * A data type member goes like this
938 * ===
939 * memb1 [0] Type1 { a(1), b(2) } (2)
940 * ===
941 * Therefore, we propose a split.
942 * ^^^^^^^^^ ^^^^^^^^^^
943 * ^TaggedIdentifier ^TypeDeclaration
944 * ^ConstrainedTypeDeclaration
945 */
946
947/*
948 * A member of a constructed data type ("a" or "b" in above example).
949 */
950DataTypeMember:
951 TaggedIdentifier ConstrainedTypeDeclaration {
952 $$ = $2;
953 assert($$->Identifier == 0);
954 $$->Identifier = $1.name;
955 $$->tag = $1.tag;
956 }
957 | ExtensionAndException {
958 $$ = $1;
959 }
960 ;
961
962ConstrainedTypeDeclaration:
963 TypeDeclaration optConstraints optMarker {
964 $$ = $1;
965 $$->constraints = $2;
966 $$->marker = $3;
967 }
968 ;
969
970ExtensionAndException:
971 TOK_ThreeDots {
972 $$ = asn1p_expr_new(asn1p_lineno);
973 checkmem($$);
974 $$->Identifier = strdup("...");
975 checkmem($$->Identifier);
976 $$->expr_type = A1TC_EXTENSIBLE;
977 $$->meta_type = AMT_TYPE;
978 }
979 | TOK_ThreeDots '!' DefinedValue {
980 $$ = asn1p_expr_new(asn1p_lineno);
981 checkmem($$);
982 $$->Identifier = strdup("...");
983 checkmem($$->Identifier);
984 $$->value = $3;
985 $$->expr_type = A1TC_EXTENSIBLE;
986 $$->meta_type = AMT_TYPE;
987 }
988 | TOK_ThreeDots '!' SignedNumber {
989 $$ = asn1p_expr_new(asn1p_lineno);
990 checkmem($$);
991 $$->Identifier = strdup("...");
992 $$->value = $3;
993 checkmem($$->Identifier);
994 $$->expr_type = A1TC_EXTENSIBLE;
995 $$->meta_type = AMT_TYPE;
996 }
997 ;
998
999TypeDeclaration:
1000 BasicType {
1001 $$ = $1;
1002 }
1003 | BasicString {
1004 $$ = asn1p_expr_new(yylineno);
1005 checkmem($$);
1006 $$->expr_type = $1;
1007 $$->meta_type = AMT_TYPE;
1008 }
1009 | ConstructedType {
1010 $$ = $1;
1011 checkmem($$);
1012 assert($$->meta_type);
1013 }
1014 /*
1015 * A parametrized assignment.
1016 */
1017 | TypeRefName '{' ActualParameterList '}' {
1018 int ret;
1019 $$ = $3;
1020 assert($$->expr_type == 0);
1021 assert($$->meta_type == 0);
1022 assert($$->reference == 0);
1023 $$->reference = asn1p_ref_new(yylineno);
1024 checkmem($$->reference);
1025 ret = asn1p_ref_add_component($$->reference, $1, RLT_UNKNOWN);
1026 checkmem(ret == 0);
1027 free($1);
1028 $$->expr_type = A1TC_PARAMETRIZED;
1029 $$->meta_type = AMT_TYPE;
1030 }
1031 /*
1032 * A DefinedType reference.
1033 * "CLASS1.&id.&id2"
1034 * or
1035 * "Module.Type"
1036 * or
1037 * "Module.identifier"
1038 * or
1039 * "Type"
1040 */
1041 | ComplexTypeReference {
1042 $$ = asn1p_expr_new(yylineno);
1043 checkmem($$);
1044 $$->reference = $1;
1045 $$->expr_type = A1TC_REFERENCE;
1046 $$->meta_type = AMT_TYPEREF;
1047 }
1048 | TOK_INSTANCE TOK_OF ComplexTypeReference {
1049 $$ = asn1p_expr_new(yylineno);
1050 checkmem($$);
1051 $$->reference = $3;
1052 $$->expr_type = A1TC_INSTANCE;
1053 $$->meta_type = AMT_TYPE;
1054 }
1055 ;
1056
1057/*
1058 * A type name consisting of several components.
1059 * === EXAMPLE ===
1060 * === EOF ===
1061 */
1062ComplexTypeReference:
1063 TOK_typereference {
1064 int ret;
1065 $$ = asn1p_ref_new(yylineno);
1066 checkmem($$);
1067 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1068 checkmem(ret == 0);
1069 free($1);
1070 }
1071 | TOK_typereference '.' TypeRefName {
1072 int ret;
1073 $$ = asn1p_ref_new(yylineno);
1074 checkmem($$);
1075 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1076 checkmem(ret == 0);
1077 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1078 checkmem(ret == 0);
1079 free($1);
1080 }
1081 | TOK_typereference '.' Identifier {
1082 int ret;
1083 $$ = asn1p_ref_new(yylineno);
1084 checkmem($$);
1085 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1086 checkmem(ret == 0);
1087 ret = asn1p_ref_add_component($$, $3, RLT_lowercase);
1088 checkmem(ret == 0);
1089 free($1);
1090 }
1091 | ObjectClassReference {
1092 int ret;
1093 $$ = asn1p_ref_new(yylineno);
1094 checkmem($$);
1095 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1096 free($1);
1097 checkmem(ret == 0);
1098 }
1099 | ObjectClassReference '.' ComplexTypeReferenceAmpList {
1100 int ret;
1101 $$ = $3;
1102 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1103 free($1);
1104 checkmem(ret == 0);
1105 /*
1106 * Move the last element infront.
1107 */
1108 {
1109 struct asn1p_ref_component_s tmp_comp;
1110 tmp_comp = $$->components[$$->comp_count-1];
1111 memmove(&$$->components[1],
1112 &$$->components[0],
1113 sizeof($$->components[0])
1114 * ($$->comp_count - 1));
1115 $$->components[0] = tmp_comp;
1116 }
1117 }
1118 ;
1119
1120ComplexTypeReferenceAmpList:
1121 ComplexTypeReferenceElement {
1122 int ret;
1123 $$ = asn1p_ref_new(yylineno);
1124 checkmem($$);
1125 ret = asn1p_ref_add_component($$, $1.name, $1.lex_type);
1126 free($1.name);
1127 checkmem(ret == 0);
1128 }
1129 | ComplexTypeReferenceAmpList '.' ComplexTypeReferenceElement {
1130 int ret;
1131 $$ = $1;
1132 ret = asn1p_ref_add_component($$, $3.name, $3.lex_type);
1133 free($3.name);
1134 checkmem(ret == 0);
1135 }
1136 ;
1137
1138ComplexTypeReferenceElement: ClassFieldName;
1139ClassFieldIdentifier: ClassFieldName;
1140
1141ClassFieldName:
1142 /* "&Type1" */
1143 TOK_typefieldreference {
1144 $$.lex_type = RLT_AmpUppercase;
1145 $$.name = $1;
1146 }
1147 /* "&id" */
1148 | TOK_valuefieldreference {
1149 $$.lex_type = RLT_Amplowercase;
1150 $$.name = $1;
1151 }
1152 ;
1153
1154
1155/*
1156 * === EXAMPLE ===
1157 * value INTEGER ::= 1
1158 * === EOF ===
1159 */
1160ValueDefinition:
1161 Identifier DefinedTypeRef TOK_PPEQ InlineOrDefinedValue {
1162 $$ = $2;
1163 assert($$->Identifier == NULL);
1164 $$->Identifier = $1;
1165 $$->meta_type = AMT_VALUE;
1166 $$->value = $4;
1167 }
1168 ;
1169
1170InlineOrDefinedValue:
1171 '{' { asn1p_lexer_hack_push_opaque_state(); }
1172 Opaque /* '}' */ {
1173 $$ = asn1p_value_frombuf($3.buf, $3.len, 0);
1174 checkmem($$);
1175 $$->type = ATV_UNPARSED;
1176 }
1177 | TOK_bstring {
1178 $$ = _convert_bitstring2binary($1, 'B');
1179 checkmem($$);
1180 }
1181 | TOK_hstring {
1182 $$ = _convert_bitstring2binary($1, 'H');
1183 checkmem($$);
1184 }
1185 | TOK_cstring {
1186 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1187 checkmem($$);
1188 }
1189 | SignedNumber {
1190 $$ = $1;
1191 }
1192 | DefinedValue {
1193 $$ = $1;
1194 }
1195 ;
1196
1197DefinedValue:
1198 Identifier {
1199 asn1p_ref_t *ref;
1200 int ret;
1201 ref = asn1p_ref_new(yylineno);
1202 checkmem(ref);
1203 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1204 checkmem(ret == 0);
1205 $$ = asn1p_value_fromref(ref, 0);
1206 checkmem($$);
1207 free($1);
1208 }
1209 | TypeRefName '.' Identifier {
1210 asn1p_ref_t *ref;
1211 int ret;
1212 ref = asn1p_ref_new(yylineno);
1213 checkmem(ref);
1214 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1215 checkmem(ret == 0);
1216 ret = asn1p_ref_add_component(ref, $3, RLT_lowercase);
1217 checkmem(ret == 0);
1218 $$ = asn1p_value_fromref(ref, 0);
1219 checkmem($$);
1220 free($1);
1221 free($3);
1222 }
1223 ;
1224
1225Opaque:
1226 TOK_opaque {
1227 $$.len = $1.len + 2;
1228 $$.buf = malloc($$.len + 1);
1229 checkmem($$.buf);
1230 $$.buf[0] = '{';
1231 $$.buf[1] = ' ';
1232 memcpy($$.buf + 2, $1.buf, $1.len);
1233 $$.buf[$$.len] = '\0';
1234 free($1.buf);
1235 }
1236 | Opaque TOK_opaque {
1237 int newsize = $1.len + $2.len;
1238 char *p = malloc(newsize + 1);
1239 checkmem(p);
1240 memcpy(p , $1.buf, $1.len);
1241 memcpy(p + $1.len, $2.buf, $2.len);
1242 p[newsize] = '\0';
1243 free($1.buf);
1244 free($2.buf);
1245 $$.buf = p;
1246 $$.len = newsize;
1247 }
1248 ;
1249
1250BasicTypeId:
1251 TOK_BOOLEAN { $$ = ASN_BASIC_BOOLEAN; }
1252 | TOK_NULL { $$ = ASN_BASIC_NULL; }
1253 | TOK_REAL { $$ = ASN_BASIC_REAL; }
1254 | BasicTypeId_UniverationCompatible { $$ = $1; }
1255 | TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; }
1256 | TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; }
1257 | TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; }
1258 | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; }
1259 | TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; }
1260 | TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; }
1261 | TOK_UTCTime { $$ = ASN_BASIC_UTCTime; }
1262 | TOK_GeneralizedTime { $$ = ASN_BASIC_GeneralizedTime; }
1263 ;
1264
1265/*
1266 * A type identifier which may be used with "{ a(1), b(2) }" clause.
1267 */
1268BasicTypeId_UniverationCompatible:
1269 TOK_INTEGER { $$ = ASN_BASIC_INTEGER; }
1270 | TOK_ENUMERATED { $$ = ASN_BASIC_ENUMERATED; }
1271 | TOK_BIT TOK_STRING { $$ = ASN_BASIC_BIT_STRING; }
1272 ;
1273
1274BasicType:
1275 BasicTypeId {
1276 $$ = asn1p_expr_new(asn1p_lineno);
1277 checkmem($$);
1278 $$->expr_type = $1;
1279 $$->meta_type = AMT_TYPE;
1280 }
1281 | BasicTypeId_UniverationCompatible UniverationDefinition {
1282 if($2) {
1283 $$ = $2;
1284 } else {
1285 $$ = asn1p_expr_new(asn1p_lineno);
1286 checkmem($$);
1287 }
1288 $$->expr_type = $1;
1289 $$->meta_type = AMT_TYPE;
1290 }
1291 ;
1292
1293BasicString:
1294 TOK_BMPString { $$ = ASN_STRING_BMPString; }
1295 | TOK_GeneralString {
1296 $$ = ASN_STRING_GeneralString;
1297 return yyerror("GeneralString is not supported");
1298 }
1299 | TOK_GraphicString {
1300 $$ = ASN_STRING_GraphicString;
1301 return yyerror("GraphicString is not supported");
1302 }
1303 | TOK_IA5String { $$ = ASN_STRING_IA5String; }
1304 | TOK_ISO646String { $$ = ASN_STRING_ISO646String; }
1305 | TOK_NumericString { $$ = ASN_STRING_NumericString; }
1306 | TOK_PrintableString { $$ = ASN_STRING_PrintableString; }
1307 | TOK_T61String {
1308 $$ = ASN_STRING_T61String;
1309 return yyerror("T61String not implemented yet");
1310 }
1311 | TOK_TeletexString { $$ = ASN_STRING_TeletexString; }
1312 | TOK_UniversalString { $$ = ASN_STRING_UniversalString; }
1313 | TOK_UTF8String { $$ = ASN_STRING_UTF8String; }
1314 | TOK_VideotexString {
1315 $$ = ASN_STRING_VideotexString;
1316 return yyerror("VideotexString is no longer supported");
1317 }
1318 | TOK_VisibleString { $$ = ASN_STRING_VisibleString; }
1319 | TOK_ObjectDescriptor { $$ = ASN_STRING_ObjectDescriptor; }
1320 ;
1321
1322ConstructedType:
1323 TOK_CHOICE '{' ConstructedDataTypeDefinition '}' {
1324 $$ = $3;
1325 assert($$->expr_type == A1TC_INVALID);
1326 $$->expr_type = ASN_CONSTR_CHOICE;
1327 $$->meta_type = AMT_TYPE;
1328 }
1329 | TOK_SEQUENCE '{' ConstructedDataTypeDefinition '}' {
1330 $$ = $3;
1331 assert($$->expr_type == A1TC_INVALID);
1332 $$->expr_type = ASN_CONSTR_SEQUENCE;
1333 $$->meta_type = AMT_TYPE;
1334 }
1335 | TOK_SET '{' ConstructedDataTypeDefinition '}' {
1336 $$ = $3;
1337 assert($$->expr_type == A1TC_INVALID);
1338 $$->expr_type = ASN_CONSTR_SET;
1339 $$->meta_type = AMT_TYPE;
1340 }
1341 | TOK_SEQUENCE optConstraints TOK_OF TypeDeclaration {
1342 $$ = asn1p_expr_new(asn1p_lineno);
1343 checkmem($$);
1344 $$->constraints = $2;
1345 $$->expr_type = ASN_CONSTR_SEQUENCE_OF;
1346 $$->meta_type = AMT_TYPE;
1347 TQ_ADD(&($$->members), $4, next);
1348 }
1349 | TOK_SET optConstraints TOK_OF TypeDeclaration {
1350 $$ = asn1p_expr_new(asn1p_lineno);
1351 checkmem($$);
1352 $$->constraints = $2;
1353 $$->expr_type = ASN_CONSTR_SET_OF;
1354 $$->meta_type = AMT_TYPE;
1355 TQ_ADD(&($$->members), $4, next);
1356 }
1357 | TOK_ANY {
1358 $$ = asn1p_expr_new(asn1p_lineno);
1359 checkmem($$);
1360 $$->expr_type = ASN_CONSTR_ANY;
1361 $$->meta_type = AMT_TYPE;
1362 }
1363 | TOK_ANY TOK_DEFINED TOK_BY Identifier {
1364 int ret;
1365 $$ = asn1p_expr_new(asn1p_lineno);
1366 checkmem($$);
1367 $$->reference = asn1p_ref_new(yylineno);
1368 ret = asn1p_ref_add_component($$->reference,
1369 $4, RLT_lowercase);
1370 checkmem(ret == 0);
1371 $$->expr_type = ASN_CONSTR_ANY;
1372 $$->meta_type = AMT_TYPE;
1373 }
1374 ;
1375
1376/*
1377 * Data type constraints.
1378 */
Lev Walkinf15320b2004-06-03 03:38:44 +00001379Union: '|' | TOK_UNION;
1380Intersection: '^' | TOK_INTERSECTION;
1381Except: TOK_EXCEPT;
1382
Lev Walkinf59d0752004-08-18 04:59:12 +00001383optConstraints:
1384 { $$ = 0; }
1385 | SetOfConstraints {
1386 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, 0);
1387 }
1388 | TOK_SIZE '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001389 /*
1390 * This is a special case, for compatibility purposes.
Lev Walkinf59d0752004-08-18 04:59:12 +00001391 * It goes without parentheses.
Lev Walkinf15320b2004-06-03 03:38:44 +00001392 */
1393 int ret;
1394 $$ = asn1p_constraint_new(yylineno);
1395 checkmem($$);
1396 $$->type = ACT_CT_SIZE;
1397 ret = asn1p_constraint_insert($$, $3);
1398 checkmem(ret == 0);
1399 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001400 ;
1401
Lev Walkinf59d0752004-08-18 04:59:12 +00001402SetOfConstraints:
1403 '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001404 $$ = $2;
1405 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001406 | SetOfConstraints '(' ElementSetSpecs ')' {
1407 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $3);
1408 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001409 ;
1410
Lev Walkinf59d0752004-08-18 04:59:12 +00001411ElementSetSpecs:
1412 ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001413 $$ = $1;
1414 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001415 | ElementSetSpec ',' TOK_ThreeDots {
Lev Walkinf15320b2004-06-03 03:38:44 +00001416 asn1p_constraint_t *ct;
1417 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001418 ct->type = ACT_EL_EXT;
1419 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1420 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001421 | ElementSetSpec ',' TOK_ThreeDots ',' ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001422 asn1p_constraint_t *ct;
1423 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001424 ct->type = ACT_EL_EXT;
1425 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
Lev Walkinb4fcdd22004-08-13 12:35:09 +00001426 ct = $$;
1427 CONSTRAINT_INSERT($$, ACT_CA_CSV, ct, $5);
Lev Walkinf15320b2004-06-03 03:38:44 +00001428 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001429 ;
1430
Lev Walkinf59d0752004-08-18 04:59:12 +00001431ElementSetSpec:
1432 ConstraintSubtypeElement {
1433 $$ = $1;
1434 }
1435 | ElementSetSpec Union ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001436 CONSTRAINT_INSERT($$, ACT_CA_UNI, $1, $3);
1437 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001438 | ElementSetSpec Intersection ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001439 CONSTRAINT_INSERT($$, ACT_CA_INT, $1, $3);
1440 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001441 | ConstraintSubtypeElement Except ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001442 CONSTRAINT_INSERT($$, ACT_CA_EXC, $1, $3);
1443 }
1444 ;
1445
1446ConstraintSubtypeElement:
Lev Walkinf59d0752004-08-18 04:59:12 +00001447 ConstraintSpec '(' ElementSetSpecs ')' {
1448 int ret;
1449 $$ = asn1p_constraint_new(yylineno);
1450 checkmem($$);
1451 $$->type = $1;
1452 ret = asn1p_constraint_insert($$, $3);
1453 checkmem(ret == 0);
1454 }
1455 | '(' ElementSetSpecs ')' {
1456 int ret;
1457 $$ = asn1p_constraint_new(yylineno);
1458 checkmem($$);
1459 $$->type = ACT_CA_SET;
1460 ret = asn1p_constraint_insert($$, $2);
1461 checkmem(ret == 0);
1462 }
1463 | ConstraintValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001464 $$ = asn1p_constraint_new(yylineno);
1465 checkmem($$);
1466 $$->type = ACT_EL_VALUE;
1467 $$->value = $1;
1468 }
1469 | ConstraintValue ConstraintRangeSpec ConstraintValue {
1470 $$ = asn1p_constraint_new(yylineno);
1471 checkmem($$);
1472 $$->type = $2;
1473 $$->range_start = $1;
1474 $$->range_stop = $3;
1475 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001476 | TOK_MIN ConstraintRangeSpec ConstraintValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001477 $$ = asn1p_constraint_new(yylineno);
1478 checkmem($$);
Lev Walkinf59d0752004-08-18 04:59:12 +00001479 $$->type = $2;
1480 $$->range_start = asn1p_value_fromint(-123);
1481 $$->range_stop = $3;
1482 $$->range_start->type = ATV_MIN;
1483 }
1484 | ConstraintValue ConstraintRangeSpec TOK_MAX {
1485 $$ = asn1p_constraint_new(yylineno);
1486 checkmem($$);
1487 $$->type = $2;
1488 $$->range_start = $1;
1489 $$->range_stop = asn1p_value_fromint(321);
1490 $$->range_stop->type = ATV_MAX;
1491 }
1492 | TOK_MIN ConstraintRangeSpec TOK_MAX {
1493 $$ = asn1p_constraint_new(yylineno);
1494 checkmem($$);
1495 $$->type = $2;
1496 $$->range_start = asn1p_value_fromint(-123);
1497 $$->range_stop = asn1p_value_fromint(321);
1498 $$->range_start->type = ATV_MIN;
1499 $$->range_stop->type = ATV_MAX;
Lev Walkinf15320b2004-06-03 03:38:44 +00001500 }
1501 | TableConstraint {
1502 $$ = $1;
1503 }
1504 | WithComponents {
1505 $$ = $1;
1506 }
1507 ;
1508
1509ConstraintRangeSpec:
1510 TOK_TwoDots { $$ = ACT_EL_RANGE; }
1511 | TOK_TwoDots '<' { $$ = ACT_EL_RLRANGE; }
1512 | '<' TOK_TwoDots { $$ = ACT_EL_LLRANGE; }
1513 | '<' TOK_TwoDots '<' { $$ = ACT_EL_ULRANGE; }
1514 ;
1515
1516ConstraintSpec:
1517 TOK_SIZE {
1518 $$ = ACT_CT_SIZE;
1519 }
1520 | TOK_FROM {
1521 $$ = ACT_CT_FROM;
1522 }
1523 ;
1524
1525ConstraintValue:
1526 SignedNumber {
1527 $$ = $1;
1528 }
1529 | Identifier {
1530 asn1p_ref_t *ref;
1531 int ret;
1532 ref = asn1p_ref_new(yylineno);
1533 checkmem(ref);
1534 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1535 checkmem(ret == 0);
1536 $$ = asn1p_value_fromref(ref, 0);
1537 checkmem($$);
1538 free($1);
1539 }
1540 | TOK_cstring {
1541 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1542 checkmem($$);
1543 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001544
Lev Walkinf15320b2004-06-03 03:38:44 +00001545 | TOK_FALSE {
1546 $$ = asn1p_value_fromint(0);
1547 checkmem($$);
1548 $$->type = ATV_FALSE;
1549 }
1550 | TOK_TRUE {
1551 $$ = asn1p_value_fromint(1);
1552 checkmem($$);
1553 $$->type = ATV_TRUE;
1554 }
1555 ;
1556
1557WithComponents:
1558 TOK_WITH TOK_COMPONENTS '{' WithComponentsList '}' {
1559 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $4, 0);
1560 }
1561 ;
1562
1563WithComponentsList:
1564 WithComponentsElement {
1565 $$ = $1;
1566 }
1567 | WithComponentsList ',' WithComponentsElement {
1568 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $1, $3);
1569 }
1570 ;
1571
1572WithComponentsElement:
1573 TOK_ThreeDots {
1574 $$ = asn1p_constraint_new(yylineno);
1575 checkmem($$);
1576 $$->type = ACT_EL_EXT;
1577 }
1578 | Identifier optConstraints optPresenceConstraint {
1579 $$ = asn1p_constraint_new(yylineno);
1580 checkmem($$);
1581 $$->type = ACT_EL_VALUE;
1582 $$->value = asn1p_value_frombuf($1, strlen($1), 0);
1583 $$->presence = $3;
1584 }
1585 ;
1586
1587/*
1588 * presence constraint for WithComponents
1589 */
1590optPresenceConstraint:
1591 { $$ = ACPRES_DEFAULT; }
1592 | PresenceConstraint { $$ = $1; }
1593 ;
1594
1595PresenceConstraint:
1596 TOK_PRESENT {
1597 $$ = ACPRES_PRESENT;
1598 }
1599 | TOK_ABSENT {
1600 $$ = ACPRES_ABSENT;
1601 }
1602 | TOK_OPTIONAL {
1603 $$ = ACPRES_OPTIONAL;
1604 }
1605 ;
1606
1607TableConstraint:
1608 SimpleTableConstraint {
1609 $$ = $1;
1610 }
1611 | ComponentRelationConstraint {
1612 $$ = $1;
1613 }
1614 ;
1615
1616/*
1617 * "{ExtensionSet}"
1618 */
1619SimpleTableConstraint:
1620 '{' TypeRefName '}' {
1621 asn1p_ref_t *ref = asn1p_ref_new(yylineno);
1622 asn1p_constraint_t *ct;
1623 int ret;
1624 ret = asn1p_ref_add_component(ref, $2, 0);
1625 checkmem(ret == 0);
1626 ct = asn1p_constraint_new(yylineno);
1627 checkmem($$);
1628 ct->type = ACT_EL_VALUE;
1629 ct->value = asn1p_value_fromref(ref, 0);
1630 CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0);
1631 }
1632 ;
1633
1634ComponentRelationConstraint:
1635 SimpleTableConstraint '{' AtNotationList '}' {
1636 CONSTRAINT_INSERT($$, ACT_CA_CRC, $1, $3);
1637 }
1638 ;
1639
1640AtNotationList:
1641 AtNotationElement {
1642 $$ = asn1p_constraint_new(yylineno);
1643 checkmem($$);
1644 $$->type = ACT_EL_VALUE;
1645 $$->value = asn1p_value_fromref($1, 0);
1646 }
1647 | AtNotationList ',' AtNotationElement {
1648 asn1p_constraint_t *ct;
1649 ct = asn1p_constraint_new(yylineno);
1650 checkmem(ct);
1651 ct->type = ACT_EL_VALUE;
1652 ct->value = asn1p_value_fromref($3, 0);
1653 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1654 }
1655 ;
1656
1657/*
1658 * @blah
1659 */
1660AtNotationElement:
1661 '@' ComponentIdList {
1662 char *p = malloc(strlen($2) + 2);
1663 int ret;
1664 *p = '@';
1665 strcpy(p + 1, $2);
1666 $$ = asn1p_ref_new(yylineno);
1667 ret = asn1p_ref_add_component($$, p, 0);
1668 checkmem(ret == 0);
1669 free(p);
1670 free($2);
1671 }
1672 | '@' '.' ComponentIdList {
1673 char *p = malloc(strlen($3) + 3);
1674 int ret;
1675 p[0] = '@';
1676 p[1] = '.';
1677 strcpy(p + 2, $3);
1678 $$ = asn1p_ref_new(yylineno);
1679 ret = asn1p_ref_add_component($$, p, 0);
1680 checkmem(ret == 0);
1681 free(p);
1682 free($3);
1683 }
1684 ;
1685
1686/* identifier "." ... */
1687ComponentIdList:
1688 Identifier {
1689 $$ = $1;
1690 }
1691 | ComponentIdList '.' Identifier {
1692 int l1 = strlen($1);
1693 int l3 = strlen($3);
1694 $$ = malloc(l1 + 1 + l3 + 1);
1695 memcpy($$, $1, l1);
1696 $$[l1] = '.';
1697 memcpy($$ + l1 + 1, $3, l3);
1698 $$[l1 + 1 + l3] = '\0';
1699 }
1700 ;
1701
1702
1703
1704/*
1705 * MARKERS
1706 */
1707
1708optMarker:
1709 { $$ = EM_NOMARK; }
1710 | Marker { $$ = $1; }
1711 ;
1712
1713Marker:
1714 TOK_OPTIONAL {
1715 $$ = EM_OPTIONAL;
1716 }
1717 | TOK_DEFAULT DefaultValue {
1718 $$ = EM_DEFAULT;
1719 /* FIXME: store DefaultValue somewhere */
1720 }
1721 ;
1722
1723DefaultValue:
1724 ConstraintValue {
1725 }
1726 | BasicTypeId {
1727 }
1728 | '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
1729 }
1730 ;
1731
1732/*
1733 * Universal enumeration definition to use in INTEGER and ENUMERATED.
1734 * === EXAMPLE ===
1735 * Gender ::= ENUMERATED { unknown(0), male(1), female(2) }
1736 * Temperature ::= INTEGER { absolute-zero(-273), freezing(0), boiling(100) }
1737 * === EOF ===
1738 */
1739/*
1740optUniverationDefinition:
1741 { $$ = 0; }
1742 | UniverationDefinition {
1743 $$ = $1;
1744 }
1745 ;
1746*/
1747
1748UniverationDefinition:
1749 '{' '}' {
1750 $$ = asn1p_expr_new(asn1p_lineno);
1751 checkmem($$);
1752 }
1753 | '{' UniverationList '}' {
1754 $$ = $2;
1755 }
1756 ;
1757
1758UniverationList:
1759 UniverationElement {
1760 $$ = asn1p_expr_new(asn1p_lineno);
1761 checkmem($$);
1762 TQ_ADD(&($$->members), $1, next);
1763 }
1764 | UniverationList ',' UniverationElement {
1765 $$ = $1;
1766 TQ_ADD(&($$->members), $3, next);
1767 }
1768 ;
1769
1770UniverationElement:
1771 Identifier {
1772 $$ = asn1p_expr_new(asn1p_lineno);
1773 checkmem($$);
1774 $$->expr_type = A1TC_UNIVERVAL;
1775 $$->meta_type = AMT_VALUE;
1776 $$->Identifier = $1;
1777 }
1778 | Identifier '(' SignedNumber ')' {
1779 $$ = asn1p_expr_new(asn1p_lineno);
1780 checkmem($$);
1781 $$->expr_type = A1TC_UNIVERVAL;
1782 $$->meta_type = AMT_VALUE;
1783 $$->Identifier = $1;
1784 $$->value = $3;
1785 }
1786 | Identifier '(' DefinedValue ')' {
1787 $$ = asn1p_expr_new(asn1p_lineno);
1788 checkmem($$);
1789 $$->expr_type = A1TC_UNIVERVAL;
1790 $$->meta_type = AMT_VALUE;
1791 $$->Identifier = $1;
1792 $$->value = $3;
1793 }
1794 | SignedNumber {
1795 $$ = asn1p_expr_new(asn1p_lineno);
1796 checkmem($$);
1797 $$->expr_type = A1TC_UNIVERVAL;
1798 $$->meta_type = AMT_VALUE;
1799 $$->value = $1;
1800 }
1801 | TOK_ThreeDots {
1802 $$ = asn1p_expr_new(asn1p_lineno);
1803 checkmem($$);
1804 $$->Identifier = strdup("...");
1805 checkmem($$->Identifier);
1806 $$->expr_type = A1TC_EXTENSIBLE;
1807 $$->meta_type = AMT_VALUE;
1808 }
1809 ;
1810
1811SignedNumber:
1812 TOK_number {
1813 $$ = asn1p_value_fromint($1);
1814 checkmem($$);
1815 }
1816 | TOK_number_negative {
1817 $$ = asn1p_value_fromint($1);
1818 checkmem($$);
1819 }
1820 ;
1821
1822/*
1823 * SEQUENCE definition.
1824 * === EXAMPLE ===
1825 * Struct1 ::= SEQUENCE {
1826 * memb1 Struct2,
1827 * memb2 SEQUENCE OF {
1828 * memb2-1 Struct 3
1829 * }
1830 * }
1831 * === EOF ===
1832 */
1833
1834
1835
1836/*
1837 * SET definition.
1838 * === EXAMPLE ===
1839 * Person ::= SET {
1840 * name [0] PrintableString (SIZE(1..20)),
1841 * country [1] PrintableString (SIZE(1..20)) DEFAULT default-country,
1842 * }
1843 * === EOF ===
1844 */
1845
1846optTag:
1847 { memset(&$$, 0, sizeof($$)); }
1848 | Tag { $$ = $1; }
1849 ;
1850
1851Tag:
1852 TOK_tag {
1853 $$ = $1;
1854 $$.tag_mode = TM_DEFAULT;
1855 }
1856 | TOK_tag TOK_IMPLICIT {
1857 $$ = $1;
1858 $$.tag_mode = TM_IMPLICIT;
1859 }
1860 | TOK_tag TOK_EXPLICIT {
1861 $$ = $1;
1862 $$.tag_mode = TM_EXPLICIT;
1863 }
1864 ;
1865
1866TypeRefName:
1867 TOK_typereference {
1868 checkmem($1);
1869 $$ = $1;
1870 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001871 | TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00001872 checkmem($1);
1873 $$ = $1;
1874 }
1875 ;
1876
Lev Walkinf59d0752004-08-18 04:59:12 +00001877
Lev Walkinf15320b2004-06-03 03:38:44 +00001878ObjectClassReference:
Lev Walkinf59d0752004-08-18 04:59:12 +00001879 TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00001880 checkmem($1);
1881 $$ = $1;
1882 }
1883 ;
1884
1885Identifier:
1886 TOK_identifier {
1887 checkmem($1);
1888 $$ = $1;
1889 }
1890 ;
1891
1892TaggedIdentifier:
1893 Identifier {
1894 memset(&$$, 0, sizeof($$));
1895 $$.name = $1;
1896 }
1897 | Identifier Tag {
1898 $$.name = $1;
1899 $$.tag = $2;
1900 }
1901 ;
1902
1903
1904%%
1905
1906
1907/*
1908 * Convert Xstring ('0101'B or '5'H) to the binary vector.
1909 */
1910static asn1p_value_t *
1911_convert_bitstring2binary(char *str, int base) {
1912 asn1p_value_t *val;
1913 int slen;
1914 int memlen;
1915 int baselen;
1916 int bits;
1917 uint8_t *binary_vector;
1918 uint8_t *bv_ptr;
1919 uint8_t cur_val;
1920
1921 assert(str);
1922 assert(str[0] == '\'');
1923
1924 switch(base) {
1925 case 'B':
1926 baselen = 1;
1927 break;
1928 case 'H':
1929 baselen = 4;
1930 break;
1931 default:
1932 assert(base == 'B' || base == 'H');
1933 errno = EINVAL;
1934 return NULL;
1935 }
1936
1937 slen = strlen(str);
1938 assert(str[slen - 1] == base);
1939 assert(str[slen - 2] == '\'');
1940
1941 memlen = slen / (8 / baselen); /* Conservative estimate */
1942
1943 bv_ptr = binary_vector = malloc(memlen + 1);
1944 if(bv_ptr == NULL)
1945 /* ENOMEM */
1946 return NULL;
1947
1948 cur_val = 0;
1949 bits = 0;
1950 while(*(++str) != '\'') {
1951 switch(baselen) {
1952 case 1:
1953 switch(*str) {
1954 case '1':
1955 cur_val |= 1 << (7 - (bits % 8));
1956 case '0':
1957 break;
1958 default:
1959 assert(!"_y UNREACH1");
1960 case ' ': case '\r': case '\n':
1961 continue;
1962 }
1963 break;
1964 case 4:
1965 switch(*str) {
1966 case '0': case '1': case '2': case '3': case '4':
1967 case '5': case '6': case '7': case '8': case '9':
1968 cur_val |= (*str - '0') << (4 - (bits % 8));
1969 break;
1970 case 'A': case 'B': case 'C':
1971 case 'D': case 'E': case 'F':
1972 cur_val |= ((*str - 'A') + 10)
1973 << (4 - (bits % 8));
1974 break;
1975 default:
1976 assert(!"_y UNREACH2");
1977 case ' ': case '\r': case '\n':
1978 continue;
1979 }
1980 break;
1981 }
1982
1983 bits += baselen;
1984 if((bits % 8) == 0) {
1985 *bv_ptr++ = cur_val;
1986 cur_val = 0;
1987 }
1988 }
1989
1990 *bv_ptr = cur_val;
1991 assert((bv_ptr - binary_vector) <= memlen);
1992
1993 val = asn1p_value_frombits(binary_vector, bits, 0);
1994 if(val == NULL) {
1995 free(binary_vector);
1996 }
1997
1998 return val;
1999}
2000
2001extern char *asn1p_text;
2002
2003int
2004yyerror(const char *msg) {
2005 fprintf(stderr,
2006 "ASN.1 grammar parse error "
2007 "near line %d (token \"%s\"): %s\n",
2008 asn1p_lineno, asn1p_text, msg);
2009 return -1;
2010}
2011
2012