blob: e009d0674d428a7c0851346ed999cc81d5bc693f [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
Lev Walkin4354b442005-06-07 21:25:42 +000012#define YYPARSE_PARAM_TYPE void **
Lev Walkinf15320b2004-06-03 03:38:44 +000013#define YYERROR_VERBOSE
14
15int yylex(void);
16int yyerror(const char *msg);
Lev Walkin8daab912005-06-07 21:32:16 +000017#ifdef YYBYACC
18int yyparse(void **param); /* byacc does not produce a prototype */
19#endif
Lev Walkinf15320b2004-06-03 03:38:44 +000020void asn1p_lexer_hack_push_opaque_state(void);
21void asn1p_lexer_hack_enable_with_syntax(void);
Lev Walkinf59d0752004-08-18 04:59:12 +000022void asn1p_lexer_hack_push_encoding_control(void);
Lev Walkinf15320b2004-06-03 03:38:44 +000023#define yylineno asn1p_lineno
24extern int asn1p_lineno;
25
Lev Walkin1ed22092005-08-12 10:06:17 +000026/*
Lev Walkinef625402005-09-05 05:17:57 +000027 * Process directives as <ASN1C:RepresentAsPointer>
Lev Walkin4696c742005-08-22 12:23:54 +000028 */
29extern int asn1p_as_pointer;
Lev Walkin4696c742005-08-22 12:23:54 +000030
31/*
Lev Walkin1ed22092005-08-12 10:06:17 +000032 * This temporary variable is used to solve the shortcomings of 1-lookahead
33 * parser.
34 */
35static struct AssignedIdentifier *saved_aid;
Lev Walkinf15320b2004-06-03 03:38:44 +000036
Lev Walkin2e9bd5c2005-08-13 09:07:11 +000037static asn1p_value_t *_convert_bitstring2binary(char *str, int base);
38static void _fixup_anonymous_identifier(asn1p_expr_t *expr);
Lev Walkinf15320b2004-06-03 03:38:44 +000039
Lev Walkin1ed22092005-08-12 10:06:17 +000040#define checkmem(ptr) do { \
41 if(!(ptr)) \
42 return yyerror("Memory failure"); \
Lev Walkinf15320b2004-06-03 03:38:44 +000043 } while(0)
44
Lev Walkin2c14a692005-08-12 10:08:45 +000045#define CONSTRAINT_INSERT(root, constr_type, arg1, arg2) do { \
Lev Walkin1ed22092005-08-12 10:06:17 +000046 if(arg1->type != constr_type) { \
47 int __ret; \
48 root = asn1p_constraint_new(yylineno); \
49 checkmem(root); \
50 root->type = constr_type; \
51 __ret = asn1p_constraint_insert(root, \
52 arg1); \
53 checkmem(__ret == 0); \
54 } else { \
55 root = arg1; \
56 } \
57 if(arg2) { \
58 int __ret \
59 = asn1p_constraint_insert(root, arg2); \
60 checkmem(__ret == 0); \
61 } \
Lev Walkinf15320b2004-06-03 03:38:44 +000062 } while(0)
63
64%}
65
66
67/*
68 * Token value definition.
69 * a_*: ASN-specific types.
70 * tv_*: Locally meaningful types.
71 */
72%union {
73 asn1p_t *a_grammar;
74 asn1p_module_flags_e a_module_flags;
75 asn1p_module_t *a_module;
76 asn1p_expr_type_e a_type; /* ASN.1 Type */
77 asn1p_expr_t *a_expr; /* Constructed collection */
78 asn1p_constraint_t *a_constr; /* Constraint */
79 enum asn1p_constraint_type_e a_ctype;/* Constraint type */
80 asn1p_xports_t *a_xports; /* IMports/EXports */
Lev Walkin1ed22092005-08-12 10:06:17 +000081 struct AssignedIdentifier a_aid; /* Assigned Identifier */
Lev Walkinf15320b2004-06-03 03:38:44 +000082 asn1p_oid_t *a_oid; /* Object Identifier */
83 asn1p_oid_arc_t a_oid_arc; /* Single OID's arc */
84 struct asn1p_type_tag_s a_tag; /* A tag */
85 asn1p_ref_t *a_ref; /* Reference to custom type */
86 asn1p_wsyntx_t *a_wsynt; /* WITH SYNTAX contents */
87 asn1p_wsyntx_chunk_t *a_wchunk; /* WITH SYNTAX chunk */
88 struct asn1p_ref_component_s a_refcomp; /* Component of a reference */
89 asn1p_value_t *a_value; /* Number, DefinedValue, etc */
90 struct asn1p_param_s a_parg; /* A parameter argument */
91 asn1p_paramlist_t *a_plist; /* A pargs list */
Lev Walkin9c974182004-09-15 11:59:51 +000092 struct asn1p_expr_marker_s a_marker; /* OPTIONAL/DEFAULT */
Lev Walkinf15320b2004-06-03 03:38:44 +000093 enum asn1p_constr_pres_e a_pres; /* PRESENT/ABSENT/OPTIONAL */
Lev Walkin144db9b2004-10-12 23:26:53 +000094 asn1c_integer_t a_int;
Lev Walkinf15320b2004-06-03 03:38:44 +000095 char *tv_str;
96 struct {
97 char *buf;
98 int len;
99 } tv_opaque;
100 struct {
101 char *name;
102 struct asn1p_type_tag_s tag;
103 } tv_nametag;
104};
105
106/*
107 * Token types returned by scanner.
108 */
109%token TOK_PPEQ /* "::=", Pseudo Pascal EQuality */
Lev Walkin57074f12006-03-16 05:11:14 +0000110%token <tv_opaque> TOK_whitespace /* A span of whitespace */
Lev Walkinf15320b2004-06-03 03:38:44 +0000111%token <tv_opaque> TOK_opaque /* opaque data (driven from .y) */
112%token <tv_str> TOK_bstring
113%token <tv_opaque> TOK_cstring
114%token <tv_str> TOK_hstring
115%token <tv_str> TOK_identifier
116%token <a_int> TOK_number
Lev Walkind9574ae2005-03-24 16:22:35 +0000117%token <a_int> TOK_tuple
118%token <a_int> TOK_quadruple
Lev Walkinf15320b2004-06-03 03:38:44 +0000119%token <a_int> TOK_number_negative
120%token <tv_str> TOK_typereference
Lev Walkinf59d0752004-08-18 04:59:12 +0000121%token <tv_str> TOK_capitalreference /* "CLASS1" */
Lev Walkinf15320b2004-06-03 03:38:44 +0000122%token <tv_str> TOK_typefieldreference /* "&Pork" */
123%token <tv_str> TOK_valuefieldreference /* "&id" */
Lev Walkin9d542d22006-03-14 16:31:37 +0000124%token <tv_str> TOK_Literal /* "BY" */
Lev Walkinf15320b2004-06-03 03:38:44 +0000125
126/*
127 * Token types representing ASN.1 standard keywords.
128 */
129%token TOK_ABSENT
130%token TOK_ABSTRACT_SYNTAX
131%token TOK_ALL
132%token TOK_ANY
133%token TOK_APPLICATION
134%token TOK_AUTOMATIC
135%token TOK_BEGIN
136%token TOK_BIT
137%token TOK_BMPString
138%token TOK_BOOLEAN
139%token TOK_BY
140%token TOK_CHARACTER
141%token TOK_CHOICE
142%token TOK_CLASS
143%token TOK_COMPONENT
144%token TOK_COMPONENTS
145%token TOK_CONSTRAINED
146%token TOK_CONTAINING
147%token TOK_DEFAULT
148%token TOK_DEFINITIONS
149%token TOK_DEFINED
150%token TOK_EMBEDDED
151%token TOK_ENCODED
Lev Walkinf59d0752004-08-18 04:59:12 +0000152%token TOK_ENCODING_CONTROL
Lev Walkinf15320b2004-06-03 03:38:44 +0000153%token TOK_END
154%token TOK_ENUMERATED
155%token TOK_EXPLICIT
156%token TOK_EXPORTS
157%token TOK_EXTENSIBILITY
158%token TOK_EXTERNAL
159%token TOK_FALSE
160%token TOK_FROM
161%token TOK_GeneralizedTime
162%token TOK_GeneralString
163%token TOK_GraphicString
164%token TOK_IA5String
165%token TOK_IDENTIFIER
166%token TOK_IMPLICIT
167%token TOK_IMPLIED
168%token TOK_IMPORTS
169%token TOK_INCLUDES
170%token TOK_INSTANCE
Lev Walkinf59d0752004-08-18 04:59:12 +0000171%token TOK_INSTRUCTIONS
Lev Walkinf15320b2004-06-03 03:38:44 +0000172%token TOK_INTEGER
173%token TOK_ISO646String
174%token TOK_MAX
175%token TOK_MIN
176%token TOK_MINUS_INFINITY
177%token TOK_NULL
178%token TOK_NumericString
179%token TOK_OBJECT
180%token TOK_ObjectDescriptor
181%token TOK_OCTET
182%token TOK_OF
183%token TOK_OPTIONAL
184%token TOK_PATTERN
185%token TOK_PDV
186%token TOK_PLUS_INFINITY
187%token TOK_PRESENT
188%token TOK_PrintableString
189%token TOK_PRIVATE
190%token TOK_REAL
191%token TOK_RELATIVE_OID
192%token TOK_SEQUENCE
193%token TOK_SET
194%token TOK_SIZE
195%token TOK_STRING
196%token TOK_SYNTAX
197%token TOK_T61String
198%token TOK_TAGS
199%token TOK_TeletexString
200%token TOK_TRUE
201%token TOK_TYPE_IDENTIFIER
202%token TOK_UNIQUE
203%token TOK_UNIVERSAL
204%token TOK_UniversalString
205%token TOK_UTCTime
206%token TOK_UTF8String
207%token TOK_VideotexString
208%token TOK_VisibleString
209%token TOK_WITH
210
Lev Walkinf15320b2004-06-03 03:38:44 +0000211%left TOK_EXCEPT
Lev Walkinf59d0752004-08-18 04:59:12 +0000212%left '^' TOK_INTERSECTION
213%left '|' TOK_UNION
Lev Walkinf15320b2004-06-03 03:38:44 +0000214
215/* Misc tags */
216%token TOK_TwoDots /* .. */
217%token TOK_ThreeDots /* ... */
Lev Walkinf15320b2004-06-03 03:38:44 +0000218
219
220/*
221 * Types defined herein.
222 */
223%type <a_grammar> ModuleList
224%type <a_module> ModuleSpecification
225%type <a_module> ModuleSpecificationBody
226%type <a_module> ModuleSpecificationElement
227%type <a_module> optModuleSpecificationBody /* Optional */
228%type <a_module_flags> optModuleSpecificationFlags
229%type <a_module_flags> ModuleSpecificationFlags /* Set of FL */
230%type <a_module_flags> ModuleSpecificationFlag /* Single FL */
231%type <a_module> ImportsDefinition
232%type <a_module> ImportsBundleSet
233%type <a_xports> ImportsBundle
234%type <a_xports> ImportsList
235%type <a_xports> ExportsDefinition
236%type <a_xports> ExportsBody
237%type <a_expr> ImportsElement
238%type <a_expr> ExportsElement
Lev Walkinf15320b2004-06-03 03:38:44 +0000239%type <a_expr> ExtensionAndException
Lev Walkin070a52d2004-08-22 03:19:54 +0000240%type <a_expr> TypeDeclaration
Lev Walkin4696c742005-08-22 12:23:54 +0000241%type <a_expr> TypeDeclarationSet
Lev Walkinf15320b2004-06-03 03:38:44 +0000242%type <a_ref> ComplexTypeReference
243%type <a_ref> ComplexTypeReferenceAmpList
244%type <a_refcomp> ComplexTypeReferenceElement
Lev Walkind370e9f2006-03-16 10:03:35 +0000245%type <a_refcomp> PrimitiveFieldReference
Lev Walkin9c2285a2006-03-09 08:49:26 +0000246%type <a_expr> FieldSpec
247%type <a_ref> FieldName
248%type <a_ref> DefinedObjectClass
Lev Walkinf15320b2004-06-03 03:38:44 +0000249%type <a_expr> ClassField
Lev Walkin9c2285a2006-03-09 08:49:26 +0000250%type <a_expr> ObjectClass
Lev Walkin070a52d2004-08-22 03:19:54 +0000251%type <a_expr> Type
Lev Walkinf15320b2004-06-03 03:38:44 +0000252%type <a_expr> DataTypeReference /* Type1 ::= Type2 */
Lev Walkin0c0bca62006-03-21 04:48:15 +0000253%type <a_expr> DefinedType
Lev Walkinf15320b2004-06-03 03:38:44 +0000254%type <a_expr> ValueSetDefinition /* Val INTEGER ::= {1|2} */
255%type <a_expr> ValueDefinition /* val INTEGER ::= 1*/
Lev Walkin9c974182004-09-15 11:59:51 +0000256%type <a_value> Value
Lev Walkin0c0bca62006-03-21 04:48:15 +0000257%type <a_value> SimpleValue
Lev Walkinf15320b2004-06-03 03:38:44 +0000258%type <a_value> DefinedValue
259%type <a_value> SignedNumber
Lev Walkin144db9b2004-10-12 23:26:53 +0000260%type <a_expr> optComponentTypeLists
Lev Walkin070a52d2004-08-22 03:19:54 +0000261%type <a_expr> ComponentTypeLists
262%type <a_expr> ComponentType
263%type <a_expr> AlternativeTypeLists
264%type <a_expr> AlternativeType
Lev Walkinf15320b2004-06-03 03:38:44 +0000265%type <a_expr> UniverationDefinition
266%type <a_expr> UniverationList
267%type <a_expr> UniverationElement
268%type <tv_str> TypeRefName
269%type <tv_str> ObjectClassReference
Lev Walkinf15320b2004-06-03 03:38:44 +0000270%type <tv_str> Identifier
Lev Walkin83cac2f2004-09-22 16:03:36 +0000271%type <tv_str> optIdentifier
Lev Walkinf15320b2004-06-03 03:38:44 +0000272%type <a_parg> ParameterArgumentName
273%type <a_plist> ParameterArgumentList
Lev Walkina00d6b32006-03-21 03:40:38 +0000274%type <a_expr> Specialization
275%type <a_expr> Specializations
Lev Walkin1ed22092005-08-12 10:06:17 +0000276%type <a_aid> AssignedIdentifier /* OID/DefinedValue */
Lev Walkinf15320b2004-06-03 03:38:44 +0000277%type <a_oid> ObjectIdentifier /* OID */
278%type <a_oid> optObjectIdentifier /* Optional OID */
279%type <a_oid> ObjectIdentifierBody
280%type <a_oid_arc> ObjectIdentifierElement
281%type <a_expr> BasicType
282%type <a_type> BasicTypeId
283%type <a_type> BasicTypeId_UniverationCompatible
284%type <a_type> BasicString
285%type <tv_opaque> Opaque
Lev Walkinc603f102005-01-23 09:51:44 +0000286%type <a_tag> Tag /* [UNIVERSAL 0] IMPLICIT */
287%type <a_tag> TagClass TagTypeValue TagPlicit
Lev Walkinf15320b2004-06-03 03:38:44 +0000288%type <a_tag> optTag /* [UNIVERSAL 0] IMPLICIT */
289%type <a_constr> optConstraints
Lev Walkind2ea1de2004-08-20 13:25:29 +0000290%type <a_constr> Constraints
Lev Walkinf59d0752004-08-18 04:59:12 +0000291%type <a_constr> SetOfConstraints
292%type <a_constr> ElementSetSpecs /* 1..2,...,3 */
293%type <a_constr> ElementSetSpec /* 1..2,...,3 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000294%type <a_constr> ConstraintSubtypeElement /* 1..2 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000295%type <a_constr> SimpleTableConstraint
296%type <a_constr> TableConstraint
Lev Walkine596bf02005-03-28 15:01:27 +0000297%type <a_constr> InnerTypeConstraint
Lev Walkinf15320b2004-06-03 03:38:44 +0000298%type <a_constr> WithComponentsList
299%type <a_constr> WithComponentsElement
300%type <a_constr> ComponentRelationConstraint
301%type <a_constr> AtNotationList
302%type <a_ref> AtNotationElement
Lev Walkinff7dd142005-03-20 12:58:00 +0000303%type <a_value> SingleValue
304%type <a_value> ContainedSubtype
Lev Walkinf15320b2004-06-03 03:38:44 +0000305%type <a_ctype> ConstraintSpec
306%type <a_ctype> ConstraintRangeSpec
Lev Walkin1e448d32005-03-24 14:26:38 +0000307%type <a_value> RestrictedCharacterStringValue
Lev Walkinf15320b2004-06-03 03:38:44 +0000308%type <a_wsynt> optWithSyntax
309%type <a_wsynt> WithSyntax
Lev Walkin9d542d22006-03-14 16:31:37 +0000310%type <a_wsynt> WithSyntaxList
311%type <a_wchunk> WithSyntaxToken
Lev Walkinf15320b2004-06-03 03:38:44 +0000312%type <a_marker> optMarker Marker
313%type <a_int> optUnique
314%type <a_pres> optPresenceConstraint PresenceConstraint
315%type <tv_str> ComponentIdList
Lev Walkinef625402005-09-05 05:17:57 +0000316%type <a_int> NSTD_IndirectMarker
Lev Walkinf15320b2004-06-03 03:38:44 +0000317
318
319%%
320
321
322ParsedGrammar:
323 ModuleList {
324 *(void **)param = $1;
325 }
326 ;
327
328ModuleList:
329 ModuleSpecification {
330 $$ = asn1p_new();
331 checkmem($$);
332 TQ_ADD(&($$->modules), $1, mod_next);
333 }
334 | ModuleList ModuleSpecification {
335 $$ = $1;
336 TQ_ADD(&($$->modules), $2, mod_next);
337 }
338 ;
339
340/*
341 * ASN module definition.
342 * === EXAMPLE ===
343 * MySyntax DEFINITIONS AUTOMATIC TAGS ::=
344 * BEGIN
345 * ...
346 * END
347 * === EOF ===
348 */
349
350ModuleSpecification:
351 TypeRefName optObjectIdentifier TOK_DEFINITIONS
352 optModuleSpecificationFlags
353 TOK_PPEQ TOK_BEGIN
354 optModuleSpecificationBody
355 TOK_END {
356
357 if($7) {
358 $$ = $7;
359 } else {
360 /* There's a chance that a module is just plain empty */
361 $$ = asn1p_module_new();
362 }
363 checkmem($$);
364
Lev Walkin1ed22092005-08-12 10:06:17 +0000365 $$->ModuleName = $1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000366 $$->module_oid = $2;
367 $$->module_flags = $4;
368 }
369 ;
370
371/*
372 * Object Identifier Definition
373 * { iso member-body(2) 3 }
374 */
375optObjectIdentifier:
376 { $$ = 0; }
377 | ObjectIdentifier { $$ = $1; }
378 ;
379
380ObjectIdentifier:
381 '{' ObjectIdentifierBody '}' {
382 $$ = $2;
383 }
384 | '{' '}' {
385 $$ = 0;
386 }
387 ;
388
389ObjectIdentifierBody:
390 ObjectIdentifierElement {
391 $$ = asn1p_oid_new();
392 asn1p_oid_add_arc($$, &$1);
393 if($1.name)
394 free($1.name);
395 }
396 | ObjectIdentifierBody ObjectIdentifierElement {
397 $$ = $1;
398 asn1p_oid_add_arc($$, &$2);
399 if($2.name)
400 free($2.name);
401 }
402 ;
403
404ObjectIdentifierElement:
405 Identifier { /* iso */
406 $$.name = $1;
407 $$.number = -1;
408 }
409 | Identifier '(' TOK_number ')' { /* iso(1) */
410 $$.name = $1;
411 $$.number = $3;
412 }
413 | TOK_number { /* 1 */
414 $$.name = 0;
415 $$.number = $1;
416 }
417 ;
418
419/*
420 * Optional module flags.
421 */
422optModuleSpecificationFlags:
423 { $$ = MSF_NOFLAGS; }
424 | ModuleSpecificationFlags {
425 $$ = $1;
426 }
427 ;
428
429/*
430 * Module flags.
431 */
432ModuleSpecificationFlags:
433 ModuleSpecificationFlag {
434 $$ = $1;
435 }
436 | ModuleSpecificationFlags ModuleSpecificationFlag {
437 $$ = $1 | $2;
438 }
439 ;
440
441/*
442 * Single module flag.
443 */
444ModuleSpecificationFlag:
445 TOK_EXPLICIT TOK_TAGS {
446 $$ = MSF_EXPLICIT_TAGS;
447 }
448 | TOK_IMPLICIT TOK_TAGS {
449 $$ = MSF_IMPLICIT_TAGS;
450 }
451 | TOK_AUTOMATIC TOK_TAGS {
452 $$ = MSF_AUTOMATIC_TAGS;
453 }
454 | TOK_EXTENSIBILITY TOK_IMPLIED {
455 $$ = MSF_EXTENSIBILITY_IMPLIED;
456 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000457 /* EncodingReferenceDefault */
458 | TOK_capitalreference TOK_INSTRUCTIONS {
459 /* X.680Amd1 specifies TAG and XER */
460 if(strcmp($1, "TAG") == 0) {
461 $$ = MSF_TAG_INSTRUCTIONS;
462 } else if(strcmp($1, "XER") == 0) {
463 $$ = MSF_XER_INSTRUCTIONS;
464 } else {
465 fprintf(stderr,
466 "WARNING: %s INSTRUCTIONS at line %d: "
467 "Unrecognized encoding reference\n",
468 $1, yylineno);
469 $$ = MSF_unk_INSTRUCTIONS;
470 }
471 free($1);
472 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000473 ;
474
475/*
476 * Optional module body.
477 */
478optModuleSpecificationBody:
479 { $$ = 0; }
480 | ModuleSpecificationBody {
Lev Walkinf15320b2004-06-03 03:38:44 +0000481 $$ = $1;
482 }
483 ;
484
485/*
486 * ASN.1 Module body.
487 */
488ModuleSpecificationBody:
489 ModuleSpecificationElement {
490 $$ = $1;
491 }
492 | ModuleSpecificationBody ModuleSpecificationElement {
493 $$ = $1;
494
Lev Walkinf59d0752004-08-18 04:59:12 +0000495 /* Behave well when one of them is skipped. */
496 if(!($1)) {
497 if($2) $$ = $2;
498 break;
499 }
500
Lev Walkinf15320b2004-06-03 03:38:44 +0000501#ifdef MY_IMPORT
502#error MY_IMPORT DEFINED ELSEWHERE!
503#endif
504#define MY_IMPORT(foo,field) do { \
Lev Walkinbc55d232004-08-13 12:31:09 +0000505 while(TQ_FIRST(&($2->foo))) { \
Lev Walkinf15320b2004-06-03 03:38:44 +0000506 TQ_ADD(&($$->foo), \
507 TQ_REMOVE(&($2->foo), field), \
508 field); \
Lev Walkinbc55d232004-08-13 12:31:09 +0000509 } \
510 assert(TQ_FIRST(&($2->foo)) == 0); \
511 } while(0)
Lev Walkinf15320b2004-06-03 03:38:44 +0000512
513 MY_IMPORT(imports, xp_next);
514 MY_IMPORT(exports, xp_next);
515 MY_IMPORT(members, next);
516#undef MY_IMPORT
517
518 }
519 ;
520
521/*
522 * One of the elements of ASN.1 module specification.
523 */
524ModuleSpecificationElement:
525 ImportsDefinition {
526 $$ = $1;
527 }
528 | ExportsDefinition {
529 $$ = asn1p_module_new();
530 checkmem($$);
531 if($1) {
532 TQ_ADD(&($$->exports), $1, xp_next);
533 } else {
534 /* "EXPORTS ALL;" ? */
535 }
536 }
537 | DataTypeReference {
538 $$ = asn1p_module_new();
539 checkmem($$);
540 assert($1->expr_type != A1TC_INVALID);
541 assert($1->meta_type != AMT_INVALID);
542 TQ_ADD(&($$->members), $1, next);
543 }
544 | ValueDefinition {
545 $$ = asn1p_module_new();
546 checkmem($$);
547 assert($1->expr_type != A1TC_INVALID);
548 assert($1->meta_type != AMT_INVALID);
549 TQ_ADD(&($$->members), $1, next);
550 }
551 /*
552 * Value set definition
553 * === EXAMPLE ===
554 * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 }
555 * === EOF ===
556 */
557 | ValueSetDefinition {
558 $$ = asn1p_module_new();
559 checkmem($$);
560 assert($1->expr_type != A1TC_INVALID);
561 assert($1->meta_type != AMT_INVALID);
562 TQ_ADD(&($$->members), $1, next);
563 }
Lev Walkinf59d0752004-08-18 04:59:12 +0000564 | TOK_ENCODING_CONTROL TOK_capitalreference
565 { asn1p_lexer_hack_push_encoding_control(); }
566 {
567 fprintf(stderr,
568 "WARNING: ENCODING-CONTROL %s "
569 "specification at line %d ignored\n",
570 $2, yylineno);
571 free($2);
572 $$ = 0;
573 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000574
575 /*
576 * Erroneous attemps
577 */
578 | BasicString {
579 return yyerror(
Lev Walkin70853052005-11-26 11:21:55 +0000580 "Attempt to redefine a standard basic string type, "
581 "please comment out or remove this type redefinition.");
Lev Walkinf15320b2004-06-03 03:38:44 +0000582 }
583 ;
584
585/*
586 * === EXAMPLE ===
587 * IMPORTS Type1, value FROM Module { iso standard(0) } ;
588 * === EOF ===
589 */
590ImportsDefinition:
591 TOK_IMPORTS ImportsBundleSet ';' {
Lev Walkin1ed22092005-08-12 10:06:17 +0000592 if(!saved_aid && 0)
593 return yyerror("Unterminated IMPORTS FROM, "
594 "expected semicolon ';'");
595 saved_aid = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +0000596 $$ = $2;
597 }
598 /*
599 * Some error cases.
600 */
601 | TOK_IMPORTS TOK_FROM /* ... */ {
602 return yyerror("Empty IMPORTS list");
603 }
604 ;
605
606ImportsBundleSet:
607 ImportsBundle {
608 $$ = asn1p_module_new();
609 checkmem($$);
610 TQ_ADD(&($$->imports), $1, xp_next);
611 }
612 | ImportsBundleSet ImportsBundle {
613 $$ = $1;
614 TQ_ADD(&($$->imports), $2, xp_next);
615 }
616 ;
617
Lev Walkin1ed22092005-08-12 10:06:17 +0000618AssignedIdentifier:
619 { memset(&$$, 0, sizeof($$)); }
620 | ObjectIdentifier { $$.oid = $1; };
621 /* | DefinedValue { $$.value = $1; }; // Handled through saved_aid */
622
Lev Walkinf15320b2004-06-03 03:38:44 +0000623ImportsBundle:
Lev Walkin1ed22092005-08-12 10:06:17 +0000624 ImportsList TOK_FROM TypeRefName AssignedIdentifier {
Lev Walkinf15320b2004-06-03 03:38:44 +0000625 $$ = $1;
Lev Walkin1ed22092005-08-12 10:06:17 +0000626 $$->fromModuleName = $3;
627 $$->identifier = $4;
628 /* This stupid thing is used for look-back hack. */
629 saved_aid = $$->identifier.oid ? 0 : &($$->identifier);
Lev Walkinf15320b2004-06-03 03:38:44 +0000630 checkmem($$);
631 }
632 ;
633
634ImportsList:
635 ImportsElement {
636 $$ = asn1p_xports_new();
637 checkmem($$);
638 TQ_ADD(&($$->members), $1, next);
639 }
640 | ImportsList ',' ImportsElement {
641 $$ = $1;
642 TQ_ADD(&($$->members), $3, next);
643 }
644 ;
645
646ImportsElement:
647 TypeRefName {
648 $$ = asn1p_expr_new(yylineno);
649 checkmem($$);
650 $$->Identifier = $1;
651 $$->expr_type = A1TC_REFERENCE;
652 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000653 | TypeRefName '{' '}' { /* Completely equivalent to above */
654 $$ = asn1p_expr_new(yylineno);
655 checkmem($$);
656 $$->Identifier = $1;
657 $$->expr_type = A1TC_REFERENCE;
658 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000659 | Identifier {
660 $$ = asn1p_expr_new(yylineno);
661 checkmem($$);
662 $$->Identifier = $1;
663 $$->expr_type = A1TC_REFERENCE;
664 }
665 ;
666
667ExportsDefinition:
668 TOK_EXPORTS ExportsBody ';' {
669 $$ = $2;
670 }
671 | TOK_EXPORTS TOK_ALL ';' {
672 $$ = 0;
673 }
674 | TOK_EXPORTS ';' {
675 /* Empty EXPORTS clause effectively prohibits export. */
676 $$ = asn1p_xports_new();
677 checkmem($$);
678 }
679 ;
680
681ExportsBody:
682 ExportsElement {
683 $$ = asn1p_xports_new();
684 assert($$);
685 TQ_ADD(&($$->members), $1, next);
686 }
687 | ExportsBody ',' ExportsElement {
688 $$ = $1;
689 TQ_ADD(&($$->members), $3, next);
690 }
691 ;
692
693ExportsElement:
694 TypeRefName {
695 $$ = asn1p_expr_new(yylineno);
696 checkmem($$);
697 $$->Identifier = $1;
698 $$->expr_type = A1TC_EXPORTVAR;
699 }
Lev Walkin144db9b2004-10-12 23:26:53 +0000700 | TypeRefName '{' '}' {
701 $$ = asn1p_expr_new(yylineno);
702 checkmem($$);
703 $$->Identifier = $1;
704 $$->expr_type = A1TC_EXPORTVAR;
705 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000706 | Identifier {
707 $$ = asn1p_expr_new(yylineno);
708 checkmem($$);
709 $$->Identifier = $1;
710 $$->expr_type = A1TC_EXPORTVAR;
711 }
712 ;
713
714
715ValueSetDefinition:
Lev Walkin0c0bca62006-03-21 04:48:15 +0000716 TypeRefName DefinedType TOK_PPEQ
Lev Walkin8ea99482005-03-31 21:48:13 +0000717 '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
Lev Walkinf15320b2004-06-03 03:38:44 +0000718 $$ = $2;
719 assert($$->Identifier == 0);
720 $$->Identifier = $1;
721 $$->meta_type = AMT_VALUESET;
Lev Walkine24403d2006-03-16 22:39:56 +0000722 /* take care of ValueSet body */
Lev Walkinf15320b2004-06-03 03:38:44 +0000723 }
724 ;
725
Lev Walkin0c0bca62006-03-21 04:48:15 +0000726DefinedType:
727 BasicType {
728 $$ = $1;
729 }
730 /*
731 * A DefinedType reference.
732 * "CLASS1.&id.&id2"
733 * or
734 * "Module.Type"
735 * or
736 * "Module.identifier"
737 * or
738 * "Type"
739 */
740 | ComplexTypeReference {
Lev Walkinf15320b2004-06-03 03:38:44 +0000741 $$ = asn1p_expr_new(yylineno);
742 checkmem($$);
743 $$->reference = $1;
744 $$->expr_type = A1TC_REFERENCE;
745 $$->meta_type = AMT_TYPEREF;
746 }
Lev Walkin0c0bca62006-03-21 04:48:15 +0000747 /*
748 * A parametrized assignment.
749 */
750 | ComplexTypeReference '{' Specializations '}' {
Lev Walkinf15320b2004-06-03 03:38:44 +0000751 $$ = asn1p_expr_new(yylineno);
752 checkmem($$);
Lev Walkin0c0bca62006-03-21 04:48:15 +0000753 $$->reference = $1;
754 $$->rhs_pspecs = $3;
755 $$->expr_type = A1TC_REFERENCE;
756 $$->meta_type = AMT_TYPEREF;
Lev Walkinf15320b2004-06-03 03:38:44 +0000757 }
758 ;
759
Lev Walkinf15320b2004-06-03 03:38:44 +0000760/*
761 * Data Type Reference.
762 * === EXAMPLE ===
763 * Type3 ::= CHOICE { a Type1, b Type 2 }
764 * === EOF ===
765 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000766DataTypeReference:
767 /*
768 * Optionally tagged type definition.
769 */
Lev Walkin9c2285a2006-03-09 08:49:26 +0000770 TypeRefName TOK_PPEQ Type {
Lev Walkinaf120f72004-09-14 02:36:39 +0000771 $$ = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000772 $$->Identifier = $1;
Lev Walkinf15320b2004-06-03 03:38:44 +0000773 assert($$->expr_type);
774 assert($$->meta_type);
775 }
Lev Walkin9c2285a2006-03-09 08:49:26 +0000776 | TypeRefName TOK_PPEQ ObjectClass {
Lev Walkinf15320b2004-06-03 03:38:44 +0000777 $$ = $3;
778 $$->Identifier = $1;
779 assert($$->expr_type == A1TC_CLASSDEF);
Lev Walkin9c2285a2006-03-09 08:49:26 +0000780 assert($$->meta_type == AMT_OBJECTCLASS);
Lev Walkinf15320b2004-06-03 03:38:44 +0000781 }
782 /*
783 * Parametrized <Type> declaration:
784 * === EXAMPLE ===
785 * SIGNED { ToBeSigned } ::= SEQUENCE {
786 * toBeSigned ToBeSigned,
787 * algorithm AlgorithmIdentifier,
788 * signature BIT STRING
789 * }
790 * === EOF ===
791 */
Lev Walkin070a52d2004-08-22 03:19:54 +0000792 | TypeRefName '{' ParameterArgumentList '}' TOK_PPEQ Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000793 $$ = $6;
794 assert($$->Identifier == 0);
795 $$->Identifier = $1;
Lev Walkina00d6b32006-03-21 03:40:38 +0000796 $$->lhs_params = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +0000797 }
798 ;
799
800ParameterArgumentList:
801 ParameterArgumentName {
802 int ret;
803 $$ = asn1p_paramlist_new(yylineno);
804 checkmem($$);
805 ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument);
806 checkmem(ret == 0);
807 if($1.governor) asn1p_ref_free($1.governor);
808 if($1.argument) free($1.argument);
809 }
810 | ParameterArgumentList ',' ParameterArgumentName {
811 int ret;
812 $$ = $1;
813 ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument);
814 checkmem(ret == 0);
815 if($3.governor) asn1p_ref_free($3.governor);
816 if($3.argument) free($3.argument);
817 }
818 ;
819
820ParameterArgumentName:
821 TypeRefName {
822 $$.governor = NULL;
823 $$.argument = $1;
824 }
825 | TypeRefName ':' Identifier {
826 int ret;
827 $$.governor = asn1p_ref_new(yylineno);
828 ret = asn1p_ref_add_component($$.governor, $1, 0);
829 checkmem(ret == 0);
830 $$.argument = $3;
831 }
Lev Walkinc8092cb2005-02-18 16:34:21 +0000832 | TypeRefName ':' TypeRefName {
833 int ret;
834 $$.governor = asn1p_ref_new(yylineno);
835 ret = asn1p_ref_add_component($$.governor, $1, 0);
836 checkmem(ret == 0);
837 $$.argument = $3;
838 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000839 | BasicTypeId ':' Identifier {
840 int ret;
841 $$.governor = asn1p_ref_new(yylineno);
842 ret = asn1p_ref_add_component($$.governor,
843 ASN_EXPR_TYPE2STR($1), 1);
844 checkmem(ret == 0);
845 $$.argument = $3;
846 }
847 ;
848
Lev Walkina00d6b32006-03-21 03:40:38 +0000849Specializations:
850 Specialization {
Lev Walkinf15320b2004-06-03 03:38:44 +0000851 $$ = asn1p_expr_new(yylineno);
852 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000853 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000854 }
Lev Walkina00d6b32006-03-21 03:40:38 +0000855 | Specializations ',' Specialization {
Lev Walkinf15320b2004-06-03 03:38:44 +0000856 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000857 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000858 }
859 ;
860
Lev Walkina00d6b32006-03-21 03:40:38 +0000861Specialization:
Lev Walkin070a52d2004-08-22 03:19:54 +0000862 Type {
Lev Walkinf15320b2004-06-03 03:38:44 +0000863 $$ = $1;
864 }
Lev Walkin0c0bca62006-03-21 04:48:15 +0000865 | SimpleValue {
866 $$ = asn1p_expr_new(yylineno);
867 checkmem($$);
868 $$->Identifier = "?";
869 $$->expr_type = A1TC_REFERENCE;
870 $$->meta_type = AMT_VALUE;
871 $$->value = $1;
872 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000873 | Identifier {
Lev Walkina00d6b32006-03-21 03:40:38 +0000874 asn1p_ref_t *ref;
Lev Walkinf15320b2004-06-03 03:38:44 +0000875 $$ = asn1p_expr_new(yylineno);
876 checkmem($$);
877 $$->Identifier = $1;
878 $$->expr_type = A1TC_REFERENCE;
879 $$->meta_type = AMT_VALUE;
Lev Walkina00d6b32006-03-21 03:40:38 +0000880 ref = asn1p_ref_new(yylineno);
881 asn1p_ref_add_component(ref, $1, RLT_lowercase);
882 $$->value = asn1p_value_fromref(ref, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000883 }
884 ;
885
886/*
Lev Walkina00d6b32006-03-21 03:40:38 +0000887 | '{' Specialization '}' {
Lev Walkinc8092cb2005-02-18 16:34:21 +0000888 $$ = asn1p_expr_new(yylineno);
889 checkmem($$);
890 asn1p_expr_add($$, $2);
891 $$->expr_type = A1TC_PARAMETRIZED;
892 $$->meta_type = AMT_TYPE;
893 }
894 ;
895*/
896
897/*
Lev Walkinf15320b2004-06-03 03:38:44 +0000898 * A collection of constructed data type members.
899 */
Lev Walkin144db9b2004-10-12 23:26:53 +0000900optComponentTypeLists:
901 { $$ = asn1p_expr_new(yylineno); }
902 | ComponentTypeLists { $$ = $1; };
903
Lev Walkin070a52d2004-08-22 03:19:54 +0000904ComponentTypeLists:
905 ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000906 $$ = asn1p_expr_new(yylineno);
907 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000908 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000909 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000910 | ComponentTypeLists ',' ComponentType {
Lev Walkinf15320b2004-06-03 03:38:44 +0000911 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000912 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000913 }
914 ;
915
Lev Walkin070a52d2004-08-22 03:19:54 +0000916ComponentType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000917 Identifier Type optMarker {
Lev Walkin070a52d2004-08-22 03:19:54 +0000918 $$ = $2;
919 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000920 $$->Identifier = $1;
Lev Walkinef625402005-09-05 05:17:57 +0000921 $3.flags |= $$->marker.flags;
Lev Walkin070a52d2004-08-22 03:19:54 +0000922 $$->marker = $3;
923 }
Lev Walkinef625402005-09-05 05:17:57 +0000924 | Type optMarker {
925 $$ = $1;
926 $2.flags |= $$->marker.flags;
927 $$->marker = $2;
928 _fixup_anonymous_identifier($$);
929 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000930 | TOK_COMPONENTS TOK_OF Type {
931 $$ = asn1p_expr_new(yylineno);
932 checkmem($$);
933 $$->meta_type = $3->meta_type;
934 $$->expr_type = A1TC_COMPONENTS_OF;
Lev Walkin1004aa92004-09-08 00:28:11 +0000935 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000936 }
937 | ExtensionAndException {
938 $$ = $1;
939 }
940 ;
941
942AlternativeTypeLists:
943 AlternativeType {
944 $$ = asn1p_expr_new(yylineno);
945 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +0000946 asn1p_expr_add($$, $1);
Lev Walkin070a52d2004-08-22 03:19:54 +0000947 }
948 | AlternativeTypeLists ',' AlternativeType {
949 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000950 asn1p_expr_add($$, $3);
Lev Walkin070a52d2004-08-22 03:19:54 +0000951 }
952 ;
953
954AlternativeType:
Lev Walkinaf120f72004-09-14 02:36:39 +0000955 Identifier Type {
Lev Walkin070a52d2004-08-22 03:19:54 +0000956 $$ = $2;
957 assert($$->Identifier == 0);
Lev Walkinaf120f72004-09-14 02:36:39 +0000958 $$->Identifier = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +0000959 }
960 | ExtensionAndException {
961 $$ = $1;
962 }
Lev Walkin2e9bd5c2005-08-13 09:07:11 +0000963 | Type {
964 $$ = $1;
965 _fixup_anonymous_identifier($$);
966 }
Lev Walkin070a52d2004-08-22 03:19:54 +0000967 ;
968
Lev Walkin9c2285a2006-03-09 08:49:26 +0000969ObjectClass:
970 TOK_CLASS '{' FieldSpec '}' optWithSyntax {
Lev Walkinf15320b2004-06-03 03:38:44 +0000971 $$ = $3;
972 checkmem($$);
973 $$->with_syntax = $5;
974 assert($$->expr_type == A1TC_CLASSDEF);
Lev Walkin9c2285a2006-03-09 08:49:26 +0000975 assert($$->meta_type == AMT_OBJECTCLASS);
Lev Walkinf15320b2004-06-03 03:38:44 +0000976 }
977 ;
978
979optUnique:
980 { $$ = 0; }
981 | TOK_UNIQUE { $$ = 1; }
982 ;
983
Lev Walkin9c2285a2006-03-09 08:49:26 +0000984FieldSpec:
Lev Walkinf15320b2004-06-03 03:38:44 +0000985 ClassField {
986 $$ = asn1p_expr_new(yylineno);
987 checkmem($$);
988 $$->expr_type = A1TC_CLASSDEF;
Lev Walkin9c2285a2006-03-09 08:49:26 +0000989 $$->meta_type = AMT_OBJECTCLASS;
Lev Walkin1004aa92004-09-08 00:28:11 +0000990 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000991 }
Lev Walkin9c2285a2006-03-09 08:49:26 +0000992 | FieldSpec ',' ClassField {
Lev Walkinf15320b2004-06-03 03:38:44 +0000993 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +0000994 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +0000995 }
996 ;
997
Lev Walkin9c2285a2006-03-09 08:49:26 +0000998 /* X.681 */
Lev Walkinf15320b2004-06-03 03:38:44 +0000999ClassField:
Lev Walkin9c2285a2006-03-09 08:49:26 +00001000
1001 /* TypeFieldSpec ::= typefieldreference TypeOptionalitySpec? */
1002 TOK_typefieldreference optMarker {
Lev Walkinf15320b2004-06-03 03:38:44 +00001003 $$ = asn1p_expr_new(yylineno);
1004 checkmem($$);
Lev Walkin9c2285a2006-03-09 08:49:26 +00001005 $$->Identifier = $1;
Lev Walkinf15320b2004-06-03 03:38:44 +00001006 $$->meta_type = AMT_OBJECTFIELD;
Lev Walkin9c2285a2006-03-09 08:49:26 +00001007 $$->expr_type = A1TC_CLASSFIELD_TFS; /* TypeFieldSpec */
Lev Walkinf15320b2004-06-03 03:38:44 +00001008 $$->marker = $2;
1009 }
Lev Walkin9c2285a2006-03-09 08:49:26 +00001010
1011 /* FixedTypeValueFieldSpec ::= valuefieldreference Type UNIQUE ? ValueOptionalitySpec ? */
1012 | TOK_valuefieldreference Type optUnique optMarker {
1013 $$ = asn1p_expr_new(yylineno);
1014 $$->Identifier = $1;
1015 $$->meta_type = AMT_OBJECTFIELD;
1016 $$->expr_type = A1TC_CLASSFIELD_FTVFS; /* FixedTypeValueFieldSpec */
Lev Walkinb7c45ca2004-11-24 17:43:29 +00001017 $$->unique = $3;
Lev Walkin9c2285a2006-03-09 08:49:26 +00001018 $$->marker = $4;
1019 asn1p_expr_add($$, $2);
Lev Walkinf15320b2004-06-03 03:38:44 +00001020 }
Lev Walkin9c2285a2006-03-09 08:49:26 +00001021
1022 /* VariableTypeValueFieldSpec ::= valuefieldreference FieldName ValueOptionalitySpec ? */
1023 | TOK_valuefieldreference FieldName optMarker {
1024 $$ = asn1p_expr_new(yylineno);
1025 $$->Identifier = $1;
1026 $$->meta_type = AMT_OBJECTFIELD;
1027 $$->expr_type = A1TC_CLASSFIELD_VTVFS;
1028 $$->reference = $2;
1029 $$->marker = $3;
1030 }
1031
Lev Walkin9c2285a2006-03-09 08:49:26 +00001032 /* ObjectFieldSpec ::= objectfieldreference DefinedObjectClass ObjectOptionalitySpec ? */
1033 | TOK_valuefieldreference DefinedObjectClass optMarker {
Lev Walkinf15320b2004-06-03 03:38:44 +00001034 $$ = asn1p_expr_new(yylineno);
1035 checkmem($$);
Lev Walkin9c2285a2006-03-09 08:49:26 +00001036 $$->Identifier = $1;
1037 $$->reference = $2;
Lev Walkinf15320b2004-06-03 03:38:44 +00001038 $$->meta_type = AMT_OBJECTFIELD;
Lev Walkin9c2285a2006-03-09 08:49:26 +00001039 $$->expr_type = A1TC_CLASSFIELD_OFS;
1040 $$->marker = $3;
Lev Walkinf15320b2004-06-03 03:38:44 +00001041 }
Lev Walkin9c2285a2006-03-09 08:49:26 +00001042
Lev Walkin54868752006-03-09 09:08:49 +00001043 /* VariableTypeValueSetFieldSpec ::= valuesetfieldreference FieldName ValueOptionalitySpec ? */
1044 | TOK_typefieldreference FieldName optMarker {
Lev Walkin9c2285a2006-03-09 08:49:26 +00001045 $$ = asn1p_expr_new(yylineno);
Lev Walkin9c2285a2006-03-09 08:49:26 +00001046 $$->Identifier = $1;
Lev Walkin9c2285a2006-03-09 08:49:26 +00001047 $$->meta_type = AMT_OBJECTFIELD;
Lev Walkin54868752006-03-09 09:08:49 +00001048 $$->expr_type = A1TC_CLASSFIELD_VTVSFS;
1049 $$->reference = $2;
Lev Walkin9c2285a2006-03-09 08:49:26 +00001050 $$->marker = $3;
1051 }
1052
1053 /* FixedTypeValueSetFieldSpec ::= valuesetfieldreference Type ValueSetOptionalitySpec ? */
1054 | TOK_typefieldreference Type optMarker {
1055 $$ = asn1p_expr_new(yylineno);
1056 checkmem($$);
1057 $$->Identifier = $1;
1058 $$->meta_type = AMT_OBJECTFIELD;
1059 $$->expr_type = A1TC_CLASSFIELD_FTVSFS;
1060 asn1p_expr_add($$, $2);
1061 $$->marker = $3;
1062 }
1063
Lev Walkin54868752006-03-09 09:08:49 +00001064 /* ObjectSetFieldSpec ::= objectsetfieldreference DefinedObjectClass ObjectOptionalitySpec ? */
1065 | TOK_typefieldreference DefinedObjectClass optMarker {
1066 $$ = asn1p_expr_new(yylineno);
1067 checkmem($$);
1068 $$->Identifier = $1;
1069 $$->reference = $2;
1070 $$->meta_type = AMT_OBJECTFIELD;
1071 $$->expr_type = A1TC_CLASSFIELD_OSFS;
1072 $$->marker = $3;
1073 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001074 ;
1075
1076optWithSyntax:
1077 { $$ = 0; }
1078 | WithSyntax {
1079 $$ = $1;
1080 }
1081 ;
1082
1083WithSyntax:
1084 TOK_WITH TOK_SYNTAX '{'
1085 { asn1p_lexer_hack_enable_with_syntax(); }
Lev Walkin9d542d22006-03-14 16:31:37 +00001086 WithSyntaxList
Lev Walkinf15320b2004-06-03 03:38:44 +00001087 '}' {
1088 $$ = $5;
1089 }
1090 ;
1091
Lev Walkin9d542d22006-03-14 16:31:37 +00001092WithSyntaxList:
1093 WithSyntaxToken {
Lev Walkinf15320b2004-06-03 03:38:44 +00001094 $$ = asn1p_wsyntx_new();
1095 TQ_ADD(&($$->chunks), $1, next);
1096 }
Lev Walkin9d542d22006-03-14 16:31:37 +00001097 | WithSyntaxList WithSyntaxToken {
Lev Walkinf15320b2004-06-03 03:38:44 +00001098 $$ = $1;
1099 TQ_ADD(&($$->chunks), $2, next);
1100 }
1101 ;
1102
Lev Walkin9d542d22006-03-14 16:31:37 +00001103WithSyntaxToken:
Lev Walkin57074f12006-03-16 05:11:14 +00001104 TOK_whitespace {
Lev Walkinf15320b2004-06-03 03:38:44 +00001105 $$ = asn1p_wsyntx_chunk_frombuf($1.buf, $1.len, 0);
Lev Walkin57074f12006-03-16 05:11:14 +00001106 $$->type = WC_WHITESPACE;
Lev Walkinf15320b2004-06-03 03:38:44 +00001107 }
Lev Walkin9d542d22006-03-14 16:31:37 +00001108 | TOK_Literal {
1109 $$ = asn1p_wsyntx_chunk_frombuf($1, strlen($1), 0);
1110 }
Lev Walkind370e9f2006-03-16 10:03:35 +00001111 | PrimitiveFieldReference {
1112 $$ = asn1p_wsyntx_chunk_frombuf($1.name, strlen($1.name), 0);
1113 $$->type = WC_FIELD;
Lev Walkinf15320b2004-06-03 03:38:44 +00001114 }
Lev Walkin9d542d22006-03-14 16:31:37 +00001115 | '[' WithSyntaxList ']' {
1116 $$ = asn1p_wsyntx_chunk_fromsyntax($2);
1117 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001118 ;
1119
Lev Walkinf15320b2004-06-03 03:38:44 +00001120ExtensionAndException:
1121 TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00001122 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001123 checkmem($$);
1124 $$->Identifier = strdup("...");
1125 checkmem($$->Identifier);
1126 $$->expr_type = A1TC_EXTENSIBLE;
1127 $$->meta_type = AMT_TYPE;
1128 }
1129 | TOK_ThreeDots '!' DefinedValue {
Lev Walkinceb20e72004-09-05 10:40:41 +00001130 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001131 checkmem($$);
1132 $$->Identifier = strdup("...");
1133 checkmem($$->Identifier);
1134 $$->value = $3;
1135 $$->expr_type = A1TC_EXTENSIBLE;
1136 $$->meta_type = AMT_TYPE;
1137 }
1138 | TOK_ThreeDots '!' SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00001139 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001140 checkmem($$);
1141 $$->Identifier = strdup("...");
1142 $$->value = $3;
1143 checkmem($$->Identifier);
1144 $$->expr_type = A1TC_EXTENSIBLE;
1145 $$->meta_type = AMT_TYPE;
1146 }
1147 ;
1148
Lev Walkin070a52d2004-08-22 03:19:54 +00001149Type:
Lev Walkinaf120f72004-09-14 02:36:39 +00001150 optTag TypeDeclaration optConstraints {
1151 $$ = $2;
1152 $$->tag = $1;
Lev Walkin070a52d2004-08-22 03:19:54 +00001153 /*
1154 * Outer constraint for SEQUENCE OF and SET OF applies
1155 * to the inner type.
1156 */
1157 if($$->expr_type == ASN_CONSTR_SEQUENCE_OF
1158 || $$->expr_type == ASN_CONSTR_SET_OF) {
1159 assert(!TQ_FIRST(&($$->members))->constraints);
Lev Walkinaf120f72004-09-14 02:36:39 +00001160 TQ_FIRST(&($$->members))->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001161 } else {
1162 if($$->constraints) {
1163 assert(!$2);
1164 } else {
Lev Walkinaf120f72004-09-14 02:36:39 +00001165 $$->constraints = $3;
Lev Walkin070a52d2004-08-22 03:19:54 +00001166 }
1167 }
Lev Walkinef625402005-09-05 05:17:57 +00001168 }
1169 ;
1170
1171NSTD_IndirectMarker:
1172 {
1173 $$ = asn1p_as_pointer ? EM_INDIRECT : 0;
1174 asn1p_as_pointer = 0;
Lev Walkin070a52d2004-08-22 03:19:54 +00001175 }
1176 ;
1177
1178TypeDeclaration:
Lev Walkinef625402005-09-05 05:17:57 +00001179 NSTD_IndirectMarker TypeDeclarationSet {
Lev Walkin4696c742005-08-22 12:23:54 +00001180 $$ = $2;
Lev Walkinef625402005-09-05 05:17:57 +00001181 $$->marker.flags |= $1;
1182
1183 if(($$->marker.flags & EM_INDIRECT)
1184 && ($$->marker.flags & EM_OPTIONAL) != EM_OPTIONAL) {
1185 fprintf(stderr,
1186 "INFO: Directive <ASN1C:RepresentAsPointer> "
1187 "applied to %s at line %d\n",
1188 ASN_EXPR_TYPE2STR($$->expr_type)
1189 ? ASN_EXPR_TYPE2STR($$->expr_type)
1190 : "member",
1191 $$->_lineno
1192 );
1193 }
Lev Walkin4696c742005-08-22 12:23:54 +00001194 }
Lev Walkinef625402005-09-05 05:17:57 +00001195 ;
Lev Walkin4696c742005-08-22 12:23:54 +00001196
1197TypeDeclarationSet:
Lev Walkin0c0bca62006-03-21 04:48:15 +00001198 DefinedType {
Lev Walkinf15320b2004-06-03 03:38:44 +00001199 $$ = $1;
1200 }
Lev Walkinef625402005-09-05 05:17:57 +00001201 | TOK_CHOICE '{' AlternativeTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001202 $$ = $3;
1203 assert($$->expr_type == A1TC_INVALID);
1204 $$->expr_type = ASN_CONSTR_CHOICE;
1205 $$->meta_type = AMT_TYPE;
Lev Walkinf15320b2004-06-03 03:38:44 +00001206 }
Lev Walkinef625402005-09-05 05:17:57 +00001207 | TOK_SEQUENCE '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001208 $$ = $3;
1209 assert($$->expr_type == A1TC_INVALID);
1210 $$->expr_type = ASN_CONSTR_SEQUENCE;
1211 $$->meta_type = AMT_TYPE;
1212 }
Lev Walkinef625402005-09-05 05:17:57 +00001213 | TOK_SET '{' optComponentTypeLists '}' {
Lev Walkin070a52d2004-08-22 03:19:54 +00001214 $$ = $3;
1215 assert($$->expr_type == A1TC_INVALID);
1216 $$->expr_type = ASN_CONSTR_SET;
1217 $$->meta_type = AMT_TYPE;
1218 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001219 | TOK_SEQUENCE optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001220 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001221 checkmem($$);
1222 $$->constraints = $2;
1223 $$->expr_type = ASN_CONSTR_SEQUENCE_OF;
1224 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001225 $6->Identifier = $4;
1226 $6->tag = $5;
1227 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001228 }
Lev Walkin83cac2f2004-09-22 16:03:36 +00001229 | TOK_SET optConstraints TOK_OF optIdentifier optTag TypeDeclaration {
Lev Walkinceb20e72004-09-05 10:40:41 +00001230 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001231 checkmem($$);
1232 $$->constraints = $2;
1233 $$->expr_type = ASN_CONSTR_SET_OF;
1234 $$->meta_type = AMT_TYPE;
Lev Walkin83cac2f2004-09-22 16:03:36 +00001235 $6->Identifier = $4;
1236 $6->tag = $5;
1237 asn1p_expr_add($$, $6);
Lev Walkin070a52d2004-08-22 03:19:54 +00001238 }
1239 | TOK_ANY {
Lev Walkinceb20e72004-09-05 10:40:41 +00001240 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001241 checkmem($$);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001242 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001243 $$->meta_type = AMT_TYPE;
1244 }
1245 | TOK_ANY TOK_DEFINED TOK_BY Identifier {
1246 int ret;
Lev Walkinceb20e72004-09-05 10:40:41 +00001247 $$ = asn1p_expr_new(yylineno);
Lev Walkin070a52d2004-08-22 03:19:54 +00001248 checkmem($$);
1249 $$->reference = asn1p_ref_new(yylineno);
1250 ret = asn1p_ref_add_component($$->reference,
1251 $4, RLT_lowercase);
1252 checkmem(ret == 0);
Lev Walkin609ccbb2004-09-04 04:49:21 +00001253 $$->expr_type = ASN_TYPE_ANY;
Lev Walkin070a52d2004-08-22 03:19:54 +00001254 $$->meta_type = AMT_TYPE;
1255 }
Lev Walkin0c0bca62006-03-21 04:48:15 +00001256
Lev Walkinf15320b2004-06-03 03:38:44 +00001257 | TOK_INSTANCE TOK_OF ComplexTypeReference {
1258 $$ = asn1p_expr_new(yylineno);
1259 checkmem($$);
1260 $$->reference = $3;
1261 $$->expr_type = A1TC_INSTANCE;
1262 $$->meta_type = AMT_TYPE;
1263 }
1264 ;
1265
1266/*
1267 * A type name consisting of several components.
1268 * === EXAMPLE ===
1269 * === EOF ===
1270 */
1271ComplexTypeReference:
1272 TOK_typereference {
1273 int ret;
1274 $$ = asn1p_ref_new(yylineno);
1275 checkmem($$);
1276 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1277 checkmem(ret == 0);
1278 free($1);
1279 }
1280 | TOK_typereference '.' TypeRefName {
1281 int ret;
1282 $$ = asn1p_ref_new(yylineno);
1283 checkmem($$);
1284 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1285 checkmem(ret == 0);
1286 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1287 checkmem(ret == 0);
1288 free($1);
1289 }
Lev Walkin9c974182004-09-15 11:59:51 +00001290 | ObjectClassReference '.' TypeRefName {
1291 int ret;
1292 $$ = asn1p_ref_new(yylineno);
1293 checkmem($$);
1294 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1295 checkmem(ret == 0);
1296 ret = asn1p_ref_add_component($$, $3, RLT_UNKNOWN);
1297 checkmem(ret == 0);
1298 free($1);
1299 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001300 | TOK_typereference '.' Identifier {
1301 int ret;
1302 $$ = asn1p_ref_new(yylineno);
1303 checkmem($$);
1304 ret = asn1p_ref_add_component($$, $1, RLT_UNKNOWN);
1305 checkmem(ret == 0);
1306 ret = asn1p_ref_add_component($$, $3, RLT_lowercase);
1307 checkmem(ret == 0);
1308 free($1);
1309 }
1310 | ObjectClassReference {
1311 int ret;
1312 $$ = asn1p_ref_new(yylineno);
1313 checkmem($$);
1314 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1315 free($1);
1316 checkmem(ret == 0);
1317 }
1318 | ObjectClassReference '.' ComplexTypeReferenceAmpList {
1319 int ret;
1320 $$ = $3;
1321 ret = asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1322 free($1);
1323 checkmem(ret == 0);
1324 /*
1325 * Move the last element infront.
1326 */
1327 {
1328 struct asn1p_ref_component_s tmp_comp;
1329 tmp_comp = $$->components[$$->comp_count-1];
1330 memmove(&$$->components[1],
1331 &$$->components[0],
1332 sizeof($$->components[0])
1333 * ($$->comp_count - 1));
1334 $$->components[0] = tmp_comp;
1335 }
1336 }
1337 ;
1338
1339ComplexTypeReferenceAmpList:
1340 ComplexTypeReferenceElement {
1341 int ret;
1342 $$ = asn1p_ref_new(yylineno);
1343 checkmem($$);
1344 ret = asn1p_ref_add_component($$, $1.name, $1.lex_type);
1345 free($1.name);
1346 checkmem(ret == 0);
1347 }
1348 | ComplexTypeReferenceAmpList '.' ComplexTypeReferenceElement {
1349 int ret;
1350 $$ = $1;
1351 ret = asn1p_ref_add_component($$, $3.name, $3.lex_type);
1352 free($3.name);
1353 checkmem(ret == 0);
1354 }
1355 ;
1356
Lev Walkind370e9f2006-03-16 10:03:35 +00001357ComplexTypeReferenceElement: PrimitiveFieldReference;
Lev Walkinf15320b2004-06-03 03:38:44 +00001358
Lev Walkind370e9f2006-03-16 10:03:35 +00001359PrimitiveFieldReference:
Lev Walkinf15320b2004-06-03 03:38:44 +00001360 /* "&Type1" */
1361 TOK_typefieldreference {
1362 $$.lex_type = RLT_AmpUppercase;
1363 $$.name = $1;
1364 }
1365 /* "&id" */
1366 | TOK_valuefieldreference {
1367 $$.lex_type = RLT_Amplowercase;
1368 $$.name = $1;
1369 }
1370 ;
1371
1372
Lev Walkin9c2285a2006-03-09 08:49:26 +00001373FieldName:
1374 /* "&Type1" */
1375 TOK_typefieldreference {
1376 $$ = asn1p_ref_new(yylineno);
1377 asn1p_ref_add_component($$, $1, RLT_AmpUppercase);
1378 }
1379 | FieldName '.' TOK_typefieldreference {
1380 $$ = $$;
1381 asn1p_ref_add_component($$, $3, RLT_AmpUppercase);
1382 }
1383 | FieldName '.' TOK_valuefieldreference {
1384 $$ = $$;
1385 asn1p_ref_add_component($$, $3, RLT_Amplowercase);
1386 }
1387 ;
1388
1389DefinedObjectClass:
1390 TOK_capitalreference {
1391 $$ = asn1p_ref_new(yylineno);
1392 asn1p_ref_add_component($$, $1, RLT_CAPITALS);
1393 }
Lev Walkin54868752006-03-09 09:08:49 +00001394/*
Lev Walkin9c2285a2006-03-09 08:49:26 +00001395 | TypeRefName '.' TOK_capitalreference {
1396 $$ = asn1p_ref_new(yylineno);
1397 asn1p_ref_add_component($$, $1, RLT_AmpUppercase);
1398 asn1p_ref_add_component($$, $3, RLT_CAPITALS);
1399 }
Lev Walkin54868752006-03-09 09:08:49 +00001400*/
Lev Walkin9c2285a2006-03-09 08:49:26 +00001401 ;
1402
1403
Lev Walkinf15320b2004-06-03 03:38:44 +00001404/*
1405 * === EXAMPLE ===
1406 * value INTEGER ::= 1
1407 * === EOF ===
1408 */
1409ValueDefinition:
Lev Walkin0c0bca62006-03-21 04:48:15 +00001410 Identifier DefinedType TOK_PPEQ Value {
Lev Walkinf15320b2004-06-03 03:38:44 +00001411 $$ = $2;
1412 assert($$->Identifier == NULL);
1413 $$->Identifier = $1;
1414 $$->meta_type = AMT_VALUE;
1415 $$->value = $4;
1416 }
1417 ;
1418
Lev Walkin9c974182004-09-15 11:59:51 +00001419Value:
Lev Walkin0c0bca62006-03-21 04:48:15 +00001420 SimpleValue
1421 | DefinedValue
1422 | Identifier ':' Value {
Lev Walkin9c974182004-09-15 11:59:51 +00001423 $$ = asn1p_value_fromint(0);
1424 checkmem($$);
1425 $$->type = ATV_CHOICE_IDENTIFIER;
1426 $$->value.choice_identifier.identifier = $1;
1427 $$->value.choice_identifier.value = $3;
1428 }
Lev Walkincbad2512005-03-24 16:27:02 +00001429 | '{' { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
Lev Walkinf15320b2004-06-03 03:38:44 +00001430 $$ = asn1p_value_frombuf($3.buf, $3.len, 0);
1431 checkmem($$);
1432 $$->type = ATV_UNPARSED;
1433 }
Lev Walkin9c974182004-09-15 11:59:51 +00001434 | TOK_NULL {
1435 $$ = asn1p_value_fromint(0);
1436 checkmem($$);
1437 $$->type = ATV_NULL;
1438 }
Lev Walkin0c0bca62006-03-21 04:48:15 +00001439 ;
1440
1441SimpleValue:
1442 TOK_FALSE {
Lev Walkin9c974182004-09-15 11:59:51 +00001443 $$ = asn1p_value_fromint(0);
1444 checkmem($$);
1445 $$->type = ATV_FALSE;
1446 }
1447 | TOK_TRUE {
1448 $$ = asn1p_value_fromint(0);
1449 checkmem($$);
1450 $$->type = ATV_TRUE;
1451 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001452 | TOK_bstring {
1453 $$ = _convert_bitstring2binary($1, 'B');
1454 checkmem($$);
1455 }
1456 | TOK_hstring {
1457 $$ = _convert_bitstring2binary($1, 'H');
1458 checkmem($$);
1459 }
Lev Walkin1e448d32005-03-24 14:26:38 +00001460 | RestrictedCharacterStringValue {
1461 $$ = $$;
Lev Walkinf15320b2004-06-03 03:38:44 +00001462 }
1463 | SignedNumber {
1464 $$ = $1;
1465 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001466 ;
1467
1468DefinedValue:
1469 Identifier {
1470 asn1p_ref_t *ref;
1471 int ret;
1472 ref = asn1p_ref_new(yylineno);
1473 checkmem(ref);
1474 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1475 checkmem(ret == 0);
1476 $$ = asn1p_value_fromref(ref, 0);
1477 checkmem($$);
1478 free($1);
1479 }
1480 | TypeRefName '.' Identifier {
1481 asn1p_ref_t *ref;
1482 int ret;
1483 ref = asn1p_ref_new(yylineno);
1484 checkmem(ref);
1485 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1486 checkmem(ret == 0);
1487 ret = asn1p_ref_add_component(ref, $3, RLT_lowercase);
1488 checkmem(ret == 0);
1489 $$ = asn1p_value_fromref(ref, 0);
1490 checkmem($$);
1491 free($1);
1492 free($3);
1493 }
1494 ;
1495
Lev Walkin1e448d32005-03-24 14:26:38 +00001496
1497RestrictedCharacterStringValue:
1498 TOK_cstring {
1499 $$ = asn1p_value_frombuf($1.buf, $1.len, 0);
1500 checkmem($$);
1501 }
Lev Walkind9574ae2005-03-24 16:22:35 +00001502 | TOK_tuple {
1503 $$ = asn1p_value_fromint($1);
1504 checkmem($$);
1505 $$->type = ATV_TUPLE;
1506 }
1507 | TOK_quadruple {
1508 $$ = asn1p_value_fromint($1);
1509 checkmem($$);
1510 $$->type = ATV_QUADRUPLE;
1511 }
1512 /*
Lev Walkin1e448d32005-03-24 14:26:38 +00001513 | '{' TOK_number ',' TOK_number '}' {
1514 asn1c_integer_t v = ($2 << 4) + $4;
1515 if($2 > 7) return yyerror("X.680:2003, #37.14 "
1516 "mandates 0..7 range for Tuple's TableColumn");
1517 if($4 > 15) return yyerror("X.680:2003, #37.14 "
1518 "mandates 0..15 range for Tuple's TableRow");
1519 $$ = asn1p_value_fromint(v);
1520 checkmem($$);
1521 $$->type = ATV_TUPLE;
1522 }
1523 | '{' TOK_number ',' TOK_number ',' TOK_number ',' TOK_number '}' {
1524 asn1c_integer_t v = ($2 << 24) | ($4 << 16) | ($6 << 8) | $8;
1525 if($2 > 127) return yyerror("X.680:2003, #37.12 "
1526 "mandates 0..127 range for Quadruple's Group");
1527 if($4 > 255) return yyerror("X.680:2003, #37.12 "
1528 "mandates 0..255 range for Quadruple's Plane");
1529 if($6 > 255) return yyerror("X.680:2003, #37.12 "
1530 "mandates 0..255 range for Quadruple's Row");
1531 if($8 > 255) return yyerror("X.680:2003, #37.12 "
1532 "mandates 0..255 range for Quadruple's Cell");
1533 $$ = asn1p_value_fromint(v);
1534 checkmem($$);
1535 $$->type = ATV_QUADRUPLE;
1536 }
Lev Walkind9574ae2005-03-24 16:22:35 +00001537 */
Lev Walkin1e448d32005-03-24 14:26:38 +00001538 ;
1539
Lev Walkinf15320b2004-06-03 03:38:44 +00001540Opaque:
1541 TOK_opaque {
Lev Walkin1893ddf2005-03-20 14:28:32 +00001542 $$.len = $1.len + 1;
Lev Walkinf15320b2004-06-03 03:38:44 +00001543 $$.buf = malloc($$.len + 1);
1544 checkmem($$.buf);
1545 $$.buf[0] = '{';
Lev Walkin1893ddf2005-03-20 14:28:32 +00001546 memcpy($$.buf + 1, $1.buf, $1.len);
Lev Walkinf15320b2004-06-03 03:38:44 +00001547 $$.buf[$$.len] = '\0';
1548 free($1.buf);
1549 }
1550 | Opaque TOK_opaque {
1551 int newsize = $1.len + $2.len;
1552 char *p = malloc(newsize + 1);
1553 checkmem(p);
1554 memcpy(p , $1.buf, $1.len);
1555 memcpy(p + $1.len, $2.buf, $2.len);
1556 p[newsize] = '\0';
1557 free($1.buf);
1558 free($2.buf);
1559 $$.buf = p;
1560 $$.len = newsize;
1561 }
1562 ;
1563
1564BasicTypeId:
1565 TOK_BOOLEAN { $$ = ASN_BASIC_BOOLEAN; }
1566 | TOK_NULL { $$ = ASN_BASIC_NULL; }
1567 | TOK_REAL { $$ = ASN_BASIC_REAL; }
1568 | BasicTypeId_UniverationCompatible { $$ = $1; }
1569 | TOK_OCTET TOK_STRING { $$ = ASN_BASIC_OCTET_STRING; }
1570 | TOK_OBJECT TOK_IDENTIFIER { $$ = ASN_BASIC_OBJECT_IDENTIFIER; }
1571 | TOK_RELATIVE_OID { $$ = ASN_BASIC_RELATIVE_OID; }
1572 | TOK_EXTERNAL { $$ = ASN_BASIC_EXTERNAL; }
1573 | TOK_EMBEDDED TOK_PDV { $$ = ASN_BASIC_EMBEDDED_PDV; }
1574 | TOK_CHARACTER TOK_STRING { $$ = ASN_BASIC_CHARACTER_STRING; }
1575 | TOK_UTCTime { $$ = ASN_BASIC_UTCTime; }
1576 | TOK_GeneralizedTime { $$ = ASN_BASIC_GeneralizedTime; }
Lev Walkinc7d939d2005-03-20 11:12:40 +00001577 | BasicString { $$ = $1; }
Lev Walkinf15320b2004-06-03 03:38:44 +00001578 ;
1579
1580/*
1581 * A type identifier which may be used with "{ a(1), b(2) }" clause.
1582 */
1583BasicTypeId_UniverationCompatible:
1584 TOK_INTEGER { $$ = ASN_BASIC_INTEGER; }
1585 | TOK_ENUMERATED { $$ = ASN_BASIC_ENUMERATED; }
1586 | TOK_BIT TOK_STRING { $$ = ASN_BASIC_BIT_STRING; }
1587 ;
1588
1589BasicType:
1590 BasicTypeId {
Lev Walkinceb20e72004-09-05 10:40:41 +00001591 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001592 checkmem($$);
1593 $$->expr_type = $1;
1594 $$->meta_type = AMT_TYPE;
1595 }
1596 | BasicTypeId_UniverationCompatible UniverationDefinition {
1597 if($2) {
1598 $$ = $2;
1599 } else {
Lev Walkinceb20e72004-09-05 10:40:41 +00001600 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001601 checkmem($$);
1602 }
1603 $$->expr_type = $1;
1604 $$->meta_type = AMT_TYPE;
1605 }
1606 ;
1607
1608BasicString:
1609 TOK_BMPString { $$ = ASN_STRING_BMPString; }
1610 | TOK_GeneralString {
1611 $$ = ASN_STRING_GeneralString;
Lev Walkin9c974182004-09-15 11:59:51 +00001612 fprintf(stderr, "WARNING: GeneralString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001613 }
1614 | TOK_GraphicString {
1615 $$ = ASN_STRING_GraphicString;
Lev Walkin9c974182004-09-15 11:59:51 +00001616 fprintf(stderr, "WARNING: GraphicString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001617 }
1618 | TOK_IA5String { $$ = ASN_STRING_IA5String; }
1619 | TOK_ISO646String { $$ = ASN_STRING_ISO646String; }
1620 | TOK_NumericString { $$ = ASN_STRING_NumericString; }
1621 | TOK_PrintableString { $$ = ASN_STRING_PrintableString; }
1622 | TOK_T61String {
1623 $$ = ASN_STRING_T61String;
Lev Walkin9c974182004-09-15 11:59:51 +00001624 fprintf(stderr, "WARNING: T61String is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001625 }
1626 | TOK_TeletexString { $$ = ASN_STRING_TeletexString; }
1627 | TOK_UniversalString { $$ = ASN_STRING_UniversalString; }
1628 | TOK_UTF8String { $$ = ASN_STRING_UTF8String; }
1629 | TOK_VideotexString {
1630 $$ = ASN_STRING_VideotexString;
Lev Walkin9c974182004-09-15 11:59:51 +00001631 fprintf(stderr, "WARNING: VideotexString is not fully supported\n");
Lev Walkinf15320b2004-06-03 03:38:44 +00001632 }
1633 | TOK_VisibleString { $$ = ASN_STRING_VisibleString; }
1634 | TOK_ObjectDescriptor { $$ = ASN_STRING_ObjectDescriptor; }
1635 ;
1636
Lev Walkind2ea1de2004-08-20 13:25:29 +00001637
Lev Walkinf15320b2004-06-03 03:38:44 +00001638/*
1639 * Data type constraints.
1640 */
Lev Walkinf15320b2004-06-03 03:38:44 +00001641Union: '|' | TOK_UNION;
1642Intersection: '^' | TOK_INTERSECTION;
1643Except: TOK_EXCEPT;
1644
Lev Walkinf59d0752004-08-18 04:59:12 +00001645optConstraints:
1646 { $$ = 0; }
Lev Walkind2ea1de2004-08-20 13:25:29 +00001647 | Constraints {
1648 $$ = $1;
1649 }
1650 ;
1651
1652Constraints:
1653 SetOfConstraints {
Lev Walkin2c14a692005-08-12 10:08:45 +00001654 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, 0);
Lev Walkinf59d0752004-08-18 04:59:12 +00001655 }
1656 | TOK_SIZE '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001657 /*
1658 * This is a special case, for compatibility purposes.
Lev Walkinf59d0752004-08-18 04:59:12 +00001659 * It goes without parentheses.
Lev Walkinf15320b2004-06-03 03:38:44 +00001660 */
Lev Walkin2c14a692005-08-12 10:08:45 +00001661 CONSTRAINT_INSERT($$, ACT_CT_SIZE, $3, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001662 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001663 ;
1664
Lev Walkinf59d0752004-08-18 04:59:12 +00001665SetOfConstraints:
1666 '(' ElementSetSpecs ')' {
Lev Walkinf15320b2004-06-03 03:38:44 +00001667 $$ = $2;
1668 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001669 | SetOfConstraints '(' ElementSetSpecs ')' {
Lev Walkin2c14a692005-08-12 10:08:45 +00001670 CONSTRAINT_INSERT($$, ACT_CA_SET, $1, $3);
Lev Walkinf59d0752004-08-18 04:59:12 +00001671 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001672 ;
1673
Lev Walkinf59d0752004-08-18 04:59:12 +00001674ElementSetSpecs:
1675 ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001676 $$ = $1;
1677 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001678 | ElementSetSpec ',' TOK_ThreeDots {
Lev Walkinf15320b2004-06-03 03:38:44 +00001679 asn1p_constraint_t *ct;
1680 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001681 ct->type = ACT_EL_EXT;
Lev Walkin2c14a692005-08-12 10:08:45 +00001682 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
Lev Walkinf15320b2004-06-03 03:38:44 +00001683 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001684 | ElementSetSpec ',' TOK_ThreeDots ',' ElementSetSpec {
Lev Walkinf15320b2004-06-03 03:38:44 +00001685 asn1p_constraint_t *ct;
1686 ct = asn1p_constraint_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00001687 ct->type = ACT_EL_EXT;
Lev Walkin2c14a692005-08-12 10:08:45 +00001688 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
Lev Walkinb4fcdd22004-08-13 12:35:09 +00001689 ct = $$;
Lev Walkin2c14a692005-08-12 10:08:45 +00001690 CONSTRAINT_INSERT($$, ACT_CA_CSV, ct, $5);
Lev Walkinf15320b2004-06-03 03:38:44 +00001691 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001692 ;
1693
Lev Walkinf59d0752004-08-18 04:59:12 +00001694ElementSetSpec:
1695 ConstraintSubtypeElement {
1696 $$ = $1;
1697 }
Lev Walkin1e448d32005-03-24 14:26:38 +00001698 | TOK_ALL TOK_EXCEPT ConstraintSubtypeElement {
Lev Walkin2c14a692005-08-12 10:08:45 +00001699 CONSTRAINT_INSERT($$, ACT_CA_AEX, $3, 0);
Lev Walkin1e448d32005-03-24 14:26:38 +00001700 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001701 | ElementSetSpec Union ConstraintSubtypeElement {
Lev Walkin2c14a692005-08-12 10:08:45 +00001702 CONSTRAINT_INSERT($$, ACT_CA_UNI, $1, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00001703 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001704 | ElementSetSpec Intersection ConstraintSubtypeElement {
Lev Walkin2c14a692005-08-12 10:08:45 +00001705 CONSTRAINT_INSERT($$, ACT_CA_INT, $1, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00001706 }
Lev Walkinf59d0752004-08-18 04:59:12 +00001707 | ConstraintSubtypeElement Except ConstraintSubtypeElement {
Lev Walkin2c14a692005-08-12 10:08:45 +00001708 CONSTRAINT_INSERT($$, ACT_CA_EXC, $1, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00001709 }
1710 ;
1711
1712ConstraintSubtypeElement:
Lev Walkinf59d0752004-08-18 04:59:12 +00001713 ConstraintSpec '(' ElementSetSpecs ')' {
1714 int ret;
1715 $$ = asn1p_constraint_new(yylineno);
1716 checkmem($$);
1717 $$->type = $1;
1718 ret = asn1p_constraint_insert($$, $3);
1719 checkmem(ret == 0);
1720 }
1721 | '(' ElementSetSpecs ')' {
1722 int ret;
1723 $$ = asn1p_constraint_new(yylineno);
1724 checkmem($$);
1725 $$->type = ACT_CA_SET;
1726 ret = asn1p_constraint_insert($$, $2);
1727 checkmem(ret == 0);
1728 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001729 | SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001730 $$ = asn1p_constraint_new(yylineno);
1731 checkmem($$);
1732 $$->type = ACT_EL_VALUE;
1733 $$->value = $1;
1734 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001735 | ContainedSubtype {
1736 $$ = asn1p_constraint_new(yylineno);
1737 checkmem($$);
1738 $$->type = ACT_EL_TYPE;
1739 $$->containedSubtype = $1;
1740 }
1741 | SingleValue ConstraintRangeSpec SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001742 $$ = asn1p_constraint_new(yylineno);
1743 checkmem($$);
1744 $$->type = $2;
1745 $$->range_start = $1;
1746 $$->range_stop = $3;
1747 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001748 | TOK_MIN ConstraintRangeSpec SingleValue {
Lev Walkinf15320b2004-06-03 03:38:44 +00001749 $$ = asn1p_constraint_new(yylineno);
1750 checkmem($$);
Lev Walkinf59d0752004-08-18 04:59:12 +00001751 $$->type = $2;
1752 $$->range_start = asn1p_value_fromint(-123);
1753 $$->range_stop = $3;
1754 $$->range_start->type = ATV_MIN;
1755 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001756 | SingleValue ConstraintRangeSpec TOK_MAX {
Lev Walkinf59d0752004-08-18 04:59:12 +00001757 $$ = asn1p_constraint_new(yylineno);
1758 checkmem($$);
1759 $$->type = $2;
1760 $$->range_start = $1;
1761 $$->range_stop = asn1p_value_fromint(321);
1762 $$->range_stop->type = ATV_MAX;
1763 }
1764 | TOK_MIN ConstraintRangeSpec TOK_MAX {
1765 $$ = asn1p_constraint_new(yylineno);
1766 checkmem($$);
1767 $$->type = $2;
1768 $$->range_start = asn1p_value_fromint(-123);
1769 $$->range_stop = asn1p_value_fromint(321);
1770 $$->range_start->type = ATV_MIN;
1771 $$->range_stop->type = ATV_MAX;
Lev Walkinf15320b2004-06-03 03:38:44 +00001772 }
1773 | TableConstraint {
1774 $$ = $1;
1775 }
Lev Walkine596bf02005-03-28 15:01:27 +00001776 | InnerTypeConstraint {
Lev Walkinf15320b2004-06-03 03:38:44 +00001777 $$ = $1;
1778 }
Lev Walkin1893ddf2005-03-20 14:28:32 +00001779 | TOK_CONSTRAINED TOK_BY '{'
1780 { asn1p_lexer_hack_push_opaque_state(); } Opaque /* '}' */ {
1781 $$ = asn1p_constraint_new(yylineno);
1782 checkmem($$);
1783 $$->type = ACT_CT_CTDBY;
1784 $$->value = asn1p_value_frombuf($5.buf, $5.len, 0);
1785 checkmem($$->value);
1786 $$->value->type = ATV_UNPARSED;
1787 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001788 ;
1789
1790ConstraintRangeSpec:
1791 TOK_TwoDots { $$ = ACT_EL_RANGE; }
1792 | TOK_TwoDots '<' { $$ = ACT_EL_RLRANGE; }
1793 | '<' TOK_TwoDots { $$ = ACT_EL_LLRANGE; }
1794 | '<' TOK_TwoDots '<' { $$ = ACT_EL_ULRANGE; }
1795 ;
1796
1797ConstraintSpec:
1798 TOK_SIZE {
1799 $$ = ACT_CT_SIZE;
1800 }
1801 | TOK_FROM {
1802 $$ = ACT_CT_FROM;
1803 }
1804 ;
1805
Lev Walkinff7dd142005-03-20 12:58:00 +00001806SingleValue:
Lev Walkinc8092cb2005-02-18 16:34:21 +00001807 TOK_FALSE {
1808 $$ = asn1p_value_fromint(0);
1809 checkmem($$);
1810 $$->type = ATV_FALSE;
1811 }
1812 | TOK_TRUE {
1813 $$ = asn1p_value_fromint(1);
1814 checkmem($$);
1815 $$->type = ATV_TRUE;
1816 }
1817 | SignedNumber {
Lev Walkinf15320b2004-06-03 03:38:44 +00001818 $$ = $1;
1819 }
Lev Walkin1e448d32005-03-24 14:26:38 +00001820 | RestrictedCharacterStringValue {
1821 $$ = $1;
Lev Walkinc8092cb2005-02-18 16:34:21 +00001822 }
Lev Walkinf15320b2004-06-03 03:38:44 +00001823 | Identifier {
1824 asn1p_ref_t *ref;
1825 int ret;
1826 ref = asn1p_ref_new(yylineno);
1827 checkmem(ref);
1828 ret = asn1p_ref_add_component(ref, $1, RLT_lowercase);
1829 checkmem(ret == 0);
1830 $$ = asn1p_value_fromref(ref, 0);
1831 checkmem($$);
1832 free($1);
1833 }
Lev Walkinff7dd142005-03-20 12:58:00 +00001834 ;
1835
1836ContainedSubtype:
1837 TypeRefName {
Lev Walkinc8092cb2005-02-18 16:34:21 +00001838 asn1p_ref_t *ref;
1839 int ret;
1840 ref = asn1p_ref_new(yylineno);
1841 checkmem(ref);
1842 ret = asn1p_ref_add_component(ref, $1, RLT_UNKNOWN);
1843 checkmem(ret == 0);
1844 $$ = asn1p_value_fromref(ref, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001845 checkmem($$);
Lev Walkinc8092cb2005-02-18 16:34:21 +00001846 free($1);
Lev Walkinf15320b2004-06-03 03:38:44 +00001847 }
1848 ;
1849
Lev Walkine596bf02005-03-28 15:01:27 +00001850InnerTypeConstraint:
1851 TOK_WITH TOK_COMPONENT SetOfConstraints {
Lev Walkin2c14a692005-08-12 10:08:45 +00001852 CONSTRAINT_INSERT($$, ACT_CT_WCOMP, $3, 0);
Lev Walkine596bf02005-03-28 15:01:27 +00001853 }
1854 | TOK_WITH TOK_COMPONENTS '{' WithComponentsList '}' {
Lev Walkin2c14a692005-08-12 10:08:45 +00001855 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $4, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001856 }
1857 ;
1858
1859WithComponentsList:
1860 WithComponentsElement {
1861 $$ = $1;
1862 }
1863 | WithComponentsList ',' WithComponentsElement {
Lev Walkin2c14a692005-08-12 10:08:45 +00001864 CONSTRAINT_INSERT($$, ACT_CT_WCOMPS, $1, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00001865 }
1866 ;
1867
1868WithComponentsElement:
1869 TOK_ThreeDots {
1870 $$ = asn1p_constraint_new(yylineno);
1871 checkmem($$);
1872 $$->type = ACT_EL_EXT;
Lev Walkine596bf02005-03-28 15:01:27 +00001873 $$->value = asn1p_value_frombuf("...", 3, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001874 }
1875 | Identifier optConstraints optPresenceConstraint {
1876 $$ = asn1p_constraint_new(yylineno);
1877 checkmem($$);
1878 $$->type = ACT_EL_VALUE;
1879 $$->value = asn1p_value_frombuf($1, strlen($1), 0);
1880 $$->presence = $3;
Lev Walkine596bf02005-03-28 15:01:27 +00001881 if($2) asn1p_constraint_insert($$, $2);
Lev Walkinf15320b2004-06-03 03:38:44 +00001882 }
1883 ;
1884
1885/*
1886 * presence constraint for WithComponents
1887 */
1888optPresenceConstraint:
1889 { $$ = ACPRES_DEFAULT; }
1890 | PresenceConstraint { $$ = $1; }
1891 ;
1892
1893PresenceConstraint:
1894 TOK_PRESENT {
1895 $$ = ACPRES_PRESENT;
1896 }
1897 | TOK_ABSENT {
1898 $$ = ACPRES_ABSENT;
1899 }
1900 | TOK_OPTIONAL {
1901 $$ = ACPRES_OPTIONAL;
1902 }
1903 ;
1904
1905TableConstraint:
1906 SimpleTableConstraint {
1907 $$ = $1;
1908 }
1909 | ComponentRelationConstraint {
1910 $$ = $1;
1911 }
1912 ;
1913
1914/*
1915 * "{ExtensionSet}"
1916 */
1917SimpleTableConstraint:
1918 '{' TypeRefName '}' {
1919 asn1p_ref_t *ref = asn1p_ref_new(yylineno);
1920 asn1p_constraint_t *ct;
1921 int ret;
1922 ret = asn1p_ref_add_component(ref, $2, 0);
1923 checkmem(ret == 0);
1924 ct = asn1p_constraint_new(yylineno);
1925 checkmem($$);
1926 ct->type = ACT_EL_VALUE;
1927 ct->value = asn1p_value_fromref(ref, 0);
Lev Walkin2c14a692005-08-12 10:08:45 +00001928 CONSTRAINT_INSERT($$, ACT_CA_CRC, ct, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +00001929 }
1930 ;
1931
1932ComponentRelationConstraint:
1933 SimpleTableConstraint '{' AtNotationList '}' {
Lev Walkin2c14a692005-08-12 10:08:45 +00001934 CONSTRAINT_INSERT($$, ACT_CA_CRC, $1, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00001935 }
1936 ;
1937
1938AtNotationList:
1939 AtNotationElement {
1940 $$ = asn1p_constraint_new(yylineno);
1941 checkmem($$);
1942 $$->type = ACT_EL_VALUE;
1943 $$->value = asn1p_value_fromref($1, 0);
1944 }
1945 | AtNotationList ',' AtNotationElement {
1946 asn1p_constraint_t *ct;
1947 ct = asn1p_constraint_new(yylineno);
1948 checkmem(ct);
1949 ct->type = ACT_EL_VALUE;
1950 ct->value = asn1p_value_fromref($3, 0);
Lev Walkin2c14a692005-08-12 10:08:45 +00001951 CONSTRAINT_INSERT($$, ACT_CA_CSV, $1, ct);
Lev Walkinf15320b2004-06-03 03:38:44 +00001952 }
1953 ;
1954
1955/*
1956 * @blah
1957 */
1958AtNotationElement:
1959 '@' ComponentIdList {
1960 char *p = malloc(strlen($2) + 2);
1961 int ret;
1962 *p = '@';
1963 strcpy(p + 1, $2);
1964 $$ = asn1p_ref_new(yylineno);
1965 ret = asn1p_ref_add_component($$, p, 0);
1966 checkmem(ret == 0);
1967 free(p);
1968 free($2);
1969 }
1970 | '@' '.' ComponentIdList {
1971 char *p = malloc(strlen($3) + 3);
1972 int ret;
1973 p[0] = '@';
1974 p[1] = '.';
1975 strcpy(p + 2, $3);
1976 $$ = asn1p_ref_new(yylineno);
1977 ret = asn1p_ref_add_component($$, p, 0);
1978 checkmem(ret == 0);
1979 free(p);
1980 free($3);
1981 }
1982 ;
1983
1984/* identifier "." ... */
1985ComponentIdList:
1986 Identifier {
1987 $$ = $1;
1988 }
1989 | ComponentIdList '.' Identifier {
1990 int l1 = strlen($1);
1991 int l3 = strlen($3);
1992 $$ = malloc(l1 + 1 + l3 + 1);
1993 memcpy($$, $1, l1);
1994 $$[l1] = '.';
1995 memcpy($$ + l1 + 1, $3, l3);
1996 $$[l1 + 1 + l3] = '\0';
1997 }
1998 ;
1999
2000
2001
2002/*
2003 * MARKERS
2004 */
2005
2006optMarker:
Lev Walkin9c974182004-09-15 11:59:51 +00002007 {
2008 $$.flags = EM_NOMARK;
2009 $$.default_value = 0;
2010 }
Lev Walkinf15320b2004-06-03 03:38:44 +00002011 | Marker { $$ = $1; }
2012 ;
2013
2014Marker:
2015 TOK_OPTIONAL {
Lev Walkin70853052005-11-26 11:21:55 +00002016 $$.flags = EM_OPTIONAL | EM_INDIRECT;
Lev Walkin9c974182004-09-15 11:59:51 +00002017 $$.default_value = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +00002018 }
Lev Walkin9c974182004-09-15 11:59:51 +00002019 | TOK_DEFAULT Value {
2020 $$.flags = EM_DEFAULT;
2021 $$.default_value = $2;
Lev Walkinf15320b2004-06-03 03:38:44 +00002022 }
2023 ;
2024
2025/*
2026 * Universal enumeration definition to use in INTEGER and ENUMERATED.
2027 * === EXAMPLE ===
2028 * Gender ::= ENUMERATED { unknown(0), male(1), female(2) }
2029 * Temperature ::= INTEGER { absolute-zero(-273), freezing(0), boiling(100) }
2030 * === EOF ===
2031 */
2032/*
2033optUniverationDefinition:
2034 { $$ = 0; }
2035 | UniverationDefinition {
2036 $$ = $1;
2037 }
2038 ;
2039*/
2040
2041UniverationDefinition:
2042 '{' '}' {
Lev Walkinceb20e72004-09-05 10:40:41 +00002043 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00002044 checkmem($$);
2045 }
2046 | '{' UniverationList '}' {
2047 $$ = $2;
2048 }
2049 ;
2050
2051UniverationList:
2052 UniverationElement {
Lev Walkinceb20e72004-09-05 10:40:41 +00002053 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00002054 checkmem($$);
Lev Walkin1004aa92004-09-08 00:28:11 +00002055 asn1p_expr_add($$, $1);
Lev Walkinf15320b2004-06-03 03:38:44 +00002056 }
2057 | UniverationList ',' UniverationElement {
2058 $$ = $1;
Lev Walkin1004aa92004-09-08 00:28:11 +00002059 asn1p_expr_add($$, $3);
Lev Walkinf15320b2004-06-03 03:38:44 +00002060 }
2061 ;
2062
2063UniverationElement:
2064 Identifier {
Lev Walkinceb20e72004-09-05 10:40:41 +00002065 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00002066 checkmem($$);
2067 $$->expr_type = A1TC_UNIVERVAL;
2068 $$->meta_type = AMT_VALUE;
2069 $$->Identifier = $1;
2070 }
2071 | Identifier '(' SignedNumber ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00002072 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00002073 checkmem($$);
2074 $$->expr_type = A1TC_UNIVERVAL;
2075 $$->meta_type = AMT_VALUE;
2076 $$->Identifier = $1;
2077 $$->value = $3;
2078 }
2079 | Identifier '(' DefinedValue ')' {
Lev Walkinceb20e72004-09-05 10:40:41 +00002080 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00002081 checkmem($$);
2082 $$->expr_type = A1TC_UNIVERVAL;
2083 $$->meta_type = AMT_VALUE;
2084 $$->Identifier = $1;
2085 $$->value = $3;
2086 }
2087 | SignedNumber {
Lev Walkinceb20e72004-09-05 10:40:41 +00002088 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00002089 checkmem($$);
2090 $$->expr_type = A1TC_UNIVERVAL;
2091 $$->meta_type = AMT_VALUE;
2092 $$->value = $1;
2093 }
2094 | TOK_ThreeDots {
Lev Walkinceb20e72004-09-05 10:40:41 +00002095 $$ = asn1p_expr_new(yylineno);
Lev Walkinf15320b2004-06-03 03:38:44 +00002096 checkmem($$);
2097 $$->Identifier = strdup("...");
2098 checkmem($$->Identifier);
2099 $$->expr_type = A1TC_EXTENSIBLE;
2100 $$->meta_type = AMT_VALUE;
2101 }
2102 ;
2103
2104SignedNumber:
2105 TOK_number {
2106 $$ = asn1p_value_fromint($1);
2107 checkmem($$);
2108 }
2109 | TOK_number_negative {
2110 $$ = asn1p_value_fromint($1);
2111 checkmem($$);
2112 }
2113 ;
2114
2115/*
2116 * SEQUENCE definition.
2117 * === EXAMPLE ===
2118 * Struct1 ::= SEQUENCE {
2119 * memb1 Struct2,
2120 * memb2 SEQUENCE OF {
2121 * memb2-1 Struct 3
2122 * }
2123 * }
2124 * === EOF ===
2125 */
2126
2127
2128
2129/*
2130 * SET definition.
2131 * === EXAMPLE ===
2132 * Person ::= SET {
2133 * name [0] PrintableString (SIZE(1..20)),
2134 * country [1] PrintableString (SIZE(1..20)) DEFAULT default-country,
2135 * }
2136 * === EOF ===
2137 */
2138
2139optTag:
2140 { memset(&$$, 0, sizeof($$)); }
2141 | Tag { $$ = $1; }
2142 ;
2143
2144Tag:
Lev Walkinc603f102005-01-23 09:51:44 +00002145 TagTypeValue TagPlicit {
Lev Walkinf15320b2004-06-03 03:38:44 +00002146 $$ = $1;
Lev Walkinc603f102005-01-23 09:51:44 +00002147 $$.tag_mode = $2.tag_mode;
Lev Walkinf15320b2004-06-03 03:38:44 +00002148 }
Lev Walkinc603f102005-01-23 09:51:44 +00002149 ;
2150
2151TagTypeValue:
2152 '[' TagClass TOK_number ']' {
2153 $$ = $2;
2154 $$.tag_value = $3;
2155 };
2156
2157TagClass:
2158 { $$.tag_class = TC_CONTEXT_SPECIFIC; }
2159 | TOK_UNIVERSAL { $$.tag_class = TC_UNIVERSAL; }
2160 | TOK_APPLICATION { $$.tag_class = TC_APPLICATION; }
2161 | TOK_PRIVATE { $$.tag_class = TC_PRIVATE; }
2162 ;
2163
2164TagPlicit:
2165 { $$.tag_mode = TM_DEFAULT; }
2166 | TOK_IMPLICIT { $$.tag_mode = TM_IMPLICIT; }
2167 | TOK_EXPLICIT { $$.tag_mode = TM_EXPLICIT; }
Lev Walkinf15320b2004-06-03 03:38:44 +00002168 ;
2169
2170TypeRefName:
2171 TOK_typereference {
2172 checkmem($1);
2173 $$ = $1;
2174 }
Lev Walkinf59d0752004-08-18 04:59:12 +00002175 | TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00002176 checkmem($1);
2177 $$ = $1;
2178 }
2179 ;
2180
Lev Walkinf59d0752004-08-18 04:59:12 +00002181
Lev Walkinf15320b2004-06-03 03:38:44 +00002182ObjectClassReference:
Lev Walkinf59d0752004-08-18 04:59:12 +00002183 TOK_capitalreference {
Lev Walkinf15320b2004-06-03 03:38:44 +00002184 checkmem($1);
2185 $$ = $1;
2186 }
2187 ;
2188
Lev Walkin83cac2f2004-09-22 16:03:36 +00002189optIdentifier:
2190 { $$ = 0; }
2191 | Identifier {
2192 $$ = $1;
2193 }
Lev Walkin8f294e02005-06-06 08:28:58 +00002194 ;
Lev Walkin83cac2f2004-09-22 16:03:36 +00002195
Lev Walkinf15320b2004-06-03 03:38:44 +00002196Identifier:
2197 TOK_identifier {
2198 checkmem($1);
2199 $$ = $1;
2200 }
2201 ;
2202
Lev Walkinf15320b2004-06-03 03:38:44 +00002203%%
2204
2205
2206/*
2207 * Convert Xstring ('0101'B or '5'H) to the binary vector.
2208 */
2209static asn1p_value_t *
2210_convert_bitstring2binary(char *str, int base) {
2211 asn1p_value_t *val;
2212 int slen;
2213 int memlen;
2214 int baselen;
2215 int bits;
2216 uint8_t *binary_vector;
2217 uint8_t *bv_ptr;
2218 uint8_t cur_val;
2219
2220 assert(str);
2221 assert(str[0] == '\'');
2222
2223 switch(base) {
2224 case 'B':
2225 baselen = 1;
2226 break;
2227 case 'H':
2228 baselen = 4;
2229 break;
2230 default:
2231 assert(base == 'B' || base == 'H');
2232 errno = EINVAL;
2233 return NULL;
2234 }
2235
2236 slen = strlen(str);
2237 assert(str[slen - 1] == base);
2238 assert(str[slen - 2] == '\'');
2239
2240 memlen = slen / (8 / baselen); /* Conservative estimate */
2241
2242 bv_ptr = binary_vector = malloc(memlen + 1);
2243 if(bv_ptr == NULL)
2244 /* ENOMEM */
2245 return NULL;
2246
2247 cur_val = 0;
2248 bits = 0;
2249 while(*(++str) != '\'') {
2250 switch(baselen) {
2251 case 1:
2252 switch(*str) {
2253 case '1':
2254 cur_val |= 1 << (7 - (bits % 8));
2255 case '0':
2256 break;
2257 default:
2258 assert(!"_y UNREACH1");
2259 case ' ': case '\r': case '\n':
2260 continue;
2261 }
2262 break;
2263 case 4:
2264 switch(*str) {
2265 case '0': case '1': case '2': case '3': case '4':
2266 case '5': case '6': case '7': case '8': case '9':
2267 cur_val |= (*str - '0') << (4 - (bits % 8));
2268 break;
2269 case 'A': case 'B': case 'C':
2270 case 'D': case 'E': case 'F':
2271 cur_val |= ((*str - 'A') + 10)
2272 << (4 - (bits % 8));
2273 break;
2274 default:
2275 assert(!"_y UNREACH2");
2276 case ' ': case '\r': case '\n':
2277 continue;
2278 }
2279 break;
2280 }
2281
2282 bits += baselen;
2283 if((bits % 8) == 0) {
2284 *bv_ptr++ = cur_val;
2285 cur_val = 0;
2286 }
2287 }
2288
2289 *bv_ptr = cur_val;
2290 assert((bv_ptr - binary_vector) <= memlen);
2291
2292 val = asn1p_value_frombits(binary_vector, bits, 0);
2293 if(val == NULL) {
2294 free(binary_vector);
2295 }
2296
2297 return val;
2298}
2299
Lev Walkin2e9bd5c2005-08-13 09:07:11 +00002300/*
2301 * For unnamed types (used in old X.208 compliant modules)
2302 * generate some sort of interim names, to not to force human being to fix
2303 * the specification's compliance to modern ASN.1 standards.
2304 */
2305static void
2306_fixup_anonymous_identifier(asn1p_expr_t *expr) {
2307 char *p;
2308 assert(expr->Identifier == 0);
2309
2310 /*
2311 * Try to figure out the type name
2312 * without going too much into details
2313 */
2314 expr->Identifier = ASN_EXPR_TYPE2STR(expr->expr_type);
2315 if(expr->reference && expr->reference->comp_count > 0)
2316 expr->Identifier = expr->reference->components[0].name;
2317
2318 fprintf(stderr,
2319 "WARNING: Line %d: expected lower-case member identifier, "
2320 "found an unnamed %s.\n"
2321 "WARNING: Obsolete X.208 syntax detected, "
2322 "please give the member a name.\n",
2323 yylineno, expr->Identifier ? expr->Identifier : "type");
2324
2325 if(!expr->Identifier)
2326 expr->Identifier = "unnamed";
2327 expr->Identifier = strdup(expr->Identifier);
2328 assert(expr->Identifier);
2329 /* Make a lowercase identifier from the type name */
2330 for(p = expr->Identifier; *p; p++) {
2331 switch(*p) {
2332 case 'A' ... 'Z': *p += 32; break;
2333 case ' ': *p = '_'; break;
2334 case '-': *p = '_'; break;
2335 }
2336 }
2337 fprintf(stderr, "NOTE: Assigning temporary identifier \"%s\". "
2338 "Name clash may occur later.\n",
2339 expr->Identifier);
2340}
2341
Lev Walkinf15320b2004-06-03 03:38:44 +00002342int
2343yyerror(const char *msg) {
Lev Walkin9d542d22006-03-14 16:31:37 +00002344 extern char *asn1p_text;
Lev Walkinf15320b2004-06-03 03:38:44 +00002345 fprintf(stderr,
2346 "ASN.1 grammar parse error "
2347 "near line %d (token \"%s\"): %s\n",
Lev Walkinceb20e72004-09-05 10:40:41 +00002348 yylineno, asn1p_text, msg);
Lev Walkinf15320b2004-06-03 03:38:44 +00002349 return -1;
2350}
2351