📄 asn1p_y.y
字号:
%{#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <assert.h>#include "asn1parser.h"#define YYPARSE_PARAM param#define YYERROR_VERBOSEint yylex(void);int yyerror(const char *msg);void asn1p_lexer_hack_push_opaque_state(void);void asn1p_lexer_hack_enable_with_syntax(void);void asn1p_lexer_hack_push_encoding_control(void);#define yylineno asn1p_linenoextern int asn1p_lineno;static asn1p_value_t * _convert_bitstring2binary(char *str, int base);#define checkmem(ptr) do { \ if(!(ptr)) \ return yyerror("Memory failure"); \ } while(0)#define CONSTRAINT_INSERT(root, constr_type, arg1, arg2) do { \ if(arg1->type != constr_type) { \ int __ret; \ root = asn1p_constraint_new(yylineno); \ checkmem(root); \ root->type = constr_type; \ __ret = asn1p_constraint_insert(root, \ arg1); \ checkmem(__ret == 0); \ } else { \ root = arg1; \ } \ if(arg2) { \ int __ret \ = asn1p_constraint_insert(root, arg2); \ checkmem(__ret == 0); \ } \ } while(0)%}/* * Token value definition. * a_*: ASN-specific types. * tv_*: Locally meaningful types. */%union { asn1p_t *a_grammar; asn1p_module_flags_e a_module_flags; asn1p_module_t *a_module; asn1p_expr_type_e a_type; /* ASN.1 Type */ asn1p_expr_t *a_expr; /* Constructed collection */ asn1p_constraint_t *a_constr; /* Constraint */ enum asn1p_constraint_type_e a_ctype;/* Constraint type */ asn1p_xports_t *a_xports; /* IMports/EXports */ asn1p_oid_t *a_oid; /* Object Identifier */ asn1p_oid_arc_t a_oid_arc; /* Single OID's arc */ struct asn1p_type_tag_s a_tag; /* A tag */ asn1p_ref_t *a_ref; /* Reference to custom type */ asn1p_wsyntx_t *a_wsynt; /* WITH SYNTAX contents */ asn1p_wsyntx_chunk_t *a_wchunk; /* WITH SYNTAX chunk */ struct asn1p_ref_component_s a_refcomp; /* Component of a reference */ asn1p_value_t *a_value; /* Number, DefinedValue, etc */ struct asn1p_param_s a_parg; /* A parameter argument */ asn1p_paramlist_t *a_plist; /* A pargs list */ struct asn1p_expr_marker_s a_marker; /* OPTIONAL/DEFAULT */ enum asn1p_constr_pres_e a_pres; /* PRESENT/ABSENT/OPTIONAL */ asn1c_integer_t a_int; char *tv_str; struct { char *buf; int len; } tv_opaque; struct { char *name; struct asn1p_type_tag_s tag; } tv_nametag;};/* * Token types returned by scanner. */%token TOK_PPEQ /* "::=", Pseudo Pascal EQuality */%token <tv_opaque> TOK_opaque /* opaque data (driven from .y) */%token <tv_str> TOK_bstring%token <tv_opaque> TOK_cstring%token <tv_str> TOK_hstring%token <tv_str> TOK_identifier%token <a_int> TOK_number%token <a_int> TOK_number_negative%token <tv_str> TOK_typereference%token <tv_str> TOK_capitalreference /* "CLASS1" */%token <tv_str> TOK_typefieldreference /* "&Pork" */%token <tv_str> TOK_valuefieldreference /* "&id" *//* * Token types representing ASN.1 standard keywords. */%token TOK_ABSENT%token TOK_ABSTRACT_SYNTAX%token TOK_ALL%token TOK_ANY%token TOK_APPLICATION%token TOK_AUTOMATIC%token TOK_BEGIN%token TOK_BIT%token TOK_BMPString%token TOK_BOOLEAN%token TOK_BY%token TOK_CHARACTER%token TOK_CHOICE%token TOK_CLASS%token TOK_COMPONENT%token TOK_COMPONENTS%token TOK_CONSTRAINED%token TOK_CONTAINING%token TOK_DEFAULT%token TOK_DEFINITIONS%token TOK_DEFINED%token TOK_EMBEDDED%token TOK_ENCODED%token TOK_ENCODING_CONTROL%token TOK_END%token TOK_ENUMERATED%token TOK_EXPLICIT%token TOK_EXPORTS%token TOK_EXTENSIBILITY%token TOK_EXTERNAL%token TOK_FALSE%token TOK_FROM%token TOK_GeneralizedTime%token TOK_GeneralString%token TOK_GraphicString%token TOK_IA5String%token TOK_IDENTIFIER%token TOK_IMPLICIT%token TOK_IMPLIED%token TOK_IMPORTS%token TOK_INCLUDES%token TOK_INSTANCE%token TOK_INSTRUCTIONS%token TOK_INTEGER%token TOK_ISO646String%token TOK_MAX%token TOK_MIN%token TOK_MINUS_INFINITY%token TOK_NULL%token TOK_NumericString%token TOK_OBJECT%token TOK_ObjectDescriptor%token TOK_OCTET%token TOK_OF%token TOK_OPTIONAL%token TOK_PATTERN%token TOK_PDV%token TOK_PLUS_INFINITY%token TOK_PRESENT%token TOK_PrintableString%token TOK_PRIVATE%token TOK_REAL%token TOK_RELATIVE_OID%token TOK_SEQUENCE%token TOK_SET%token TOK_SIZE%token TOK_STRING%token TOK_SYNTAX%token TOK_T61String%token TOK_TAGS%token TOK_TeletexString%token TOK_TRUE%token TOK_TYPE_IDENTIFIER%token TOK_UNIQUE%token TOK_UNIVERSAL%token TOK_UniversalString%token TOK_UTCTime%token TOK_UTF8String%token TOK_VideotexString%token TOK_VisibleString%token TOK_WITH%left TOK_EXCEPT%left '^' TOK_INTERSECTION%left '|' TOK_UNION/* Misc tags */%token TOK_TwoDots /* .. */%token TOK_ThreeDots /* ... *//* * Types defined herein. */%type <a_grammar> ModuleList%type <a_module> ModuleSpecification%type <a_module> ModuleSpecificationBody%type <a_module> ModuleSpecificationElement%type <a_module> optModuleSpecificationBody /* Optional */%type <a_module_flags> optModuleSpecificationFlags%type <a_module_flags> ModuleSpecificationFlags /* Set of FL */%type <a_module_flags> ModuleSpecificationFlag /* Single FL */%type <a_module> ImportsDefinition%type <a_module> ImportsBundleSet%type <a_xports> ImportsBundle%type <a_xports> ImportsList%type <a_xports> ExportsDefinition%type <a_xports> ExportsBody%type <a_expr> ImportsElement%type <a_expr> ExportsElement%type <a_expr> ExtensionAndException%type <a_expr> TypeDeclaration%type <a_ref> ComplexTypeReference%type <a_ref> ComplexTypeReferenceAmpList%type <a_refcomp> ComplexTypeReferenceElement%type <a_refcomp> ClassFieldIdentifier%type <a_refcomp> ClassFieldName%type <a_expr> ClassFieldList%type <a_expr> ClassField%type <a_expr> ClassDeclaration%type <a_expr> Type%type <a_expr> DataTypeReference /* Type1 ::= Type2 */%type <a_expr> DefinedTypeRef%type <a_expr> ValueSetDefinition /* Val INTEGER ::= {1|2} */%type <a_expr> ValueDefinition /* val INTEGER ::= 1*/%type <a_expr> optValueSetBody%type <a_expr> ValueSetBody%type <a_expr> ValueSetElement%type <a_value> Value%type <a_value> DefinedValue%type <a_value> SignedNumber%type <a_expr> optComponentTypeLists%type <a_expr> ComponentTypeLists%type <a_expr> ComponentType%type <a_expr> AlternativeTypeLists%type <a_expr> AlternativeType//%type <a_expr> optUniverationDefinition%type <a_expr> UniverationDefinition%type <a_expr> UniverationList%type <a_expr> UniverationElement%type <tv_str> TypeRefName%type <tv_str> ObjectClassReference%type <tv_str> Identifier%type <tv_str> optIdentifier%type <a_parg> ParameterArgumentName%type <a_plist> ParameterArgumentList%type <a_expr> ActualParameter%type <a_expr> ActualParameterList%type <a_oid> ObjectIdentifier /* OID */%type <a_oid> optObjectIdentifier /* Optional OID */%type <a_oid> ObjectIdentifierBody%type <a_oid_arc> ObjectIdentifierElement%type <a_expr> BasicType%type <a_type> BasicTypeId%type <a_type> BasicTypeId_UniverationCompatible%type <a_type> BasicString%type <tv_opaque> Opaque//%type <tv_opaque> StringValue%type <a_tag> Tag /* [UNIVERSAL 0] IMPLICIT */%type <a_tag> TagClass TagTypeValue TagPlicit%type <a_tag> optTag /* [UNIVERSAL 0] IMPLICIT */%type <a_constr> optConstraints%type <a_constr> Constraints%type <a_constr> SetOfConstraints%type <a_constr> ElementSetSpecs /* 1..2,...,3 */%type <a_constr> ElementSetSpec /* 1..2,...,3 */%type <a_constr> ConstraintSubtypeElement /* 1..2 */%type <a_constr> SimpleTableConstraint%type <a_constr> TableConstraint%type <a_constr> WithComponents%type <a_constr> WithComponentsList%type <a_constr> WithComponentsElement%type <a_constr> ComponentRelationConstraint%type <a_constr> AtNotationList%type <a_ref> AtNotationElement%type <a_value> ConstraintValue%type <a_ctype> ConstraintSpec%type <a_ctype> ConstraintRangeSpec%type <a_wsynt> optWithSyntax%type <a_wsynt> WithSyntax%type <a_wsynt> WithSyntaxFormat%type <a_wchunk> WithSyntaxFormatToken%type <a_marker> optMarker Marker%type <a_int> optUnique%type <a_pres> optPresenceConstraint PresenceConstraint%type <tv_str> ComponentIdList%%ParsedGrammar: ModuleList { *(void **)param = $1; } ;ModuleList: ModuleSpecification { $$ = asn1p_new(); checkmem($$); TQ_ADD(&($$->modules), $1, mod_next); } | ModuleList ModuleSpecification { $$ = $1; TQ_ADD(&($$->modules), $2, mod_next); } ;/* * ASN module definition. * === EXAMPLE === * MySyntax DEFINITIONS AUTOMATIC TAGS ::= * BEGIN * ... * END * === EOF === */ModuleSpecification: TypeRefName optObjectIdentifier TOK_DEFINITIONS optModuleSpecificationFlags TOK_PPEQ TOK_BEGIN optModuleSpecificationBody TOK_END { if($7) { $$ = $7; } else { /* There's a chance that a module is just plain empty */ $$ = asn1p_module_new(); } checkmem($$); $$->Identifier = $1; $$->module_oid = $2; $$->module_flags = $4; } ;/* * Object Identifier Definition * { iso member-body(2) 3 } */optObjectIdentifier: { $$ = 0; } | ObjectIdentifier { $$ = $1; } ; ObjectIdentifier: '{' ObjectIdentifierBody '}' { $$ = $2; } | '{' '}' { $$ = 0; } ;ObjectIdentifierBody: ObjectIdentifierElement { $$ = asn1p_oid_new(); asn1p_oid_add_arc($$, &$1); if($1.name) free($1.name); } | ObjectIdentifierBody ObjectIdentifierElement { $$ = $1; asn1p_oid_add_arc($$, &$2); if($2.name) free($2.name); } ;ObjectIdentifierElement: Identifier { /* iso */ $$.name = $1; $$.number = -1; } | Identifier '(' TOK_number ')' { /* iso(1) */ $$.name = $1; $$.number = $3; } | TOK_number { /* 1 */ $$.name = 0; $$.number = $1; } ; /* * Optional module flags. */optModuleSpecificationFlags: { $$ = MSF_NOFLAGS; } | ModuleSpecificationFlags { $$ = $1; } ;/* * Module flags. */ModuleSpecificationFlags: ModuleSpecificationFlag { $$ = $1; } | ModuleSpecificationFlags ModuleSpecificationFlag { $$ = $1 | $2; } ;/* * Single module flag. */ModuleSpecificationFlag: TOK_EXPLICIT TOK_TAGS { $$ = MSF_EXPLICIT_TAGS; } | TOK_IMPLICIT TOK_TAGS { $$ = MSF_IMPLICIT_TAGS; } | TOK_AUTOMATIC TOK_TAGS { $$ = MSF_AUTOMATIC_TAGS; } | TOK_EXTENSIBILITY TOK_IMPLIED { $$ = MSF_EXTENSIBILITY_IMPLIED; } /* EncodingReferenceDefault */ | TOK_capitalreference TOK_INSTRUCTIONS { /* X.680Amd1 specifies TAG and XER */ if(strcmp($1, "TAG") == 0) { $$ = MSF_TAG_INSTRUCTIONS; } else if(strcmp($1, "XER") == 0) { $$ = MSF_XER_INSTRUCTIONS; } else { fprintf(stderr, "WARNING: %s INSTRUCTIONS at line %d: " "Unrecognized encoding reference\n", $1, yylineno); $$ = MSF_unk_INSTRUCTIONS; } free($1); } ;/* * Optional module body. */optModuleSpecificationBody: { $$ = 0; } | ModuleSpecificationBody { $$ = $1; } ;/* * ASN.1 Module body. */ModuleSpecificationBody: ModuleSpecificationElement { $$ = $1; } | ModuleSpecificationBody ModuleSpecificationElement { $$ = $1; /* Behave well when one of them is skipped. */ if(!($1)) { if($2) $$ = $2; break; }#ifdef MY_IMPORT#error MY_IMPORT DEFINED ELSEWHERE!#endif#define MY_IMPORT(foo,field) do { \ while(TQ_FIRST(&($2->foo))) { \ TQ_ADD(&($$->foo), \ TQ_REMOVE(&($2->foo), field), \ field); \ } \ assert(TQ_FIRST(&($2->foo)) == 0); \ } while(0) MY_IMPORT(imports, xp_next); MY_IMPORT(exports, xp_next); MY_IMPORT(members, next);#undef MY_IMPORT } ;/* * One of the elements of ASN.1 module specification. */ModuleSpecificationElement: ImportsDefinition { $$ = $1; } | ExportsDefinition { $$ = asn1p_module_new(); checkmem($$); if($1) { TQ_ADD(&($$->exports), $1, xp_next); } else { /* "EXPORTS ALL;" ? */ } } | DataTypeReference { $$ = asn1p_module_new(); checkmem($$); assert($1->expr_type != A1TC_INVALID); assert($1->meta_type != AMT_INVALID); TQ_ADD(&($$->members), $1, next); } | ValueDefinition { $$ = asn1p_module_new(); checkmem($$); assert($1->expr_type != A1TC_INVALID); assert($1->meta_type != AMT_INVALID); TQ_ADD(&($$->members), $1, next); } /* * Value set definition * === EXAMPLE === * EvenNumbers INTEGER ::= { 2 | 4 | 6 | 8 } * === EOF === */ | ValueSetDefinition { $$ = asn1p_module_new(); checkmem($$); assert($1->expr_type != A1TC_INVALID); assert($1->meta_type != AMT_INVALID); TQ_ADD(&($$->members), $1, next); } | TOK_ENCODING_CONTROL TOK_capitalreference { asn1p_lexer_hack_push_encoding_control(); } { fprintf(stderr, "WARNING: ENCODING-CONTROL %s " "specification at line %d ignored\n", $2, yylineno); free($2); $$ = 0; } /* * Erroneous attemps */ | BasicString { return yyerror( "Attempt to redefine a standard basic type, " "use -ftypesXY to switch back " "to older version of ASN.1 standard"); } ;/* * === EXAMPLE === * IMPORTS Type1, value FROM Module { iso standard(0) } ; * === EOF === */ImportsDefinition: TOK_IMPORTS ImportsBundleSet ';' { $$ = $2; } /* * Some error cases. */ | TOK_IMPORTS TOK_FROM /* ... */ { return yyerror("Empty IMPORTS list"); } ;ImportsBundleSet: ImportsBundle { $$ = asn1p_module_new(); checkmem($$); TQ_ADD(&($$->imports), $1, xp_next); } | ImportsBundleSet ImportsBundle { $$ = $1; TQ_ADD(&($$->imports), $2, xp_next); } ;ImportsBundle: ImportsList TOK_FROM TypeRefName optObjectIdentifier { $$ = $1; $$->from = $3; $$->from_oid = $4; checkmem($$); } ;ImportsList: ImportsElement { $$ = asn1p_xports_new(); checkmem($$); TQ_ADD(&($$->members), $1, next); } | ImportsList ',' ImportsElement { $$ = $1; TQ_ADD(&($$->members), $3, next); } ;ImportsElement: TypeRefName { $$ = asn1p_expr_new(yylineno); checkmem($$); $$->Identifier = $1; $$->expr_type = A1TC_REFERENCE; } | TypeRefName '{' '}' { /* Completely equivalent to above */ $$ = asn1p_expr_new(yylineno); checkmem($$); $$->Identifier = $1; $$->expr_type = A1TC_REFERENCE; } | Identifier { $$ = asn1p_expr_new(yylineno); checkmem($$); $$->Identifier = $1; $$->expr_type = A1TC_REFERENCE; } ;ExportsDefinition: TOK_EXPORTS ExportsBody ';' { $$ = $2; } | TOK_EXPORTS TOK_ALL ';' { $$ = 0; } | TOK_EXPORTS ';' { /* Empty EXPORTS clause effectively prohibits export. */ $$ = asn1p_xports_new(); checkmem($$); } ;ExportsBody: ExportsElement { $$ = asn1p_xports_new(); assert($$); TQ_ADD(&($$->members), $1, next); } | ExportsBody ',' ExportsElement { $$ = $1; TQ_ADD(&($$->members), $3, next); } ;ExportsElement: TypeRefName { $$ = asn1p_expr_new(yylineno); checkmem($$); $$->Identifier = $1; $$->expr_type = A1TC_EXPORTVAR; } | TypeRefName '{' '}' { $$ = asn1p_expr_new(yylineno); checkmem($$); $$->Identifier = $1; $$->expr_type = A1TC_EXPORTVAR; } | Identifier { $$ = asn1p_expr_new(yylineno); checkmem($$); $$->Identifier = $1; $$->expr_type = A1TC_EXPORTVAR; } ;ValueSetDefinition: TypeRefName DefinedTypeRef TOK_PPEQ '{' optValueSetBody '}' { $$ = $2; assert($$->Identifier == 0); $$->Identifier = $1; $$->meta_type = AMT_VALUESET; // take care of optValueSetBody } ;DefinedTypeRef: ComplexTypeReference { $$ = asn1p_expr_new(yylineno); checkmem($$); $$->reference = $1; $$->expr_type = A1TC_REFERENCE; $$->meta_type = AMT_TYPEREF; } | BasicTypeId { $$ = asn1p_expr_new(yylineno); checkmem($$); $$->expr_type = $1; $$->meta_type = AMT_TYPE; } ;optValueSetBody: { } | ValueSetBody { } ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -