1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
13 * Szabo, Janos Zoltan – initial implementation
14 * Zalanyi, Balazs Andor
16 ******************************************************************************/
17 /* Parser for "extension" attributes of functions, external functions and
18 * port types related to message encoding. */
22 #include "../../common/dbgnew.hh"
23 #include "../string.hh"
24 #include "../Identifier.hh"
25 #include "../Setting.hh"
27 #include "AST_ttcn3.hh"
28 #include "Attributes.hh"
29 #include "Ttcnstuff.hh"
30 #include "../stack.hh"
33 using namespace Common;
35 /* Various C macros */
37 #define YYERROR_VERBOSE
38 #define yytext coding_attrib_text
40 /* C/C++ declarations */
44 extern const char *coding_attrib_infile;
46 /* Init the lexer. Located in coding_attrib_la.l */
47 extern void init_coding_attrib_lex(const AttributeSpec& attrib);
48 extern void cleanup_coding_attrib_lex();
50 ExtensionAttributes *extatrs = 0;
52 static void yyerror(const char *str);
56 /*********************************************************************
58 *********************************************************************/
60 %name-prefix="coding_attrib_"
61 %output="coding_attrib_p.cc"
64 /*********************************************************************
66 *********************************************************************/
69 ErrorBehaviorList *errorbehaviorlist;
70 ErrorBehaviorSetting *errorbehaviorsetting;
71 PrintingType *printing;
73 Ttcn::Reference *reference;
77 TypeMapping *typemapping;
78 TypeMappings *typemappings;
79 TypeMappingTarget *typemappingtarget;
80 TypeMappingTargets *typemappingtargets;
83 Type::MessageEncodingType_t encoding_type;
84 string *encoding_options;
88 Type::MessageEncodingType_t encoding_type;
89 string *encoding_options;
90 ErrorBehaviorList *eb_list;
94 TypeMappings *in_mappings, *out_mappings;
98 Ttcn::Reference *port_type_ref;
99 TypeMappings *in_mappings, *out_mappings;
102 Def_Function_Base::prototype_t prototype;
103 Type::typetype_t typetype;
104 Type::MessageEncodingType_t encoding_type;
105 ExtensionAttributes *extattrs;
106 ExtensionAttribute *extattr;
110 /*********************************************************************
111 * Tokens with semantic value
112 *********************************************************************/
114 %token <prototype> PrototypeSetting
115 %token <encoding_type> EncodingType
116 %token <str> EncodingOption
117 %token <str> ErrorBehaviorString
118 %token <id> IDentifier "Identifier"
119 %token <number> Number
120 %token <str> CustomEncoding
122 /*********************************************************************
123 * Tokens without semantic value
124 *********************************************************************/
126 /* TTCN-3 keywords */
128 %token AddressKeyword "address"
129 %token AnyTypeKeyword "anytype"
130 %token BitStringKeyword "bitstring"
131 %token BooleanKeyword "boolean"
132 %token CharStringKeyword "charstring"
133 %token DefaultKeyword "default"
134 %token EncodeKeyword "encode"
135 %token FloatKeyword "float"
136 %token FunctionKeyword "function"
137 %token HexStringKeyword "hexstring"
138 %token InKeyword "in"
139 %token IntegerKeyword "integer"
140 %token ObjectIdentifierKeyword "objid"
141 %token OctetStringKeyword "octetstring"
142 %token OutKeyword "out"
143 %token UniversalKeyword "universal"
144 %token VerdictTypeKeyword "verdicttype"
145 %token VersionKeyword "version"
146 %token RequiresKeyword "requires"
147 %token ReqTitanKeyword "requiresTitan"
149 /* Non-standard keywords used by the attributes with context-sensitive
152 %token DecodeKeyword "decode"
153 %token DiscardKeyword "discard"
154 %token ErrorBehaviorKeyword "errorbehavior"
155 %token InternalKeyword "internal"
156 %token PrototypeKeyword "prototype"
157 %token ProviderKeyword "provider"
158 %token SimpleKeyword "simple"
159 %token UserKeyword "user"
160 %token TransparentKeyword "transparent"
161 %token PrintingKeyword "printing"
163 %token CompactKeyword "compact"
164 %token PrettyKeyword "pretty"
166 %token RedirectSymbol "->"
173 /*********************************************************************
174 * Semantic types of nonterminals
175 *********************************************************************/
177 %type <errorbehaviorsetting> ErrorBehaviorSetting
178 %type <errorbehaviorlist> ErrorBehaviorSettingList ErrorBehaviorAttribute
179 %type <printing> PrintingAttribute PrintingType
180 %type <reference> FunctionMapping FunctionReference PortTypeReference
182 %type <str> EncodingOptions
184 %type <types> TypeList
185 %type <typemapping> TypeMapping
186 %type <typemappings> TypeMappingList
187 %type <typemappingtarget> TypeMappingTarget
188 %type <typemappingtargets> TypeMappingTargetList
190 %type <encdec_attribute> DecodeAttribute EncDecAttributeBody EncodeAttribute
191 %type <encdec_mapping> DecodeMapping EncodeMapping
192 %type <in_out_mappings> InOutTypeMapping InOutTypeMappingList
193 %type <user_attribute> UserAttribute
195 %type <prototype> PrototypeAttribute
196 %type <typetype> PredefinedType
198 %type <extattr> ExtensionAttribute ExternalFunctionAttribute
199 PortTypeAttribute AnyTypeAttribute EncDecValueAttribute
200 VersionAttribute RequiresAttribute TransparentAttribute
202 %type <extattrs> ExtensionAttributes
204 /*********************************************************************
206 *********************************************************************/
208 %destructor { delete $$; }
211 ErrorBehaviorAttribute
213 ErrorBehaviorSettingList
225 TypeMappingTargetList
228 ExternalFunctionAttribute
238 %destructor { delete $$.encoding_options; }
244 delete $$.encoding_options;
251 delete $$.in_mappings;
252 delete $$.out_mappings;
258 delete $$.port_type_ref;
259 delete $$.in_mappings;
260 delete $$.out_mappings;
268 /*********************************************************************
270 *********************************************************************/
275 if (extatrs == 0) extatrs = $1;
286 $$ = new ExtensionAttributes;
288 | ExtensionAttributes ExtensionAttribute
291 if ($2 != NULL) $$->add($2);
296 ExternalFunctionAttribute
299 | EncDecValueAttribute
302 | TransparentAttribute
306 VersionKeyword IDentifier
308 $$ = new ExtensionAttribute(NULL, 0, 0, 0, $2); // VERSION
309 $$->set_location(coding_attrib_infile, @$);
310 if ($$->get_type() == ExtensionAttribute::NONE) {
311 $$->error("Incorrect version data '%s'", $2->get_name().c_str());
317 | VersionKeyword '<' IDentifier '>'
319 $$ = new ExtensionAttribute(NULL, 0, 0, 0, $3, ExtensionAttribute::VERSION_TEMPLATE);
320 $$->set_location(coding_attrib_infile, @$);
321 if ($$->get_type() == ExtensionAttribute::NONE) {
322 $$->error("Incorrect version template '<%s>'", $3->get_name().c_str());
328 | VersionKeyword IDentifier Number Number IDentifier
329 { // version CNL 113 200 R2D2
330 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, 0, $5); // VERSION
331 $$->set_location(coding_attrib_infile, @$);
332 if ($$->get_type() == ExtensionAttribute::NONE) {
333 $$->error("Incorrect version data '%s %d %d %s'",
334 $2->get_dispname().c_str(), $3, $4, $5->get_dispname().c_str());
341 | VersionKeyword IDentifier Number Number '<' IDentifier '>'
342 { // version CNL 113 200 <RnXnn>
343 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, 0, $6, ExtensionAttribute::VERSION_TEMPLATE); // VERSION
344 $$->set_location(coding_attrib_infile, @$);
345 if ($$->get_type() == ExtensionAttribute::NONE) {
346 $$->error("Incorrect version data '%s %d %d <%s>'",
347 $2->get_dispname().c_str(), $3, $4, $6->get_dispname().c_str());
354 | VersionKeyword IDentifier Number Number '/' Number IDentifier
355 { // version CNL 113 200 / 1 R2D2
356 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, $6, $7); // VERSION
357 $$->set_location(coding_attrib_infile, @$);
358 if ($$->get_type() == ExtensionAttribute::NONE) {
359 $$->error("Incorrect version data '%s %d %d / %d %s'",
360 $2->get_dispname().c_str(), $3, $4, $6, $7->get_dispname().c_str());
367 | VersionKeyword IDentifier Number Number '/' Number '<' IDentifier '>'
368 { // version CNL 113 200 / 1 <RnXnn>
369 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, $6, $8, ExtensionAttribute::VERSION_TEMPLATE); // VERSION
370 $$->set_location(coding_attrib_infile, @$);
371 if ($$->get_type() == ExtensionAttribute::NONE) {
372 $$->error("Incorrect version data '%s %d %d / %d <%s>'",
373 $2->get_dispname().c_str(), $3, $4, $6, $8->get_dispname().c_str());
383 RequiresKeyword IDentifier IDentifier
385 $$ = new ExtensionAttribute($2, NULL, 0, 0, 0, $3); // REQUIRES
386 $$->set_location(coding_attrib_infile, @$);
387 if ($$->get_type() == ExtensionAttribute::NONE) {
388 /* parsing the version has failed */
389 $$->error("Incorrect version data '%s'", $3->get_name().c_str());
396 | RequiresKeyword IDentifier IDentifier Number Number IDentifier
397 { // module CNL xxx xxx R1A
398 $$ = new ExtensionAttribute($2, $3->get_dispname().c_str(), $4, $5, 0, $6); // REQUIRES
399 $$->set_location(coding_attrib_infile, @$);
400 if ($$->get_type() == ExtensionAttribute::NONE) {
401 $$->error("Incorrect version data '%s %d %d %s'",
402 $3->get_dispname().c_str(), $4, $5, $6->get_dispname().c_str());
410 | RequiresKeyword IDentifier IDentifier Number Number '/' Number IDentifier
411 { // module CNL xxx xxx / 1 R9A
412 $$ = new ExtensionAttribute($2, $3->get_dispname().c_str(), $4, $5, $7, $8); // REQUIRES
413 $$->set_location(coding_attrib_infile, @$);
414 if ($$->get_type() == ExtensionAttribute::NONE) {
415 $$->error("Incorrect version data '%s %d %d / %d %s'",
416 $3->get_dispname().c_str(), $4, $5, $7, $8->get_dispname().c_str());
424 | ReqTitanKeyword IDentifier
426 $$ = new ExtensionAttribute(NULL, 0, 0, 0, $2, ExtensionAttribute::REQ_TITAN);
427 $$->set_location(coding_attrib_infile, @$);
428 if ($$->get_type() == ExtensionAttribute::NONE) {
429 /* parsing the version has failed */
430 $$->error("Incorrect version data '%s'", $2->get_name().c_str());
436 | ReqTitanKeyword IDentifier Number Number IDentifier
438 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, 0, $5, ExtensionAttribute::REQ_TITAN);
439 $$->set_location(coding_attrib_infile, @$);
440 if ($$->get_type() == ExtensionAttribute::NONE) {
441 $$->error("Incorrect version data '%s %d %d %s'",
442 $2->get_dispname().c_str(), $3, $4, $5->get_dispname().c_str());
449 | ReqTitanKeyword IDentifier Number Number '/' Number IDentifier
450 { // CRL 113 200 / 2 R1A
451 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, $6, $7, ExtensionAttribute::REQ_TITAN);
452 $$->set_location(coding_attrib_infile, @$);
453 if ($$->get_type() == ExtensionAttribute::NONE) {
454 $$->error("Incorrect version data '%s %d %d / %d %s'",
455 $2->get_dispname().c_str(), $3, $4, $6, $7->get_dispname().c_str());
464 TransparentAttribute: TransparentKeyword
466 $$ = new ExtensionAttribute(ExtensionAttribute::TRANSPARENT);
467 $$->set_location(coding_attrib_infile, @$);
471 EncDecValueAttribute:
474 $$ = new ExtensionAttribute($1.in_mappings, $1.out_mappings); // ENCDECVALUE
475 $$->set_location(coding_attrib_infile, @$);
479 /* FunctionAttribute is covered by the PrototypeAttribute branch */
480 ExternalFunctionAttribute:
483 $$ = new ExtensionAttribute($1); // PROTOTYPE
484 $$->set_location(coding_attrib_infile, @$);
488 $$ = new ExtensionAttribute(ExtensionAttribute::ENCODE,
489 $1.encoding_type, $1.encoding_options);
490 $$->set_location(coding_attrib_infile, @$);
494 $$ = new ExtensionAttribute(ExtensionAttribute::DECODE,
495 $1.encoding_type, $1.encoding_options);
496 $$->set_location(coding_attrib_infile, @$);
498 | ErrorBehaviorAttribute
500 $$ = new ExtensionAttribute($1); // ERRORBEHAVIOR
501 $$->set_location(coding_attrib_infile, @$);
505 $$ = new ExtensionAttribute($1); // PRINTING
506 $$->set_location(coding_attrib_infile, @$);
513 $$ = new ExtensionAttribute(PortTypeBody::TP_INTERNAL); // PORT_API
514 $$->set_location(coding_attrib_infile, @$);
518 $$ = new ExtensionAttribute(PortTypeBody::TP_ADDRESS); // PORT_API
519 $$->set_location(coding_attrib_infile, @$);
523 $$ = new ExtensionAttribute(ExtensionAttribute::PORT_TYPE_PROVIDER);
524 $$->set_location(coding_attrib_infile, @$);
528 $$ = new ExtensionAttribute($1.port_type_ref,
529 $1.in_mappings, $1.out_mappings); // PORT_TYPE_USER
530 $$->set_location(coding_attrib_infile, @$);
535 PrototypeKeyword '(' PrototypeSetting ')' { $$ = $3; }
539 EncodeKeyword EncDecAttributeBody { $$ = $2; }
543 DecodeKeyword EncDecAttributeBody { $$ = $2; }
549 $$.encoding_type = $2;
550 $$.encoding_options = 0;
552 | '(' EncodingType ':' EncodingOptions ')'
554 $$.encoding_type = $2;
555 $$.encoding_options = $4;
557 | '(' CustomEncoding ')'
559 $$.encoding_type = Type::CT_CUSTOM;
560 $$.encoding_options = $2;
565 EncodingOption { $$ = $1; }
566 | EncodingOptions EncodingOption
575 ErrorBehaviorAttribute:
576 ErrorBehaviorKeyword '(' ErrorBehaviorSettingList ')'
579 $$->set_location(coding_attrib_infile, @$);
583 ErrorBehaviorSettingList:
586 $$ = new ErrorBehaviorList();
589 | ErrorBehaviorSettingList ',' ErrorBehaviorSetting
596 ErrorBehaviorSetting:
597 ErrorBehaviorString ':' ErrorBehaviorString
599 $$ = new ErrorBehaviorSetting(*$1, *$3);
600 $$->set_location(coding_attrib_infile, @$);
607 PrintingKeyword '(' PrintingType ')'
610 $$->set_location(coding_attrib_infile, @$);
617 $$ = new PrintingType();
618 $$->set_printing(PrintingType::PT_COMPACT);
622 $$ = new PrintingType();
623 $$->set_printing(PrintingType::PT_PRETTY);
628 UserKeyword PortTypeReference InOutTypeMappingList
630 $$.port_type_ref = $2;
631 $$.in_mappings = $3.in_mappings;
632 $$.out_mappings = $3.out_mappings;
639 $$ = new Ttcn::Reference($1);
640 $$->set_location(coding_attrib_infile, @$);
642 | IDentifier '.' IDentifier
644 $$ = new Ttcn::Reference($1, $3);
645 $$->set_location(coding_attrib_infile, @$);
649 InOutTypeMappingList:
650 InOutTypeMapping { $$ = $1; }
651 | InOutTypeMappingList InOutTypeMapping
653 if ($1.in_mappings) {
654 $$.in_mappings = $1.in_mappings;
655 if ($2.in_mappings) {
656 $$.in_mappings->steal_mappings($2.in_mappings);
657 delete $2.in_mappings;
659 } else $$.in_mappings = $2.in_mappings;
660 if ($1.out_mappings) {
661 $$.out_mappings = $1.out_mappings;
662 if ($2.out_mappings) {
663 $$.out_mappings->steal_mappings($2.out_mappings);
664 delete $2.out_mappings;
666 } else $$.out_mappings = $2.out_mappings;
671 InKeyword '(' TypeMappingList ')'
674 $$.in_mappings->set_location(coding_attrib_infile, @$);
677 | OutKeyword '(' TypeMappingList ')'
680 $$.out_mappings = $3;
681 $$.out_mappings->set_location(coding_attrib_infile, @$);
688 $$ = new TypeMappings();
691 | TypeMappingList ';' TypeMapping
699 Type RedirectSymbol TypeMappingTargetList
701 $$ = new TypeMapping($1, $3);
702 $$->set_location(coding_attrib_infile, @$);
706 TypeMappingTargetList:
709 $$ = new TypeMappingTargets();
712 | TypeMappingTargetList ',' TypeMappingTarget
720 Type ':' SimpleKeyword
722 $$ = new TypeMappingTarget($1, TypeMappingTarget::TM_SIMPLE);
723 $$->set_location(coding_attrib_infile, @$);
725 | '-' ':' DiscardKeyword
727 $$ = new TypeMappingTarget(0, TypeMappingTarget::TM_DISCARD);
728 $$->set_location(coding_attrib_infile, @$);
730 | Type ':' FunctionMapping
732 $$ = new TypeMappingTarget($1, TypeMappingTarget::TM_FUNCTION, $3);
733 $$->set_location(coding_attrib_infile, @$);
735 | Type ':' EncodeMapping
737 $$ = new TypeMappingTarget($1, TypeMappingTarget::TM_ENCODE,
738 $3.encoding_type, $3.encoding_options, $3.eb_list);
739 $$->set_location(coding_attrib_infile, @$);
741 | Type ':' DecodeMapping
743 $$ = new TypeMappingTarget($1, TypeMappingTarget::TM_DECODE,
744 $3.encoding_type, $3.encoding_options, $3.eb_list);
745 $$->set_location(coding_attrib_infile, @$);
750 FunctionKeyword '(' FunctionReference ')' { $$ = $3; }
756 $$ = new Ttcn::Reference($1);
757 $$->set_location(coding_attrib_infile, @$);
759 | IDentifier '.' IDentifier
761 $$ = new Ttcn::Reference($1, $3);
762 $$->set_location(coding_attrib_infile, @$);
769 $$.encoding_type = $1.encoding_type;
770 $$.encoding_options = $1.encoding_options;
773 | EncodeAttribute ErrorBehaviorAttribute
775 $$.encoding_type = $1.encoding_type;
776 $$.encoding_options = $1.encoding_options;
784 $$.encoding_type = $1.encoding_type;
785 $$.encoding_options = $1.encoding_options;
788 | DecodeAttribute ErrorBehaviorAttribute
790 $$.encoding_type = $1.encoding_type;
791 $$.encoding_options = $1.encoding_options;
800 $$->set_location(coding_attrib_infile, @$);
804 $$ = new Type(Type::T_REFD, $1);
805 $$->set_location(coding_attrib_infile, @$);
809 PredefinedType: /* typetype_t */
810 BitStringKeyword { $$ = Type::T_BSTR; }
811 | BooleanKeyword { $$ = Type::T_BOOL; }
812 | CharStringKeyword { $$ = Type::T_CSTR; }
813 | UniversalKeyword CharStringKeyword { $$ = Type::T_USTR; }
814 | IntegerKeyword { $$ = Type::T_INT; }
815 | OctetStringKeyword { $$ = Type::T_OSTR; }
816 | HexStringKeyword { $$ = Type::T_HSTR; }
817 | VerdictTypeKeyword { $$ = Type::T_VERDICT; }
818 | FloatKeyword { $$ = Type::T_REAL; }
819 | AddressKeyword { $$ = Type::T_ADDRESS; }
820 | DefaultKeyword { $$ = Type::T_DEFAULT; }
823 Location loc(coding_attrib_infile, @$);
824 loc.error("Type `anytype' as a field of `anytype' is not supported");
827 | ObjectIdentifierKeyword { $$ = Type::T_OID; }
830 ReferencedType: /* a Reference* */
833 $$ = new Ttcn::Reference($1);
834 $$->set_location(coding_attrib_infile, @$);
836 | IDentifier '.' IDentifier
838 $$ = new Ttcn::Reference($1, $3);
839 $$->set_location(coding_attrib_infile, @$);
845 AnyTypeKeyword TypeList
847 $$ = new ExtensionAttribute($2); // ANYTYPELIST
848 $$->set_location(coding_attrib_infile, @$);
857 $$->set_location(coding_attrib_infile, @$);
863 $$->set_location(coding_attrib_infile, @$);
869 static void yyerror(const char *str)
871 Location loc(coding_attrib_infile, yylloc);
873 // the most recently parsed token is known
874 loc.error("at or before token `%s': %s", yytext, str);
876 // the most recently parsed token is unknown
877 loc.error("%s", str);
881 /** Parse all extension attributes in a "with" statement */
882 ExtensionAttributes * parse_extattributes(WithAttribPath *w_attrib_path)
885 if (!w_attrib_path) FATAL_ERROR("parse_extattributes(): NULL pointer");
886 // Collect attributes from outer scopes
887 vector<SingleWithAttrib> const& real_attribs =
888 w_attrib_path->get_real_attrib();
889 const size_t nof_attribs = real_attribs.size();
891 for (size_t i = 0; i < nof_attribs; i++) {
892 SingleWithAttrib *attrib = real_attribs[i];
893 if (attrib->get_attribKeyword() == SingleWithAttrib::AT_EXTENSION) {
894 Qualifiers *qualifiers = attrib->get_attribQualifiers();
895 if (!qualifiers || qualifiers->get_nof_qualifiers() == 0) {
896 // Only care about extension attributes without qualifiers
897 Error_Context cntxt(attrib, "In `extension' attribute");
898 init_coding_attrib_lex(attrib->get_attribSpec());
899 int result = yyparse(); /* 0=ok, 1=error, 2=out of memory */
901 cleanup_coding_attrib_lex();
902 } // if no qualifiers