blob: b6be6f6f6b315af74668d85961bd31cc6c472001 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001%{
2
3#include <stdlib.h>
4#include <stdio.h>
5#include <string.h>
6#include <errno.h>
7#include <assert.h>
8
9#include "asn1parser.h"
10
11#define YYPARSE_PARAM param
12#define YYERROR_VERBOSE
13
14int yylex(void);
15int yyerror(const char *msg);
16void asn1p_lexer_hack_push_opaque_state(void);
17void asn1p_lexer_hack_enable_with_syntax(void);
Lev Walkinf59d0752004-08-18 04:59:12 +000018void asn1p_lexer_hack_push_encoding_control(void);
Lev Walkinf15320b2004-06-03 03:38:44 +000019#define yylineno asn1p_lineno
20extern int asn1p_lineno;
21
22
23static asn1p_value_t *
24 _convert_bitstring2binary(char *str, int base);
25
Lev Walkin1004aa92004-09-08 00:28:11 +000026#define checkmem(ptr) do { \
27 if(!(ptr)) \
28 return yyerror("Memory failure"); \
Lev Walkinf15320b2004-06-03 03:38:44 +000029 } while(0)
30
31#define CONSTRAINT_INSERT(root, constr_type, arg1, arg2) do { \
32 if(arg1->type != constr_type) { \
33 int __ret; \
34 root = asn1p_constraint_new(yylineno); \
35 checkmem(root); \
36 root->type = constr_type; \
37 __ret = asn1p_constraint_insert(root, \
38 arg1); \
39 checkmem(__ret == 0); \
40 } else { \
41 root = arg1; \
42 } \
43 if(arg2) { \
44 int __ret \
45 = asn1p_constraint_insert(root, arg2); \
46 checkmem(__ret == 0); \
47 } \
48 } while(0)
49
50%}
51
52
53/*
54 * Token value definition.
55 * a_*: ASN-specific types.
56 * tv_*: Locally meaningful types.
57 */
58%union {
59 asn1p_t *a_grammar;
60 asn1p_module_flags_e a_module_flags;
61 asn1p_module_t *a_module;
62 asn1p_expr_type_e a_type; /* ASN.1 Type */
63 asn1p_expr_t *a_expr; /* Constructed collection */
64 asn1p_constraint_t *a_constr; /* Constraint */
65 enum asn1p_constraint_type_e a_ctype;/* Constraint type */
66 asn1p_xports_t *a_xports; /* IMports/EXports */
67 asn1p_oid_t *a_oid; /* Object Identifier */
68 asn1p_oid_arc_t a_oid_arc; /* Single OID's arc */
69 struct asn1p_type_tag_s a_tag; /* A tag */
70 asn1p_ref_t *a_ref; /* Reference to custom type */
71 asn1p_wsyntx_t *a_wsynt; /* WITH SYNTAX contents */
72 asn1p_wsyntx_chunk_t *a_wchunk; /* WITH SYNTAX chunk */
73 struct asn1p_ref_component_s a_refcomp; /* Component of a reference */
74 asn1p_value_t *a_value; /* Number, DefinedValue, etc */
75 struct asn1p_param_s a_parg; /* A parameter argument */
76 asn1p_paramlist_t *a_plist; /* A pargs list */
Lev Walkin9c974182004-09-15 11:59:51 +000077 struct asn1p_expr_marker_s a_marker; /* OPTIONAL/DEFAULT */
Lev Walkinf15320b2004-06-03 03:38:44 +000078 enum asn1p_constr_pres_e a_pres; /* PRESENT/ABSENT/OPTIONAL */
Lev Walkin144db9b2004-10-12 23:26:53 +000079 asn1c_integer_t a_int;
Lev Walkinf15320b2004-06-03 03:38:44 +000080 char *tv_str;
81 struct {
82 char *buf;
83 int len;
84 } tv_opaque;
85 struct {
86 char *name;
87 struct asn1p_type_tag_s tag;
88 } tv_nametag;
89};
90
91/*
92 * Token types returned by scanner.
93 */
94%token TOK_PPEQ /* "::=", Pseudo Pascal EQuality */
95%token <tv_opaque> TOK_opaque /* opaque data (driven from .y) */
96%token <tv_str> TOK_bstring
97%token <tv_opaque> TOK_cstring
98%token <tv_str> TOK_hstring
99%token <tv_str> TOK_identifier
100%token <a_int> TOK_number
101%token <a_int> TOK_number_negative
102%token <tv_str> TOK_typereference
Lev Walkinf59d0752004-08-18 04:59:12 +0000103%token <tv_str> TOK_capitalreference /* "CLASS1" */
Lev Walkinf15320b2004-06-03 03:38:44 +0000104%token <tv_str> TOK_typefieldreference /* "&Pork" */
105%token <tv_str> TOK_valuefieldreference /* "&id" */
106
107/*
108 * Token types representing ASN.1 standard keywords.
109 */
110%token TOK_ABSENT
111%token TOK_ABSTRACT_SYNTAX
112%token TOK_ALL
113%token TOK_ANY
114%token TOK_APPLICATION
115%token TOK_AUTOMATIC
116%token TOK_BEGIN
117%token TOK_BIT
118%token TOK_BMPString
119%token TOK_BOOLEAN
120%token TOK_BY
121%token TOK_CHARACTER
122%token TOK_CHOICE
123%token TOK_CLASS
124%token TOK_COMPONENT
125%token TOK_COMPONENTS
126%token TOK_CONSTRAINED
127%token TOK_CONTAINING
128%token TOK_DEFAULT
129%token TOK_DEFINITIONS
130%token TOK_DEFINED
131%token TOK_EMBEDDED
132%token TOK_ENCODED
Lev Walkinf59d0752004-08-18 04:59:12 +0000133%token TOK_ENCODING_CONTROL
Lev Walkinf15320b2004-06-03 03:38:44 +0000134%token TOK_END
135%token TOK_ENUMERATED
136%token TOK_EXPLICIT
137%token TOK_EXPORTS
138%token TOK_EXTENSIBILITY
139%token TOK_EXTERNAL
140%token TOK_FALSE
141%token TOK_FROM
142%token TOK_GeneralizedTime
143%token TOK_GeneralString
144%token TOK_GraphicString
145%token TOK_IA5String
146%token TOK_IDENTIFIER
147%token TOK_IMPLICIT
148%token TOK_IMPLIED
149%token TOK_IMPORTS
150%token TOK_INCLUDES
151%token TOK_INSTANCE
Lev Walkinf59d0752004-08-18 04:59:12 +0000152%token TOK_INSTRUCTIONS
Lev Walkinf15320b2004-06-03 03:38:44 +0000153%token TOK_INTEGER
154%token TOK_ISO646String
155%token TOK_MAX
156%token TOK_MIN
157%token TOK_MINUS_INFINITY
158%token TOK_NULL
159%token TOK_NumericString
160%token TOK_OBJECT
161%token TOK_ObjectDescriptor
162%token TOK_OCTET
163%token TOK_OF
164%token TOK_OPTIONAL
165%token TOK_PATTERN
166%token TOK_PDV
167%token TOK_PLUS_INFINITY
168%token TOK_PRESENT
169%token TOK_PrintableString
170%token TOK_PRIVATE
171%token TOK_REAL
172%token TOK_RELATIVE_OID
173%token TOK_SEQUENCE
174%token TOK_SET
175%token TOK_SIZE
176%token TOK_STRING
177%token TOK_SYNTAX
178%token TOK_T61String
179%token TOK_TAGS
180%token TOK_TeletexString
181%token TOK_TRUE
182%token TOK_TYPE_IDENTIFIER
183%token TOK_UNIQUE
184%token TOK_UNIVERSAL
185%token TOK_UniversalString
186%token TOK_UTCTime
187%token TOK_UTF8String
188%token TOK_VideotexString
189%token TOK_VisibleString
190%token TOK_WITH
191
Lev Walkinf15320b2004-06-03 03:38:44 +0000192%left TOK_EXCEPT
Lev Walkinf59d0752004-08-18 04:59:12 +0000193%left '^' TOK_INTERSECTION
194%left '|' TOK_UNION
Lev Walkinf15320b2004-06-03 03:38:44 +0000195
196/* Misc tags */
197%token TOK_TwoDots /* .. */
198%token TOK_ThreeDots /* ... */
Lev Walkinf15320b2004-06-03 03:38:44 +0000199
200
201/*
202 * Types defined herein.
203 */
204%type <a_grammar> ModuleList
205%type <a_module> ModuleSpecification
206%type <a_module> ModuleSpecificationBody
207%type <a_module> ModuleSpecificationElement
208%type <a_module> optModuleSpecificationBody /* Optional */
209%type <a_module_flags> optModuleSpecificationFlags
210%type <a_module_flags> ModuleSpecificationFlags /* Set of FL */
211%type <a_module_flags> ModuleSpecificationFlag /* Single FL */
212%type <a_module> ImportsDefinition
213%type <a_module> ImportsBundleSet
214%type <a_xports> ImportsBundle
215%type <a_xports> ImportsList
216%type <a_xports> ExportsDefinition
217%type <a_xports> ExportsBody
218%type <a_expr> ImportsElement
219%type <a_expr> ExportsElement
Lev Walkinf15320b2004-06-03 03:38:44 +0000220%type <a_expr> ExtensionAndException
Lev Walkin070a52d2004-08-22 03:19:54 +0000221%type <a_expr> TypeDeclaration
Lev Walkinf15320b2004-06-03 03:38:44 +0000222%type <a_ref> ComplexTypeReference
223%type <a_ref> ComplexTypeReferenceAmpList
224%type <a_refcomp> ComplexTypeReferenceElement
225%type <a_refcomp> ClassFieldIdentifier
226%type <a_refcomp> ClassFieldName
227%type <a_expr> ClassFieldList
228%type <a_expr> ClassField
229%type <a_expr> ClassDeclaration
Lev Walkin070a52d2004-08-22 03:19:54 +0000230%type <a_expr> Type
Lev Walkinf15320b2004-06-03 03:38:44 +0000231%type <a_expr> DataTypeReference /* Type1 ::= Type2 */
232%type <a_expr> DefinedTypeRef
233%type <a_expr> ValueSetDefinition /* Val INTEGER ::= {1|2} */
234%type <a_expr> ValueDefinition /* val INTEGER ::= 1*/
Lev Walkinceb20e72004-09-05 10:40:41 +0000235%type <a_expr> optValueSetBody
236%type <a_expr> ValueSetBody
237%type <a_expr> ValueSetElement
Lev Walkin9c974182004-09-15 11:59:51 +0000238%type <a_value> Value
Lev Walkinf15320b2004-06-03 03:38:44 +0000239%type <a_value> DefinedValue
240%type <a_value> SignedNumber
Lev Walkin144db9b2004-10-12 23:26:53 +0000241%type <a_expr> optComponentTypeLists
Lev Walkin070a52d2004-08-22 03:19:54 +0000242%type <a_expr> ComponentTypeLists
243%type <a_expr> ComponentType
244%type <a_expr> AlternativeTypeLists
245%type <a_expr> AlternativeType
Lev Walkinf15320b2004-06-03 03:38:44 +0000246//%type <a_expr> optUniverationDefinition
247%type <a_expr> UniverationDefinition
248%type <a_expr> UniverationList
249%type <a_expr> UniverationElement
250%type <tv_str> TypeRefName
251%type <tv_str> ObjectClassReference
Lev Walkinf15320b2004-06-03 03:38:44 +0000252%type <tv_str> Identifier
Lev Walkin83cac2f2004-09-22 16:03:36 +0000253%type <tv_str> optIdentifier
Lev Walkinf15320b2004-06-03 03:38:44 +0000254%type <a_parg> ParameterArgumentName
255%type <a_plist> ParameterArgumentList
256%type <a_expr> ActualParameter
257%type <a_expr> ActualParameterList
258%type <a_oid> ObjectIdentifier /* OID */
259%type <a_oid> optObjectIdentifier /* Optional OID */
260%type <a_oid> ObjectIdentifierBody
261%type <a_oid_arc> ObjectIdentifierElement
262%type <a_expr> BasicType
263%type <a_type> BasicTypeId
264%type <a_type> BasicTypeId_UniverationCompatible
265%type <a_type> BasicString
266%type <tv_opaque> Opaque
267//%type <tv_opaque> StringValue
Lev Walkinc603f102005-01-23 09:51:44 +0000268%type <a_tag> Tag /* [UNIVERSAL 0] IMPLICIT */
269%type <a_tag> TagClass TagTypeValue TagPlicit
Lev Walkinf15320b2004-06-03 03:38:44 +0000270%type <a_tag> optTag /* [UNIVERSAL 0] IMPLICIT */
271%type <a_constr> optConstraints
Lev Walkind2ea1de2004-08-20 13:25:29 +0000272%type <a_constr> Constraints
Lev Walkinf59d0752004-08-18 04:59:12 +0000273%type <a_constr> SetOfConstraints
274%type <a_constr> ElementSetSpecs /* 1..2,...,3 */
275%type <a_constr> ElementSetSpec /* 1..2,...,3 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000276%type <a_constr> ConstraintSubtypeElement /* 1..2 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000277%type <a_constr> SimpleTableConstraint
278%type <a_constr> TableConstraint
279%type <a_constr> WithComponents
280%type <a_constr> WithComponentsList
281%type <a_constr> WithComponentsElement
282%type <a_constr> ComponentRelationConstraint
283%type <a_constr> AtNotationList
284%type <a_ref> AtNotationElement
Lev Walkinff7dd142005-03-20 12:58:00 +0000285%type <a_value> SingleValue
286%type <a_value> ContainedSubtype
Lev Walkinf15320b2004-06-03 03:38:44 +0000287%type <a_ctype> ConstraintSpec
288%type <a_ctype> ConstraintRangeSpec
Lev Walkin1e448d32005-03-24 14:26:38 +0000289%type <a_value> RestrictedCharacterStringValue
Lev Walkinf15320b2004-06-03 03:38:44 +0000290%type <a_wsynt> optWithSyntax
291%type <a_wsynt> WithSyntax
292%type <a_wsynt> WithSyntaxFormat
293%type <a_wchunk> WithSyntaxFormatToken
294%type <a_marker> optMarker Marker
295%type <a_int> optUnique
296%type <a_pres> optPresenceConstraint PresenceConstraint
297%type <tv_str> ComponentIdList
298
299
300%%
301
302
303ParsedGrammar:
304 ModuleList {
305 *(void **)param = $1;
306 }
307 ;
308
309ModuleList:
310 ModuleSpecification {
311 $$ = asn1p_new();
312 checkmem($$);
313 TQ_ADD(&($$->modules), $1, mod_next);
314 }
315 | ModuleList ModuleSpecification {
316 $$ = $1;
317 TQ_ADD(&($$->modules), $2, mod_next);
318 }
319 ;
320
321/*
322 * ASN module definition.
323 * === EXAMPLE ===
324 * MySyntax DEFINITIONS AUTOMATIC TAGS ::=
325 * BEGIN
326 * ...
327 * END
328 * === EOF ===
329 */
330
331ModuleSpecification:
332 TypeRefName optObjectIdentifier TOK_DEFINITIONS
333 optModuleSpecificationFlags
334 TOK_PPEQ TOK_BEGIN
335 optModuleSpecificationBody
336 TOK_END {
337
338 if($7) {
339 $$ = $7;
340 } else {
341 /* There's a chance that a module is just plain empty */
342 $$ = asn1p_module_new();
343 }
344 checkmem($$);
345
346 $$->Identifier = $1;
347 $$->module_oid = $2;
348 $$->module_flags = $4;
349 }
350 ;
351
352/*
353 * Object Identifier Definition
354 * { iso member-body(2) 3 }
355 */
356optObjectIdentifier:
357 { $$ = 0; }
358 | ObjectIdentifier { $$ = $1; }
359 ;
360
361ObjectIdentifier:
362 '{' ObjectIdentifierBody '}' {
363 $$ = $2;
364 }
365 | '{' '}' {
366 $$ = 0;
367 }
368 ;
369
370ObjectIdentifierBody:
371 ObjectIdentifierElement {
372 $$ = asn1p_oid_new();
373 asn1p_oid_add_arc($$, &$1);
374 if($1.name)
375 free($1.name);
376 }
377 | ObjectIdentifierBody ObjectIdentifierElement {
378 $$ = $1;
379 asn1p_oid_add_arc($$, &$2);
380 if($2.name)
381 free($2.name);
382 }
383 ;
384
385ObjectIdentifierElement:
386 Identifier { /* iso */
387 $$.name = $1;
388 $$.number = -1;
389 }
390 | Identifier '(' TOK_number ')' { /* iso(1) */
391 $$.name = $1;
392 $$.number = $3;
393 }
394 | TOK_number { /* 1 */
395 $$.name = 0;
396 $$.number = $1;
397 }
398 ;
399
400/*
401 * Optional module flags.
402 */
403optModuleSpecificationFlags:
404 { $$ = MSF_NOFLAGS; }
405 | ModuleSpecificationFlags {
406 $$ = $1;
407 }
408 ;
409
410/*
411 * Module flags.
412 */
413ModuleSpecificationFlags:
414 ModuleSpecificationFlag {
415 $$ = $1;
416 }
417 | ModuleSpecificationFlags ModuleSpecificationFlag {
418 $$ = $1 | $2;
419 }
420 ;
421
422/*
423 * Single module flag.
424 */
425ModuleSpecificationFlag:
426 TOK_EXPLICIT TOK_TAGS {
427 $$ = MSF_EXPLICIT_TAGS;
428 }
429 | TOK_IMPLICIT TOK_TAGS {
430 $$ = MSF_IMPLICIT_TAGS;
431 }
432 | TOK_AUTOMATIC TOK_TAGS {
433 $$ = MSF_AUTOMATIC_TAGS;
434 }
435 | TOK_EXTENSIBILITY TOK_IMPLIED {
436 $$ = MSF_EXTENSIBILITY_IMPLIED;
437 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000438 /* EncodingReferenceDefault */
439 | TOK_capitalreference TOK_INSTRUCTIONS {
440 /* X.680Amd1 specifies TAG and XER */
441 if(strcmp($1, "TAG") == 0) {
442 $$ = MSF_TAG_INSTRUCTIONS;
443 } else if(strcmp($1, "XER") == 0) {
444 $$ = MSF_XER_INSTRUCTIONS;
445 } else {
446 fprintf(stderr,
447 "WARNING: %s INSTRUCTIONS at line %d: "
448 "Unrecognized encoding reference\n",
449 $1, yylineno);
450 $$ = MSF_unk_INSTRUCTIONS;
451 }
452 free($1);
453 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000454 ;
455
456/*
457 * Optional module body.
458 */
459optModuleSpecificationBody:
460 { $$ = 0; }
461 | ModuleSpecificationBody {
Lev Walkinf15320b2004-06-03 03:38:44 +0000462 $$ = $1;
463 }
464 ;
465
466/*
467 * ASN.1 Module body.
468 */
469ModuleSpecificationBody:
470 ModuleSpecificationElement {
471 $$ = $1;
472 }
473 | ModuleSpecificationBody ModuleSpecificationElement {
474 $$ = $1;
475
Lev Walkinf59d0752004-08-18 04:59:12 +0000476 /* Behave well when one of them is skipped. */
477 if(!($1)) {
478 if($2) $$ = $2;
479 break;
480 }
481
Lev Walkinf15320b2004-06-03 03:38:44 +0000482#ifdef MY_IMPORT
483#error MY_IMPORT DEFINED ELSEWHERE!
484#endif
485#define MY_IMPORT(foo,field) do { \
Lev Walkinbc55d232004-08-13 12:31:09 +0000486 while(TQ_FIRST(&($2->foo))) { \
Lev Walkinf15320b2004-06-03 03:38:44 +0000487 TQ_ADD(&($$->foo), \
488 TQ_REMOVE(&($2->foo), field), \
489 field); \
Lev Walkinbc55d232004-08-13 12:31:09 +0000490 } \
491 assert(TQ_FIRST(&($2->foo)) == 0); \
492 } while(0)
Lev Walkinf15320b2004-06-03 03:38:44 +0000493
494 MY_IMPORT(imports, xp_next);
495 MY_IMPORT(exports, xp_next);
496 MY_IMPORT(members, next);
497#undef MY_IMPORT
498
499 }
500 ;
501
502/*
503 * One of the elements of ASN.1 module specification.
504 */
505ModuleSpecificationElement:
506 ImportsDefinition {
507 $$ = $1;
508 }
509 | ExportsDefinition {
510 $$ = asn1p_module_new();
511 checkmem($$);
512 if($1) {
513 TQ_ADD(&($$->exports), $1, xp_next);
514 } else {
515 /* "EXPORTS ALL;" ? */
516 }
517 }
518 | DataTypeReference {
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 | ValueDefinition {
526 $$ = asn1p_module_new();
527 checkmem($$);
528 assert($1->expr_type != A1TC_INVALID);
529 assert($1->meta_type != AMT_INVALID);
530 TQ_ADD(&($$->members), $1, next);
531 }
532 /*
533 * Value set definition
534 * === EXAMPLE ===
535 * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 }
536 * === EOF ===
537 */
538 | ValueSetDefinition {
539 $$ = asn1p_module_new();
540 checkmem($$);
541 assert($1->expr_type != A1TC_INVALID);
542 assert($1->meta_type != AMT_INVALID);
543 TQ_ADD(&($$->members), $1, next);
544 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000545 | TOK_ENCODING_CONTROL TOK_capitalreference
546 { asn1p_lexer_hack_push_encoding_control(); }
547 {
548 fprintf(stderr,
549 "WARNING: ENCODING-CONTROL %s "
550 "specification at line %d ignored\n",
551 $2, yylineno);
552 free($2);
553 $$ = 0;
554 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000555
556 /*
557 * Erroneous attemps
558 */
559 | BasicString {
560 return yyerror(
561 "Attempt to redefine a standard basic type, "
562 "use -ftypesXY to switch back "
563 "to older version of ASN.1 standard");
564 }
565 ;
566
567/*
568 * === EXAMPLE ===
569 * IMPORTS Type1, value FROM Module { iso standard(0) } ;
570 * === EOF ===
571 */
572ImportsDefinition:
573 TOK_IMPORTS ImportsBundleSet ';' {
574 $$ = $2;
575 }
576 /*
577 * Some error cases.
578 */
579 | TOK_IMPORTS TOK_FROM /* ... */ {
580 return yyerror("Empty IMPORTS list");
581 }
582 ;
583
584ImportsBundleSet:
585 ImportsBundle {
586 $$ = asn1p_module_new();
587 checkmem($$);
588 TQ_ADD(&($$->imports), $1, xp_next);
589 }
590 | ImportsBundleSet ImportsBundle {
591 $$ = $1;
592 TQ_ADD(&($$->imports), $2, xp_next);
593 }
594 ;
595
596ImportsBundle:
597 ImportsList TOK_FROM TypeRefName optObjectIdentifier {
598 $$ = $1;
599 $$->from = $3;
600 $$->from_oid = $4;
601 checkmem($$);
602 }
603 ;
604
605ImportsList:
606 ImportsElement {
607 $$ = asn1p_xports_new();
608 checkmem($$);
609 TQ_ADD(&($$->members), $1, next);
610 }
611 | ImportsList ',' ImportsElement {
612 $$ = $1;
613 TQ_ADD(&($$->members), $3, next);
614 }
615 ;
616
617ImportsElement:
618 TypeRefName {
619 $$ = asn1p_expr_new(yylineno);
620 checkmem($$);
621 $$->Identifier = $1;
622 $$->expr_type = A1TC_REFERENCE;
623 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000624 | TypeRefName '{' '}' { /* Completely equivalent to above */
625 $$ = asn1p_expr_new(yylineno);
626 checkmem($$);
627 $$->Identifier = $1;
628 $$->expr_type = A1TC_REFERENCE;
629 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000630 | Identifier {
631 $$ = asn1p_expr_new(yylineno);
632 checkmem($$);
633 $$->Identifier = $1;
634 $$->expr_type = A1TC_REFERENCE;
635 }
636 ;
637
638ExportsDefinition:
639 TOK_EXPORTS ExportsBody ';' {
640 $$ = $2;
641 }
642 | TOK_EXPORTS TOK_ALL ';' {
643 $$ = 0;
644 }
645 | TOK_EXPORTS ';' {
646 /* Empty EXPORTS clause effectively prohibits export. */
647 $$ = asn1p_xports_new();
648 checkmem($$);
649 }
650 ;
651
652ExportsBody:
653 ExportsElement {
654 $$ = asn1p_xports_new();
655 assert($$);
656 TQ_ADD(&($$->members), $1, next);
657 }
658 | ExportsBody ',' ExportsElement {
659 $$ = $1;
660 TQ_ADD(&($$->members), $3, next);
661 }
662 ;
663
664ExportsElement:
665 TypeRefName {
666 $$ = asn1p_expr_new(yylineno);
667 checkmem($$);
668 $$->Identifier = $1;
669 $$->expr_type = A1TC_EXPORTVAR;
670 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000671 | TypeRefName '{' '}' {
672 $$ = asn1p_expr_new(yylineno);
673 checkmem($$);
674 $$->Identifier = $1;
675 $$->expr_type = A1TC_EXPORTVAR;
676 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000677 | Identifier {
678 $$ = asn1p_expr_new(yylineno);
679 checkmem($$);
680 $$->Identifier = $1;
681 $$->expr_type = A1TC_EXPORTVAR;
682 }
683 ;
684
685
686ValueSetDefinition:
687 TypeRefName DefinedTypeRef TOK_PPEQ '{' optValueSetBody '}' {
688 $$ = $2;
689 assert($$->Identifier == 0);
690 $$->Identifier = $1;
691 $$->meta_type = AMT_VALUESET;
692 // take care of optValueSetBody
693 }
694 ;
695
696DefinedTypeRef:
697 ComplexTypeReference {
698 $$ = asn1p_expr_new(yylineno);
699 checkmem($$);
700 $$->reference = $1;
701 $$->expr_type = A1TC_REFERENCE;
702 $$->meta_type = AMT_TYPEREF;
703 }
704 | BasicTypeId {
705 $$ = asn1p_expr_new(yylineno);
706 checkmem($$);
707 $$->expr_type = $1;
708 $$->meta_type = AMT_TYPE;
709 }
710 ;
711
712optValueSetBody:
713 { }
Lev Walkinceb20e72004-09-05 10:40:41 +0000714 | ValueSetBody {
715 }
716 ;
717
718/*
719 * X.680 does not permit ElementSetSpecs starting with ellipsis,
720 * i.e. (..., A, B). This is very strange: the ElementSetSpecs is used
721 * inside ValueSet, and ValueSets "in the wild" tend to have the first
722 * ellipsis.
723 */
724ValueSetBody:
725 ValueSetElement {
726 }
727 | ValueSetBody ',' ValueSetElement {
728 }
729 ;
730
731ValueSetElement:
732 TOK_ThreeDots {
733 }
734 | ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +0000735 }
736 ;
737
738
739/*
740 * Data Type Reference.
741 * === EXAMPLE ===
742 * Type3 ::= CHOICE { a Type1, b Type 2 }
743 * === EOF ===
744 */
745
746DataTypeReference:
747 /*
748 * Optionally tagged type definition.
749 */
750 TypeRefName TOK_PPEQ optTag TOK_TYPE_IDENTIFIER {
751 $$ = asn1p_expr_new(yylineno);
752 checkmem($$);
753 $$->Identifier = $1;
754 $$->tag = $3;
755 $$->expr_type = A1TC_TYPEID;
756 $$->meta_type = AMT_TYPE;
757 }
Lev Walkinaf120f72004-09-14 02:36:39 +0000758 | TypeRefName TOK_PPEQ Type {
759 $$ = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000760 $$->Identifier = $1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000761 assert($$->expr_type);
762 assert($$->meta_type);
763 }
764 | TypeRefName TOK_PPEQ ClassDeclaration {
765 $$ = $3;
766 $$->Identifier = $1;
767 assert($$->expr_type == A1TC_CLASSDEF);
768 assert($$->meta_type == AMT_OBJECT);
769 }
770 /*
771 * Parametrized <Type> declaration:
772 * === EXAMPLE ===
773 * SIGNED { ToBeSigned } ::= SEQUENCE {
774 * toBeSigned ToBeSigned,
775 * algorithm AlgorithmIdentifier,
776 * signature BIT STRING
777 * }
778 * === EOF ===
779 */
Lev Walkin070a52d2004-08-22 03:19:54 +0000780 | TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000781 $$ = $6;
782 assert($$->Identifier == 0);
783 $$->Identifier = $1;
784 $$->params = $3;
785 $$->meta_type = AMT_PARAMTYPE;
786 }
787 ;
788
789ParameterArgumentList:
790 ParameterArgumentName {
791 int ret;
792 $$ = asn1p_paramlist_new(yylineno);
793 checkmem($$);
794 ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument);
795 checkmem(ret == 0);
796 if($1.governor) asn1p_ref_free($1.governor);
797 if($1.argument) free($1.argument);
798 }
799 | ParameterArgumentList ',' ParameterArgumentName {
800 int ret;
801 $$ = $1;
802 ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument);
803 checkmem(ret == 0);
804 if($3.governor) asn1p_ref_free($3.governor);
805 if($3.argument) free($3.argument);
806 }
807 ;
808
809ParameterArgumentName:
810 TypeRefName {
811 $$.governor = NULL;
812 $$.argument = $1;
813 }
814 | TypeRefName ':' Identifier {
815 int ret;
816 $$.governor = asn1p_ref_new(yylineno);
817 ret = asn1p_ref_add_component($$.governor, $1, 0);
818 checkmem(ret == 0);
819 $$.argument = $3;
820 }
Lev Walkinc8092cb2005-02-18 16:34:21 +0000821 | TypeRefName ':' TypeRefName {
822 int ret;
823 $$.governor = asn1p_ref_new(yylineno);
824 ret = asn1p_ref_add_component($$.governor, $1, 0);
825 checkmem(ret == 0);
826 $$.argument = $3;
827 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000828 | BasicTypeId ':' Identifier {
829 int ret;
830 $$.governor = asn1p_ref_new(yylineno);
831 ret = asn1p_ref_add_component($$.governor,
832 ASN_EXPR_TYPE2STR($1), 1);
833 checkmem(ret == 0);
834 $$.argument = $3;
835 }
836 ;
837
838ActualParameterList:
839 ActualParameter {
840 $$ = asn1p_expr_new(yylineno);
841 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000842 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000843 }
844 | ActualParameterList ',' ActualParameter {
845 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000846 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000847 }
848 ;
849
850ActualParameter:
Lev Walkin070a52d2004-08-22 03:19:54 +0000851 Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000852 $$ = $1;
853 }
854 | Identifier {
855 $$ = asn1p_expr_new(yylineno);
856 checkmem($$);
857 $$->Identifier = $1;
858 $$->expr_type = A1TC_REFERENCE;
859 $$->meta_type = AMT_VALUE;
860 }
861 ;
862
863/*
Lev Walkinc8092cb2005-02-18 16:34:21 +0000864 | '{' ActualParameter '}' {
865 $$ = asn1p_expr_new(yylineno);
866 checkmem($$);
867 asn1p_expr_add($$, $2);
868 $$->expr_type = A1TC_PARAMETRIZED;
869 $$->meta_type = AMT_TYPE;
870 }
871 ;
872*/
873
874/*
Lev Walkinf15320b2004-06-03 03:38:44 +0000875 * A collection of constructed data type members.
876 */
Lev Walkin144db9b2004-10-12 23:26:53 +0000877optComponentTypeLists:
878 { $$ = asn1p_expr_new(yylineno); }
879 | ComponentTypeLists { $$ = $1; };
880
Lev Walkin070a52d2004-08-22 03:19:54 +0000881ComponentTypeLists:
882 ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000883 $$ = asn1p_expr_new(yylineno);
884 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000885 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000886 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000887 | ComponentTypeLists ',' ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000888 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000889 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000890 }
891 ;
892
Lev Walkin070a52d2004-08-22 03:19:54 +0000893ComponentType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000894 Identifier Type optMarker {
Lev Walkin070a52d2004-08-22 03:19:54 +0000895 $$ = $2;
896 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000897 $$->Identifier = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000898 $$->marker = $3;
899 }
900 | TOK_COMPONENTS TOK_OF Type {
901 $$ = asn1p_expr_new(yylineno);
902 checkmem($$);
903 $$->meta_type = $3->meta_type;
904 $$->expr_type = A1TC_COMPONENTS_OF;
Lev Walkin1004aa92004-09-08 00:28:11 +0000905 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000906 }
907 | ExtensionAndException {
908 $$ = $1;
909 }
910 ;
911
912AlternativeTypeLists:
913 AlternativeType {
914 $$ = asn1p_expr_new(yylineno);
915 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000916 asn1p_expr_add($$, $1);
Lev Walkin070a52d2004-08-22 03:19:54 +0000917 }
918 | AlternativeTypeLists ',' AlternativeType {
919 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000920 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000921 }
922 ;
923
924AlternativeType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000925 Identifier Type {
Lev Walkin070a52d2004-08-22 03:19:54 +0000926 $$ = $2;
927 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000928 $$->Identifier = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000929 }
930 | ExtensionAndException {
931 $$ = $1;
932 }
933 ;
934
Lev Walkinf15320b2004-06-03 03:38:44 +0000935ClassDeclaration:
936 TOK_CLASS '{' ClassFieldList '}' optWithSyntax {
937 $$ = $3;
938 checkmem($$);
939 $$->with_syntax = $5;
940 assert($$->expr_type == A1TC_CLASSDEF);
941 assert($$->meta_type == AMT_OBJECT);
942 }
943 ;
944
945optUnique:
946 { $$ = 0; }
947 | TOK_UNIQUE { $$ = 1; }
948 ;
949
950ClassFieldList:
951 ClassField {
952 $$ = asn1p_expr_new(yylineno);
953 checkmem($$);
954 $$->expr_type = A1TC_CLASSDEF;
955 $$->meta_type = AMT_OBJECT;
Lev Walkin1004aa92004-09-08 00:28:11 +0000956 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000957 }
958 | ClassFieldList ',' ClassField {
959 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000960 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000961 }
962 ;
963
964ClassField:
965 ClassFieldIdentifier optMarker {
966 $$ = asn1p_expr_new(yylineno);
967 checkmem($$);
968 $$->Identifier = $1.name;
969 $$->expr_type = A1TC_CLASSFIELD;
970 $$->meta_type = AMT_OBJECTFIELD;
971 $$->marker = $2;
972 }
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000973 | ClassFieldIdentifier Type optUnique optMarker {
Lev Walkinf15320b2004-06-03 03:38:44 +0000974 $$ = $2;
975 $$->Identifier = $1.name;
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000976 $$->marker = $4;
977 $$->unique = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000978 }
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000979 | ClassFieldIdentifier ClassFieldIdentifier optUnique optMarker {
Lev Walkinf15320b2004-06-03 03:38:44 +0000980 int ret;
981 $$ = asn1p_expr_new(yylineno);
982 checkmem($$);
983 $$->Identifier = $1.name;
984 $$->reference = asn1p_ref_new(yylineno);
985 checkmem($$->reference);
986 ret = asn1p_ref_add_component($$->reference,
987 $2.name, $2.lex_type);
988 checkmem(ret == 0);
989 $$->expr_type = A1TC_CLASSFIELD;
990 $$->meta_type = AMT_OBJECTFIELD;
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000991 $$->marker = $4;
992 $$->unique = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000993 }
994 ;
995
996optWithSyntax:
997 { $$ = 0; }
998 | WithSyntax {
999 $$ = $1;
1000 }
1001 ;
1002
1003WithSyntax:
1004 TOK_WITH TOK_SYNTAX '{'
1005 { asn1p_lexer_hack_enable_with_syntax(); }
1006 WithSyntaxFormat
1007 '}' {
1008 $$ = $5;
1009 }
1010 ;
1011
1012WithSyntaxFormat:
1013 WithSyntaxFormatToken {
1014 $$ = asn1p_wsyntx_new();
1015 TQ_ADD(&($$->chunks), $1, next);
1016 }
1017 | WithSyntaxFormat WithSyntaxFormatToken {
1018 $$ = $1;
1019 TQ_ADD(&($$->chunks), $2, next);
1020 }
1021 ;
1022
1023WithSyntaxFormatToken:
1024 TOK_opaque {
1025 $$ = asn1p_wsyntx_chunk_frombuf($1.buf, $1.len, 0);
1026 }
1027 | ClassFieldIdentifier {
1028 asn1p_ref_t *ref;
1029 int ret;
1030 ref = asn1p_ref_new(yylineno);
1031 checkmem(ref);
1032 ret = asn1p_ref_add_component(ref, $1.name, $1.lex_type);
1033 checkmem(ret == 0);
1034 $$ = asn1p_wsyntx_chunk_fromref(ref, 0);
1035 }
1036 ;
1037
Lev Walkinf15320b2004-06-03 03:38:44 +00001038ExtensionAndException:
1039 TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001040 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001041 checkmem($$);
1042 $$->Identifier = strdup("...");
1043 checkmem($$->Identifier);
1044 $$->expr_type = A1TC_EXTENSIBLE;
1045 $$->meta_type = AMT_TYPE;
1046 }
1047 | TOK_ThreeDots '!' DefinedValue {
Lev Walkinceb20e72004-09-05 10:40:41 +00001048 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001049 checkmem($$);
1050 $$->Identifier = strdup("...");
1051 checkmem($$->Identifier);
1052 $$->value = $3;
1053 $$->expr_type = A1TC_EXTENSIBLE;
1054 $$->meta_type = AMT_TYPE;
1055 }
1056 | TOK_ThreeDots '!' SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001057 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001058 checkmem($$);
1059 $$->Identifier = strdup("...");
1060 $$->value = $3;
1061 checkmem($$->Identifier);
1062 $$->expr_type = A1TC_EXTENSIBLE;
1063 $$->meta_type = AMT_TYPE;
1064 }
1065 ;
1066
Lev Walkin070a52d2004-08-22 03:19:54 +00001067Type:
Lev Walkinaf120f72004-09-14 02:36:39 +00001068 optTag TypeDeclaration optConstraints {
1069 $$ = $2;
1070 $$->tag = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +00001071 /*
1072 * Outer constraint for SEQUENCE OF and SET OF applies
1073 * to the inner type.
1074 */
1075 if($$->expr_type == ASN_CONSTR_SEQUENCE_OF
1076 || $$->expr_type == ASN_CONSTR_SET_OF) {
1077 assert(!TQ_FIRST(&($$->members))->constraints);
Lev Walkinaf120f72004-09-14 02:36:39 +00001078 TQ_FIRST(&($$->members))->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001079 } else {
1080 if($$->constraints) {
1081 assert(!$2);
1082 } else {
Lev Walkinaf120f72004-09-14 02:36:39 +00001083 $$->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001084 }
1085 }
1086 }
1087 ;
1088
1089TypeDeclaration:
Lev Walkinf15320b2004-06-03 03:38:44 +00001090 BasicType {
1091 $$ = $1;
1092 }
Lev Walkin070a52d2004-08-22 03:19:54 +00001093 | TOK_CHOICE '{' AlternativeTypeLists '}' {
1094 $$ = $3;
1095 assert($$->expr_type == A1TC_INVALID);
1096 $$->expr_type = ASN_CONSTR_CHOICE;
1097 $$->meta_type = AMT_TYPE;
Lev Walkinf15320b2004-06-03 03:38:44 +00001098 }
Lev Walkin144db9b2004-10-12 23:26:53 +00001099 | TOK_SEQUENCE '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001100 $$ = $3;
1101 assert($$->expr_type == A1TC_INVALID);
1102 $$->expr_type = ASN_CONSTR_SEQUENCE;
1103 $$->meta_type = AMT_TYPE;
1104 }
Lev Walkin144db9b2004-10-12 23:26:53 +00001105 | TOK_SET '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001106 $$ = $3;
1107 assert($$->expr_type == A1TC_INVALID);
1108 $$->expr_type = ASN_CONSTR_SET;
1109 $$->meta_type = AMT_TYPE;
1110 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001111 | TOK_SEQUENCE optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001112 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001113 checkmem($$);
1114 $$->constraints = $2;
1115 $$->expr_type = ASN_CONSTR_SEQUENCE_OF;
1116 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001117 $6->Identifier = $4;
1118 $6->tag = $5;
1119 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001120 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001121 | TOK_SET optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001122 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001123 checkmem($$);
1124 $$->constraints = $2;
1125 $$->expr_type = ASN_CONSTR_SET_OF;
1126 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001127 $6->Identifier = $4;
1128 $6->tag = $5;
1129 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001130 }
1131 | TOK_ANY {
Lev Walkinceb20e72004-09-05 10:40:41 +00001132 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001133 checkmem($$);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001134 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001135 $$->meta_type = AMT_TYPE;
1136 }
1137 | TOK_ANY TOK_DEFINED TOK_BY Identifier {
1138 int ret;
Lev Walkinceb20e72004-09-05 10:40:41 +00001139 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001140 checkmem($$);
1141 $$->reference = asn1p_ref_new(yylineno);
1142 ret = asn1p_ref_add_component($$->reference,
1143 $4, RLT_lowercase);
1144 checkmem(ret == 0);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001145 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001146 $$->meta_type = AMT_TYPE;
1147 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001148 /*
1149 * A parametrized assignment.
1150 */
1151 | TypeRefName '{' ActualParameterList '}' {
1152 int ret;
1153 $$ = $3;
1154 assert($$->expr_type == 0);
1155 assert($$->meta_type == 0);
1156 assert($$->reference == 0);
1157 $$->reference = asn1p_ref_new(yylineno);
1158 checkmem($$->reference);
1159 ret = asn1p_ref_add_component($$->reference, $1, RLT_UNKNOWN);
1160 checkmem(ret == 0);
1161 free($1);
1162 $$->expr_type = A1TC_PARAMETRIZED;
1163 $$->meta_type = AMT_TYPE;
1164 }
1165 /*
1166 * A DefinedType reference.
1167 * "CLASS1.&id.&id2"
1168 * or
1169 * "Module.Type"
1170 * or
1171 * "Module.identifier"
1172 * or
1173 * "Type"
1174 */
1175 | ComplexTypeReference {
1176 $$ = asn1p_expr_new(yylineno);
1177 checkmem($$);
1178 $$->reference = $1;
1179 $$->expr_type = A1TC_REFERENCE;
1180 $$->meta_type = AMT_TYPEREF;
1181 }
1182 | TOK_INSTANCE TOK_OF ComplexTypeReference {
1183 $$ = asn1p_expr_new(yylineno);
1184 checkmem($$);
1185 $$->reference = $3;
1186 $$->expr_type = A1TC_INSTANCE;
1187 $$->meta_type = AMT_TYPE;
1188 }
1189 ;
1190
1191/*
1192 * A type name consisting of several components.
1193 * === EXAMPLE ===
1194 * === EOF ===
1195 */
1196ComplexTypeReference:
1197 TOK_typereference {
1198 int ret;
1199 $$ = asn1p_ref_new(yylineno);
1200 checkmem($$);
1201 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1202 checkmem(ret == 0);
1203 free($1);
1204 }
1205 | TOK_typereference '.' TypeRefName {
1206 int ret;
1207 $$ = asn1p_ref_new(yylineno);
1208 checkmem($$);
1209 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1210 checkmem(ret == 0);
1211 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1212 checkmem(ret == 0);
1213 free($1);
1214 }
Lev Walkin9c974182004-09-15 11:59:51 +00001215 | ObjectClassReference '.' TypeRefName {
1216 int ret;
1217 $$ = asn1p_ref_new(yylineno);
1218 checkmem($$);
1219 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1220 checkmem(ret == 0);
1221 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1222 checkmem(ret == 0);
1223 free($1);
1224 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001225 | TOK_typereference '.' Identifier {
1226 int ret;
1227 $$ = asn1p_ref_new(yylineno);
1228 checkmem($$);
1229 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1230 checkmem(ret == 0);
1231 ret = asn1p_ref_add_component($$, $3, RLT_lowercase);
1232 checkmem(ret == 0);
1233 free($1);
1234 }
1235 | ObjectClassReference {
1236 int ret;
1237 $$ = asn1p_ref_new(yylineno);
1238 checkmem($$);
1239 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1240 free($1);
1241 checkmem(ret == 0);
1242 }
1243 | ObjectClassReference '.' ComplexTypeReferenceAmpList {
1244 int ret;
1245 $$ = $3;
1246 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1247 free($1);
1248 checkmem(ret == 0);
1249 /*
1250 * Move the last element infront.
1251 */
1252 {
1253 struct asn1p_ref_component_s tmp_comp;
1254 tmp_comp = $$->components[$$->comp_count-1];
1255 memmove(&$$->components[1],
1256 &$$->components[0],
1257 sizeof($$->components[0])
1258 * ($$->comp_count - 1));
1259 $$->components[0] = tmp_comp;
1260 }
1261 }
1262 ;
1263
1264ComplexTypeReferenceAmpList:
1265 ComplexTypeReferenceElement {
1266 int ret;
1267 $$ = asn1p_ref_new(yylineno);
1268 checkmem($$);
1269 ret = asn1p_ref_add_component($$, $1.name, $1.lex_type);
1270 free($1.name);
1271 checkmem(ret == 0);
1272 }
1273 | ComplexTypeReferenceAmpList '.' ComplexTypeReferenceElement {
1274 int ret;
1275 $$ = $1;
1276 ret = asn1p_ref_add_component($$, $3.name, $3.lex_type);
1277 free($3.name);
1278 checkmem(ret == 0);
1279 }
1280 ;
1281
1282ComplexTypeReferenceElement: ClassFieldName;
1283ClassFieldIdentifier: ClassFieldName;
1284
1285ClassFieldName:
1286 /* "&Type1" */
1287 TOK_typefieldreference {
1288 $$.lex_type = RLT_AmpUppercase;
1289 $$.name = $1;
1290 }
1291 /* "&id" */
1292 | TOK_valuefieldreference {
1293 $$.lex_type = RLT_Amplowercase;
1294 $$.name = $1;
1295 }
1296 ;
1297
1298
1299/*
1300 * === EXAMPLE ===
1301 * value INTEGER ::= 1
1302 * === EOF ===
1303 */
1304ValueDefinition:
Lev Walkin9c974182004-09-15 11:59:51 +00001305 Identifier DefinedTypeRef TOK_PPEQ Value {
Lev Walkinf15320b2004-06-03 03:38:44 +00001306 $$ = $2;
1307 assert($$->Identifier == NULL);
1308 $$->Identifier = $1;
1309 $$->meta_type = AMT_VALUE;
1310 $$->value = $4;
1311 }
1312 ;
1313
Lev Walkin9c974182004-09-15 11:59:51 +00001314Value:
1315 Identifier ':' Value {
1316 $$ = asn1p_value_fromint(0);
1317 checkmem($$);
1318 $$->type = ATV_CHOICE_IDENTIFIER;
1319 $$->value.choice_identifier.identifier = $1;
1320 $$->value.choice_identifier.value = $3;
1321 }
1322 | '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
Lev Walkinf15320b2004-06-03 03:38:44 +00001323 $$ = asn1p_value_frombuf($3.buf, $3.len, 0);
1324 checkmem($$);
1325 $$->type = ATV_UNPARSED;
1326 }
Lev Walkin9c974182004-09-15 11:59:51 +00001327 | TOK_NULL {
1328 $$ = asn1p_value_fromint(0);
1329 checkmem($$);
1330 $$->type = ATV_NULL;
1331 }
1332 | TOK_FALSE {
1333 $$ = asn1p_value_fromint(0);
1334 checkmem($$);
1335 $$->type = ATV_FALSE;
1336 }
1337 | TOK_TRUE {
1338 $$ = asn1p_value_fromint(0);
1339 checkmem($$);
1340 $$->type = ATV_TRUE;
1341 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001342 | TOK_bstring {
1343 $$ = _convert_bitstring2binary($1, 'B');
1344 checkmem($$);
1345 }
1346 | TOK_hstring {
1347 $$ = _convert_bitstring2binary($1, 'H');
1348 checkmem($$);
1349 }
Lev Walkin1e448d32005-03-24 14:26:38 +00001350 | RestrictedCharacterStringValue {
1351 $$ = $$;
Lev Walkinf15320b2004-06-03 03:38:44 +00001352 }
1353 | SignedNumber {
1354 $$ = $1;
1355 }
1356 | DefinedValue {
1357 $$ = $1;
1358 }
1359 ;
1360
1361DefinedValue:
1362 Identifier {
1363 asn1p_ref_t *ref;
1364 int ret;
1365 ref = asn1p_ref_new(yylineno);
1366 checkmem(ref);
1367 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1368 checkmem(ret == 0);
1369 $$ = asn1p_value_fromref(ref, 0);
1370 checkmem($$);
1371 free($1);
1372 }
1373 | TypeRefName '.' Identifier {
1374 asn1p_ref_t *ref;
1375 int ret;
1376 ref = asn1p_ref_new(yylineno);
1377 checkmem(ref);
1378 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1379 checkmem(ret == 0);
1380 ret = asn1p_ref_add_component(ref, $3, RLT_lowercase);
1381 checkmem(ret == 0);
1382 $$ = asn1p_value_fromref(ref, 0);
1383 checkmem($$);
1384 free($1);
1385 free($3);
1386 }
1387 ;
1388
Lev Walkin1e448d32005-03-24 14:26:38 +00001389
1390RestrictedCharacterStringValue:
1391 TOK_cstring {
1392 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1393 checkmem($$);
1394 }
1395 | '{' TOK_number ',' TOK_number '}' {
1396 asn1c_integer_t v = ($2 << 4) + $4;
1397 if($2 > 7) return yyerror("X.680:2003, #37.14 "
1398 "mandates 0..7 range for Tuple's TableColumn");
1399 if($4 > 15) return yyerror("X.680:2003, #37.14 "
1400 "mandates 0..15 range for Tuple's TableRow");
1401 $$ = asn1p_value_fromint(v);
1402 checkmem($$);
1403 $$->type = ATV_TUPLE;
1404 }
1405 | '{' TOK_number ',' TOK_number ',' TOK_number ',' TOK_number '}' {
1406 asn1c_integer_t v = ($2 << 24) | ($4 << 16) | ($6 << 8) | $8;
1407 if($2 > 127) return yyerror("X.680:2003, #37.12 "
1408 "mandates 0..127 range for Quadruple's Group");
1409 if($4 > 255) return yyerror("X.680:2003, #37.12 "
1410 "mandates 0..255 range for Quadruple's Plane");
1411 if($6 > 255) return yyerror("X.680:2003, #37.12 "
1412 "mandates 0..255 range for Quadruple's Row");
1413 if($8 > 255) return yyerror("X.680:2003, #37.12 "
1414 "mandates 0..255 range for Quadruple's Cell");
1415 $$ = asn1p_value_fromint(v);
1416 checkmem($$);
1417 $$->type = ATV_QUADRUPLE;
1418 }
1419 ;
1420
Lev Walkinf15320b2004-06-03 03:38:44 +00001421Opaque:
1422 TOK_opaque {
Lev Walkin1893ddf2005-03-20 14:28:32 +00001423 $$.len = $1.len + 1;
Lev Walkinf15320b2004-06-03 03:38:44 +00001424 $$.buf = malloc($$.len + 1);
1425 checkmem($$.buf);
1426 $$.buf[0] = '{';
Lev Walkin1893ddf2005-03-20 14:28:32 +00001427 memcpy($$.buf + 1, $1.buf, $1.len);
Lev Walkinf15320b2004-06-03 03:38:44 +00001428 $$.buf[$$.len] = '\0';
1429 free($1.buf);
1430 }
1431 | Opaque TOK_opaque {
1432 int newsize = $1.len + $2.len;
1433 char *p = malloc(newsize + 1);
1434 checkmem(p);
1435 memcpy(p , $1.buf, $1.len);
1436 memcpy(p + $1.len, $2.buf, $2.len);
1437 p[newsize] = '\0';
1438 free($1.buf);
1439 free($2.buf);
1440 $$.buf = p;
1441 $$.len = newsize;
1442 }
1443 ;
1444
1445BasicTypeId:
1446 TOK_BOOLEAN { $$ = ASN_BASIC_BOOLEAN; }
1447 | TOK_NULL { $$ = ASN_BASIC_NULL; }
1448 | TOK_REAL { $$ = ASN_BASIC_REAL; }
1449 | BasicTypeId_UniverationCompatible { $$ = $1; }
1450 | TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; }
1451 | TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; }
1452 | TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; }
1453 | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; }
1454 | TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; }
1455 | TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; }
1456 | TOK_UTCTime { $$ = ASN_BASIC_UTCTime; }
1457 | TOK_GeneralizedTime { $$ = ASN_BASIC_GeneralizedTime; }
Lev Walkinc7d939d2005-03-20 11:12:40 +00001458 | BasicString { $$ = $1; }
Lev Walkinf15320b2004-06-03 03:38:44 +00001459 ;
1460
1461/*
1462 * A type identifier which may be used with "{ a(1), b(2) }" clause.
1463 */
1464BasicTypeId_UniverationCompatible:
1465 TOK_INTEGER { $$ = ASN_BASIC_INTEGER; }
1466 | TOK_ENUMERATED { $$ = ASN_BASIC_ENUMERATED; }
1467 | TOK_BIT TOK_STRING { $$ = ASN_BASIC_BIT_STRING; }
1468 ;
1469
1470BasicType:
1471 BasicTypeId {
Lev Walkinceb20e72004-09-05 10:40:41 +00001472 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001473 checkmem($$);
1474 $$->expr_type = $1;
1475 $$->meta_type = AMT_TYPE;
1476 }
1477 | BasicTypeId_UniverationCompatible UniverationDefinition {
1478 if($2) {
1479 $$ = $2;
1480 } else {
Lev Walkinceb20e72004-09-05 10:40:41 +00001481 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001482 checkmem($$);
1483 }
1484 $$->expr_type = $1;
1485 $$->meta_type = AMT_TYPE;
1486 }
1487 ;
1488
1489BasicString:
1490 TOK_BMPString { $$ = ASN_STRING_BMPString; }
1491 | TOK_GeneralString {
1492 $$ = ASN_STRING_GeneralString;
Lev Walkin9c974182004-09-15 11:59:51 +00001493 fprintf(stderr, "WARNING: GeneralString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001494 }
1495 | TOK_GraphicString {
1496 $$ = ASN_STRING_GraphicString;
Lev Walkin9c974182004-09-15 11:59:51 +00001497 fprintf(stderr, "WARNING: GraphicString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001498 }
1499 | TOK_IA5String { $$ = ASN_STRING_IA5String; }
1500 | TOK_ISO646String { $$ = ASN_STRING_ISO646String; }
1501 | TOK_NumericString { $$ = ASN_STRING_NumericString; }
1502 | TOK_PrintableString { $$ = ASN_STRING_PrintableString; }
1503 | TOK_T61String {
1504 $$ = ASN_STRING_T61String;
Lev Walkin9c974182004-09-15 11:59:51 +00001505 fprintf(stderr, "WARNING: T61String is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001506 }
1507 | TOK_TeletexString { $$ = ASN_STRING_TeletexString; }
1508 | TOK_UniversalString { $$ = ASN_STRING_UniversalString; }
1509 | TOK_UTF8String { $$ = ASN_STRING_UTF8String; }
1510 | TOK_VideotexString {
1511 $$ = ASN_STRING_VideotexString;
Lev Walkin9c974182004-09-15 11:59:51 +00001512 fprintf(stderr, "WARNING: VideotexString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001513 }
1514 | TOK_VisibleString { $$ = ASN_STRING_VisibleString; }
1515 | TOK_ObjectDescriptor { $$ = ASN_STRING_ObjectDescriptor; }
1516 ;
1517
Lev Walkind2ea1de2004-08-20 13:25:29 +00001518
Lev Walkinf15320b2004-06-03 03:38:44 +00001519/*
1520 * Data type constraints.
1521 */
Lev Walkinf15320b2004-06-03 03:38:44 +00001522Union: '|' | TOK_UNION;
1523Intersection: '^' | TOK_INTERSECTION;
1524Except: TOK_EXCEPT;
1525
Lev Walkinf59d0752004-08-18 04:59:12 +00001526optConstraints:
1527 { $$ = 0; }
Lev Walkind2ea1de2004-08-20 13:25:29 +00001528 | Constraints {
1529 $$ = $1;
1530 }
1531 ;
1532
1533Constraints:
1534 SetOfConstraints {
Lev Walkinf59d0752004-08-18 04:59:12 +00001535 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, 0);
1536 }
1537 | TOK_SIZE '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001538 /*
1539 * This is a special case, for compatibility purposes.
Lev Walkinf59d0752004-08-18 04:59:12 +00001540 * It goes without parentheses.
Lev Walkinf15320b2004-06-03 03:38:44 +00001541 */
Lev Walkind2ea1de2004-08-20 13:25:29 +00001542 CONSTRAINT_INSERT($$, ACT_CT_SIZE, $3, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001543 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001544 ;
1545
Lev Walkinf59d0752004-08-18 04:59:12 +00001546SetOfConstraints:
1547 '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001548 $$ = $2;
1549 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001550 | SetOfConstraints '(' ElementSetSpecs ')' {
1551 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $3);
1552 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001553 ;
1554
Lev Walkinf59d0752004-08-18 04:59:12 +00001555ElementSetSpecs:
1556 ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001557 $$ = $1;
1558 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001559 | ElementSetSpec ',' TOK_ThreeDots {
Lev Walkinf15320b2004-06-03 03:38:44 +00001560 asn1p_constraint_t *ct;
1561 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001562 ct->type = ACT_EL_EXT;
1563 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1564 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001565 | ElementSetSpec ',' TOK_ThreeDots ',' ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001566 asn1p_constraint_t *ct;
1567 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001568 ct->type = ACT_EL_EXT;
1569 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
Lev Walkinb4fcdd22004-08-13 12:35:09 +00001570 ct = $$;
1571 CONSTRAINT_INSERT($$, ACT_CA_CSV, ct, $5);
Lev Walkinf15320b2004-06-03 03:38:44 +00001572 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001573 ;
1574
Lev Walkinf59d0752004-08-18 04:59:12 +00001575ElementSetSpec:
1576 ConstraintSubtypeElement {
1577 $$ = $1;
1578 }
Lev Walkin1e448d32005-03-24 14:26:38 +00001579 | TOK_ALL TOK_EXCEPT ConstraintSubtypeElement {
1580 CONSTRAINT_INSERT($$, ACT_CA_AEX, $3, 0);
1581 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001582 | ElementSetSpec Union ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001583 CONSTRAINT_INSERT($$, ACT_CA_UNI, $1, $3);
1584 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001585 | ElementSetSpec Intersection ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001586 CONSTRAINT_INSERT($$, ACT_CA_INT, $1, $3);
1587 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001588 | ConstraintSubtypeElement Except ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001589 CONSTRAINT_INSERT($$, ACT_CA_EXC, $1, $3);
1590 }
1591 ;
1592
1593ConstraintSubtypeElement:
Lev Walkinf59d0752004-08-18 04:59:12 +00001594 ConstraintSpec '(' ElementSetSpecs ')' {
1595 int ret;
1596 $$ = asn1p_constraint_new(yylineno);
1597 checkmem($$);
1598 $$->type = $1;
1599 ret = asn1p_constraint_insert($$, $3);
1600 checkmem(ret == 0);
1601 }
1602 | '(' ElementSetSpecs ')' {
1603 int ret;
1604 $$ = asn1p_constraint_new(yylineno);
1605 checkmem($$);
1606 $$->type = ACT_CA_SET;
1607 ret = asn1p_constraint_insert($$, $2);
1608 checkmem(ret == 0);
1609 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001610 | SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001611 $$ = asn1p_constraint_new(yylineno);
1612 checkmem($$);
1613 $$->type = ACT_EL_VALUE;
1614 $$->value = $1;
1615 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001616 | ContainedSubtype {
1617 $$ = asn1p_constraint_new(yylineno);
1618 checkmem($$);
1619 $$->type = ACT_EL_TYPE;
1620 $$->containedSubtype = $1;
1621 }
1622 | SingleValue ConstraintRangeSpec SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001623 $$ = asn1p_constraint_new(yylineno);
1624 checkmem($$);
1625 $$->type = $2;
1626 $$->range_start = $1;
1627 $$->range_stop = $3;
1628 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001629 | TOK_MIN ConstraintRangeSpec SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001630 $$ = asn1p_constraint_new(yylineno);
1631 checkmem($$);
Lev Walkinf59d0752004-08-18 04:59:12 +00001632 $$->type = $2;
1633 $$->range_start = asn1p_value_fromint(-123);
1634 $$->range_stop = $3;
1635 $$->range_start->type = ATV_MIN;
1636 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001637 | SingleValue ConstraintRangeSpec TOK_MAX {
Lev Walkinf59d0752004-08-18 04:59:12 +00001638 $$ = asn1p_constraint_new(yylineno);
1639 checkmem($$);
1640 $$->type = $2;
1641 $$->range_start = $1;
1642 $$->range_stop = asn1p_value_fromint(321);
1643 $$->range_stop->type = ATV_MAX;
1644 }
1645 | TOK_MIN ConstraintRangeSpec TOK_MAX {
1646 $$ = asn1p_constraint_new(yylineno);
1647 checkmem($$);
1648 $$->type = $2;
1649 $$->range_start = asn1p_value_fromint(-123);
1650 $$->range_stop = asn1p_value_fromint(321);
1651 $$->range_start->type = ATV_MIN;
1652 $$->range_stop->type = ATV_MAX;
Lev Walkinf15320b2004-06-03 03:38:44 +00001653 }
1654 | TableConstraint {
1655 $$ = $1;
1656 }
1657 | WithComponents {
1658 $$ = $1;
1659 }
Lev Walkin1893ddf2005-03-20 14:28:32 +00001660 | TOK_CONSTRAINED TOK_BY '{'
1661 { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
1662 $$ = asn1p_constraint_new(yylineno);
1663 checkmem($$);
1664 $$->type = ACT_CT_CTDBY;
1665 $$->value = asn1p_value_frombuf($5.buf, $5.len, 0);
1666 checkmem($$->value);
1667 $$->value->type = ATV_UNPARSED;
1668 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001669 ;
1670
1671ConstraintRangeSpec:
1672 TOK_TwoDots { $$ = ACT_EL_RANGE; }
1673 | TOK_TwoDots '<' { $$ = ACT_EL_RLRANGE; }
1674 | '<' TOK_TwoDots { $$ = ACT_EL_LLRANGE; }
1675 | '<' TOK_TwoDots '<' { $$ = ACT_EL_ULRANGE; }
1676 ;
1677
1678ConstraintSpec:
1679 TOK_SIZE {
1680 $$ = ACT_CT_SIZE;
1681 }
1682 | TOK_FROM {
1683 $$ = ACT_CT_FROM;
1684 }
1685 ;
1686
Lev Walkinff7dd142005-03-20 12:58:00 +00001687SingleValue:
Lev Walkinc8092cb2005-02-18 16:34:21 +00001688 TOK_FALSE {
1689 $$ = asn1p_value_fromint(0);
1690 checkmem($$);
1691 $$->type = ATV_FALSE;
1692 }
1693 | TOK_TRUE {
1694 $$ = asn1p_value_fromint(1);
1695 checkmem($$);
1696 $$->type = ATV_TRUE;
1697 }
1698 | SignedNumber {
Lev Walkinf15320b2004-06-03 03:38:44 +00001699 $$ = $1;
1700 }
Lev Walkin1e448d32005-03-24 14:26:38 +00001701 | RestrictedCharacterStringValue {
1702 $$ = $1;
Lev Walkinc8092cb2005-02-18 16:34:21 +00001703 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001704 | Identifier {
1705 asn1p_ref_t *ref;
1706 int ret;
1707 ref = asn1p_ref_new(yylineno);
1708 checkmem(ref);
1709 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1710 checkmem(ret == 0);
1711 $$ = asn1p_value_fromref(ref, 0);
1712 checkmem($$);
1713 free($1);
1714 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001715 ;
1716
1717ContainedSubtype:
1718 TypeRefName {
Lev Walkinc8092cb2005-02-18 16:34:21 +00001719 asn1p_ref_t *ref;
1720 int ret;
1721 ref = asn1p_ref_new(yylineno);
1722 checkmem(ref);
1723 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1724 checkmem(ret == 0);
1725 $$ = asn1p_value_fromref(ref, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001726 checkmem($$);
Lev Walkinc8092cb2005-02-18 16:34:21 +00001727 free($1);
Lev Walkinf15320b2004-06-03 03:38:44 +00001728 }
1729 ;
1730
1731WithComponents:
1732 TOK_WITH TOK_COMPONENTS '{' WithComponentsList '}' {
1733 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $4, 0);
1734 }
1735 ;
1736
1737WithComponentsList:
1738 WithComponentsElement {
1739 $$ = $1;
1740 }
1741 | WithComponentsList ',' WithComponentsElement {
1742 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $1, $3);
1743 }
1744 ;
1745
1746WithComponentsElement:
1747 TOK_ThreeDots {
1748 $$ = asn1p_constraint_new(yylineno);
1749 checkmem($$);
1750 $$->type = ACT_EL_EXT;
1751 }
1752 | Identifier optConstraints optPresenceConstraint {
1753 $$ = asn1p_constraint_new(yylineno);
1754 checkmem($$);
1755 $$->type = ACT_EL_VALUE;
1756 $$->value = asn1p_value_frombuf($1, strlen($1), 0);
1757 $$->presence = $3;
1758 }
1759 ;
1760
1761/*
1762 * presence constraint for WithComponents
1763 */
1764optPresenceConstraint:
1765 { $$ = ACPRES_DEFAULT; }
1766 | PresenceConstraint { $$ = $1; }
1767 ;
1768
1769PresenceConstraint:
1770 TOK_PRESENT {
1771 $$ = ACPRES_PRESENT;
1772 }
1773 | TOK_ABSENT {
1774 $$ = ACPRES_ABSENT;
1775 }
1776 | TOK_OPTIONAL {
1777 $$ = ACPRES_OPTIONAL;
1778 }
1779 ;
1780
1781TableConstraint:
1782 SimpleTableConstraint {
1783 $$ = $1;
1784 }
1785 | ComponentRelationConstraint {
1786 $$ = $1;
1787 }
1788 ;
1789
1790/*
1791 * "{ExtensionSet}"
1792 */
1793SimpleTableConstraint:
1794 '{' TypeRefName '}' {
1795 asn1p_ref_t *ref = asn1p_ref_new(yylineno);
1796 asn1p_constraint_t *ct;
1797 int ret;
1798 ret = asn1p_ref_add_component(ref, $2, 0);
1799 checkmem(ret == 0);
1800 ct = asn1p_constraint_new(yylineno);
1801 checkmem($$);
1802 ct->type = ACT_EL_VALUE;
1803 ct->value = asn1p_value_fromref(ref, 0);
1804 CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0);
1805 }
1806 ;
1807
1808ComponentRelationConstraint:
1809 SimpleTableConstraint '{' AtNotationList '}' {
1810 CONSTRAINT_INSERT($$, ACT_CA_CRC, $1, $3);
1811 }
1812 ;
1813
1814AtNotationList:
1815 AtNotationElement {
1816 $$ = asn1p_constraint_new(yylineno);
1817 checkmem($$);
1818 $$->type = ACT_EL_VALUE;
1819 $$->value = asn1p_value_fromref($1, 0);
1820 }
1821 | AtNotationList ',' AtNotationElement {
1822 asn1p_constraint_t *ct;
1823 ct = asn1p_constraint_new(yylineno);
1824 checkmem(ct);
1825 ct->type = ACT_EL_VALUE;
1826 ct->value = asn1p_value_fromref($3, 0);
1827 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1828 }
1829 ;
1830
1831/*
1832 * @blah
1833 */
1834AtNotationElement:
1835 '@' ComponentIdList {
1836 char *p = malloc(strlen($2) + 2);
1837 int ret;
1838 *p = '@';
1839 strcpy(p + 1, $2);
1840 $$ = asn1p_ref_new(yylineno);
1841 ret = asn1p_ref_add_component($$, p, 0);
1842 checkmem(ret == 0);
1843 free(p);
1844 free($2);
1845 }
1846 | '@' '.' ComponentIdList {
1847 char *p = malloc(strlen($3) + 3);
1848 int ret;
1849 p[0] = '@';
1850 p[1] = '.';
1851 strcpy(p + 2, $3);
1852 $$ = asn1p_ref_new(yylineno);
1853 ret = asn1p_ref_add_component($$, p, 0);
1854 checkmem(ret == 0);
1855 free(p);
1856 free($3);
1857 }
1858 ;
1859
1860/* identifier "." ... */
1861ComponentIdList:
1862 Identifier {
1863 $$ = $1;
1864 }
1865 | ComponentIdList '.' Identifier {
1866 int l1 = strlen($1);
1867 int l3 = strlen($3);
1868 $$ = malloc(l1 + 1 + l3 + 1);
1869 memcpy($$, $1, l1);
1870 $$[l1] = '.';
1871 memcpy($$ + l1 + 1, $3, l3);
1872 $$[l1 + 1 + l3] = '\0';
1873 }
1874 ;
1875
1876
1877
1878/*
1879 * MARKERS
1880 */
1881
1882optMarker:
Lev Walkin9c974182004-09-15 11:59:51 +00001883 {
1884 $$.flags = EM_NOMARK;
1885 $$.default_value = 0;
1886 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001887 | Marker { $$ = $1; }
1888 ;
1889
1890Marker:
1891 TOK_OPTIONAL {
Lev Walkin9c974182004-09-15 11:59:51 +00001892 $$.flags = EM_OPTIONAL;
1893 $$.default_value = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +00001894 }
Lev Walkin9c974182004-09-15 11:59:51 +00001895 | TOK_DEFAULT Value {
1896 $$.flags = EM_DEFAULT;
1897 $$.default_value = $2;
Lev Walkinf15320b2004-06-03 03:38:44 +00001898 }
1899 ;
1900
1901/*
1902 * Universal enumeration definition to use in INTEGER and ENUMERATED.
1903 * === EXAMPLE ===
1904 * Gender ::= ENUMERATED { unknown(0), male(1), female(2) }
1905 * Temperature ::= INTEGER { absolute-zero(-273), freezing(0), boiling(100) }
1906 * === EOF ===
1907 */
1908/*
1909optUniverationDefinition:
1910 { $$ = 0; }
1911 | UniverationDefinition {
1912 $$ = $1;
1913 }
1914 ;
1915*/
1916
1917UniverationDefinition:
1918 '{' '}' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001919 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001920 checkmem($$);
1921 }
1922 | '{' UniverationList '}' {
1923 $$ = $2;
1924 }
1925 ;
1926
1927UniverationList:
1928 UniverationElement {
Lev Walkinceb20e72004-09-05 10:40:41 +00001929 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001930 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +00001931 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +00001932 }
1933 | UniverationList ',' UniverationElement {
1934 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +00001935 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00001936 }
1937 ;
1938
1939UniverationElement:
1940 Identifier {
Lev Walkinceb20e72004-09-05 10:40:41 +00001941 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001942 checkmem($$);
1943 $$->expr_type = A1TC_UNIVERVAL;
1944 $$->meta_type = AMT_VALUE;
1945 $$->Identifier = $1;
1946 }
1947 | Identifier '(' SignedNumber ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001948 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001949 checkmem($$);
1950 $$->expr_type = A1TC_UNIVERVAL;
1951 $$->meta_type = AMT_VALUE;
1952 $$->Identifier = $1;
1953 $$->value = $3;
1954 }
1955 | Identifier '(' DefinedValue ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001956 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001957 checkmem($$);
1958 $$->expr_type = A1TC_UNIVERVAL;
1959 $$->meta_type = AMT_VALUE;
1960 $$->Identifier = $1;
1961 $$->value = $3;
1962 }
1963 | SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001964 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001965 checkmem($$);
1966 $$->expr_type = A1TC_UNIVERVAL;
1967 $$->meta_type = AMT_VALUE;
1968 $$->value = $1;
1969 }
1970 | TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001971 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001972 checkmem($$);
1973 $$->Identifier = strdup("...");
1974 checkmem($$->Identifier);
1975 $$->expr_type = A1TC_EXTENSIBLE;
1976 $$->meta_type = AMT_VALUE;
1977 }
1978 ;
1979
1980SignedNumber:
1981 TOK_number {
1982 $$ = asn1p_value_fromint($1);
1983 checkmem($$);
1984 }
1985 | TOK_number_negative {
1986 $$ = asn1p_value_fromint($1);
1987 checkmem($$);
1988 }
1989 ;
1990
1991/*
1992 * SEQUENCE definition.
1993 * === EXAMPLE ===
1994 * Struct1 ::= SEQUENCE {
1995 * memb1 Struct2,
1996 * memb2 SEQUENCE OF {
1997 * memb2-1 Struct 3
1998 * }
1999 * }
2000 * === EOF ===
2001 */
2002
2003
2004
2005/*
2006 * SET definition.
2007 * === EXAMPLE ===
2008 * Person ::= SET {
2009 * name [0] PrintableString (SIZE(1..20)),
2010 * country [1] PrintableString (SIZE(1..20)) DEFAULT default-country,
2011 * }
2012 * === EOF ===
2013 */
2014
2015optTag:
2016 { memset(&$$, 0, sizeof($$)); }
2017 | Tag { $$ = $1; }
2018 ;
2019
2020Tag:
Lev Walkinc603f102005-01-23 09:51:44 +00002021 TagTypeValue TagPlicit {
Lev Walkinf15320b2004-06-03 03:38:44 +00002022 $$ = $1;
Lev Walkinc603f102005-01-23 09:51:44 +00002023 $$.tag_mode = $2.tag_mode;
Lev Walkinf15320b2004-06-03 03:38:44 +00002024 }
Lev Walkinc603f102005-01-23 09:51:44 +00002025 ;
2026
2027TagTypeValue:
2028 '[' TagClass TOK_number ']' {
2029 $$ = $2;
2030 $$.tag_value = $3;
2031 };
2032
2033TagClass:
2034 { $$.tag_class = TC_CONTEXT_SPECIFIC; }
2035 | TOK_UNIVERSAL { $$.tag_class = TC_UNIVERSAL; }
2036 | TOK_APPLICATION { $$.tag_class = TC_APPLICATION; }
2037 | TOK_PRIVATE { $$.tag_class = TC_PRIVATE; }
2038 ;
2039
2040TagPlicit:
2041 { $$.tag_mode = TM_DEFAULT; }
2042 | TOK_IMPLICIT { $$.tag_mode = TM_IMPLICIT; }
2043 | TOK_EXPLICIT { $$.tag_mode = TM_EXPLICIT; }
Lev Walkinf15320b2004-06-03 03:38:44 +00002044 ;
2045
2046TypeRefName:
2047 TOK_typereference {
2048 checkmem($1);
2049 $$ = $1;
2050 }
Lev Walkinf59d0752004-08-18 04:59:12 +00002051 | TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00002052 checkmem($1);
2053 $$ = $1;
2054 }
2055 ;
2056
Lev Walkinf59d0752004-08-18 04:59:12 +00002057
Lev Walkinf15320b2004-06-03 03:38:44 +00002058ObjectClassReference:
Lev Walkinf59d0752004-08-18 04:59:12 +00002059 TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00002060 checkmem($1);
2061 $$ = $1;
2062 }
2063 ;
2064
Lev Walkin83cac2f2004-09-22 16:03:36 +00002065optIdentifier:
2066 { $$ = 0; }
2067 | Identifier {
2068 $$ = $1;
2069 }
2070
Lev Walkinf15320b2004-06-03 03:38:44 +00002071Identifier:
2072 TOK_identifier {
2073 checkmem($1);
2074 $$ = $1;
2075 }
2076 ;
2077
Lev Walkinf15320b2004-06-03 03:38:44 +00002078%%
2079
2080
2081/*
2082 * Convert Xstring ('0101'B or '5'H) to the binary vector.
2083 */
2084static asn1p_value_t *
2085_convert_bitstring2binary(char *str, int base) {
2086 asn1p_value_t *val;
2087 int slen;
2088 int memlen;
2089 int baselen;
2090 int bits;
2091 uint8_t *binary_vector;
2092 uint8_t *bv_ptr;
2093 uint8_t cur_val;
2094
2095 assert(str);
2096 assert(str[0] == '\'');
2097
2098 switch(base) {
2099 case 'B':
2100 baselen = 1;
2101 break;
2102 case 'H':
2103 baselen = 4;
2104 break;
2105 default:
2106 assert(base == 'B' || base == 'H');
2107 errno = EINVAL;
2108 return NULL;
2109 }
2110
2111 slen = strlen(str);
2112 assert(str[slen - 1] == base);
2113 assert(str[slen - 2] == '\'');
2114
2115 memlen = slen / (8 / baselen); /* Conservative estimate */
2116
2117 bv_ptr = binary_vector = malloc(memlen + 1);
2118 if(bv_ptr == NULL)
2119 /* ENOMEM */
2120 return NULL;
2121
2122 cur_val = 0;
2123 bits = 0;
2124 while(*(++str) != '\'') {
2125 switch(baselen) {
2126 case 1:
2127 switch(*str) {
2128 case '1':
2129 cur_val |= 1 << (7 - (bits % 8));
2130 case '0':
2131 break;
2132 default:
2133 assert(!"_y UNREACH1");
2134 case ' ': case '\r': case '\n':
2135 continue;
2136 }
2137 break;
2138 case 4:
2139 switch(*str) {
2140 case '0': case '1': case '2': case '3': case '4':
2141 case '5': case '6': case '7': case '8': case '9':
2142 cur_val |= (*str - '0') << (4 - (bits % 8));
2143 break;
2144 case 'A': case 'B': case 'C':
2145 case 'D': case 'E': case 'F':
2146 cur_val |= ((*str - 'A') + 10)
2147 << (4 - (bits % 8));
2148 break;
2149 default:
2150 assert(!"_y UNREACH2");
2151 case ' ': case '\r': case '\n':
2152 continue;
2153 }
2154 break;
2155 }
2156
2157 bits += baselen;
2158 if((bits % 8) == 0) {
2159 *bv_ptr++ = cur_val;
2160 cur_val = 0;
2161 }
2162 }
2163
2164 *bv_ptr = cur_val;
2165 assert((bv_ptr - binary_vector) <= memlen);
2166
2167 val = asn1p_value_frombits(binary_vector, bits, 0);
2168 if(val == NULL) {
2169 free(binary_vector);
2170 }
2171
2172 return val;
2173}
2174
2175extern char *asn1p_text;
2176
2177int
2178yyerror(const char *msg) {
2179 fprintf(stderr,
2180 "ASN.1 grammar parse error "
2181 "near line %d (token \"%s\"): %s\n",
Lev Walkinceb20e72004-09-05 10:40:41 +00002182 yylineno, asn1p_text, msg);
Lev Walkinf15320b2004-06-03 03:38:44 +00002183 return -1;
2184}
2185
2186