blob: a4842e250581f6a6289b60678a4d09df4b4cb6bf [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
Lev Walkind9574ae2005-03-24 16:22:35 +0000101%token <a_int> TOK_tuple
102%token <a_int> TOK_quadruple
Lev Walkinf15320b2004-06-03 03:38:44 +0000103%token <a_int> TOK_number_negative
104%token <tv_str> TOK_typereference
Lev Walkinf59d0752004-08-18 04:59:12 +0000105%token <tv_str> TOK_capitalreference /* "CLASS1" */
Lev Walkinf15320b2004-06-03 03:38:44 +0000106%token <tv_str> TOK_typefieldreference /* "&Pork" */
107%token <tv_str> TOK_valuefieldreference /* "&id" */
108
109/*
110 * Token types representing ASN.1 standard keywords.
111 */
112%token TOK_ABSENT
113%token TOK_ABSTRACT_SYNTAX
114%token TOK_ALL
115%token TOK_ANY
116%token TOK_APPLICATION
117%token TOK_AUTOMATIC
118%token TOK_BEGIN
119%token TOK_BIT
120%token TOK_BMPString
121%token TOK_BOOLEAN
122%token TOK_BY
123%token TOK_CHARACTER
124%token TOK_CHOICE
125%token TOK_CLASS
126%token TOK_COMPONENT
127%token TOK_COMPONENTS
128%token TOK_CONSTRAINED
129%token TOK_CONTAINING
130%token TOK_DEFAULT
131%token TOK_DEFINITIONS
132%token TOK_DEFINED
133%token TOK_EMBEDDED
134%token TOK_ENCODED
Lev Walkinf59d0752004-08-18 04:59:12 +0000135%token TOK_ENCODING_CONTROL
Lev Walkinf15320b2004-06-03 03:38:44 +0000136%token TOK_END
137%token TOK_ENUMERATED
138%token TOK_EXPLICIT
139%token TOK_EXPORTS
140%token TOK_EXTENSIBILITY
141%token TOK_EXTERNAL
142%token TOK_FALSE
143%token TOK_FROM
144%token TOK_GeneralizedTime
145%token TOK_GeneralString
146%token TOK_GraphicString
147%token TOK_IA5String
148%token TOK_IDENTIFIER
149%token TOK_IMPLICIT
150%token TOK_IMPLIED
151%token TOK_IMPORTS
152%token TOK_INCLUDES
153%token TOK_INSTANCE
Lev Walkinf59d0752004-08-18 04:59:12 +0000154%token TOK_INSTRUCTIONS
Lev Walkinf15320b2004-06-03 03:38:44 +0000155%token TOK_INTEGER
156%token TOK_ISO646String
157%token TOK_MAX
158%token TOK_MIN
159%token TOK_MINUS_INFINITY
160%token TOK_NULL
161%token TOK_NumericString
162%token TOK_OBJECT
163%token TOK_ObjectDescriptor
164%token TOK_OCTET
165%token TOK_OF
166%token TOK_OPTIONAL
167%token TOK_PATTERN
168%token TOK_PDV
169%token TOK_PLUS_INFINITY
170%token TOK_PRESENT
171%token TOK_PrintableString
172%token TOK_PRIVATE
173%token TOK_REAL
174%token TOK_RELATIVE_OID
175%token TOK_SEQUENCE
176%token TOK_SET
177%token TOK_SIZE
178%token TOK_STRING
179%token TOK_SYNTAX
180%token TOK_T61String
181%token TOK_TAGS
182%token TOK_TeletexString
183%token TOK_TRUE
184%token TOK_TYPE_IDENTIFIER
185%token TOK_UNIQUE
186%token TOK_UNIVERSAL
187%token TOK_UniversalString
188%token TOK_UTCTime
189%token TOK_UTF8String
190%token TOK_VideotexString
191%token TOK_VisibleString
192%token TOK_WITH
193
Lev Walkinf15320b2004-06-03 03:38:44 +0000194%left TOK_EXCEPT
Lev Walkinf59d0752004-08-18 04:59:12 +0000195%left '^' TOK_INTERSECTION
196%left '|' TOK_UNION
Lev Walkinf15320b2004-06-03 03:38:44 +0000197
198/* Misc tags */
199%token TOK_TwoDots /* .. */
200%token TOK_ThreeDots /* ... */
Lev Walkinf15320b2004-06-03 03:38:44 +0000201
202
203/*
204 * Types defined herein.
205 */
206%type <a_grammar> ModuleList
207%type <a_module> ModuleSpecification
208%type <a_module> ModuleSpecificationBody
209%type <a_module> ModuleSpecificationElement
210%type <a_module> optModuleSpecificationBody /* Optional */
211%type <a_module_flags> optModuleSpecificationFlags
212%type <a_module_flags> ModuleSpecificationFlags /* Set of FL */
213%type <a_module_flags> ModuleSpecificationFlag /* Single FL */
214%type <a_module> ImportsDefinition
215%type <a_module> ImportsBundleSet
216%type <a_xports> ImportsBundle
217%type <a_xports> ImportsList
218%type <a_xports> ExportsDefinition
219%type <a_xports> ExportsBody
220%type <a_expr> ImportsElement
221%type <a_expr> ExportsElement
Lev Walkinf15320b2004-06-03 03:38:44 +0000222%type <a_expr> ExtensionAndException
Lev Walkin070a52d2004-08-22 03:19:54 +0000223%type <a_expr> TypeDeclaration
Lev Walkinf15320b2004-06-03 03:38:44 +0000224%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
Lev Walkin070a52d2004-08-22 03:19:54 +0000232%type <a_expr> Type
Lev Walkinf15320b2004-06-03 03:38:44 +0000233%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*/
Lev Walkinceb20e72004-09-05 10:40:41 +0000237%type <a_expr> optValueSetBody
238%type <a_expr> ValueSetBody
239%type <a_expr> ValueSetElement
Lev Walkin9c974182004-09-15 11:59:51 +0000240%type <a_value> Value
Lev Walkinf15320b2004-06-03 03:38:44 +0000241%type <a_value> DefinedValue
242%type <a_value> SignedNumber
Lev Walkin144db9b2004-10-12 23:26:53 +0000243%type <a_expr> optComponentTypeLists
Lev Walkin070a52d2004-08-22 03:19:54 +0000244%type <a_expr> ComponentTypeLists
245%type <a_expr> ComponentType
246%type <a_expr> AlternativeTypeLists
247%type <a_expr> AlternativeType
Lev Walkinf15320b2004-06-03 03:38:44 +0000248//%type <a_expr> optUniverationDefinition
249%type <a_expr> UniverationDefinition
250%type <a_expr> UniverationList
251%type <a_expr> UniverationElement
252%type <tv_str> TypeRefName
253%type <tv_str> ObjectClassReference
Lev Walkinf15320b2004-06-03 03:38:44 +0000254%type <tv_str> Identifier
Lev Walkin83cac2f2004-09-22 16:03:36 +0000255%type <tv_str> optIdentifier
Lev Walkinf15320b2004-06-03 03:38:44 +0000256%type <a_parg> ParameterArgumentName
257%type <a_plist> ParameterArgumentList
258%type <a_expr> ActualParameter
259%type <a_expr> ActualParameterList
260%type <a_oid> ObjectIdentifier /* OID */
261%type <a_oid> optObjectIdentifier /* Optional OID */
262%type <a_oid> ObjectIdentifierBody
263%type <a_oid_arc> ObjectIdentifierElement
264%type <a_expr> BasicType
265%type <a_type> BasicTypeId
266%type <a_type> BasicTypeId_UniverationCompatible
267%type <a_type> BasicString
268%type <tv_opaque> Opaque
269//%type <tv_opaque> StringValue
Lev Walkinc603f102005-01-23 09:51:44 +0000270%type <a_tag> Tag /* [UNIVERSAL 0] IMPLICIT */
271%type <a_tag> TagClass TagTypeValue TagPlicit
Lev Walkinf15320b2004-06-03 03:38:44 +0000272%type <a_tag> optTag /* [UNIVERSAL 0] IMPLICIT */
273%type <a_constr> optConstraints
Lev Walkind2ea1de2004-08-20 13:25:29 +0000274%type <a_constr> Constraints
Lev Walkinf59d0752004-08-18 04:59:12 +0000275%type <a_constr> SetOfConstraints
276%type <a_constr> ElementSetSpecs /* 1..2,...,3 */
277%type <a_constr> ElementSetSpec /* 1..2,...,3 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000278%type <a_constr> ConstraintSubtypeElement /* 1..2 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000279%type <a_constr> SimpleTableConstraint
280%type <a_constr> TableConstraint
Lev Walkine596bf02005-03-28 15:01:27 +0000281%type <a_constr> InnerTypeConstraint
Lev Walkinf15320b2004-06-03 03:38:44 +0000282%type <a_constr> WithComponentsList
283%type <a_constr> WithComponentsElement
284%type <a_constr> ComponentRelationConstraint
285%type <a_constr> AtNotationList
286%type <a_ref> AtNotationElement
Lev Walkinff7dd142005-03-20 12:58:00 +0000287%type <a_value> SingleValue
288%type <a_value> ContainedSubtype
Lev Walkinf15320b2004-06-03 03:38:44 +0000289%type <a_ctype> ConstraintSpec
290%type <a_ctype> ConstraintRangeSpec
Lev Walkin1e448d32005-03-24 14:26:38 +0000291%type <a_value> RestrictedCharacterStringValue
Lev Walkinf15320b2004-06-03 03:38:44 +0000292%type <a_wsynt> optWithSyntax
293%type <a_wsynt> WithSyntax
294%type <a_wsynt> WithSyntaxFormat
295%type <a_wchunk> WithSyntaxFormatToken
296%type <a_marker> optMarker Marker
297%type <a_int> optUnique
298%type <a_pres> optPresenceConstraint PresenceConstraint
299%type <tv_str> ComponentIdList
300
301
302%%
303
304
305ParsedGrammar:
306 ModuleList {
307 *(void **)param = $1;
308 }
309 ;
310
311ModuleList:
312 ModuleSpecification {
313 $$ = asn1p_new();
314 checkmem($$);
315 TQ_ADD(&($$->modules), $1, mod_next);
316 }
317 | ModuleList ModuleSpecification {
318 $$ = $1;
319 TQ_ADD(&($$->modules), $2, mod_next);
320 }
321 ;
322
323/*
324 * ASN module definition.
325 * === EXAMPLE ===
326 * MySyntax DEFINITIONS AUTOMATIC TAGS ::=
327 * BEGIN
328 * ...
329 * END
330 * === EOF ===
331 */
332
333ModuleSpecification:
334 TypeRefName optObjectIdentifier TOK_DEFINITIONS
335 optModuleSpecificationFlags
336 TOK_PPEQ TOK_BEGIN
337 optModuleSpecificationBody
338 TOK_END {
339
340 if($7) {
341 $$ = $7;
342 } else {
343 /* There's a chance that a module is just plain empty */
344 $$ = asn1p_module_new();
345 }
346 checkmem($$);
347
348 $$->Identifier = $1;
349 $$->module_oid = $2;
350 $$->module_flags = $4;
351 }
352 ;
353
354/*
355 * Object Identifier Definition
356 * { iso member-body(2) 3 }
357 */
358optObjectIdentifier:
359 { $$ = 0; }
360 | ObjectIdentifier { $$ = $1; }
361 ;
362
363ObjectIdentifier:
364 '{' ObjectIdentifierBody '}' {
365 $$ = $2;
366 }
367 | '{' '}' {
368 $$ = 0;
369 }
370 ;
371
372ObjectIdentifierBody:
373 ObjectIdentifierElement {
374 $$ = asn1p_oid_new();
375 asn1p_oid_add_arc($$, &$1);
376 if($1.name)
377 free($1.name);
378 }
379 | ObjectIdentifierBody ObjectIdentifierElement {
380 $$ = $1;
381 asn1p_oid_add_arc($$, &$2);
382 if($2.name)
383 free($2.name);
384 }
385 ;
386
387ObjectIdentifierElement:
388 Identifier { /* iso */
389 $$.name = $1;
390 $$.number = -1;
391 }
392 | Identifier '(' TOK_number ')' { /* iso(1) */
393 $$.name = $1;
394 $$.number = $3;
395 }
396 | TOK_number { /* 1 */
397 $$.name = 0;
398 $$.number = $1;
399 }
400 ;
401
402/*
403 * Optional module flags.
404 */
405optModuleSpecificationFlags:
406 { $$ = MSF_NOFLAGS; }
407 | ModuleSpecificationFlags {
408 $$ = $1;
409 }
410 ;
411
412/*
413 * Module flags.
414 */
415ModuleSpecificationFlags:
416 ModuleSpecificationFlag {
417 $$ = $1;
418 }
419 | ModuleSpecificationFlags ModuleSpecificationFlag {
420 $$ = $1 | $2;
421 }
422 ;
423
424/*
425 * Single module flag.
426 */
427ModuleSpecificationFlag:
428 TOK_EXPLICIT TOK_TAGS {
429 $$ = MSF_EXPLICIT_TAGS;
430 }
431 | TOK_IMPLICIT TOK_TAGS {
432 $$ = MSF_IMPLICIT_TAGS;
433 }
434 | TOK_AUTOMATIC TOK_TAGS {
435 $$ = MSF_AUTOMATIC_TAGS;
436 }
437 | TOK_EXTENSIBILITY TOK_IMPLIED {
438 $$ = MSF_EXTENSIBILITY_IMPLIED;
439 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000440 /* EncodingReferenceDefault */
441 | TOK_capitalreference TOK_INSTRUCTIONS {
442 /* X.680Amd1 specifies TAG and XER */
443 if(strcmp($1, "TAG") == 0) {
444 $$ = MSF_TAG_INSTRUCTIONS;
445 } else if(strcmp($1, "XER") == 0) {
446 $$ = MSF_XER_INSTRUCTIONS;
447 } else {
448 fprintf(stderr,
449 "WARNING: %s INSTRUCTIONS at line %d: "
450 "Unrecognized encoding reference\n",
451 $1, yylineno);
452 $$ = MSF_unk_INSTRUCTIONS;
453 }
454 free($1);
455 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000456 ;
457
458/*
459 * Optional module body.
460 */
461optModuleSpecificationBody:
462 { $$ = 0; }
463 | ModuleSpecificationBody {
Lev Walkinf15320b2004-06-03 03:38:44 +0000464 $$ = $1;
465 }
466 ;
467
468/*
469 * ASN.1 Module body.
470 */
471ModuleSpecificationBody:
472 ModuleSpecificationElement {
473 $$ = $1;
474 }
475 | ModuleSpecificationBody ModuleSpecificationElement {
476 $$ = $1;
477
Lev Walkinf59d0752004-08-18 04:59:12 +0000478 /* Behave well when one of them is skipped. */
479 if(!($1)) {
480 if($2) $$ = $2;
481 break;
482 }
483
Lev Walkinf15320b2004-06-03 03:38:44 +0000484#ifdef MY_IMPORT
485#error MY_IMPORT DEFINED ELSEWHERE!
486#endif
487#define MY_IMPORT(foo,field) do { \
Lev Walkinbc55d232004-08-13 12:31:09 +0000488 while(TQ_FIRST(&($2->foo))) { \
Lev Walkinf15320b2004-06-03 03:38:44 +0000489 TQ_ADD(&($$->foo), \
490 TQ_REMOVE(&($2->foo), field), \
491 field); \
Lev Walkinbc55d232004-08-13 12:31:09 +0000492 } \
493 assert(TQ_FIRST(&($2->foo)) == 0); \
494 } while(0)
Lev Walkinf15320b2004-06-03 03:38:44 +0000495
496 MY_IMPORT(imports, xp_next);
497 MY_IMPORT(exports, xp_next);
498 MY_IMPORT(members, next);
499#undef MY_IMPORT
500
501 }
502 ;
503
504/*
505 * One of the elements of ASN.1 module specification.
506 */
507ModuleSpecificationElement:
508 ImportsDefinition {
509 $$ = $1;
510 }
511 | ExportsDefinition {
512 $$ = asn1p_module_new();
513 checkmem($$);
514 if($1) {
515 TQ_ADD(&($$->exports), $1, xp_next);
516 } else {
517 /* "EXPORTS ALL;" ? */
518 }
519 }
520 | DataTypeReference {
521 $$ = asn1p_module_new();
522 checkmem($$);
523 assert($1->expr_type != A1TC_INVALID);
524 assert($1->meta_type != AMT_INVALID);
525 TQ_ADD(&($$->members), $1, next);
526 }
527 | ValueDefinition {
528 $$ = asn1p_module_new();
529 checkmem($$);
530 assert($1->expr_type != A1TC_INVALID);
531 assert($1->meta_type != AMT_INVALID);
532 TQ_ADD(&($$->members), $1, next);
533 }
534 /*
535 * Value set definition
536 * === EXAMPLE ===
537 * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 }
538 * === EOF ===
539 */
540 | ValueSetDefinition {
541 $$ = asn1p_module_new();
542 checkmem($$);
543 assert($1->expr_type != A1TC_INVALID);
544 assert($1->meta_type != AMT_INVALID);
545 TQ_ADD(&($$->members), $1, next);
546 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000547 | TOK_ENCODING_CONTROL TOK_capitalreference
548 { asn1p_lexer_hack_push_encoding_control(); }
549 {
550 fprintf(stderr,
551 "WARNING: ENCODING-CONTROL %s "
552 "specification at line %d ignored\n",
553 $2, yylineno);
554 free($2);
555 $$ = 0;
556 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000557
558 /*
559 * Erroneous attemps
560 */
561 | BasicString {
562 return yyerror(
563 "Attempt to redefine a standard basic type, "
564 "use -ftypesXY to switch back "
565 "to older version of ASN.1 standard");
566 }
567 ;
568
569/*
570 * === EXAMPLE ===
571 * IMPORTS Type1, value FROM Module { iso standard(0) } ;
572 * === EOF ===
573 */
574ImportsDefinition:
575 TOK_IMPORTS ImportsBundleSet ';' {
576 $$ = $2;
577 }
578 /*
579 * Some error cases.
580 */
581 | TOK_IMPORTS TOK_FROM /* ... */ {
582 return yyerror("Empty IMPORTS list");
583 }
584 ;
585
586ImportsBundleSet:
587 ImportsBundle {
588 $$ = asn1p_module_new();
589 checkmem($$);
590 TQ_ADD(&($$->imports), $1, xp_next);
591 }
592 | ImportsBundleSet ImportsBundle {
593 $$ = $1;
594 TQ_ADD(&($$->imports), $2, xp_next);
595 }
596 ;
597
598ImportsBundle:
599 ImportsList TOK_FROM TypeRefName optObjectIdentifier {
600 $$ = $1;
601 $$->from = $3;
602 $$->from_oid = $4;
603 checkmem($$);
604 }
605 ;
606
607ImportsList:
608 ImportsElement {
609 $$ = asn1p_xports_new();
610 checkmem($$);
611 TQ_ADD(&($$->members), $1, next);
612 }
613 | ImportsList ',' ImportsElement {
614 $$ = $1;
615 TQ_ADD(&($$->members), $3, next);
616 }
617 ;
618
619ImportsElement:
620 TypeRefName {
621 $$ = asn1p_expr_new(yylineno);
622 checkmem($$);
623 $$->Identifier = $1;
624 $$->expr_type = A1TC_REFERENCE;
625 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000626 | TypeRefName '{' '}' { /* Completely equivalent to above */
627 $$ = asn1p_expr_new(yylineno);
628 checkmem($$);
629 $$->Identifier = $1;
630 $$->expr_type = A1TC_REFERENCE;
631 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000632 | Identifier {
633 $$ = asn1p_expr_new(yylineno);
634 checkmem($$);
635 $$->Identifier = $1;
636 $$->expr_type = A1TC_REFERENCE;
637 }
638 ;
639
640ExportsDefinition:
641 TOK_EXPORTS ExportsBody ';' {
642 $$ = $2;
643 }
644 | TOK_EXPORTS TOK_ALL ';' {
645 $$ = 0;
646 }
647 | TOK_EXPORTS ';' {
648 /* Empty EXPORTS clause effectively prohibits export. */
649 $$ = asn1p_xports_new();
650 checkmem($$);
651 }
652 ;
653
654ExportsBody:
655 ExportsElement {
656 $$ = asn1p_xports_new();
657 assert($$);
658 TQ_ADD(&($$->members), $1, next);
659 }
660 | ExportsBody ',' ExportsElement {
661 $$ = $1;
662 TQ_ADD(&($$->members), $3, next);
663 }
664 ;
665
666ExportsElement:
667 TypeRefName {
668 $$ = asn1p_expr_new(yylineno);
669 checkmem($$);
670 $$->Identifier = $1;
671 $$->expr_type = A1TC_EXPORTVAR;
672 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000673 | TypeRefName '{' '}' {
674 $$ = asn1p_expr_new(yylineno);
675 checkmem($$);
676 $$->Identifier = $1;
677 $$->expr_type = A1TC_EXPORTVAR;
678 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000679 | Identifier {
680 $$ = asn1p_expr_new(yylineno);
681 checkmem($$);
682 $$->Identifier = $1;
683 $$->expr_type = A1TC_EXPORTVAR;
684 }
685 ;
686
687
688ValueSetDefinition:
689 TypeRefName DefinedTypeRef TOK_PPEQ '{' optValueSetBody '}' {
690 $$ = $2;
691 assert($$->Identifier == 0);
692 $$->Identifier = $1;
693 $$->meta_type = AMT_VALUESET;
694 // take care of optValueSetBody
695 }
696 ;
697
698DefinedTypeRef:
699 ComplexTypeReference {
700 $$ = asn1p_expr_new(yylineno);
701 checkmem($$);
702 $$->reference = $1;
703 $$->expr_type = A1TC_REFERENCE;
704 $$->meta_type = AMT_TYPEREF;
705 }
706 | BasicTypeId {
707 $$ = asn1p_expr_new(yylineno);
708 checkmem($$);
709 $$->expr_type = $1;
710 $$->meta_type = AMT_TYPE;
711 }
712 ;
713
714optValueSetBody:
715 { }
Lev Walkinceb20e72004-09-05 10:40:41 +0000716 | ValueSetBody {
717 }
718 ;
719
720/*
721 * X.680 does not permit ElementSetSpecs starting with ellipsis,
722 * i.e. (..., A, B). This is very strange: the ElementSetSpecs is used
723 * inside ValueSet, and ValueSets "in the wild" tend to have the first
724 * ellipsis.
725 */
726ValueSetBody:
727 ValueSetElement {
728 }
729 | ValueSetBody ',' ValueSetElement {
730 }
731 ;
732
733ValueSetElement:
734 TOK_ThreeDots {
735 }
736 | ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +0000737 }
738 ;
739
740
741/*
742 * Data Type Reference.
743 * === EXAMPLE ===
744 * Type3 ::= CHOICE { a Type1, b Type 2 }
745 * === EOF ===
746 */
747
748DataTypeReference:
749 /*
750 * Optionally tagged type definition.
751 */
752 TypeRefName TOK_PPEQ optTag TOK_TYPE_IDENTIFIER {
753 $$ = asn1p_expr_new(yylineno);
754 checkmem($$);
755 $$->Identifier = $1;
756 $$->tag = $3;
757 $$->expr_type = A1TC_TYPEID;
758 $$->meta_type = AMT_TYPE;
759 }
Lev Walkinaf120f72004-09-14 02:36:39 +0000760 | TypeRefName TOK_PPEQ Type {
761 $$ = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000762 $$->Identifier = $1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000763 assert($$->expr_type);
764 assert($$->meta_type);
765 }
766 | TypeRefName TOK_PPEQ ClassDeclaration {
767 $$ = $3;
768 $$->Identifier = $1;
769 assert($$->expr_type == A1TC_CLASSDEF);
770 assert($$->meta_type == AMT_OBJECT);
771 }
772 /*
773 * Parametrized <Type> declaration:
774 * === EXAMPLE ===
775 * SIGNED { ToBeSigned } ::= SEQUENCE {
776 * toBeSigned ToBeSigned,
777 * algorithm AlgorithmIdentifier,
778 * signature BIT STRING
779 * }
780 * === EOF ===
781 */
Lev Walkin070a52d2004-08-22 03:19:54 +0000782 | TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000783 $$ = $6;
784 assert($$->Identifier == 0);
785 $$->Identifier = $1;
786 $$->params = $3;
787 $$->meta_type = AMT_PARAMTYPE;
788 }
789 ;
790
791ParameterArgumentList:
792 ParameterArgumentName {
793 int ret;
794 $$ = asn1p_paramlist_new(yylineno);
795 checkmem($$);
796 ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument);
797 checkmem(ret == 0);
798 if($1.governor) asn1p_ref_free($1.governor);
799 if($1.argument) free($1.argument);
800 }
801 | ParameterArgumentList ',' ParameterArgumentName {
802 int ret;
803 $$ = $1;
804 ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument);
805 checkmem(ret == 0);
806 if($3.governor) asn1p_ref_free($3.governor);
807 if($3.argument) free($3.argument);
808 }
809 ;
810
811ParameterArgumentName:
812 TypeRefName {
813 $$.governor = NULL;
814 $$.argument = $1;
815 }
816 | TypeRefName ':' Identifier {
817 int ret;
818 $$.governor = asn1p_ref_new(yylineno);
819 ret = asn1p_ref_add_component($$.governor, $1, 0);
820 checkmem(ret == 0);
821 $$.argument = $3;
822 }
Lev Walkinc8092cb2005-02-18 16:34:21 +0000823 | TypeRefName ':' TypeRefName {
824 int ret;
825 $$.governor = asn1p_ref_new(yylineno);
826 ret = asn1p_ref_add_component($$.governor, $1, 0);
827 checkmem(ret == 0);
828 $$.argument = $3;
829 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000830 | BasicTypeId ':' Identifier {
831 int ret;
832 $$.governor = asn1p_ref_new(yylineno);
833 ret = asn1p_ref_add_component($$.governor,
834 ASN_EXPR_TYPE2STR($1), 1);
835 checkmem(ret == 0);
836 $$.argument = $3;
837 }
838 ;
839
840ActualParameterList:
841 ActualParameter {
842 $$ = asn1p_expr_new(yylineno);
843 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000844 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000845 }
846 | ActualParameterList ',' ActualParameter {
847 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000848 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000849 }
850 ;
851
852ActualParameter:
Lev Walkin070a52d2004-08-22 03:19:54 +0000853 Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000854 $$ = $1;
855 }
856 | Identifier {
857 $$ = asn1p_expr_new(yylineno);
858 checkmem($$);
859 $$->Identifier = $1;
860 $$->expr_type = A1TC_REFERENCE;
861 $$->meta_type = AMT_VALUE;
862 }
863 ;
864
865/*
Lev Walkinc8092cb2005-02-18 16:34:21 +0000866 | '{' ActualParameter '}' {
867 $$ = asn1p_expr_new(yylineno);
868 checkmem($$);
869 asn1p_expr_add($$, $2);
870 $$->expr_type = A1TC_PARAMETRIZED;
871 $$->meta_type = AMT_TYPE;
872 }
873 ;
874*/
875
876/*
Lev Walkinf15320b2004-06-03 03:38:44 +0000877 * A collection of constructed data type members.
878 */
Lev Walkin144db9b2004-10-12 23:26:53 +0000879optComponentTypeLists:
880 { $$ = asn1p_expr_new(yylineno); }
881 | ComponentTypeLists { $$ = $1; };
882
Lev Walkin070a52d2004-08-22 03:19:54 +0000883ComponentTypeLists:
884 ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000885 $$ = asn1p_expr_new(yylineno);
886 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000887 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000888 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000889 | ComponentTypeLists ',' ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000890 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000891 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000892 }
893 ;
894
Lev Walkin070a52d2004-08-22 03:19:54 +0000895ComponentType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000896 Identifier Type optMarker {
Lev Walkin070a52d2004-08-22 03:19:54 +0000897 $$ = $2;
898 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000899 $$->Identifier = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000900 $$->marker = $3;
901 }
902 | TOK_COMPONENTS TOK_OF Type {
903 $$ = asn1p_expr_new(yylineno);
904 checkmem($$);
905 $$->meta_type = $3->meta_type;
906 $$->expr_type = A1TC_COMPONENTS_OF;
Lev Walkin1004aa92004-09-08 00:28:11 +0000907 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000908 }
909 | ExtensionAndException {
910 $$ = $1;
911 }
912 ;
913
914AlternativeTypeLists:
915 AlternativeType {
916 $$ = asn1p_expr_new(yylineno);
917 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000918 asn1p_expr_add($$, $1);
Lev Walkin070a52d2004-08-22 03:19:54 +0000919 }
920 | AlternativeTypeLists ',' AlternativeType {
921 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000922 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000923 }
924 ;
925
926AlternativeType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000927 Identifier Type {
Lev Walkin070a52d2004-08-22 03:19:54 +0000928 $$ = $2;
929 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000930 $$->Identifier = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000931 }
932 | ExtensionAndException {
933 $$ = $1;
934 }
935 ;
936
Lev Walkinf15320b2004-06-03 03:38:44 +0000937ClassDeclaration:
938 TOK_CLASS '{' ClassFieldList '}' optWithSyntax {
939 $$ = $3;
940 checkmem($$);
941 $$->with_syntax = $5;
942 assert($$->expr_type == A1TC_CLASSDEF);
943 assert($$->meta_type == AMT_OBJECT);
944 }
945 ;
946
947optUnique:
948 { $$ = 0; }
949 | TOK_UNIQUE { $$ = 1; }
950 ;
951
952ClassFieldList:
953 ClassField {
954 $$ = asn1p_expr_new(yylineno);
955 checkmem($$);
956 $$->expr_type = A1TC_CLASSDEF;
957 $$->meta_type = AMT_OBJECT;
Lev Walkin1004aa92004-09-08 00:28:11 +0000958 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000959 }
960 | ClassFieldList ',' ClassField {
961 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000962 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000963 }
964 ;
965
966ClassField:
967 ClassFieldIdentifier optMarker {
968 $$ = asn1p_expr_new(yylineno);
969 checkmem($$);
970 $$->Identifier = $1.name;
971 $$->expr_type = A1TC_CLASSFIELD;
972 $$->meta_type = AMT_OBJECTFIELD;
973 $$->marker = $2;
974 }
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000975 | ClassFieldIdentifier Type optUnique optMarker {
Lev Walkinf15320b2004-06-03 03:38:44 +0000976 $$ = $2;
977 $$->Identifier = $1.name;
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000978 $$->marker = $4;
979 $$->unique = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000980 }
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000981 | ClassFieldIdentifier ClassFieldIdentifier optUnique optMarker {
Lev Walkinf15320b2004-06-03 03:38:44 +0000982 int ret;
983 $$ = asn1p_expr_new(yylineno);
984 checkmem($$);
985 $$->Identifier = $1.name;
986 $$->reference = asn1p_ref_new(yylineno);
987 checkmem($$->reference);
988 ret = asn1p_ref_add_component($$->reference,
989 $2.name, $2.lex_type);
990 checkmem(ret == 0);
991 $$->expr_type = A1TC_CLASSFIELD;
992 $$->meta_type = AMT_OBJECTFIELD;
Lev Walkinb7c45ca2004-11-24 17:43:29 +0000993 $$->marker = $4;
994 $$->unique = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000995 }
996 ;
997
998optWithSyntax:
999 { $$ = 0; }
1000 | WithSyntax {
1001 $$ = $1;
1002 }
1003 ;
1004
1005WithSyntax:
1006 TOK_WITH TOK_SYNTAX '{'
1007 { asn1p_lexer_hack_enable_with_syntax(); }
1008 WithSyntaxFormat
1009 '}' {
1010 $$ = $5;
1011 }
1012 ;
1013
1014WithSyntaxFormat:
1015 WithSyntaxFormatToken {
1016 $$ = asn1p_wsyntx_new();
1017 TQ_ADD(&($$->chunks), $1, next);
1018 }
1019 | WithSyntaxFormat WithSyntaxFormatToken {
1020 $$ = $1;
1021 TQ_ADD(&($$->chunks), $2, next);
1022 }
1023 ;
1024
1025WithSyntaxFormatToken:
1026 TOK_opaque {
1027 $$ = asn1p_wsyntx_chunk_frombuf($1.buf, $1.len, 0);
1028 }
1029 | ClassFieldIdentifier {
1030 asn1p_ref_t *ref;
1031 int ret;
1032 ref = asn1p_ref_new(yylineno);
1033 checkmem(ref);
1034 ret = asn1p_ref_add_component(ref, $1.name, $1.lex_type);
1035 checkmem(ret == 0);
1036 $$ = asn1p_wsyntx_chunk_fromref(ref, 0);
1037 }
1038 ;
1039
Lev Walkinf15320b2004-06-03 03:38:44 +00001040ExtensionAndException:
1041 TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001042 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001043 checkmem($$);
1044 $$->Identifier = strdup("...");
1045 checkmem($$->Identifier);
1046 $$->expr_type = A1TC_EXTENSIBLE;
1047 $$->meta_type = AMT_TYPE;
1048 }
1049 | TOK_ThreeDots '!' DefinedValue {
Lev Walkinceb20e72004-09-05 10:40:41 +00001050 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001051 checkmem($$);
1052 $$->Identifier = strdup("...");
1053 checkmem($$->Identifier);
1054 $$->value = $3;
1055 $$->expr_type = A1TC_EXTENSIBLE;
1056 $$->meta_type = AMT_TYPE;
1057 }
1058 | TOK_ThreeDots '!' SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001059 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001060 checkmem($$);
1061 $$->Identifier = strdup("...");
1062 $$->value = $3;
1063 checkmem($$->Identifier);
1064 $$->expr_type = A1TC_EXTENSIBLE;
1065 $$->meta_type = AMT_TYPE;
1066 }
1067 ;
1068
Lev Walkin070a52d2004-08-22 03:19:54 +00001069Type:
Lev Walkinaf120f72004-09-14 02:36:39 +00001070 optTag TypeDeclaration optConstraints {
1071 $$ = $2;
1072 $$->tag = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +00001073 /*
1074 * Outer constraint for SEQUENCE OF and SET OF applies
1075 * to the inner type.
1076 */
1077 if($$->expr_type == ASN_CONSTR_SEQUENCE_OF
1078 || $$->expr_type == ASN_CONSTR_SET_OF) {
1079 assert(!TQ_FIRST(&($$->members))->constraints);
Lev Walkinaf120f72004-09-14 02:36:39 +00001080 TQ_FIRST(&($$->members))->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001081 } else {
1082 if($$->constraints) {
1083 assert(!$2);
1084 } else {
Lev Walkinaf120f72004-09-14 02:36:39 +00001085 $$->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001086 }
1087 }
1088 }
1089 ;
1090
1091TypeDeclaration:
Lev Walkinf15320b2004-06-03 03:38:44 +00001092 BasicType {
1093 $$ = $1;
1094 }
Lev Walkin070a52d2004-08-22 03:19:54 +00001095 | TOK_CHOICE '{' AlternativeTypeLists '}' {
1096 $$ = $3;
1097 assert($$->expr_type == A1TC_INVALID);
1098 $$->expr_type = ASN_CONSTR_CHOICE;
1099 $$->meta_type = AMT_TYPE;
Lev Walkinf15320b2004-06-03 03:38:44 +00001100 }
Lev Walkin144db9b2004-10-12 23:26:53 +00001101 | TOK_SEQUENCE '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001102 $$ = $3;
1103 assert($$->expr_type == A1TC_INVALID);
1104 $$->expr_type = ASN_CONSTR_SEQUENCE;
1105 $$->meta_type = AMT_TYPE;
1106 }
Lev Walkin144db9b2004-10-12 23:26:53 +00001107 | TOK_SET '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001108 $$ = $3;
1109 assert($$->expr_type == A1TC_INVALID);
1110 $$->expr_type = ASN_CONSTR_SET;
1111 $$->meta_type = AMT_TYPE;
1112 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001113 | TOK_SEQUENCE optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001114 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001115 checkmem($$);
1116 $$->constraints = $2;
1117 $$->expr_type = ASN_CONSTR_SEQUENCE_OF;
1118 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001119 $6->Identifier = $4;
1120 $6->tag = $5;
1121 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001122 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001123 | TOK_SET optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001124 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001125 checkmem($$);
1126 $$->constraints = $2;
1127 $$->expr_type = ASN_CONSTR_SET_OF;
1128 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001129 $6->Identifier = $4;
1130 $6->tag = $5;
1131 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001132 }
1133 | TOK_ANY {
Lev Walkinceb20e72004-09-05 10:40:41 +00001134 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001135 checkmem($$);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001136 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001137 $$->meta_type = AMT_TYPE;
1138 }
1139 | TOK_ANY TOK_DEFINED TOK_BY Identifier {
1140 int ret;
Lev Walkinceb20e72004-09-05 10:40:41 +00001141 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001142 checkmem($$);
1143 $$->reference = asn1p_ref_new(yylineno);
1144 ret = asn1p_ref_add_component($$->reference,
1145 $4, RLT_lowercase);
1146 checkmem(ret == 0);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001147 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001148 $$->meta_type = AMT_TYPE;
1149 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001150 /*
1151 * A parametrized assignment.
1152 */
1153 | TypeRefName '{' ActualParameterList '}' {
1154 int ret;
1155 $$ = $3;
1156 assert($$->expr_type == 0);
1157 assert($$->meta_type == 0);
1158 assert($$->reference == 0);
1159 $$->reference = asn1p_ref_new(yylineno);
1160 checkmem($$->reference);
1161 ret = asn1p_ref_add_component($$->reference, $1, RLT_UNKNOWN);
1162 checkmem(ret == 0);
1163 free($1);
1164 $$->expr_type = A1TC_PARAMETRIZED;
1165 $$->meta_type = AMT_TYPE;
1166 }
1167 /*
1168 * A DefinedType reference.
1169 * "CLASS1.&id.&id2"
1170 * or
1171 * "Module.Type"
1172 * or
1173 * "Module.identifier"
1174 * or
1175 * "Type"
1176 */
1177 | ComplexTypeReference {
1178 $$ = asn1p_expr_new(yylineno);
1179 checkmem($$);
1180 $$->reference = $1;
1181 $$->expr_type = A1TC_REFERENCE;
1182 $$->meta_type = AMT_TYPEREF;
1183 }
1184 | TOK_INSTANCE TOK_OF ComplexTypeReference {
1185 $$ = asn1p_expr_new(yylineno);
1186 checkmem($$);
1187 $$->reference = $3;
1188 $$->expr_type = A1TC_INSTANCE;
1189 $$->meta_type = AMT_TYPE;
1190 }
1191 ;
1192
1193/*
1194 * A type name consisting of several components.
1195 * === EXAMPLE ===
1196 * === EOF ===
1197 */
1198ComplexTypeReference:
1199 TOK_typereference {
1200 int ret;
1201 $$ = asn1p_ref_new(yylineno);
1202 checkmem($$);
1203 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1204 checkmem(ret == 0);
1205 free($1);
1206 }
1207 | TOK_typereference '.' TypeRefName {
1208 int ret;
1209 $$ = asn1p_ref_new(yylineno);
1210 checkmem($$);
1211 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1212 checkmem(ret == 0);
1213 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1214 checkmem(ret == 0);
1215 free($1);
1216 }
Lev Walkin9c974182004-09-15 11:59:51 +00001217 | ObjectClassReference '.' TypeRefName {
1218 int ret;
1219 $$ = asn1p_ref_new(yylineno);
1220 checkmem($$);
1221 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1222 checkmem(ret == 0);
1223 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1224 checkmem(ret == 0);
1225 free($1);
1226 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001227 | TOK_typereference '.' Identifier {
1228 int ret;
1229 $$ = asn1p_ref_new(yylineno);
1230 checkmem($$);
1231 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1232 checkmem(ret == 0);
1233 ret = asn1p_ref_add_component($$, $3, RLT_lowercase);
1234 checkmem(ret == 0);
1235 free($1);
1236 }
1237 | ObjectClassReference {
1238 int ret;
1239 $$ = asn1p_ref_new(yylineno);
1240 checkmem($$);
1241 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1242 free($1);
1243 checkmem(ret == 0);
1244 }
1245 | ObjectClassReference '.' ComplexTypeReferenceAmpList {
1246 int ret;
1247 $$ = $3;
1248 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1249 free($1);
1250 checkmem(ret == 0);
1251 /*
1252 * Move the last element infront.
1253 */
1254 {
1255 struct asn1p_ref_component_s tmp_comp;
1256 tmp_comp = $$->components[$$->comp_count-1];
1257 memmove(&$$->components[1],
1258 &$$->components[0],
1259 sizeof($$->components[0])
1260 * ($$->comp_count - 1));
1261 $$->components[0] = tmp_comp;
1262 }
1263 }
1264 ;
1265
1266ComplexTypeReferenceAmpList:
1267 ComplexTypeReferenceElement {
1268 int ret;
1269 $$ = asn1p_ref_new(yylineno);
1270 checkmem($$);
1271 ret = asn1p_ref_add_component($$, $1.name, $1.lex_type);
1272 free($1.name);
1273 checkmem(ret == 0);
1274 }
1275 | ComplexTypeReferenceAmpList '.' ComplexTypeReferenceElement {
1276 int ret;
1277 $$ = $1;
1278 ret = asn1p_ref_add_component($$, $3.name, $3.lex_type);
1279 free($3.name);
1280 checkmem(ret == 0);
1281 }
1282 ;
1283
1284ComplexTypeReferenceElement: ClassFieldName;
1285ClassFieldIdentifier: ClassFieldName;
1286
1287ClassFieldName:
1288 /* "&Type1" */
1289 TOK_typefieldreference {
1290 $$.lex_type = RLT_AmpUppercase;
1291 $$.name = $1;
1292 }
1293 /* "&id" */
1294 | TOK_valuefieldreference {
1295 $$.lex_type = RLT_Amplowercase;
1296 $$.name = $1;
1297 }
1298 ;
1299
1300
1301/*
1302 * === EXAMPLE ===
1303 * value INTEGER ::= 1
1304 * === EOF ===
1305 */
1306ValueDefinition:
Lev Walkin9c974182004-09-15 11:59:51 +00001307 Identifier DefinedTypeRef TOK_PPEQ Value {
Lev Walkinf15320b2004-06-03 03:38:44 +00001308 $$ = $2;
1309 assert($$->Identifier == NULL);
1310 $$->Identifier = $1;
1311 $$->meta_type = AMT_VALUE;
1312 $$->value = $4;
1313 }
1314 ;
1315
Lev Walkin9c974182004-09-15 11:59:51 +00001316Value:
1317 Identifier ':' Value {
1318 $$ = asn1p_value_fromint(0);
1319 checkmem($$);
1320 $$->type = ATV_CHOICE_IDENTIFIER;
1321 $$->value.choice_identifier.identifier = $1;
1322 $$->value.choice_identifier.value = $3;
1323 }
Lev Walkincbad2512005-03-24 16:27:02 +00001324 | '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
Lev Walkinf15320b2004-06-03 03:38:44 +00001325 $$ = asn1p_value_frombuf($3.buf, $3.len, 0);
1326 checkmem($$);
1327 $$->type = ATV_UNPARSED;
1328 }
Lev Walkin9c974182004-09-15 11:59:51 +00001329 | TOK_NULL {
1330 $$ = asn1p_value_fromint(0);
1331 checkmem($$);
1332 $$->type = ATV_NULL;
1333 }
1334 | TOK_FALSE {
1335 $$ = asn1p_value_fromint(0);
1336 checkmem($$);
1337 $$->type = ATV_FALSE;
1338 }
1339 | TOK_TRUE {
1340 $$ = asn1p_value_fromint(0);
1341 checkmem($$);
1342 $$->type = ATV_TRUE;
1343 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001344 | TOK_bstring {
1345 $$ = _convert_bitstring2binary($1, 'B');
1346 checkmem($$);
1347 }
1348 | TOK_hstring {
1349 $$ = _convert_bitstring2binary($1, 'H');
1350 checkmem($$);
1351 }
Lev Walkin1e448d32005-03-24 14:26:38 +00001352 | RestrictedCharacterStringValue {
1353 $$ = $$;
Lev Walkinf15320b2004-06-03 03:38:44 +00001354 }
1355 | SignedNumber {
1356 $$ = $1;
1357 }
1358 | DefinedValue {
1359 $$ = $1;
1360 }
1361 ;
1362
1363DefinedValue:
1364 Identifier {
1365 asn1p_ref_t *ref;
1366 int ret;
1367 ref = asn1p_ref_new(yylineno);
1368 checkmem(ref);
1369 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1370 checkmem(ret == 0);
1371 $$ = asn1p_value_fromref(ref, 0);
1372 checkmem($$);
1373 free($1);
1374 }
1375 | TypeRefName '.' Identifier {
1376 asn1p_ref_t *ref;
1377 int ret;
1378 ref = asn1p_ref_new(yylineno);
1379 checkmem(ref);
1380 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1381 checkmem(ret == 0);
1382 ret = asn1p_ref_add_component(ref, $3, RLT_lowercase);
1383 checkmem(ret == 0);
1384 $$ = asn1p_value_fromref(ref, 0);
1385 checkmem($$);
1386 free($1);
1387 free($3);
1388 }
1389 ;
1390
Lev Walkin1e448d32005-03-24 14:26:38 +00001391
1392RestrictedCharacterStringValue:
1393 TOK_cstring {
1394 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1395 checkmem($$);
1396 }
Lev Walkind9574ae2005-03-24 16:22:35 +00001397 | TOK_tuple {
1398 $$ = asn1p_value_fromint($1);
1399 checkmem($$);
1400 $$->type = ATV_TUPLE;
1401 }
1402 | TOK_quadruple {
1403 $$ = asn1p_value_fromint($1);
1404 checkmem($$);
1405 $$->type = ATV_QUADRUPLE;
1406 }
1407 /*
Lev Walkin1e448d32005-03-24 14:26:38 +00001408 | '{' TOK_number ',' TOK_number '}' {
1409 asn1c_integer_t v = ($2 << 4) + $4;
1410 if($2 > 7) return yyerror("X.680:2003, #37.14 "
1411 "mandates 0..7 range for Tuple's TableColumn");
1412 if($4 > 15) return yyerror("X.680:2003, #37.14 "
1413 "mandates 0..15 range for Tuple's TableRow");
1414 $$ = asn1p_value_fromint(v);
1415 checkmem($$);
1416 $$->type = ATV_TUPLE;
1417 }
1418 | '{' TOK_number ',' TOK_number ',' TOK_number ',' TOK_number '}' {
1419 asn1c_integer_t v = ($2 << 24) | ($4 << 16) | ($6 << 8) | $8;
1420 if($2 > 127) return yyerror("X.680:2003, #37.12 "
1421 "mandates 0..127 range for Quadruple's Group");
1422 if($4 > 255) return yyerror("X.680:2003, #37.12 "
1423 "mandates 0..255 range for Quadruple's Plane");
1424 if($6 > 255) return yyerror("X.680:2003, #37.12 "
1425 "mandates 0..255 range for Quadruple's Row");
1426 if($8 > 255) return yyerror("X.680:2003, #37.12 "
1427 "mandates 0..255 range for Quadruple's Cell");
1428 $$ = asn1p_value_fromint(v);
1429 checkmem($$);
1430 $$->type = ATV_QUADRUPLE;
1431 }
Lev Walkind9574ae2005-03-24 16:22:35 +00001432 */
Lev Walkin1e448d32005-03-24 14:26:38 +00001433 ;
1434
Lev Walkinf15320b2004-06-03 03:38:44 +00001435Opaque:
1436 TOK_opaque {
Lev Walkin1893ddf2005-03-20 14:28:32 +00001437 $$.len = $1.len + 1;
Lev Walkinf15320b2004-06-03 03:38:44 +00001438 $$.buf = malloc($$.len + 1);
1439 checkmem($$.buf);
1440 $$.buf[0] = '{';
Lev Walkin1893ddf2005-03-20 14:28:32 +00001441 memcpy($$.buf + 1, $1.buf, $1.len);
Lev Walkinf15320b2004-06-03 03:38:44 +00001442 $$.buf[$$.len] = '\0';
1443 free($1.buf);
1444 }
1445 | Opaque TOK_opaque {
1446 int newsize = $1.len + $2.len;
1447 char *p = malloc(newsize + 1);
1448 checkmem(p);
1449 memcpy(p , $1.buf, $1.len);
1450 memcpy(p + $1.len, $2.buf, $2.len);
1451 p[newsize] = '\0';
1452 free($1.buf);
1453 free($2.buf);
1454 $$.buf = p;
1455 $$.len = newsize;
1456 }
1457 ;
1458
1459BasicTypeId:
1460 TOK_BOOLEAN { $$ = ASN_BASIC_BOOLEAN; }
1461 | TOK_NULL { $$ = ASN_BASIC_NULL; }
1462 | TOK_REAL { $$ = ASN_BASIC_REAL; }
1463 | BasicTypeId_UniverationCompatible { $$ = $1; }
1464 | TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; }
1465 | TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; }
1466 | TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; }
1467 | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; }
1468 | TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; }
1469 | TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; }
1470 | TOK_UTCTime { $$ = ASN_BASIC_UTCTime; }
1471 | TOK_GeneralizedTime { $$ = ASN_BASIC_GeneralizedTime; }
Lev Walkinc7d939d2005-03-20 11:12:40 +00001472 | BasicString { $$ = $1; }
Lev Walkinf15320b2004-06-03 03:38:44 +00001473 ;
1474
1475/*
1476 * A type identifier which may be used with "{ a(1), b(2) }" clause.
1477 */
1478BasicTypeId_UniverationCompatible:
1479 TOK_INTEGER { $$ = ASN_BASIC_INTEGER; }
1480 | TOK_ENUMERATED { $$ = ASN_BASIC_ENUMERATED; }
1481 | TOK_BIT TOK_STRING { $$ = ASN_BASIC_BIT_STRING; }
1482 ;
1483
1484BasicType:
1485 BasicTypeId {
Lev Walkinceb20e72004-09-05 10:40:41 +00001486 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001487 checkmem($$);
1488 $$->expr_type = $1;
1489 $$->meta_type = AMT_TYPE;
1490 }
1491 | BasicTypeId_UniverationCompatible UniverationDefinition {
1492 if($2) {
1493 $$ = $2;
1494 } else {
Lev Walkinceb20e72004-09-05 10:40:41 +00001495 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001496 checkmem($$);
1497 }
1498 $$->expr_type = $1;
1499 $$->meta_type = AMT_TYPE;
1500 }
1501 ;
1502
1503BasicString:
1504 TOK_BMPString { $$ = ASN_STRING_BMPString; }
1505 | TOK_GeneralString {
1506 $$ = ASN_STRING_GeneralString;
Lev Walkin9c974182004-09-15 11:59:51 +00001507 fprintf(stderr, "WARNING: GeneralString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001508 }
1509 | TOK_GraphicString {
1510 $$ = ASN_STRING_GraphicString;
Lev Walkin9c974182004-09-15 11:59:51 +00001511 fprintf(stderr, "WARNING: GraphicString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001512 }
1513 | TOK_IA5String { $$ = ASN_STRING_IA5String; }
1514 | TOK_ISO646String { $$ = ASN_STRING_ISO646String; }
1515 | TOK_NumericString { $$ = ASN_STRING_NumericString; }
1516 | TOK_PrintableString { $$ = ASN_STRING_PrintableString; }
1517 | TOK_T61String {
1518 $$ = ASN_STRING_T61String;
Lev Walkin9c974182004-09-15 11:59:51 +00001519 fprintf(stderr, "WARNING: T61String is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001520 }
1521 | TOK_TeletexString { $$ = ASN_STRING_TeletexString; }
1522 | TOK_UniversalString { $$ = ASN_STRING_UniversalString; }
1523 | TOK_UTF8String { $$ = ASN_STRING_UTF8String; }
1524 | TOK_VideotexString {
1525 $$ = ASN_STRING_VideotexString;
Lev Walkin9c974182004-09-15 11:59:51 +00001526 fprintf(stderr, "WARNING: VideotexString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001527 }
1528 | TOK_VisibleString { $$ = ASN_STRING_VisibleString; }
1529 | TOK_ObjectDescriptor { $$ = ASN_STRING_ObjectDescriptor; }
1530 ;
1531
Lev Walkind2ea1de2004-08-20 13:25:29 +00001532
Lev Walkinf15320b2004-06-03 03:38:44 +00001533/*
1534 * Data type constraints.
1535 */
Lev Walkinf15320b2004-06-03 03:38:44 +00001536Union: '|' | TOK_UNION;
1537Intersection: '^' | TOK_INTERSECTION;
1538Except: TOK_EXCEPT;
1539
Lev Walkinf59d0752004-08-18 04:59:12 +00001540optConstraints:
1541 { $$ = 0; }
Lev Walkind2ea1de2004-08-20 13:25:29 +00001542 | Constraints {
1543 $$ = $1;
1544 }
1545 ;
1546
1547Constraints:
1548 SetOfConstraints {
Lev Walkinf59d0752004-08-18 04:59:12 +00001549 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, 0);
1550 }
1551 | TOK_SIZE '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001552 /*
1553 * This is a special case, for compatibility purposes.
Lev Walkinf59d0752004-08-18 04:59:12 +00001554 * It goes without parentheses.
Lev Walkinf15320b2004-06-03 03:38:44 +00001555 */
Lev Walkind2ea1de2004-08-20 13:25:29 +00001556 CONSTRAINT_INSERT($$, ACT_CT_SIZE, $3, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001557 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001558 ;
1559
Lev Walkinf59d0752004-08-18 04:59:12 +00001560SetOfConstraints:
1561 '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001562 $$ = $2;
1563 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001564 | SetOfConstraints '(' ElementSetSpecs ')' {
1565 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $3);
1566 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001567 ;
1568
Lev Walkinf59d0752004-08-18 04:59:12 +00001569ElementSetSpecs:
1570 ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001571 $$ = $1;
1572 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001573 | ElementSetSpec ',' TOK_ThreeDots {
Lev Walkinf15320b2004-06-03 03:38:44 +00001574 asn1p_constraint_t *ct;
1575 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001576 ct->type = ACT_EL_EXT;
1577 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1578 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001579 | ElementSetSpec ',' TOK_ThreeDots ',' ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001580 asn1p_constraint_t *ct;
1581 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001582 ct->type = ACT_EL_EXT;
1583 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
Lev Walkinb4fcdd22004-08-13 12:35:09 +00001584 ct = $$;
1585 CONSTRAINT_INSERT($$, ACT_CA_CSV, ct, $5);
Lev Walkinf15320b2004-06-03 03:38:44 +00001586 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001587 ;
1588
Lev Walkinf59d0752004-08-18 04:59:12 +00001589ElementSetSpec:
1590 ConstraintSubtypeElement {
1591 $$ = $1;
1592 }
Lev Walkin1e448d32005-03-24 14:26:38 +00001593 | TOK_ALL TOK_EXCEPT ConstraintSubtypeElement {
1594 CONSTRAINT_INSERT($$, ACT_CA_AEX, $3, 0);
1595 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001596 | ElementSetSpec Union ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001597 CONSTRAINT_INSERT($$, ACT_CA_UNI, $1, $3);
1598 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001599 | ElementSetSpec Intersection ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001600 CONSTRAINT_INSERT($$, ACT_CA_INT, $1, $3);
1601 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001602 | ConstraintSubtypeElement Except ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001603 CONSTRAINT_INSERT($$, ACT_CA_EXC, $1, $3);
1604 }
1605 ;
1606
1607ConstraintSubtypeElement:
Lev Walkinf59d0752004-08-18 04:59:12 +00001608 ConstraintSpec '(' ElementSetSpecs ')' {
1609 int ret;
1610 $$ = asn1p_constraint_new(yylineno);
1611 checkmem($$);
1612 $$->type = $1;
1613 ret = asn1p_constraint_insert($$, $3);
1614 checkmem(ret == 0);
1615 }
1616 | '(' ElementSetSpecs ')' {
1617 int ret;
1618 $$ = asn1p_constraint_new(yylineno);
1619 checkmem($$);
1620 $$->type = ACT_CA_SET;
1621 ret = asn1p_constraint_insert($$, $2);
1622 checkmem(ret == 0);
1623 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001624 | SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001625 $$ = asn1p_constraint_new(yylineno);
1626 checkmem($$);
1627 $$->type = ACT_EL_VALUE;
1628 $$->value = $1;
1629 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001630 | ContainedSubtype {
1631 $$ = asn1p_constraint_new(yylineno);
1632 checkmem($$);
1633 $$->type = ACT_EL_TYPE;
1634 $$->containedSubtype = $1;
1635 }
1636 | SingleValue ConstraintRangeSpec SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001637 $$ = asn1p_constraint_new(yylineno);
1638 checkmem($$);
1639 $$->type = $2;
1640 $$->range_start = $1;
1641 $$->range_stop = $3;
1642 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001643 | TOK_MIN ConstraintRangeSpec SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001644 $$ = asn1p_constraint_new(yylineno);
1645 checkmem($$);
Lev Walkinf59d0752004-08-18 04:59:12 +00001646 $$->type = $2;
1647 $$->range_start = asn1p_value_fromint(-123);
1648 $$->range_stop = $3;
1649 $$->range_start->type = ATV_MIN;
1650 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001651 | SingleValue ConstraintRangeSpec TOK_MAX {
Lev Walkinf59d0752004-08-18 04:59:12 +00001652 $$ = asn1p_constraint_new(yylineno);
1653 checkmem($$);
1654 $$->type = $2;
1655 $$->range_start = $1;
1656 $$->range_stop = asn1p_value_fromint(321);
1657 $$->range_stop->type = ATV_MAX;
1658 }
1659 | TOK_MIN ConstraintRangeSpec TOK_MAX {
1660 $$ = asn1p_constraint_new(yylineno);
1661 checkmem($$);
1662 $$->type = $2;
1663 $$->range_start = asn1p_value_fromint(-123);
1664 $$->range_stop = asn1p_value_fromint(321);
1665 $$->range_start->type = ATV_MIN;
1666 $$->range_stop->type = ATV_MAX;
Lev Walkinf15320b2004-06-03 03:38:44 +00001667 }
1668 | TableConstraint {
1669 $$ = $1;
1670 }
Lev Walkine596bf02005-03-28 15:01:27 +00001671 | InnerTypeConstraint {
Lev Walkinf15320b2004-06-03 03:38:44 +00001672 $$ = $1;
1673 }
Lev Walkin1893ddf2005-03-20 14:28:32 +00001674 | TOK_CONSTRAINED TOK_BY '{'
1675 { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
1676 $$ = asn1p_constraint_new(yylineno);
1677 checkmem($$);
1678 $$->type = ACT_CT_CTDBY;
1679 $$->value = asn1p_value_frombuf($5.buf, $5.len, 0);
1680 checkmem($$->value);
1681 $$->value->type = ATV_UNPARSED;
1682 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001683 ;
1684
1685ConstraintRangeSpec:
1686 TOK_TwoDots { $$ = ACT_EL_RANGE; }
1687 | TOK_TwoDots '<' { $$ = ACT_EL_RLRANGE; }
1688 | '<' TOK_TwoDots { $$ = ACT_EL_LLRANGE; }
1689 | '<' TOK_TwoDots '<' { $$ = ACT_EL_ULRANGE; }
1690 ;
1691
1692ConstraintSpec:
1693 TOK_SIZE {
1694 $$ = ACT_CT_SIZE;
1695 }
1696 | TOK_FROM {
1697 $$ = ACT_CT_FROM;
1698 }
1699 ;
1700
Lev Walkinff7dd142005-03-20 12:58:00 +00001701SingleValue:
Lev Walkinc8092cb2005-02-18 16:34:21 +00001702 TOK_FALSE {
1703 $$ = asn1p_value_fromint(0);
1704 checkmem($$);
1705 $$->type = ATV_FALSE;
1706 }
1707 | TOK_TRUE {
1708 $$ = asn1p_value_fromint(1);
1709 checkmem($$);
1710 $$->type = ATV_TRUE;
1711 }
1712 | SignedNumber {
Lev Walkinf15320b2004-06-03 03:38:44 +00001713 $$ = $1;
1714 }
Lev Walkin1e448d32005-03-24 14:26:38 +00001715 | RestrictedCharacterStringValue {
1716 $$ = $1;
Lev Walkinc8092cb2005-02-18 16:34:21 +00001717 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001718 | Identifier {
1719 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_lowercase);
1724 checkmem(ret == 0);
1725 $$ = asn1p_value_fromref(ref, 0);
1726 checkmem($$);
1727 free($1);
1728 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001729 ;
1730
1731ContainedSubtype:
1732 TypeRefName {
Lev Walkinc8092cb2005-02-18 16:34:21 +00001733 asn1p_ref_t *ref;
1734 int ret;
1735 ref = asn1p_ref_new(yylineno);
1736 checkmem(ref);
1737 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1738 checkmem(ret == 0);
1739 $$ = asn1p_value_fromref(ref, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001740 checkmem($$);
Lev Walkinc8092cb2005-02-18 16:34:21 +00001741 free($1);
Lev Walkinf15320b2004-06-03 03:38:44 +00001742 }
1743 ;
1744
Lev Walkine596bf02005-03-28 15:01:27 +00001745InnerTypeConstraint:
1746 TOK_WITH TOK_COMPONENT SetOfConstraints {
1747 CONSTRAINT_INSERT($$, ACT_CT_WCOMP, $3, 0);
1748 }
1749 | TOK_WITH TOK_COMPONENTS '{' WithComponentsList '}' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001750 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $4, 0);
1751 }
1752 ;
1753
1754WithComponentsList:
1755 WithComponentsElement {
1756 $$ = $1;
1757 }
1758 | WithComponentsList ',' WithComponentsElement {
1759 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $1, $3);
1760 }
1761 ;
1762
1763WithComponentsElement:
1764 TOK_ThreeDots {
1765 $$ = asn1p_constraint_new(yylineno);
1766 checkmem($$);
1767 $$->type = ACT_EL_EXT;
Lev Walkine596bf02005-03-28 15:01:27 +00001768 $$->value = asn1p_value_frombuf("...", 3, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001769 }
1770 | Identifier optConstraints optPresenceConstraint {
1771 $$ = asn1p_constraint_new(yylineno);
1772 checkmem($$);
1773 $$->type = ACT_EL_VALUE;
1774 $$->value = asn1p_value_frombuf($1, strlen($1), 0);
1775 $$->presence = $3;
Lev Walkine596bf02005-03-28 15:01:27 +00001776 if($2) asn1p_constraint_insert($$, $2);
Lev Walkinf15320b2004-06-03 03:38:44 +00001777 }
1778 ;
1779
1780/*
1781 * presence constraint for WithComponents
1782 */
1783optPresenceConstraint:
1784 { $$ = ACPRES_DEFAULT; }
1785 | PresenceConstraint { $$ = $1; }
1786 ;
1787
1788PresenceConstraint:
1789 TOK_PRESENT {
1790 $$ = ACPRES_PRESENT;
1791 }
1792 | TOK_ABSENT {
1793 $$ = ACPRES_ABSENT;
1794 }
1795 | TOK_OPTIONAL {
1796 $$ = ACPRES_OPTIONAL;
1797 }
1798 ;
1799
1800TableConstraint:
1801 SimpleTableConstraint {
1802 $$ = $1;
1803 }
1804 | ComponentRelationConstraint {
1805 $$ = $1;
1806 }
1807 ;
1808
1809/*
1810 * "{ExtensionSet}"
1811 */
1812SimpleTableConstraint:
1813 '{' TypeRefName '}' {
1814 asn1p_ref_t *ref = asn1p_ref_new(yylineno);
1815 asn1p_constraint_t *ct;
1816 int ret;
1817 ret = asn1p_ref_add_component(ref, $2, 0);
1818 checkmem(ret == 0);
1819 ct = asn1p_constraint_new(yylineno);
1820 checkmem($$);
1821 ct->type = ACT_EL_VALUE;
1822 ct->value = asn1p_value_fromref(ref, 0);
1823 CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0);
1824 }
1825 ;
1826
1827ComponentRelationConstraint:
1828 SimpleTableConstraint '{' AtNotationList '}' {
1829 CONSTRAINT_INSERT($$, ACT_CA_CRC, $1, $3);
1830 }
1831 ;
1832
1833AtNotationList:
1834 AtNotationElement {
1835 $$ = asn1p_constraint_new(yylineno);
1836 checkmem($$);
1837 $$->type = ACT_EL_VALUE;
1838 $$->value = asn1p_value_fromref($1, 0);
1839 }
1840 | AtNotationList ',' AtNotationElement {
1841 asn1p_constraint_t *ct;
1842 ct = asn1p_constraint_new(yylineno);
1843 checkmem(ct);
1844 ct->type = ACT_EL_VALUE;
1845 ct->value = asn1p_value_fromref($3, 0);
1846 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1847 }
1848 ;
1849
1850/*
1851 * @blah
1852 */
1853AtNotationElement:
1854 '@' ComponentIdList {
1855 char *p = malloc(strlen($2) + 2);
1856 int ret;
1857 *p = '@';
1858 strcpy(p + 1, $2);
1859 $$ = asn1p_ref_new(yylineno);
1860 ret = asn1p_ref_add_component($$, p, 0);
1861 checkmem(ret == 0);
1862 free(p);
1863 free($2);
1864 }
1865 | '@' '.' ComponentIdList {
1866 char *p = malloc(strlen($3) + 3);
1867 int ret;
1868 p[0] = '@';
1869 p[1] = '.';
1870 strcpy(p + 2, $3);
1871 $$ = asn1p_ref_new(yylineno);
1872 ret = asn1p_ref_add_component($$, p, 0);
1873 checkmem(ret == 0);
1874 free(p);
1875 free($3);
1876 }
1877 ;
1878
1879/* identifier "." ... */
1880ComponentIdList:
1881 Identifier {
1882 $$ = $1;
1883 }
1884 | ComponentIdList '.' Identifier {
1885 int l1 = strlen($1);
1886 int l3 = strlen($3);
1887 $$ = malloc(l1 + 1 + l3 + 1);
1888 memcpy($$, $1, l1);
1889 $$[l1] = '.';
1890 memcpy($$ + l1 + 1, $3, l3);
1891 $$[l1 + 1 + l3] = '\0';
1892 }
1893 ;
1894
1895
1896
1897/*
1898 * MARKERS
1899 */
1900
1901optMarker:
Lev Walkin9c974182004-09-15 11:59:51 +00001902 {
1903 $$.flags = EM_NOMARK;
1904 $$.default_value = 0;
1905 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001906 | Marker { $$ = $1; }
1907 ;
1908
1909Marker:
1910 TOK_OPTIONAL {
Lev Walkin9c974182004-09-15 11:59:51 +00001911 $$.flags = EM_OPTIONAL;
1912 $$.default_value = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +00001913 }
Lev Walkin9c974182004-09-15 11:59:51 +00001914 | TOK_DEFAULT Value {
1915 $$.flags = EM_DEFAULT;
1916 $$.default_value = $2;
Lev Walkinf15320b2004-06-03 03:38:44 +00001917 }
1918 ;
1919
1920/*
1921 * Universal enumeration definition to use in INTEGER and ENUMERATED.
1922 * === EXAMPLE ===
1923 * Gender ::= ENUMERATED { unknown(0), male(1), female(2) }
1924 * Temperature ::= INTEGER { absolute-zero(-273), freezing(0), boiling(100) }
1925 * === EOF ===
1926 */
1927/*
1928optUniverationDefinition:
1929 { $$ = 0; }
1930 | UniverationDefinition {
1931 $$ = $1;
1932 }
1933 ;
1934*/
1935
1936UniverationDefinition:
1937 '{' '}' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001938 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001939 checkmem($$);
1940 }
1941 | '{' UniverationList '}' {
1942 $$ = $2;
1943 }
1944 ;
1945
1946UniverationList:
1947 UniverationElement {
Lev Walkinceb20e72004-09-05 10:40:41 +00001948 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001949 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +00001950 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +00001951 }
1952 | UniverationList ',' UniverationElement {
1953 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +00001954 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00001955 }
1956 ;
1957
1958UniverationElement:
1959 Identifier {
Lev Walkinceb20e72004-09-05 10:40:41 +00001960 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001961 checkmem($$);
1962 $$->expr_type = A1TC_UNIVERVAL;
1963 $$->meta_type = AMT_VALUE;
1964 $$->Identifier = $1;
1965 }
1966 | Identifier '(' SignedNumber ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001967 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001968 checkmem($$);
1969 $$->expr_type = A1TC_UNIVERVAL;
1970 $$->meta_type = AMT_VALUE;
1971 $$->Identifier = $1;
1972 $$->value = $3;
1973 }
1974 | Identifier '(' DefinedValue ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001975 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001976 checkmem($$);
1977 $$->expr_type = A1TC_UNIVERVAL;
1978 $$->meta_type = AMT_VALUE;
1979 $$->Identifier = $1;
1980 $$->value = $3;
1981 }
1982 | SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001983 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001984 checkmem($$);
1985 $$->expr_type = A1TC_UNIVERVAL;
1986 $$->meta_type = AMT_VALUE;
1987 $$->value = $1;
1988 }
1989 | TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001990 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001991 checkmem($$);
1992 $$->Identifier = strdup("...");
1993 checkmem($$->Identifier);
1994 $$->expr_type = A1TC_EXTENSIBLE;
1995 $$->meta_type = AMT_VALUE;
1996 }
1997 ;
1998
1999SignedNumber:
2000 TOK_number {
2001 $$ = asn1p_value_fromint($1);
2002 checkmem($$);
2003 }
2004 | TOK_number_negative {
2005 $$ = asn1p_value_fromint($1);
2006 checkmem($$);
2007 }
2008 ;
2009
2010/*
2011 * SEQUENCE definition.
2012 * === EXAMPLE ===
2013 * Struct1 ::= SEQUENCE {
2014 * memb1 Struct2,
2015 * memb2 SEQUENCE OF {
2016 * memb2-1 Struct 3
2017 * }
2018 * }
2019 * === EOF ===
2020 */
2021
2022
2023
2024/*
2025 * SET definition.
2026 * === EXAMPLE ===
2027 * Person ::= SET {
2028 * name [0] PrintableString (SIZE(1..20)),
2029 * country [1] PrintableString (SIZE(1..20)) DEFAULT default-country,
2030 * }
2031 * === EOF ===
2032 */
2033
2034optTag:
2035 { memset(&$$, 0, sizeof($$)); }
2036 | Tag { $$ = $1; }
2037 ;
2038
2039Tag:
Lev Walkinc603f102005-01-23 09:51:44 +00002040 TagTypeValue TagPlicit {
Lev Walkinf15320b2004-06-03 03:38:44 +00002041 $$ = $1;
Lev Walkinc603f102005-01-23 09:51:44 +00002042 $$.tag_mode = $2.tag_mode;
Lev Walkinf15320b2004-06-03 03:38:44 +00002043 }
Lev Walkinc603f102005-01-23 09:51:44 +00002044 ;
2045
2046TagTypeValue:
2047 '[' TagClass TOK_number ']' {
2048 $$ = $2;
2049 $$.tag_value = $3;
2050 };
2051
2052TagClass:
2053 { $$.tag_class = TC_CONTEXT_SPECIFIC; }
2054 | TOK_UNIVERSAL { $$.tag_class = TC_UNIVERSAL; }
2055 | TOK_APPLICATION { $$.tag_class = TC_APPLICATION; }
2056 | TOK_PRIVATE { $$.tag_class = TC_PRIVATE; }
2057 ;
2058
2059TagPlicit:
2060 { $$.tag_mode = TM_DEFAULT; }
2061 | TOK_IMPLICIT { $$.tag_mode = TM_IMPLICIT; }
2062 | TOK_EXPLICIT { $$.tag_mode = TM_EXPLICIT; }
Lev Walkinf15320b2004-06-03 03:38:44 +00002063 ;
2064
2065TypeRefName:
2066 TOK_typereference {
2067 checkmem($1);
2068 $$ = $1;
2069 }
Lev Walkinf59d0752004-08-18 04:59:12 +00002070 | TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00002071 checkmem($1);
2072 $$ = $1;
2073 }
2074 ;
2075
Lev Walkinf59d0752004-08-18 04:59:12 +00002076
Lev Walkinf15320b2004-06-03 03:38:44 +00002077ObjectClassReference:
Lev Walkinf59d0752004-08-18 04:59:12 +00002078 TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00002079 checkmem($1);
2080 $$ = $1;
2081 }
2082 ;
2083
Lev Walkin83cac2f2004-09-22 16:03:36 +00002084optIdentifier:
2085 { $$ = 0; }
2086 | Identifier {
2087 $$ = $1;
2088 }
2089
Lev Walkinf15320b2004-06-03 03:38:44 +00002090Identifier:
2091 TOK_identifier {
2092 checkmem($1);
2093 $$ = $1;
2094 }
2095 ;
2096
Lev Walkinf15320b2004-06-03 03:38:44 +00002097%%
2098
2099
2100/*
2101 * Convert Xstring ('0101'B or '5'H) to the binary vector.
2102 */
2103static asn1p_value_t *
2104_convert_bitstring2binary(char *str, int base) {
2105 asn1p_value_t *val;
2106 int slen;
2107 int memlen;
2108 int baselen;
2109 int bits;
2110 uint8_t *binary_vector;
2111 uint8_t *bv_ptr;
2112 uint8_t cur_val;
2113
2114 assert(str);
2115 assert(str[0] == '\'');
2116
2117 switch(base) {
2118 case 'B':
2119 baselen = 1;
2120 break;
2121 case 'H':
2122 baselen = 4;
2123 break;
2124 default:
2125 assert(base == 'B' || base == 'H');
2126 errno = EINVAL;
2127 return NULL;
2128 }
2129
2130 slen = strlen(str);
2131 assert(str[slen - 1] == base);
2132 assert(str[slen - 2] == '\'');
2133
2134 memlen = slen / (8 / baselen); /* Conservative estimate */
2135
2136 bv_ptr = binary_vector = malloc(memlen + 1);
2137 if(bv_ptr == NULL)
2138 /* ENOMEM */
2139 return NULL;
2140
2141 cur_val = 0;
2142 bits = 0;
2143 while(*(++str) != '\'') {
2144 switch(baselen) {
2145 case 1:
2146 switch(*str) {
2147 case '1':
2148 cur_val |= 1 << (7 - (bits % 8));
2149 case '0':
2150 break;
2151 default:
2152 assert(!"_y UNREACH1");
2153 case ' ': case '\r': case '\n':
2154 continue;
2155 }
2156 break;
2157 case 4:
2158 switch(*str) {
2159 case '0': case '1': case '2': case '3': case '4':
2160 case '5': case '6': case '7': case '8': case '9':
2161 cur_val |= (*str - '0') << (4 - (bits % 8));
2162 break;
2163 case 'A': case 'B': case 'C':
2164 case 'D': case 'E': case 'F':
2165 cur_val |= ((*str - 'A') + 10)
2166 << (4 - (bits % 8));
2167 break;
2168 default:
2169 assert(!"_y UNREACH2");
2170 case ' ': case '\r': case '\n':
2171 continue;
2172 }
2173 break;
2174 }
2175
2176 bits += baselen;
2177 if((bits % 8) == 0) {
2178 *bv_ptr++ = cur_val;
2179 cur_val = 0;
2180 }
2181 }
2182
2183 *bv_ptr = cur_val;
2184 assert((bv_ptr - binary_vector) <= memlen);
2185
2186 val = asn1p_value_frombits(binary_vector, bits, 0);
2187 if(val == NULL) {
2188 free(binary_vector);
2189 }
2190
2191 return val;
2192}
2193
2194extern char *asn1p_text;
2195
2196int
2197yyerror(const char *msg) {
2198 fprintf(stderr,
2199 "ASN.1 grammar parse error "
2200 "near line %d (token \"%s\"): %s\n",
Lev Walkinceb20e72004-09-05 10:40:41 +00002201 yylineno, asn1p_text, msg);
Lev Walkinf15320b2004-06-03 03:38:44 +00002202 return -1;
2203}
2204
2205