blob: 2d7a9cb578df10eb68ab702128b670756eca9e14 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001%{
2
3#include <stdlib.h>
4#include <stdio.h>
5#include <string.h>
6#include <errno.h>
7#include <assert.h>
8
9#include "asn1parser.h"
10
11#define YYPARSE_PARAM param
12#define YYERROR_VERBOSE
13
14int yylex(void);
15int yyerror(const char *msg);
16void asn1p_lexer_hack_push_opaque_state(void);
17void asn1p_lexer_hack_enable_with_syntax(void);
Lev Walkinf59d0752004-08-18 04:59:12 +000018void asn1p_lexer_hack_push_encoding_control(void);
Lev Walkinf15320b2004-06-03 03:38:44 +000019#define yylineno asn1p_lineno
20extern int asn1p_lineno;
21
22
23static asn1p_value_t *
24 _convert_bitstring2binary(char *str, int base);
25
26#define checkmem(ptr) do { \
27 if(!(ptr)) \
28 return yyerror("Memory failure"); \
29 } while(0)
30
31#define CONSTRAINT_INSERT(root, constr_type, arg1, arg2) do { \
32 if(arg1->type != constr_type) { \
33 int __ret; \
34 root = asn1p_constraint_new(yylineno); \
35 checkmem(root); \
36 root->type = constr_type; \
37 __ret = asn1p_constraint_insert(root, \
38 arg1); \
39 checkmem(__ret == 0); \
40 } else { \
41 root = arg1; \
42 } \
43 if(arg2) { \
44 int __ret \
45 = asn1p_constraint_insert(root, arg2); \
46 checkmem(__ret == 0); \
47 } \
48 } while(0)
49
50%}
51
52
53/*
54 * Token value definition.
55 * a_*: ASN-specific types.
56 * tv_*: Locally meaningful types.
57 */
58%union {
59 asn1p_t *a_grammar;
60 asn1p_module_flags_e a_module_flags;
61 asn1p_module_t *a_module;
62 asn1p_expr_type_e a_type; /* ASN.1 Type */
63 asn1p_expr_t *a_expr; /* Constructed collection */
64 asn1p_constraint_t *a_constr; /* Constraint */
65 enum asn1p_constraint_type_e a_ctype;/* Constraint type */
66 asn1p_xports_t *a_xports; /* IMports/EXports */
67 asn1p_oid_t *a_oid; /* Object Identifier */
68 asn1p_oid_arc_t a_oid_arc; /* Single OID's arc */
69 struct asn1p_type_tag_s a_tag; /* A tag */
70 asn1p_ref_t *a_ref; /* Reference to custom type */
71 asn1p_wsyntx_t *a_wsynt; /* WITH SYNTAX contents */
72 asn1p_wsyntx_chunk_t *a_wchunk; /* WITH SYNTAX chunk */
73 struct asn1p_ref_component_s a_refcomp; /* Component of a reference */
74 asn1p_value_t *a_value; /* Number, DefinedValue, etc */
75 struct asn1p_param_s a_parg; /* A parameter argument */
76 asn1p_paramlist_t *a_plist; /* A pargs list */
77 enum asn1p_expr_marker_e a_marker; /* OPTIONAL/DEFAULT */
78 enum asn1p_constr_pres_e a_pres; /* PRESENT/ABSENT/OPTIONAL */
79 asn1_integer_t a_int;
80 char *tv_str;
81 struct {
82 char *buf;
83 int len;
84 } tv_opaque;
85 struct {
86 char *name;
87 struct asn1p_type_tag_s tag;
88 } tv_nametag;
89};
90
91/*
92 * Token types returned by scanner.
93 */
94%token TOK_PPEQ /* "::=", Pseudo Pascal EQuality */
95%token <tv_opaque> TOK_opaque /* opaque data (driven from .y) */
96%token <tv_str> TOK_bstring
97%token <tv_opaque> TOK_cstring
98%token <tv_str> TOK_hstring
99%token <tv_str> TOK_identifier
100%token <a_int> TOK_number
101%token <a_int> TOK_number_negative
102%token <tv_str> TOK_typereference
Lev Walkinf59d0752004-08-18 04:59:12 +0000103%token <tv_str> TOK_capitalreference /* "CLASS1" */
Lev Walkinf15320b2004-06-03 03:38:44 +0000104%token <tv_str> TOK_typefieldreference /* "&Pork" */
105%token <tv_str> TOK_valuefieldreference /* "&id" */
106
107/*
108 * Token types representing ASN.1 standard keywords.
109 */
110%token TOK_ABSENT
111%token TOK_ABSTRACT_SYNTAX
112%token TOK_ALL
113%token TOK_ANY
114%token TOK_APPLICATION
115%token TOK_AUTOMATIC
116%token TOK_BEGIN
117%token TOK_BIT
118%token TOK_BMPString
119%token TOK_BOOLEAN
120%token TOK_BY
121%token TOK_CHARACTER
122%token TOK_CHOICE
123%token TOK_CLASS
124%token TOK_COMPONENT
125%token TOK_COMPONENTS
126%token TOK_CONSTRAINED
127%token TOK_CONTAINING
128%token TOK_DEFAULT
129%token TOK_DEFINITIONS
130%token TOK_DEFINED
131%token TOK_EMBEDDED
132%token TOK_ENCODED
Lev Walkinf59d0752004-08-18 04:59:12 +0000133%token TOK_ENCODING_CONTROL
Lev Walkinf15320b2004-06-03 03:38:44 +0000134%token TOK_END
135%token TOK_ENUMERATED
136%token TOK_EXPLICIT
137%token TOK_EXPORTS
138%token TOK_EXTENSIBILITY
139%token TOK_EXTERNAL
140%token TOK_FALSE
141%token TOK_FROM
142%token TOK_GeneralizedTime
143%token TOK_GeneralString
144%token TOK_GraphicString
145%token TOK_IA5String
146%token TOK_IDENTIFIER
147%token TOK_IMPLICIT
148%token TOK_IMPLIED
149%token TOK_IMPORTS
150%token TOK_INCLUDES
151%token TOK_INSTANCE
Lev Walkinf59d0752004-08-18 04:59:12 +0000152%token TOK_INSTRUCTIONS
Lev Walkinf15320b2004-06-03 03:38:44 +0000153%token TOK_INTEGER
154%token TOK_ISO646String
155%token TOK_MAX
156%token TOK_MIN
157%token TOK_MINUS_INFINITY
158%token TOK_NULL
159%token TOK_NumericString
160%token TOK_OBJECT
161%token TOK_ObjectDescriptor
162%token TOK_OCTET
163%token TOK_OF
164%token TOK_OPTIONAL
165%token TOK_PATTERN
166%token TOK_PDV
167%token TOK_PLUS_INFINITY
168%token TOK_PRESENT
169%token TOK_PrintableString
170%token TOK_PRIVATE
171%token TOK_REAL
172%token TOK_RELATIVE_OID
173%token TOK_SEQUENCE
174%token TOK_SET
175%token TOK_SIZE
176%token TOK_STRING
177%token TOK_SYNTAX
178%token TOK_T61String
179%token TOK_TAGS
180%token TOK_TeletexString
181%token TOK_TRUE
182%token TOK_TYPE_IDENTIFIER
183%token TOK_UNIQUE
184%token TOK_UNIVERSAL
185%token TOK_UniversalString
186%token TOK_UTCTime
187%token TOK_UTF8String
188%token TOK_VideotexString
189%token TOK_VisibleString
190%token TOK_WITH
191
Lev Walkinf15320b2004-06-03 03:38:44 +0000192%left TOK_EXCEPT
Lev Walkinf59d0752004-08-18 04:59:12 +0000193%left '^' TOK_INTERSECTION
194%left '|' TOK_UNION
Lev Walkinf15320b2004-06-03 03:38:44 +0000195
196/* Misc tags */
197%token TOK_TwoDots /* .. */
198%token TOK_ThreeDots /* ... */
199%token <a_tag> TOK_tag /* [0] */
200
201
202/*
203 * Types defined herein.
204 */
205%type <a_grammar> ModuleList
206%type <a_module> ModuleSpecification
207%type <a_module> ModuleSpecificationBody
208%type <a_module> ModuleSpecificationElement
209%type <a_module> optModuleSpecificationBody /* Optional */
210%type <a_module_flags> optModuleSpecificationFlags
211%type <a_module_flags> ModuleSpecificationFlags /* Set of FL */
212%type <a_module_flags> ModuleSpecificationFlag /* Single FL */
213%type <a_module> ImportsDefinition
214%type <a_module> ImportsBundleSet
215%type <a_xports> ImportsBundle
216%type <a_xports> ImportsList
217%type <a_xports> ExportsDefinition
218%type <a_xports> ExportsBody
219%type <a_expr> ImportsElement
220%type <a_expr> ExportsElement
Lev Walkinf15320b2004-06-03 03:38:44 +0000221%type <a_expr> ExtensionAndException
Lev Walkin070a52d2004-08-22 03:19:54 +0000222%type <a_expr> TypeDeclaration
Lev Walkinf15320b2004-06-03 03:38:44 +0000223%type <a_ref> ComplexTypeReference
224%type <a_ref> ComplexTypeReferenceAmpList
225%type <a_refcomp> ComplexTypeReferenceElement
226%type <a_refcomp> ClassFieldIdentifier
227%type <a_refcomp> ClassFieldName
228%type <a_expr> ClassFieldList
229%type <a_expr> ClassField
230%type <a_expr> ClassDeclaration
Lev Walkin070a52d2004-08-22 03:19:54 +0000231%type <a_expr> Type
Lev Walkinf15320b2004-06-03 03:38:44 +0000232%type <a_expr> DataTypeReference /* Type1 ::= Type2 */
233%type <a_expr> DefinedTypeRef
234%type <a_expr> ValueSetDefinition /* Val INTEGER ::= {1|2} */
235%type <a_expr> ValueDefinition /* val INTEGER ::= 1*/
Lev Walkinceb20e72004-09-05 10:40:41 +0000236%type <a_expr> optValueSetBody
237%type <a_expr> ValueSetBody
238%type <a_expr> ValueSetElement
Lev Walkinf15320b2004-06-03 03:38:44 +0000239%type <a_value> InlineOrDefinedValue
240%type <a_value> DefinedValue
241%type <a_value> SignedNumber
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
252%type <tv_nametag> TaggedIdentifier
253%type <tv_str> Identifier
254%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
268%type <a_tag> Tag /* [UNIVERSAL 0] IMPLICIT */
269%type <a_tag> optTag /* [UNIVERSAL 0] IMPLICIT */
270%type <a_constr> optConstraints
Lev Walkind2ea1de2004-08-20 13:25:29 +0000271%type <a_constr> Constraints
Lev Walkinf59d0752004-08-18 04:59:12 +0000272%type <a_constr> SetOfConstraints
273%type <a_constr> ElementSetSpecs /* 1..2,...,3 */
274%type <a_constr> ElementSetSpec /* 1..2,...,3 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000275%type <a_constr> ConstraintSubtypeElement /* 1..2 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000276%type <a_constr> SimpleTableConstraint
277%type <a_constr> TableConstraint
278%type <a_constr> WithComponents
279%type <a_constr> WithComponentsList
280%type <a_constr> WithComponentsElement
281%type <a_constr> ComponentRelationConstraint
282%type <a_constr> AtNotationList
283%type <a_ref> AtNotationElement
284%type <a_value> ConstraintValue
285%type <a_ctype> ConstraintSpec
286%type <a_ctype> ConstraintRangeSpec
287%type <a_wsynt> optWithSyntax
288%type <a_wsynt> WithSyntax
289%type <a_wsynt> WithSyntaxFormat
290%type <a_wchunk> WithSyntaxFormatToken
291%type <a_marker> optMarker Marker
292%type <a_int> optUnique
293%type <a_pres> optPresenceConstraint PresenceConstraint
294%type <tv_str> ComponentIdList
295
296
297%%
298
299
300ParsedGrammar:
301 ModuleList {
302 *(void **)param = $1;
303 }
304 ;
305
306ModuleList:
307 ModuleSpecification {
308 $$ = asn1p_new();
309 checkmem($$);
310 TQ_ADD(&($$->modules), $1, mod_next);
311 }
312 | ModuleList ModuleSpecification {
313 $$ = $1;
314 TQ_ADD(&($$->modules), $2, mod_next);
315 }
316 ;
317
318/*
319 * ASN module definition.
320 * === EXAMPLE ===
321 * MySyntax DEFINITIONS AUTOMATIC TAGS ::=
322 * BEGIN
323 * ...
324 * END
325 * === EOF ===
326 */
327
328ModuleSpecification:
329 TypeRefName optObjectIdentifier TOK_DEFINITIONS
330 optModuleSpecificationFlags
331 TOK_PPEQ TOK_BEGIN
332 optModuleSpecificationBody
333 TOK_END {
334
335 if($7) {
336 $$ = $7;
337 } else {
338 /* There's a chance that a module is just plain empty */
339 $$ = asn1p_module_new();
340 }
341 checkmem($$);
342
343 $$->Identifier = $1;
344 $$->module_oid = $2;
345 $$->module_flags = $4;
346 }
347 ;
348
349/*
350 * Object Identifier Definition
351 * { iso member-body(2) 3 }
352 */
353optObjectIdentifier:
354 { $$ = 0; }
355 | ObjectIdentifier { $$ = $1; }
356 ;
357
358ObjectIdentifier:
359 '{' ObjectIdentifierBody '}' {
360 $$ = $2;
361 }
362 | '{' '}' {
363 $$ = 0;
364 }
365 ;
366
367ObjectIdentifierBody:
368 ObjectIdentifierElement {
369 $$ = asn1p_oid_new();
370 asn1p_oid_add_arc($$, &$1);
371 if($1.name)
372 free($1.name);
373 }
374 | ObjectIdentifierBody ObjectIdentifierElement {
375 $$ = $1;
376 asn1p_oid_add_arc($$, &$2);
377 if($2.name)
378 free($2.name);
379 }
380 ;
381
382ObjectIdentifierElement:
383 Identifier { /* iso */
384 $$.name = $1;
385 $$.number = -1;
386 }
387 | Identifier '(' TOK_number ')' { /* iso(1) */
388 $$.name = $1;
389 $$.number = $3;
390 }
391 | TOK_number { /* 1 */
392 $$.name = 0;
393 $$.number = $1;
394 }
395 ;
396
397/*
398 * Optional module flags.
399 */
400optModuleSpecificationFlags:
401 { $$ = MSF_NOFLAGS; }
402 | ModuleSpecificationFlags {
403 $$ = $1;
404 }
405 ;
406
407/*
408 * Module flags.
409 */
410ModuleSpecificationFlags:
411 ModuleSpecificationFlag {
412 $$ = $1;
413 }
414 | ModuleSpecificationFlags ModuleSpecificationFlag {
415 $$ = $1 | $2;
416 }
417 ;
418
419/*
420 * Single module flag.
421 */
422ModuleSpecificationFlag:
423 TOK_EXPLICIT TOK_TAGS {
424 $$ = MSF_EXPLICIT_TAGS;
425 }
426 | TOK_IMPLICIT TOK_TAGS {
427 $$ = MSF_IMPLICIT_TAGS;
428 }
429 | TOK_AUTOMATIC TOK_TAGS {
430 $$ = MSF_AUTOMATIC_TAGS;
431 }
432 | TOK_EXTENSIBILITY TOK_IMPLIED {
433 $$ = MSF_EXTENSIBILITY_IMPLIED;
434 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000435 /* EncodingReferenceDefault */
436 | TOK_capitalreference TOK_INSTRUCTIONS {
437 /* X.680Amd1 specifies TAG and XER */
438 if(strcmp($1, "TAG") == 0) {
439 $$ = MSF_TAG_INSTRUCTIONS;
440 } else if(strcmp($1, "XER") == 0) {
441 $$ = MSF_XER_INSTRUCTIONS;
442 } else {
443 fprintf(stderr,
444 "WARNING: %s INSTRUCTIONS at line %d: "
445 "Unrecognized encoding reference\n",
446 $1, yylineno);
447 $$ = MSF_unk_INSTRUCTIONS;
448 }
449 free($1);
450 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000451 ;
452
453/*
454 * Optional module body.
455 */
456optModuleSpecificationBody:
457 { $$ = 0; }
458 | ModuleSpecificationBody {
Lev Walkinf15320b2004-06-03 03:38:44 +0000459 $$ = $1;
460 }
461 ;
462
463/*
464 * ASN.1 Module body.
465 */
466ModuleSpecificationBody:
467 ModuleSpecificationElement {
468 $$ = $1;
469 }
470 | ModuleSpecificationBody ModuleSpecificationElement {
471 $$ = $1;
472
Lev Walkinf59d0752004-08-18 04:59:12 +0000473 /* Behave well when one of them is skipped. */
474 if(!($1)) {
475 if($2) $$ = $2;
476 break;
477 }
478
Lev Walkinf15320b2004-06-03 03:38:44 +0000479#ifdef MY_IMPORT
480#error MY_IMPORT DEFINED ELSEWHERE!
481#endif
482#define MY_IMPORT(foo,field) do { \
Lev Walkinbc55d232004-08-13 12:31:09 +0000483 while(TQ_FIRST(&($2->foo))) { \
Lev Walkinf15320b2004-06-03 03:38:44 +0000484 TQ_ADD(&($$->foo), \
485 TQ_REMOVE(&($2->foo), field), \
486 field); \
Lev Walkinbc55d232004-08-13 12:31:09 +0000487 } \
488 assert(TQ_FIRST(&($2->foo)) == 0); \
489 } while(0)
Lev Walkinf15320b2004-06-03 03:38:44 +0000490
491 MY_IMPORT(imports, xp_next);
492 MY_IMPORT(exports, xp_next);
493 MY_IMPORT(members, next);
494#undef MY_IMPORT
495
496 }
497 ;
498
499/*
500 * One of the elements of ASN.1 module specification.
501 */
502ModuleSpecificationElement:
503 ImportsDefinition {
504 $$ = $1;
505 }
506 | ExportsDefinition {
507 $$ = asn1p_module_new();
508 checkmem($$);
509 if($1) {
510 TQ_ADD(&($$->exports), $1, xp_next);
511 } else {
512 /* "EXPORTS ALL;" ? */
513 }
514 }
515 | DataTypeReference {
516 $$ = asn1p_module_new();
517 checkmem($$);
518 assert($1->expr_type != A1TC_INVALID);
519 assert($1->meta_type != AMT_INVALID);
520 TQ_ADD(&($$->members), $1, next);
521 }
522 | ValueDefinition {
523 $$ = asn1p_module_new();
524 checkmem($$);
525 assert($1->expr_type != A1TC_INVALID);
526 assert($1->meta_type != AMT_INVALID);
527 TQ_ADD(&($$->members), $1, next);
528 }
529 /*
530 * Value set definition
531 * === EXAMPLE ===
532 * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 }
533 * === EOF ===
534 */
535 | ValueSetDefinition {
536 $$ = asn1p_module_new();
537 checkmem($$);
538 assert($1->expr_type != A1TC_INVALID);
539 assert($1->meta_type != AMT_INVALID);
540 TQ_ADD(&($$->members), $1, next);
541 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000542 | TOK_ENCODING_CONTROL TOK_capitalreference
543 { asn1p_lexer_hack_push_encoding_control(); }
544 {
545 fprintf(stderr,
546 "WARNING: ENCODING-CONTROL %s "
547 "specification at line %d ignored\n",
548 $2, yylineno);
549 free($2);
550 $$ = 0;
551 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000552
553 /*
554 * Erroneous attemps
555 */
556 | BasicString {
557 return yyerror(
558 "Attempt to redefine a standard basic type, "
559 "use -ftypesXY to switch back "
560 "to older version of ASN.1 standard");
561 }
562 ;
563
564/*
565 * === EXAMPLE ===
566 * IMPORTS Type1, value FROM Module { iso standard(0) } ;
567 * === EOF ===
568 */
569ImportsDefinition:
570 TOK_IMPORTS ImportsBundleSet ';' {
571 $$ = $2;
572 }
573 /*
574 * Some error cases.
575 */
576 | TOK_IMPORTS TOK_FROM /* ... */ {
577 return yyerror("Empty IMPORTS list");
578 }
579 ;
580
581ImportsBundleSet:
582 ImportsBundle {
583 $$ = asn1p_module_new();
584 checkmem($$);
585 TQ_ADD(&($$->imports), $1, xp_next);
586 }
587 | ImportsBundleSet ImportsBundle {
588 $$ = $1;
589 TQ_ADD(&($$->imports), $2, xp_next);
590 }
591 ;
592
593ImportsBundle:
594 ImportsList TOK_FROM TypeRefName optObjectIdentifier {
595 $$ = $1;
596 $$->from = $3;
597 $$->from_oid = $4;
598 checkmem($$);
599 }
600 ;
601
602ImportsList:
603 ImportsElement {
604 $$ = asn1p_xports_new();
605 checkmem($$);
606 TQ_ADD(&($$->members), $1, next);
607 }
608 | ImportsList ',' ImportsElement {
609 $$ = $1;
610 TQ_ADD(&($$->members), $3, next);
611 }
612 ;
613
614ImportsElement:
615 TypeRefName {
616 $$ = asn1p_expr_new(yylineno);
617 checkmem($$);
618 $$->Identifier = $1;
619 $$->expr_type = A1TC_REFERENCE;
620 }
621 | Identifier {
622 $$ = asn1p_expr_new(yylineno);
623 checkmem($$);
624 $$->Identifier = $1;
625 $$->expr_type = A1TC_REFERENCE;
626 }
627 ;
628
629ExportsDefinition:
630 TOK_EXPORTS ExportsBody ';' {
631 $$ = $2;
632 }
633 | TOK_EXPORTS TOK_ALL ';' {
634 $$ = 0;
635 }
636 | TOK_EXPORTS ';' {
637 /* Empty EXPORTS clause effectively prohibits export. */
638 $$ = asn1p_xports_new();
639 checkmem($$);
640 }
641 ;
642
643ExportsBody:
644 ExportsElement {
645 $$ = asn1p_xports_new();
646 assert($$);
647 TQ_ADD(&($$->members), $1, next);
648 }
649 | ExportsBody ',' ExportsElement {
650 $$ = $1;
651 TQ_ADD(&($$->members), $3, next);
652 }
653 ;
654
655ExportsElement:
656 TypeRefName {
657 $$ = asn1p_expr_new(yylineno);
658 checkmem($$);
659 $$->Identifier = $1;
660 $$->expr_type = A1TC_EXPORTVAR;
661 }
662 | Identifier {
663 $$ = asn1p_expr_new(yylineno);
664 checkmem($$);
665 $$->Identifier = $1;
666 $$->expr_type = A1TC_EXPORTVAR;
667 }
668 ;
669
670
671ValueSetDefinition:
672 TypeRefName DefinedTypeRef TOK_PPEQ '{' optValueSetBody '}' {
673 $$ = $2;
674 assert($$->Identifier == 0);
675 $$->Identifier = $1;
676 $$->meta_type = AMT_VALUESET;
677 // take care of optValueSetBody
678 }
679 ;
680
681DefinedTypeRef:
682 ComplexTypeReference {
683 $$ = asn1p_expr_new(yylineno);
684 checkmem($$);
685 $$->reference = $1;
686 $$->expr_type = A1TC_REFERENCE;
687 $$->meta_type = AMT_TYPEREF;
688 }
689 | BasicTypeId {
690 $$ = asn1p_expr_new(yylineno);
691 checkmem($$);
692 $$->expr_type = $1;
693 $$->meta_type = AMT_TYPE;
694 }
695 ;
696
697optValueSetBody:
698 { }
Lev Walkinceb20e72004-09-05 10:40:41 +0000699 | ValueSetBody {
700 }
701 ;
702
703/*
704 * X.680 does not permit ElementSetSpecs starting with ellipsis,
705 * i.e. (..., A, B). This is very strange: the ElementSetSpecs is used
706 * inside ValueSet, and ValueSets "in the wild" tend to have the first
707 * ellipsis.
708 */
709ValueSetBody:
710 ValueSetElement {
711 }
712 | ValueSetBody ',' ValueSetElement {
713 }
714 ;
715
716ValueSetElement:
717 TOK_ThreeDots {
718 }
719 | ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +0000720 }
721 ;
722
723
724/*
725 * Data Type Reference.
726 * === EXAMPLE ===
727 * Type3 ::= CHOICE { a Type1, b Type 2 }
728 * === EOF ===
729 */
730
731DataTypeReference:
732 /*
733 * Optionally tagged type definition.
734 */
735 TypeRefName TOK_PPEQ optTag TOK_TYPE_IDENTIFIER {
736 $$ = asn1p_expr_new(yylineno);
737 checkmem($$);
738 $$->Identifier = $1;
739 $$->tag = $3;
740 $$->expr_type = A1TC_TYPEID;
741 $$->meta_type = AMT_TYPE;
742 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000743 | TypeRefName TOK_PPEQ optTag Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000744 $$ = $4;
745 $$->Identifier = $1;
746 $$->tag = $3;
747 assert($$->expr_type);
748 assert($$->meta_type);
749 }
750 | TypeRefName TOK_PPEQ ClassDeclaration {
751 $$ = $3;
752 $$->Identifier = $1;
753 assert($$->expr_type == A1TC_CLASSDEF);
754 assert($$->meta_type == AMT_OBJECT);
755 }
756 /*
757 * Parametrized <Type> declaration:
758 * === EXAMPLE ===
759 * SIGNED { ToBeSigned } ::= SEQUENCE {
760 * toBeSigned ToBeSigned,
761 * algorithm AlgorithmIdentifier,
762 * signature BIT STRING
763 * }
764 * === EOF ===
765 */
Lev Walkin070a52d2004-08-22 03:19:54 +0000766 | TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000767 $$ = $6;
768 assert($$->Identifier == 0);
769 $$->Identifier = $1;
770 $$->params = $3;
771 $$->meta_type = AMT_PARAMTYPE;
772 }
773 ;
774
775ParameterArgumentList:
776 ParameterArgumentName {
777 int ret;
778 $$ = asn1p_paramlist_new(yylineno);
779 checkmem($$);
780 ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument);
781 checkmem(ret == 0);
782 if($1.governor) asn1p_ref_free($1.governor);
783 if($1.argument) free($1.argument);
784 }
785 | ParameterArgumentList ',' ParameterArgumentName {
786 int ret;
787 $$ = $1;
788 ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument);
789 checkmem(ret == 0);
790 if($3.governor) asn1p_ref_free($3.governor);
791 if($3.argument) free($3.argument);
792 }
793 ;
794
795ParameterArgumentName:
796 TypeRefName {
797 $$.governor = NULL;
798 $$.argument = $1;
799 }
800 | TypeRefName ':' Identifier {
801 int ret;
802 $$.governor = asn1p_ref_new(yylineno);
803 ret = asn1p_ref_add_component($$.governor, $1, 0);
804 checkmem(ret == 0);
805 $$.argument = $3;
806 }
807 | BasicTypeId ':' Identifier {
808 int ret;
809 $$.governor = asn1p_ref_new(yylineno);
810 ret = asn1p_ref_add_component($$.governor,
811 ASN_EXPR_TYPE2STR($1), 1);
812 checkmem(ret == 0);
813 $$.argument = $3;
814 }
815 ;
816
817ActualParameterList:
818 ActualParameter {
819 $$ = asn1p_expr_new(yylineno);
820 checkmem($$);
821 TQ_ADD(&($$->members), $1, next);
822 }
823 | ActualParameterList ',' ActualParameter {
824 $$ = $1;
825 TQ_ADD(&($$->members), $3, next);
826 }
827 ;
828
829ActualParameter:
Lev Walkin070a52d2004-08-22 03:19:54 +0000830 Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000831 $$ = $1;
832 }
833 | Identifier {
834 $$ = asn1p_expr_new(yylineno);
835 checkmem($$);
836 $$->Identifier = $1;
837 $$->expr_type = A1TC_REFERENCE;
838 $$->meta_type = AMT_VALUE;
839 }
840 ;
841
842/*
843 * A collection of constructed data type members.
844 */
Lev Walkin070a52d2004-08-22 03:19:54 +0000845ComponentTypeLists:
846 ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000847 $$ = asn1p_expr_new(yylineno);
848 checkmem($$);
849 TQ_ADD(&($$->members), $1, next);
850 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000851 | ComponentTypeLists ',' ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000852 $$ = $1;
853 TQ_ADD(&($$->members), $3, next);
854 }
855 ;
856
Lev Walkin070a52d2004-08-22 03:19:54 +0000857ComponentType:
858 TaggedIdentifier Type optMarker {
859 $$ = $2;
860 assert($$->Identifier == 0);
861 $$->Identifier = $1.name;
862 $$->tag = $1.tag;
863 $$->marker = $3;
864 }
865 | TOK_COMPONENTS TOK_OF Type {
866 $$ = asn1p_expr_new(yylineno);
867 checkmem($$);
868 $$->meta_type = $3->meta_type;
869 $$->expr_type = A1TC_COMPONENTS_OF;
870 TQ_ADD(&($$->members), $3, next);
871 }
872 | ExtensionAndException {
873 $$ = $1;
874 }
875 ;
876
877AlternativeTypeLists:
878 AlternativeType {
879 $$ = asn1p_expr_new(yylineno);
880 checkmem($$);
881 TQ_ADD(&($$->members), $1, next);
882 }
883 | AlternativeTypeLists ',' AlternativeType {
884 $$ = $1;
885 TQ_ADD(&($$->members), $3, next);
886 }
887 ;
888
889AlternativeType:
890 TaggedIdentifier Type {
891 $$ = $2;
892 assert($$->Identifier == 0);
893 $$->Identifier = $1.name;
894 $$->tag = $1.tag;
895 }
896 | ExtensionAndException {
897 $$ = $1;
898 }
899 ;
900
Lev Walkinf15320b2004-06-03 03:38:44 +0000901ClassDeclaration:
902 TOK_CLASS '{' ClassFieldList '}' optWithSyntax {
903 $$ = $3;
904 checkmem($$);
905 $$->with_syntax = $5;
906 assert($$->expr_type == A1TC_CLASSDEF);
907 assert($$->meta_type == AMT_OBJECT);
908 }
909 ;
910
911optUnique:
912 { $$ = 0; }
913 | TOK_UNIQUE { $$ = 1; }
914 ;
915
916ClassFieldList:
917 ClassField {
918 $$ = asn1p_expr_new(yylineno);
919 checkmem($$);
920 $$->expr_type = A1TC_CLASSDEF;
921 $$->meta_type = AMT_OBJECT;
922 TQ_ADD(&($$->members), $1, next);
923 }
924 | ClassFieldList ',' ClassField {
925 $$ = $1;
926 TQ_ADD(&($$->members), $3, next);
927 }
928 ;
929
930ClassField:
931 ClassFieldIdentifier optMarker {
932 $$ = asn1p_expr_new(yylineno);
933 checkmem($$);
934 $$->Identifier = $1.name;
935 $$->expr_type = A1TC_CLASSFIELD;
936 $$->meta_type = AMT_OBJECTFIELD;
937 $$->marker = $2;
938 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000939 | ClassFieldIdentifier Type optMarker optUnique {
Lev Walkinf15320b2004-06-03 03:38:44 +0000940 $$ = $2;
941 $$->Identifier = $1.name;
Lev Walkin070a52d2004-08-22 03:19:54 +0000942 $$->marker = $3;
943 $$->unique = $4;
Lev Walkinf15320b2004-06-03 03:38:44 +0000944 }
945 | ClassFieldIdentifier ClassFieldIdentifier optMarker optUnique {
946 int ret;
947 $$ = asn1p_expr_new(yylineno);
948 checkmem($$);
949 $$->Identifier = $1.name;
950 $$->reference = asn1p_ref_new(yylineno);
951 checkmem($$->reference);
952 ret = asn1p_ref_add_component($$->reference,
953 $2.name, $2.lex_type);
954 checkmem(ret == 0);
955 $$->expr_type = A1TC_CLASSFIELD;
956 $$->meta_type = AMT_OBJECTFIELD;
957 $$->marker = $3;
958 $$->unique = $4;
959 }
960 ;
961
962optWithSyntax:
963 { $$ = 0; }
964 | WithSyntax {
965 $$ = $1;
966 }
967 ;
968
969WithSyntax:
970 TOK_WITH TOK_SYNTAX '{'
971 { asn1p_lexer_hack_enable_with_syntax(); }
972 WithSyntaxFormat
973 '}' {
974 $$ = $5;
975 }
976 ;
977
978WithSyntaxFormat:
979 WithSyntaxFormatToken {
980 $$ = asn1p_wsyntx_new();
981 TQ_ADD(&($$->chunks), $1, next);
982 }
983 | WithSyntaxFormat WithSyntaxFormatToken {
984 $$ = $1;
985 TQ_ADD(&($$->chunks), $2, next);
986 }
987 ;
988
989WithSyntaxFormatToken:
990 TOK_opaque {
991 $$ = asn1p_wsyntx_chunk_frombuf($1.buf, $1.len, 0);
992 }
993 | ClassFieldIdentifier {
994 asn1p_ref_t *ref;
995 int ret;
996 ref = asn1p_ref_new(yylineno);
997 checkmem(ref);
998 ret = asn1p_ref_add_component(ref, $1.name, $1.lex_type);
999 checkmem(ret == 0);
1000 $$ = asn1p_wsyntx_chunk_fromref(ref, 0);
1001 }
1002 ;
1003
Lev Walkinf15320b2004-06-03 03:38:44 +00001004ExtensionAndException:
1005 TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001006 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001007 checkmem($$);
1008 $$->Identifier = strdup("...");
1009 checkmem($$->Identifier);
1010 $$->expr_type = A1TC_EXTENSIBLE;
1011 $$->meta_type = AMT_TYPE;
1012 }
1013 | TOK_ThreeDots '!' DefinedValue {
Lev Walkinceb20e72004-09-05 10:40:41 +00001014 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001015 checkmem($$);
1016 $$->Identifier = strdup("...");
1017 checkmem($$->Identifier);
1018 $$->value = $3;
1019 $$->expr_type = A1TC_EXTENSIBLE;
1020 $$->meta_type = AMT_TYPE;
1021 }
1022 | TOK_ThreeDots '!' SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001023 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001024 checkmem($$);
1025 $$->Identifier = strdup("...");
1026 $$->value = $3;
1027 checkmem($$->Identifier);
1028 $$->expr_type = A1TC_EXTENSIBLE;
1029 $$->meta_type = AMT_TYPE;
1030 }
1031 ;
1032
Lev Walkin070a52d2004-08-22 03:19:54 +00001033Type:
1034 TypeDeclaration optConstraints {
1035 $$ = $1;
1036 /*
1037 * Outer constraint for SEQUENCE OF and SET OF applies
1038 * to the inner type.
1039 */
1040 if($$->expr_type == ASN_CONSTR_SEQUENCE_OF
1041 || $$->expr_type == ASN_CONSTR_SET_OF) {
1042 assert(!TQ_FIRST(&($$->members))->constraints);
1043 TQ_FIRST(&($$->members))->constraints = $2;
1044 } else {
1045 if($$->constraints) {
1046 assert(!$2);
1047 } else {
1048 $$->constraints = $2;
1049 }
1050 }
1051 }
1052 ;
1053
1054TypeDeclaration:
Lev Walkinf15320b2004-06-03 03:38:44 +00001055 BasicType {
1056 $$ = $1;
1057 }
1058 | BasicString {
1059 $$ = asn1p_expr_new(yylineno);
1060 checkmem($$);
1061 $$->expr_type = $1;
1062 $$->meta_type = AMT_TYPE;
1063 }
Lev Walkin070a52d2004-08-22 03:19:54 +00001064 | TOK_CHOICE '{' AlternativeTypeLists '}' {
1065 $$ = $3;
1066 assert($$->expr_type == A1TC_INVALID);
1067 $$->expr_type = ASN_CONSTR_CHOICE;
1068 $$->meta_type = AMT_TYPE;
Lev Walkinf15320b2004-06-03 03:38:44 +00001069 }
Lev Walkin070a52d2004-08-22 03:19:54 +00001070 | TOK_SEQUENCE '{' ComponentTypeLists '}' {
1071 $$ = $3;
1072 assert($$->expr_type == A1TC_INVALID);
1073 $$->expr_type = ASN_CONSTR_SEQUENCE;
1074 $$->meta_type = AMT_TYPE;
1075 }
1076 | TOK_SET '{' ComponentTypeLists '}' {
1077 $$ = $3;
1078 assert($$->expr_type == A1TC_INVALID);
1079 $$->expr_type = ASN_CONSTR_SET;
1080 $$->meta_type = AMT_TYPE;
1081 }
1082 | TOK_SEQUENCE optConstraints TOK_OF TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001083 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001084 checkmem($$);
1085 $$->constraints = $2;
1086 $$->expr_type = ASN_CONSTR_SEQUENCE_OF;
1087 $$->meta_type = AMT_TYPE;
1088 TQ_ADD(&($$->members), $4, next);
1089 }
1090 | TOK_SET optConstraints TOK_OF TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001091 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001092 checkmem($$);
1093 $$->constraints = $2;
1094 $$->expr_type = ASN_CONSTR_SET_OF;
1095 $$->meta_type = AMT_TYPE;
1096 TQ_ADD(&($$->members), $4, next);
1097 }
1098 | TOK_ANY {
Lev Walkinceb20e72004-09-05 10:40:41 +00001099 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001100 checkmem($$);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001101 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001102 $$->meta_type = AMT_TYPE;
1103 }
1104 | TOK_ANY TOK_DEFINED TOK_BY Identifier {
1105 int ret;
Lev Walkinceb20e72004-09-05 10:40:41 +00001106 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001107 checkmem($$);
1108 $$->reference = asn1p_ref_new(yylineno);
1109 ret = asn1p_ref_add_component($$->reference,
1110 $4, RLT_lowercase);
1111 checkmem(ret == 0);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001112 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001113 $$->meta_type = AMT_TYPE;
1114 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001115 /*
1116 * A parametrized assignment.
1117 */
1118 | TypeRefName '{' ActualParameterList '}' {
1119 int ret;
1120 $$ = $3;
1121 assert($$->expr_type == 0);
1122 assert($$->meta_type == 0);
1123 assert($$->reference == 0);
1124 $$->reference = asn1p_ref_new(yylineno);
1125 checkmem($$->reference);
1126 ret = asn1p_ref_add_component($$->reference, $1, RLT_UNKNOWN);
1127 checkmem(ret == 0);
1128 free($1);
1129 $$->expr_type = A1TC_PARAMETRIZED;
1130 $$->meta_type = AMT_TYPE;
1131 }
1132 /*
1133 * A DefinedType reference.
1134 * "CLASS1.&id.&id2"
1135 * or
1136 * "Module.Type"
1137 * or
1138 * "Module.identifier"
1139 * or
1140 * "Type"
1141 */
1142 | ComplexTypeReference {
1143 $$ = asn1p_expr_new(yylineno);
1144 checkmem($$);
1145 $$->reference = $1;
1146 $$->expr_type = A1TC_REFERENCE;
1147 $$->meta_type = AMT_TYPEREF;
1148 }
1149 | TOK_INSTANCE TOK_OF ComplexTypeReference {
1150 $$ = asn1p_expr_new(yylineno);
1151 checkmem($$);
1152 $$->reference = $3;
1153 $$->expr_type = A1TC_INSTANCE;
1154 $$->meta_type = AMT_TYPE;
1155 }
1156 ;
1157
1158/*
1159 * A type name consisting of several components.
1160 * === EXAMPLE ===
1161 * === EOF ===
1162 */
1163ComplexTypeReference:
1164 TOK_typereference {
1165 int ret;
1166 $$ = asn1p_ref_new(yylineno);
1167 checkmem($$);
1168 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1169 checkmem(ret == 0);
1170 free($1);
1171 }
1172 | TOK_typereference '.' TypeRefName {
1173 int ret;
1174 $$ = asn1p_ref_new(yylineno);
1175 checkmem($$);
1176 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1177 checkmem(ret == 0);
1178 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1179 checkmem(ret == 0);
1180 free($1);
1181 }
1182 | TOK_typereference '.' Identifier {
1183 int ret;
1184 $$ = asn1p_ref_new(yylineno);
1185 checkmem($$);
1186 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1187 checkmem(ret == 0);
1188 ret = asn1p_ref_add_component($$, $3, RLT_lowercase);
1189 checkmem(ret == 0);
1190 free($1);
1191 }
1192 | ObjectClassReference {
1193 int ret;
1194 $$ = asn1p_ref_new(yylineno);
1195 checkmem($$);
1196 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1197 free($1);
1198 checkmem(ret == 0);
1199 }
1200 | ObjectClassReference '.' ComplexTypeReferenceAmpList {
1201 int ret;
1202 $$ = $3;
1203 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1204 free($1);
1205 checkmem(ret == 0);
1206 /*
1207 * Move the last element infront.
1208 */
1209 {
1210 struct asn1p_ref_component_s tmp_comp;
1211 tmp_comp = $$->components[$$->comp_count-1];
1212 memmove(&$$->components[1],
1213 &$$->components[0],
1214 sizeof($$->components[0])
1215 * ($$->comp_count - 1));
1216 $$->components[0] = tmp_comp;
1217 }
1218 }
1219 ;
1220
1221ComplexTypeReferenceAmpList:
1222 ComplexTypeReferenceElement {
1223 int ret;
1224 $$ = asn1p_ref_new(yylineno);
1225 checkmem($$);
1226 ret = asn1p_ref_add_component($$, $1.name, $1.lex_type);
1227 free($1.name);
1228 checkmem(ret == 0);
1229 }
1230 | ComplexTypeReferenceAmpList '.' ComplexTypeReferenceElement {
1231 int ret;
1232 $$ = $1;
1233 ret = asn1p_ref_add_component($$, $3.name, $3.lex_type);
1234 free($3.name);
1235 checkmem(ret == 0);
1236 }
1237 ;
1238
1239ComplexTypeReferenceElement: ClassFieldName;
1240ClassFieldIdentifier: ClassFieldName;
1241
1242ClassFieldName:
1243 /* "&Type1" */
1244 TOK_typefieldreference {
1245 $$.lex_type = RLT_AmpUppercase;
1246 $$.name = $1;
1247 }
1248 /* "&id" */
1249 | TOK_valuefieldreference {
1250 $$.lex_type = RLT_Amplowercase;
1251 $$.name = $1;
1252 }
1253 ;
1254
1255
1256/*
1257 * === EXAMPLE ===
1258 * value INTEGER ::= 1
1259 * === EOF ===
1260 */
1261ValueDefinition:
1262 Identifier DefinedTypeRef TOK_PPEQ InlineOrDefinedValue {
1263 $$ = $2;
1264 assert($$->Identifier == NULL);
1265 $$->Identifier = $1;
1266 $$->meta_type = AMT_VALUE;
1267 $$->value = $4;
1268 }
1269 ;
1270
1271InlineOrDefinedValue:
1272 '{' { asn1p_lexer_hack_push_opaque_state(); }
1273 Opaque /* '}' */ {
1274 $$ = asn1p_value_frombuf($3.buf, $3.len, 0);
1275 checkmem($$);
1276 $$->type = ATV_UNPARSED;
1277 }
1278 | TOK_bstring {
1279 $$ = _convert_bitstring2binary($1, 'B');
1280 checkmem($$);
1281 }
1282 | TOK_hstring {
1283 $$ = _convert_bitstring2binary($1, 'H');
1284 checkmem($$);
1285 }
1286 | TOK_cstring {
1287 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1288 checkmem($$);
1289 }
1290 | SignedNumber {
1291 $$ = $1;
1292 }
1293 | DefinedValue {
1294 $$ = $1;
1295 }
1296 ;
1297
1298DefinedValue:
1299 Identifier {
1300 asn1p_ref_t *ref;
1301 int ret;
1302 ref = asn1p_ref_new(yylineno);
1303 checkmem(ref);
1304 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1305 checkmem(ret == 0);
1306 $$ = asn1p_value_fromref(ref, 0);
1307 checkmem($$);
1308 free($1);
1309 }
1310 | TypeRefName '.' Identifier {
1311 asn1p_ref_t *ref;
1312 int ret;
1313 ref = asn1p_ref_new(yylineno);
1314 checkmem(ref);
1315 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1316 checkmem(ret == 0);
1317 ret = asn1p_ref_add_component(ref, $3, RLT_lowercase);
1318 checkmem(ret == 0);
1319 $$ = asn1p_value_fromref(ref, 0);
1320 checkmem($$);
1321 free($1);
1322 free($3);
1323 }
1324 ;
1325
1326Opaque:
1327 TOK_opaque {
1328 $$.len = $1.len + 2;
1329 $$.buf = malloc($$.len + 1);
1330 checkmem($$.buf);
1331 $$.buf[0] = '{';
1332 $$.buf[1] = ' ';
1333 memcpy($$.buf + 2, $1.buf, $1.len);
1334 $$.buf[$$.len] = '\0';
1335 free($1.buf);
1336 }
1337 | Opaque TOK_opaque {
1338 int newsize = $1.len + $2.len;
1339 char *p = malloc(newsize + 1);
1340 checkmem(p);
1341 memcpy(p , $1.buf, $1.len);
1342 memcpy(p + $1.len, $2.buf, $2.len);
1343 p[newsize] = '\0';
1344 free($1.buf);
1345 free($2.buf);
1346 $$.buf = p;
1347 $$.len = newsize;
1348 }
1349 ;
1350
1351BasicTypeId:
1352 TOK_BOOLEAN { $$ = ASN_BASIC_BOOLEAN; }
1353 | TOK_NULL { $$ = ASN_BASIC_NULL; }
1354 | TOK_REAL { $$ = ASN_BASIC_REAL; }
1355 | BasicTypeId_UniverationCompatible { $$ = $1; }
1356 | TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; }
1357 | TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; }
1358 | TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; }
1359 | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; }
1360 | TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; }
1361 | TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; }
1362 | TOK_UTCTime { $$ = ASN_BASIC_UTCTime; }
1363 | TOK_GeneralizedTime { $$ = ASN_BASIC_GeneralizedTime; }
1364 ;
1365
1366/*
1367 * A type identifier which may be used with "{ a(1), b(2) }" clause.
1368 */
1369BasicTypeId_UniverationCompatible:
1370 TOK_INTEGER { $$ = ASN_BASIC_INTEGER; }
1371 | TOK_ENUMERATED { $$ = ASN_BASIC_ENUMERATED; }
1372 | TOK_BIT TOK_STRING { $$ = ASN_BASIC_BIT_STRING; }
1373 ;
1374
1375BasicType:
1376 BasicTypeId {
Lev Walkinceb20e72004-09-05 10:40:41 +00001377 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001378 checkmem($$);
1379 $$->expr_type = $1;
1380 $$->meta_type = AMT_TYPE;
1381 }
1382 | BasicTypeId_UniverationCompatible UniverationDefinition {
1383 if($2) {
1384 $$ = $2;
1385 } else {
Lev Walkinceb20e72004-09-05 10:40:41 +00001386 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001387 checkmem($$);
1388 }
1389 $$->expr_type = $1;
1390 $$->meta_type = AMT_TYPE;
1391 }
1392 ;
1393
1394BasicString:
1395 TOK_BMPString { $$ = ASN_STRING_BMPString; }
1396 | TOK_GeneralString {
1397 $$ = ASN_STRING_GeneralString;
1398 return yyerror("GeneralString is not supported");
1399 }
1400 | TOK_GraphicString {
1401 $$ = ASN_STRING_GraphicString;
1402 return yyerror("GraphicString is not supported");
1403 }
1404 | TOK_IA5String { $$ = ASN_STRING_IA5String; }
1405 | TOK_ISO646String { $$ = ASN_STRING_ISO646String; }
1406 | TOK_NumericString { $$ = ASN_STRING_NumericString; }
1407 | TOK_PrintableString { $$ = ASN_STRING_PrintableString; }
1408 | TOK_T61String {
1409 $$ = ASN_STRING_T61String;
1410 return yyerror("T61String not implemented yet");
1411 }
1412 | TOK_TeletexString { $$ = ASN_STRING_TeletexString; }
1413 | TOK_UniversalString { $$ = ASN_STRING_UniversalString; }
1414 | TOK_UTF8String { $$ = ASN_STRING_UTF8String; }
1415 | TOK_VideotexString {
1416 $$ = ASN_STRING_VideotexString;
1417 return yyerror("VideotexString is no longer supported");
1418 }
1419 | TOK_VisibleString { $$ = ASN_STRING_VisibleString; }
1420 | TOK_ObjectDescriptor { $$ = ASN_STRING_ObjectDescriptor; }
1421 ;
1422
Lev Walkind2ea1de2004-08-20 13:25:29 +00001423
Lev Walkinf15320b2004-06-03 03:38:44 +00001424/*
1425 * Data type constraints.
1426 */
Lev Walkinf15320b2004-06-03 03:38:44 +00001427Union: '|' | TOK_UNION;
1428Intersection: '^' | TOK_INTERSECTION;
1429Except: TOK_EXCEPT;
1430
Lev Walkinf59d0752004-08-18 04:59:12 +00001431optConstraints:
1432 { $$ = 0; }
Lev Walkind2ea1de2004-08-20 13:25:29 +00001433 | Constraints {
1434 $$ = $1;
1435 }
1436 ;
1437
1438Constraints:
1439 SetOfConstraints {
Lev Walkinf59d0752004-08-18 04:59:12 +00001440 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, 0);
1441 }
1442 | TOK_SIZE '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001443 /*
1444 * This is a special case, for compatibility purposes.
Lev Walkinf59d0752004-08-18 04:59:12 +00001445 * It goes without parentheses.
Lev Walkinf15320b2004-06-03 03:38:44 +00001446 */
Lev Walkind2ea1de2004-08-20 13:25:29 +00001447 CONSTRAINT_INSERT($$, ACT_CT_SIZE, $3, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001448 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001449 ;
1450
Lev Walkinf59d0752004-08-18 04:59:12 +00001451SetOfConstraints:
1452 '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001453 $$ = $2;
1454 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001455 | SetOfConstraints '(' ElementSetSpecs ')' {
1456 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $3);
1457 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001458 ;
1459
Lev Walkinf59d0752004-08-18 04:59:12 +00001460ElementSetSpecs:
1461 ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001462 $$ = $1;
1463 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001464 | ElementSetSpec ',' TOK_ThreeDots {
Lev Walkinf15320b2004-06-03 03:38:44 +00001465 asn1p_constraint_t *ct;
1466 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001467 ct->type = ACT_EL_EXT;
1468 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1469 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001470 | ElementSetSpec ',' TOK_ThreeDots ',' ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001471 asn1p_constraint_t *ct;
1472 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001473 ct->type = ACT_EL_EXT;
1474 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
Lev Walkinb4fcdd22004-08-13 12:35:09 +00001475 ct = $$;
1476 CONSTRAINT_INSERT($$, ACT_CA_CSV, ct, $5);
Lev Walkinf15320b2004-06-03 03:38:44 +00001477 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001478 ;
1479
Lev Walkinf59d0752004-08-18 04:59:12 +00001480ElementSetSpec:
1481 ConstraintSubtypeElement {
1482 $$ = $1;
1483 }
1484 | ElementSetSpec Union ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001485 CONSTRAINT_INSERT($$, ACT_CA_UNI, $1, $3);
1486 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001487 | ElementSetSpec Intersection ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001488 CONSTRAINT_INSERT($$, ACT_CA_INT, $1, $3);
1489 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001490 | ConstraintSubtypeElement Except ConstraintSubtypeElement {
Lev Walkinf15320b2004-06-03 03:38:44 +00001491 CONSTRAINT_INSERT($$, ACT_CA_EXC, $1, $3);
1492 }
1493 ;
1494
1495ConstraintSubtypeElement:
Lev Walkinf59d0752004-08-18 04:59:12 +00001496 ConstraintSpec '(' ElementSetSpecs ')' {
1497 int ret;
1498 $$ = asn1p_constraint_new(yylineno);
1499 checkmem($$);
1500 $$->type = $1;
1501 ret = asn1p_constraint_insert($$, $3);
1502 checkmem(ret == 0);
1503 }
1504 | '(' ElementSetSpecs ')' {
1505 int ret;
1506 $$ = asn1p_constraint_new(yylineno);
1507 checkmem($$);
1508 $$->type = ACT_CA_SET;
1509 ret = asn1p_constraint_insert($$, $2);
1510 checkmem(ret == 0);
1511 }
1512 | ConstraintValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001513 $$ = asn1p_constraint_new(yylineno);
1514 checkmem($$);
1515 $$->type = ACT_EL_VALUE;
1516 $$->value = $1;
1517 }
1518 | ConstraintValue ConstraintRangeSpec ConstraintValue {
1519 $$ = asn1p_constraint_new(yylineno);
1520 checkmem($$);
1521 $$->type = $2;
1522 $$->range_start = $1;
1523 $$->range_stop = $3;
1524 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001525 | TOK_MIN ConstraintRangeSpec ConstraintValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001526 $$ = asn1p_constraint_new(yylineno);
1527 checkmem($$);
Lev Walkinf59d0752004-08-18 04:59:12 +00001528 $$->type = $2;
1529 $$->range_start = asn1p_value_fromint(-123);
1530 $$->range_stop = $3;
1531 $$->range_start->type = ATV_MIN;
1532 }
1533 | ConstraintValue ConstraintRangeSpec TOK_MAX {
1534 $$ = asn1p_constraint_new(yylineno);
1535 checkmem($$);
1536 $$->type = $2;
1537 $$->range_start = $1;
1538 $$->range_stop = asn1p_value_fromint(321);
1539 $$->range_stop->type = ATV_MAX;
1540 }
1541 | TOK_MIN ConstraintRangeSpec TOK_MAX {
1542 $$ = asn1p_constraint_new(yylineno);
1543 checkmem($$);
1544 $$->type = $2;
1545 $$->range_start = asn1p_value_fromint(-123);
1546 $$->range_stop = asn1p_value_fromint(321);
1547 $$->range_start->type = ATV_MIN;
1548 $$->range_stop->type = ATV_MAX;
Lev Walkinf15320b2004-06-03 03:38:44 +00001549 }
1550 | TableConstraint {
1551 $$ = $1;
1552 }
1553 | WithComponents {
1554 $$ = $1;
1555 }
1556 ;
1557
1558ConstraintRangeSpec:
1559 TOK_TwoDots { $$ = ACT_EL_RANGE; }
1560 | TOK_TwoDots '<' { $$ = ACT_EL_RLRANGE; }
1561 | '<' TOK_TwoDots { $$ = ACT_EL_LLRANGE; }
1562 | '<' TOK_TwoDots '<' { $$ = ACT_EL_ULRANGE; }
1563 ;
1564
1565ConstraintSpec:
1566 TOK_SIZE {
1567 $$ = ACT_CT_SIZE;
1568 }
1569 | TOK_FROM {
1570 $$ = ACT_CT_FROM;
1571 }
1572 ;
1573
1574ConstraintValue:
1575 SignedNumber {
1576 $$ = $1;
1577 }
1578 | Identifier {
1579 asn1p_ref_t *ref;
1580 int ret;
1581 ref = asn1p_ref_new(yylineno);
1582 checkmem(ref);
1583 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1584 checkmem(ret == 0);
1585 $$ = asn1p_value_fromref(ref, 0);
1586 checkmem($$);
1587 free($1);
1588 }
1589 | TOK_cstring {
1590 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1591 checkmem($$);
1592 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001593
Lev Walkinf15320b2004-06-03 03:38:44 +00001594 | TOK_FALSE {
1595 $$ = asn1p_value_fromint(0);
1596 checkmem($$);
1597 $$->type = ATV_FALSE;
1598 }
1599 | TOK_TRUE {
1600 $$ = asn1p_value_fromint(1);
1601 checkmem($$);
1602 $$->type = ATV_TRUE;
1603 }
1604 ;
1605
1606WithComponents:
1607 TOK_WITH TOK_COMPONENTS '{' WithComponentsList '}' {
1608 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $4, 0);
1609 }
1610 ;
1611
1612WithComponentsList:
1613 WithComponentsElement {
1614 $$ = $1;
1615 }
1616 | WithComponentsList ',' WithComponentsElement {
1617 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $1, $3);
1618 }
1619 ;
1620
1621WithComponentsElement:
1622 TOK_ThreeDots {
1623 $$ = asn1p_constraint_new(yylineno);
1624 checkmem($$);
1625 $$->type = ACT_EL_EXT;
1626 }
1627 | Identifier optConstraints optPresenceConstraint {
1628 $$ = asn1p_constraint_new(yylineno);
1629 checkmem($$);
1630 $$->type = ACT_EL_VALUE;
1631 $$->value = asn1p_value_frombuf($1, strlen($1), 0);
1632 $$->presence = $3;
1633 }
1634 ;
1635
1636/*
1637 * presence constraint for WithComponents
1638 */
1639optPresenceConstraint:
1640 { $$ = ACPRES_DEFAULT; }
1641 | PresenceConstraint { $$ = $1; }
1642 ;
1643
1644PresenceConstraint:
1645 TOK_PRESENT {
1646 $$ = ACPRES_PRESENT;
1647 }
1648 | TOK_ABSENT {
1649 $$ = ACPRES_ABSENT;
1650 }
1651 | TOK_OPTIONAL {
1652 $$ = ACPRES_OPTIONAL;
1653 }
1654 ;
1655
1656TableConstraint:
1657 SimpleTableConstraint {
1658 $$ = $1;
1659 }
1660 | ComponentRelationConstraint {
1661 $$ = $1;
1662 }
1663 ;
1664
1665/*
1666 * "{ExtensionSet}"
1667 */
1668SimpleTableConstraint:
1669 '{' TypeRefName '}' {
1670 asn1p_ref_t *ref = asn1p_ref_new(yylineno);
1671 asn1p_constraint_t *ct;
1672 int ret;
1673 ret = asn1p_ref_add_component(ref, $2, 0);
1674 checkmem(ret == 0);
1675 ct = asn1p_constraint_new(yylineno);
1676 checkmem($$);
1677 ct->type = ACT_EL_VALUE;
1678 ct->value = asn1p_value_fromref(ref, 0);
1679 CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0);
1680 }
1681 ;
1682
1683ComponentRelationConstraint:
1684 SimpleTableConstraint '{' AtNotationList '}' {
1685 CONSTRAINT_INSERT($$, ACT_CA_CRC, $1, $3);
1686 }
1687 ;
1688
1689AtNotationList:
1690 AtNotationElement {
1691 $$ = asn1p_constraint_new(yylineno);
1692 checkmem($$);
1693 $$->type = ACT_EL_VALUE;
1694 $$->value = asn1p_value_fromref($1, 0);
1695 }
1696 | AtNotationList ',' AtNotationElement {
1697 asn1p_constraint_t *ct;
1698 ct = asn1p_constraint_new(yylineno);
1699 checkmem(ct);
1700 ct->type = ACT_EL_VALUE;
1701 ct->value = asn1p_value_fromref($3, 0);
1702 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
1703 }
1704 ;
1705
1706/*
1707 * @blah
1708 */
1709AtNotationElement:
1710 '@' ComponentIdList {
1711 char *p = malloc(strlen($2) + 2);
1712 int ret;
1713 *p = '@';
1714 strcpy(p + 1, $2);
1715 $$ = asn1p_ref_new(yylineno);
1716 ret = asn1p_ref_add_component($$, p, 0);
1717 checkmem(ret == 0);
1718 free(p);
1719 free($2);
1720 }
1721 | '@' '.' ComponentIdList {
1722 char *p = malloc(strlen($3) + 3);
1723 int ret;
1724 p[0] = '@';
1725 p[1] = '.';
1726 strcpy(p + 2, $3);
1727 $$ = asn1p_ref_new(yylineno);
1728 ret = asn1p_ref_add_component($$, p, 0);
1729 checkmem(ret == 0);
1730 free(p);
1731 free($3);
1732 }
1733 ;
1734
1735/* identifier "." ... */
1736ComponentIdList:
1737 Identifier {
1738 $$ = $1;
1739 }
1740 | ComponentIdList '.' Identifier {
1741 int l1 = strlen($1);
1742 int l3 = strlen($3);
1743 $$ = malloc(l1 + 1 + l3 + 1);
1744 memcpy($$, $1, l1);
1745 $$[l1] = '.';
1746 memcpy($$ + l1 + 1, $3, l3);
1747 $$[l1 + 1 + l3] = '\0';
1748 }
1749 ;
1750
1751
1752
1753/*
1754 * MARKERS
1755 */
1756
1757optMarker:
1758 { $$ = EM_NOMARK; }
1759 | Marker { $$ = $1; }
1760 ;
1761
1762Marker:
1763 TOK_OPTIONAL {
1764 $$ = EM_OPTIONAL;
1765 }
1766 | TOK_DEFAULT DefaultValue {
1767 $$ = EM_DEFAULT;
1768 /* FIXME: store DefaultValue somewhere */
1769 }
1770 ;
1771
1772DefaultValue:
1773 ConstraintValue {
1774 }
1775 | BasicTypeId {
1776 }
1777 | '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
1778 }
1779 ;
1780
1781/*
1782 * Universal enumeration definition to use in INTEGER and ENUMERATED.
1783 * === EXAMPLE ===
1784 * Gender ::= ENUMERATED { unknown(0), male(1), female(2) }
1785 * Temperature ::= INTEGER { absolute-zero(-273), freezing(0), boiling(100) }
1786 * === EOF ===
1787 */
1788/*
1789optUniverationDefinition:
1790 { $$ = 0; }
1791 | UniverationDefinition {
1792 $$ = $1;
1793 }
1794 ;
1795*/
1796
1797UniverationDefinition:
1798 '{' '}' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001799 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001800 checkmem($$);
1801 }
1802 | '{' UniverationList '}' {
1803 $$ = $2;
1804 }
1805 ;
1806
1807UniverationList:
1808 UniverationElement {
Lev Walkinceb20e72004-09-05 10:40:41 +00001809 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001810 checkmem($$);
1811 TQ_ADD(&($$->members), $1, next);
1812 }
1813 | UniverationList ',' UniverationElement {
1814 $$ = $1;
1815 TQ_ADD(&($$->members), $3, next);
1816 }
1817 ;
1818
1819UniverationElement:
1820 Identifier {
Lev Walkinceb20e72004-09-05 10:40:41 +00001821 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001822 checkmem($$);
1823 $$->expr_type = A1TC_UNIVERVAL;
1824 $$->meta_type = AMT_VALUE;
1825 $$->Identifier = $1;
1826 }
1827 | Identifier '(' SignedNumber ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001828 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001829 checkmem($$);
1830 $$->expr_type = A1TC_UNIVERVAL;
1831 $$->meta_type = AMT_VALUE;
1832 $$->Identifier = $1;
1833 $$->value = $3;
1834 }
1835 | Identifier '(' DefinedValue ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00001836 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001837 checkmem($$);
1838 $$->expr_type = A1TC_UNIVERVAL;
1839 $$->meta_type = AMT_VALUE;
1840 $$->Identifier = $1;
1841 $$->value = $3;
1842 }
1843 | SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001844 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001845 checkmem($$);
1846 $$->expr_type = A1TC_UNIVERVAL;
1847 $$->meta_type = AMT_VALUE;
1848 $$->value = $1;
1849 }
1850 | TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001851 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001852 checkmem($$);
1853 $$->Identifier = strdup("...");
1854 checkmem($$->Identifier);
1855 $$->expr_type = A1TC_EXTENSIBLE;
1856 $$->meta_type = AMT_VALUE;
1857 }
1858 ;
1859
1860SignedNumber:
1861 TOK_number {
1862 $$ = asn1p_value_fromint($1);
1863 checkmem($$);
1864 }
1865 | TOK_number_negative {
1866 $$ = asn1p_value_fromint($1);
1867 checkmem($$);
1868 }
1869 ;
1870
1871/*
1872 * SEQUENCE definition.
1873 * === EXAMPLE ===
1874 * Struct1 ::= SEQUENCE {
1875 * memb1 Struct2,
1876 * memb2 SEQUENCE OF {
1877 * memb2-1 Struct 3
1878 * }
1879 * }
1880 * === EOF ===
1881 */
1882
1883
1884
1885/*
1886 * SET definition.
1887 * === EXAMPLE ===
1888 * Person ::= SET {
1889 * name [0] PrintableString (SIZE(1..20)),
1890 * country [1] PrintableString (SIZE(1..20)) DEFAULT default-country,
1891 * }
1892 * === EOF ===
1893 */
1894
1895optTag:
1896 { memset(&$$, 0, sizeof($$)); }
1897 | Tag { $$ = $1; }
1898 ;
1899
1900Tag:
1901 TOK_tag {
1902 $$ = $1;
1903 $$.tag_mode = TM_DEFAULT;
1904 }
1905 | TOK_tag TOK_IMPLICIT {
1906 $$ = $1;
1907 $$.tag_mode = TM_IMPLICIT;
1908 }
1909 | TOK_tag TOK_EXPLICIT {
1910 $$ = $1;
1911 $$.tag_mode = TM_EXPLICIT;
1912 }
1913 ;
1914
1915TypeRefName:
1916 TOK_typereference {
1917 checkmem($1);
1918 $$ = $1;
1919 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001920 | TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00001921 checkmem($1);
1922 $$ = $1;
1923 }
1924 ;
1925
Lev Walkinf59d0752004-08-18 04:59:12 +00001926
Lev Walkinf15320b2004-06-03 03:38:44 +00001927ObjectClassReference:
Lev Walkinf59d0752004-08-18 04:59:12 +00001928 TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00001929 checkmem($1);
1930 $$ = $1;
1931 }
1932 ;
1933
1934Identifier:
1935 TOK_identifier {
1936 checkmem($1);
1937 $$ = $1;
1938 }
1939 ;
1940
1941TaggedIdentifier:
1942 Identifier {
1943 memset(&$$, 0, sizeof($$));
1944 $$.name = $1;
1945 }
1946 | Identifier Tag {
1947 $$.name = $1;
1948 $$.tag = $2;
1949 }
1950 ;
1951
1952
1953%%
1954
1955
1956/*
1957 * Convert Xstring ('0101'B or '5'H) to the binary vector.
1958 */
1959static asn1p_value_t *
1960_convert_bitstring2binary(char *str, int base) {
1961 asn1p_value_t *val;
1962 int slen;
1963 int memlen;
1964 int baselen;
1965 int bits;
1966 uint8_t *binary_vector;
1967 uint8_t *bv_ptr;
1968 uint8_t cur_val;
1969
1970 assert(str);
1971 assert(str[0] == '\'');
1972
1973 switch(base) {
1974 case 'B':
1975 baselen = 1;
1976 break;
1977 case 'H':
1978 baselen = 4;
1979 break;
1980 default:
1981 assert(base == 'B' || base == 'H');
1982 errno = EINVAL;
1983 return NULL;
1984 }
1985
1986 slen = strlen(str);
1987 assert(str[slen - 1] == base);
1988 assert(str[slen - 2] == '\'');
1989
1990 memlen = slen / (8 / baselen); /* Conservative estimate */
1991
1992 bv_ptr = binary_vector = malloc(memlen + 1);
1993 if(bv_ptr == NULL)
1994 /* ENOMEM */
1995 return NULL;
1996
1997 cur_val = 0;
1998 bits = 0;
1999 while(*(++str) != '\'') {
2000 switch(baselen) {
2001 case 1:
2002 switch(*str) {
2003 case '1':
2004 cur_val |= 1 << (7 - (bits % 8));
2005 case '0':
2006 break;
2007 default:
2008 assert(!"_y UNREACH1");
2009 case ' ': case '\r': case '\n':
2010 continue;
2011 }
2012 break;
2013 case 4:
2014 switch(*str) {
2015 case '0': case '1': case '2': case '3': case '4':
2016 case '5': case '6': case '7': case '8': case '9':
2017 cur_val |= (*str - '0') << (4 - (bits % 8));
2018 break;
2019 case 'A': case 'B': case 'C':
2020 case 'D': case 'E': case 'F':
2021 cur_val |= ((*str - 'A') + 10)
2022 << (4 - (bits % 8));
2023 break;
2024 default:
2025 assert(!"_y UNREACH2");
2026 case ' ': case '\r': case '\n':
2027 continue;
2028 }
2029 break;
2030 }
2031
2032 bits += baselen;
2033 if((bits % 8) == 0) {
2034 *bv_ptr++ = cur_val;
2035 cur_val = 0;
2036 }
2037 }
2038
2039 *bv_ptr = cur_val;
2040 assert((bv_ptr - binary_vector) <= memlen);
2041
2042 val = asn1p_value_frombits(binary_vector, bits, 0);
2043 if(val == NULL) {
2044 free(binary_vector);
2045 }
2046
2047 return val;
2048}
2049
2050extern char *asn1p_text;
2051
2052int
2053yyerror(const char *msg) {
2054 fprintf(stderr,
2055 "ASN.1 grammar parse error "
2056 "near line %d (token \"%s\"): %s\n",
Lev Walkinceb20e72004-09-05 10:40:41 +00002057 yylineno, asn1p_text, msg);
Lev Walkinf15320b2004-06-03 03:38:44 +00002058 return -1;
2059}
2060
2061