1 /******************************************************************************
2 * Copyright (c) 2000-2014 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
7 ******************************************************************************/
8 /* Parser for "extension" attributes of functions, external functions and
9 * port types related to message encoding. */
13 #include "../../common/dbgnew.hh"
14 #include "../string.hh"
15 #include "../Identifier.hh"
16 #include "../Setting.hh"
18 #include "AST_ttcn3.hh"
19 #include "Attributes.hh"
20 #include "Ttcnstuff.hh"
21 #include "../stack.hh"
24 using namespace Common;
26 /* Various C macros */
28 #define YYERROR_VERBOSE
29 #define yytext coding_attrib_text
31 /* C/C++ declarations */
35 extern const char *coding_attrib_infile;
37 /* Init the lexer. Located in coding_attrib_la.l */
38 extern void init_coding_attrib_lex(const AttributeSpec& attrib);
39 extern void cleanup_coding_attrib_lex();
41 ExtensionAttributes *extatrs = 0;
43 static void yyerror(const char *str);
47 /*********************************************************************
49 *********************************************************************/
51 %name-prefix="coding_attrib_"
52 %output="coding_attrib_p.cc"
55 /*********************************************************************
57 *********************************************************************/
60 ErrorBehaviorList *errorbehaviorlist;
61 ErrorBehaviorSetting *errorbehaviorsetting;
62 PrintingType *printing;
64 Ttcn::Reference *reference;
68 TypeMapping *typemapping;
69 TypeMappings *typemappings;
70 TypeMappingTarget *typemappingtarget;
71 TypeMappingTargets *typemappingtargets;
74 Type::MessageEncodingType_t encoding_type;
75 string *encoding_options;
79 Type::MessageEncodingType_t encoding_type;
80 string *encoding_options;
81 ErrorBehaviorList *eb_list;
85 TypeMappings *in_mappings, *out_mappings;
89 Ttcn::Reference *port_type_ref;
90 TypeMappings *in_mappings, *out_mappings;
93 Def_Function_Base::prototype_t prototype;
94 Type::typetype_t typetype;
95 Type::MessageEncodingType_t encoding_type;
96 ExtensionAttributes *extattrs;
97 ExtensionAttribute *extattr;
101 /*********************************************************************
102 * Tokens with semantic value
103 *********************************************************************/
105 %token <prototype> PrototypeSetting
106 %token <encoding_type> EncodingType
107 %token <str> EncodingOption
108 %token <str> ErrorBehaviorString
109 %token <id> IDentifier "Identifier"
110 %token <number> Number
112 /*********************************************************************
113 * Tokens without semantic value
114 *********************************************************************/
116 /* TTCN-3 keywords */
118 %token AddressKeyword "address"
119 %token AnyTypeKeyword "anytype"
120 %token BitStringKeyword "bitstring"
121 %token BooleanKeyword "boolean"
122 %token CharStringKeyword "charstring"
123 %token DefaultKeyword "default"
124 %token EncodeKeyword "encode"
125 %token FloatKeyword "float"
126 %token FunctionKeyword "function"
127 %token HexStringKeyword "hexstring"
128 %token InKeyword "in"
129 %token IntegerKeyword "integer"
130 %token ObjectIdentifierKeyword "objid"
131 %token OctetStringKeyword "octetstring"
132 %token OutKeyword "out"
133 %token UniversalKeyword "universal"
134 %token VerdictTypeKeyword "verdicttype"
135 %token VersionKeyword "version"
136 %token RequiresKeyword "requires"
137 %token ReqTitanKeyword "requiresTitan"
139 /* Non-standard keywords used by the attributes with context-sensitive
142 %token DecodeKeyword "decode"
143 %token DiscardKeyword "discard"
144 %token ErrorBehaviorKeyword "errorbehavior"
145 %token InternalKeyword "internal"
146 %token PrototypeKeyword "prototype"
147 %token ProviderKeyword "provider"
148 %token SimpleKeyword "simple"
149 %token UserKeyword "user"
150 %token TransparentKeyword "transparent"
151 %token PrintingKeyword "printing"
153 %token CompactKeyword "compact"
154 %token PrettyKeyword "pretty"
156 %token RedirectSymbol "->"
163 /*********************************************************************
164 * Semantic types of nonterminals
165 *********************************************************************/
167 %type <errorbehaviorsetting> ErrorBehaviorSetting
168 %type <errorbehaviorlist> ErrorBehaviorSettingList ErrorBehaviorAttribute
169 %type <printing> PrintingAttribute PrintingType
170 %type <reference> FunctionMapping FunctionReference PortTypeReference
172 %type <str> EncodingOptions
174 %type <types> TypeList
175 %type <typemapping> TypeMapping
176 %type <typemappings> TypeMappingList
177 %type <typemappingtarget> TypeMappingTarget
178 %type <typemappingtargets> TypeMappingTargetList
180 %type <encdec_attribute> DecodeAttribute EncDecAttributeBody EncodeAttribute
181 %type <encdec_mapping> DecodeMapping EncodeMapping
182 %type <in_out_mappings> InOutTypeMapping InOutTypeMappingList
183 %type <user_attribute> UserAttribute
185 %type <prototype> PrototypeAttribute
186 %type <typetype> PredefinedType
188 %type <extattr> ExtensionAttribute ExternalFunctionAttribute
189 PortTypeAttribute AnyTypeAttribute EncDecValueAttribute
190 VersionAttribute RequiresAttribute TransparentAttribute
192 %type <extattrs> ExtensionAttributes
194 /*********************************************************************
196 *********************************************************************/
198 %destructor { delete $$; }
201 ErrorBehaviorAttribute
203 ErrorBehaviorSettingList
215 TypeMappingTargetList
218 ExternalFunctionAttribute
227 %destructor { delete $$.encoding_options; }
233 delete $$.encoding_options;
240 delete $$.in_mappings;
241 delete $$.out_mappings;
247 delete $$.port_type_ref;
248 delete $$.in_mappings;
249 delete $$.out_mappings;
257 /*********************************************************************
259 *********************************************************************/
264 if (extatrs == 0) extatrs = $1;
275 $$ = new ExtensionAttributes;
277 | ExtensionAttributes ExtensionAttribute
280 if ($2 != NULL) $$->add($2);
285 ExternalFunctionAttribute
288 | EncDecValueAttribute
291 | TransparentAttribute
295 VersionKeyword IDentifier
297 $$ = new ExtensionAttribute(NULL, 0, 0, 0, $2); // VERSION
298 $$->set_location(coding_attrib_infile, @$);
299 if ($$->get_type() == ExtensionAttribute::NONE) {
300 $$->error("Incorrect version data '%s'", $2->get_name().c_str());
306 | VersionKeyword '<' IDentifier '>'
308 $$ = new ExtensionAttribute(NULL, 0, 0, 0, $3, ExtensionAttribute::VERSION_TEMPLATE);
309 $$->set_location(coding_attrib_infile, @$);
310 if ($$->get_type() == ExtensionAttribute::NONE) {
311 $$->error("Incorrect version template '<%s>'", $3->get_name().c_str());
317 | VersionKeyword IDentifier Number Number IDentifier
318 { // version CNL 113 200 R2D2
319 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, 0, $5); // VERSION
320 $$->set_location(coding_attrib_infile, @$);
321 if ($$->get_type() == ExtensionAttribute::NONE) {
322 $$->error("Incorrect version data '%s %d %d %s'",
323 $2->get_dispname().c_str(), $3, $4, $5->get_dispname().c_str());
330 | VersionKeyword IDentifier Number Number '<' IDentifier '>'
331 { // version CNL 113 200 <RnXnn>
332 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, 0, $6, ExtensionAttribute::VERSION_TEMPLATE); // VERSION
333 $$->set_location(coding_attrib_infile, @$);
334 if ($$->get_type() == ExtensionAttribute::NONE) {
335 $$->error("Incorrect version data '%s %d %d <%s>'",
336 $2->get_dispname().c_str(), $3, $4, $6->get_dispname().c_str());
343 | VersionKeyword IDentifier Number Number '/' Number IDentifier
344 { // version CNL 113 200 / 1 R2D2
345 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, $6, $7); // VERSION
346 $$->set_location(coding_attrib_infile, @$);
347 if ($$->get_type() == ExtensionAttribute::NONE) {
348 $$->error("Incorrect version data '%s %d %d / %d %s'",
349 $2->get_dispname().c_str(), $3, $4, $6, $7->get_dispname().c_str());
356 | VersionKeyword IDentifier Number Number '/' Number '<' IDentifier '>'
357 { // version CNL 113 200 / 1 <RnXnn>
358 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, $6, $8, ExtensionAttribute::VERSION_TEMPLATE); // VERSION
359 $$->set_location(coding_attrib_infile, @$);
360 if ($$->get_type() == ExtensionAttribute::NONE) {
361 $$->error("Incorrect version data '%s %d %d / %d <%s>'",
362 $2->get_dispname().c_str(), $3, $4, $6, $8->get_dispname().c_str());
372 RequiresKeyword IDentifier IDentifier
374 $$ = new ExtensionAttribute($2, NULL, 0, 0, 0, $3); // REQUIRES
375 $$->set_location(coding_attrib_infile, @$);
376 if ($$->get_type() == ExtensionAttribute::NONE) {
377 /* parsing the version has failed */
378 $$->error("Incorrect version data '%s'", $3->get_name().c_str());
385 | RequiresKeyword IDentifier IDentifier Number Number IDentifier
386 { // module CNL xxx xxx R1A
387 $$ = new ExtensionAttribute($2, $3->get_dispname().c_str(), $4, $5, 0, $6); // REQUIRES
388 $$->set_location(coding_attrib_infile, @$);
389 if ($$->get_type() == ExtensionAttribute::NONE) {
390 $$->error("Incorrect version data '%s %d %d %s'",
391 $3->get_dispname().c_str(), $4, $5, $6->get_dispname().c_str());
399 | RequiresKeyword IDentifier IDentifier Number Number '/' Number IDentifier
400 { // module CNL xxx xxx / 1 R9A
401 $$ = new ExtensionAttribute($2, $3->get_dispname().c_str(), $4, $5, $7, $8); // REQUIRES
402 $$->set_location(coding_attrib_infile, @$);
403 if ($$->get_type() == ExtensionAttribute::NONE) {
404 $$->error("Incorrect version data '%s %d %d / %d %s'",
405 $3->get_dispname().c_str(), $4, $5, $7, $8->get_dispname().c_str());
413 | ReqTitanKeyword IDentifier
415 $$ = new ExtensionAttribute(NULL, 0, 0, 0, $2, ExtensionAttribute::REQ_TITAN);
416 $$->set_location(coding_attrib_infile, @$);
417 if ($$->get_type() == ExtensionAttribute::NONE) {
418 /* parsing the version has failed */
419 $$->error("Incorrect version data '%s'", $2->get_name().c_str());
425 | ReqTitanKeyword IDentifier Number Number IDentifier
427 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, 0, $5, ExtensionAttribute::REQ_TITAN);
428 $$->set_location(coding_attrib_infile, @$);
429 if ($$->get_type() == ExtensionAttribute::NONE) {
430 $$->error("Incorrect version data '%s %d %d %s'",
431 $2->get_dispname().c_str(), $3, $4, $5->get_dispname().c_str());
438 | ReqTitanKeyword IDentifier Number Number '/' Number IDentifier
439 { // CRL 113 200 / 2 R1A
440 $$ = new ExtensionAttribute($2->get_dispname().c_str(), $3, $4, $6, $7, ExtensionAttribute::REQ_TITAN);
441 $$->set_location(coding_attrib_infile, @$);
442 if ($$->get_type() == ExtensionAttribute::NONE) {
443 $$->error("Incorrect version data '%s %d %d / %d %s'",
444 $2->get_dispname().c_str(), $3, $4, $6, $7->get_dispname().c_str());
453 TransparentAttribute: TransparentKeyword
455 $$ = new ExtensionAttribute(ExtensionAttribute::TRANSPARENT);
456 $$->set_location(coding_attrib_infile, @$);
460 EncDecValueAttribute:
463 $$ = new ExtensionAttribute($1.in_mappings, $1.out_mappings); // ENCDECVALUE
464 $$->set_location(coding_attrib_infile, @$);
468 /* FunctionAttribute is covered by the PrototypeAttribute branch */
469 ExternalFunctionAttribute:
472 $$ = new ExtensionAttribute($1); // PROTOTYPE
473 $$->set_location(coding_attrib_infile, @$);
477 $$ = new ExtensionAttribute(ExtensionAttribute::ENCODE,
478 $1.encoding_type, $1.encoding_options);
479 $$->set_location(coding_attrib_infile, @$);
483 $$ = new ExtensionAttribute(ExtensionAttribute::DECODE,
484 $1.encoding_type, $1.encoding_options);
485 $$->set_location(coding_attrib_infile, @$);
487 | ErrorBehaviorAttribute
489 $$ = new ExtensionAttribute($1); // ERRORBEHAVIOR
490 $$->set_location(coding_attrib_infile, @$);
494 $$ = new ExtensionAttribute($1); // PRINTING
495 $$->set_location(coding_attrib_infile, @$);
502 $$ = new ExtensionAttribute(PortTypeBody::TP_INTERNAL); // PORT_API
503 $$->set_location(coding_attrib_infile, @$);
507 $$ = new ExtensionAttribute(PortTypeBody::TP_ADDRESS); // PORT_API
508 $$->set_location(coding_attrib_infile, @$);
512 $$ = new ExtensionAttribute(ExtensionAttribute::PORT_TYPE_PROVIDER);
513 $$->set_location(coding_attrib_infile, @$);
517 $$ = new ExtensionAttribute($1.port_type_ref,
518 $1.in_mappings, $1.out_mappings); // PORT_TYPE_USER
519 $$->set_location(coding_attrib_infile, @$);
524 PrototypeKeyword '(' PrototypeSetting ')' { $$ = $3; }
528 EncodeKeyword EncDecAttributeBody { $$ = $2; }
532 DecodeKeyword EncDecAttributeBody { $$ = $2; }
538 $$.encoding_type = $2;
539 $$.encoding_options = 0;
541 | '(' EncodingType ':' EncodingOptions ')'
543 $$.encoding_type = $2;
544 $$.encoding_options = $4;
549 EncodingOption { $$ = $1; }
550 | EncodingOptions EncodingOption
559 ErrorBehaviorAttribute:
560 ErrorBehaviorKeyword '(' ErrorBehaviorSettingList ')'
563 $$->set_location(coding_attrib_infile, @$);
567 ErrorBehaviorSettingList:
570 $$ = new ErrorBehaviorList();
573 | ErrorBehaviorSettingList ',' ErrorBehaviorSetting
580 ErrorBehaviorSetting:
581 ErrorBehaviorString ':' ErrorBehaviorString
583 $$ = new ErrorBehaviorSetting(*$1, *$3);
584 $$->set_location(coding_attrib_infile, @$);
591 PrintingKeyword '(' PrintingType ')'
594 $$->set_location(coding_attrib_infile, @$);
601 $$ = new PrintingType();
602 $$->set_printing(PrintingType::PT_COMPACT);
606 $$ = new PrintingType();
607 $$->set_printing(PrintingType::PT_PRETTY);
612 UserKeyword PortTypeReference InOutTypeMappingList
614 $$.port_type_ref = $2;
615 $$.in_mappings = $3.in_mappings;
616 $$.out_mappings = $3.out_mappings;
623 $$ = new Ttcn::Reference($1);
624 $$->set_location(coding_attrib_infile, @$);
626 | IDentifier '.' IDentifier
628 $$ = new Ttcn::Reference($1, $3);
629 $$->set_location(coding_attrib_infile, @$);
633 InOutTypeMappingList:
634 InOutTypeMapping { $$ = $1; }
635 | InOutTypeMappingList InOutTypeMapping
637 if ($1.in_mappings) {
638 $$.in_mappings = $1.in_mappings;
639 if ($2.in_mappings) {
640 $$.in_mappings->steal_mappings($2.in_mappings);
641 delete $2.in_mappings;
643 } else $$.in_mappings = $2.in_mappings;
644 if ($1.out_mappings) {
645 $$.out_mappings = $1.out_mappings;
646 if ($2.out_mappings) {
647 $$.out_mappings->steal_mappings($2.out_mappings);
648 delete $2.out_mappings;
650 } else $$.out_mappings = $2.out_mappings;
655 InKeyword '(' TypeMappingList ')'
658 $$.in_mappings->set_location(coding_attrib_infile, @$);
661 | OutKeyword '(' TypeMappingList ')'
664 $$.out_mappings = $3;
665 $$.out_mappings->set_location(coding_attrib_infile, @$);
672 $$ = new TypeMappings();
675 | TypeMappingList ';' TypeMapping
683 Type RedirectSymbol TypeMappingTargetList
685 $$ = new TypeMapping($1, $3);
686 $$->set_location(coding_attrib_infile, @$);
690 TypeMappingTargetList:
693 $$ = new TypeMappingTargets();
696 | TypeMappingTargetList ',' TypeMappingTarget
704 Type ':' SimpleKeyword
706 $$ = new TypeMappingTarget($1, TypeMappingTarget::TM_SIMPLE);
707 $$->set_location(coding_attrib_infile, @$);
709 | '-' ':' DiscardKeyword
711 $$ = new TypeMappingTarget(0, TypeMappingTarget::TM_DISCARD);
712 $$->set_location(coding_attrib_infile, @$);
714 | Type ':' FunctionMapping
716 $$ = new TypeMappingTarget($1, TypeMappingTarget::TM_FUNCTION, $3);
717 $$->set_location(coding_attrib_infile, @$);
719 | Type ':' EncodeMapping
721 $$ = new TypeMappingTarget($1, TypeMappingTarget::TM_ENCODE,
722 $3.encoding_type, $3.encoding_options, $3.eb_list);
723 $$->set_location(coding_attrib_infile, @$);
725 | Type ':' DecodeMapping
727 $$ = new TypeMappingTarget($1, TypeMappingTarget::TM_DECODE,
728 $3.encoding_type, $3.encoding_options, $3.eb_list);
729 $$->set_location(coding_attrib_infile, @$);
734 FunctionKeyword '(' FunctionReference ')' { $$ = $3; }
740 $$ = new Ttcn::Reference($1);
741 $$->set_location(coding_attrib_infile, @$);
743 | IDentifier '.' IDentifier
745 $$ = new Ttcn::Reference($1, $3);
746 $$->set_location(coding_attrib_infile, @$);
753 $$.encoding_type = $1.encoding_type;
754 $$.encoding_options = $1.encoding_options;
757 | EncodeAttribute ErrorBehaviorAttribute
759 $$.encoding_type = $1.encoding_type;
760 $$.encoding_options = $1.encoding_options;
768 $$.encoding_type = $1.encoding_type;
769 $$.encoding_options = $1.encoding_options;
772 | DecodeAttribute ErrorBehaviorAttribute
774 $$.encoding_type = $1.encoding_type;
775 $$.encoding_options = $1.encoding_options;
784 $$->set_location(coding_attrib_infile, @$);
788 $$ = new Type(Type::T_REFD, $1);
789 $$->set_location(coding_attrib_infile, @$);
793 PredefinedType: /* typetype_t */
794 BitStringKeyword { $$ = Type::T_BSTR; }
795 | BooleanKeyword { $$ = Type::T_BOOL; }
796 | CharStringKeyword { $$ = Type::T_CSTR; }
797 | UniversalKeyword CharStringKeyword { $$ = Type::T_USTR; }
798 | IntegerKeyword { $$ = Type::T_INT; }
799 | OctetStringKeyword { $$ = Type::T_OSTR; }
800 | HexStringKeyword { $$ = Type::T_HSTR; }
801 | VerdictTypeKeyword { $$ = Type::T_VERDICT; }
802 | FloatKeyword { $$ = Type::T_REAL; }
803 | AddressKeyword { $$ = Type::T_ADDRESS; }
804 | DefaultKeyword { $$ = Type::T_DEFAULT; }
807 Location loc(coding_attrib_infile, @$);
808 loc.error("Type `anytype' as a field of `anytype' is not supported");
811 | ObjectIdentifierKeyword { $$ = Type::T_OID; }
814 ReferencedType: /* a Reference* */
817 $$ = new Ttcn::Reference($1);
818 $$->set_location(coding_attrib_infile, @$);
820 | IDentifier '.' IDentifier
822 $$ = new Ttcn::Reference($1, $3);
823 $$->set_location(coding_attrib_infile, @$);
829 AnyTypeKeyword TypeList
831 $$ = new ExtensionAttribute($2); // ANYTYPELIST
832 $$->set_location(coding_attrib_infile, @$);
841 $$->set_location(coding_attrib_infile, @$);
847 $$->set_location(coding_attrib_infile, @$);
853 static void yyerror(const char *str)
855 Location loc(coding_attrib_infile, yylloc);
857 // the most recently parsed token is known
858 loc.error("at or before token `%s': %s", yytext, str);
860 // the most recently parsed token is unknown
861 loc.error("%s", str);
865 /** Parse all extension attributes in a "with" statement */
866 ExtensionAttributes * parse_extattributes(WithAttribPath *w_attrib_path)
869 if (!w_attrib_path) FATAL_ERROR("parse_extattributes(): NULL pointer");
870 // Collect attributes from outer scopes
871 vector<SingleWithAttrib> const& real_attribs =
872 w_attrib_path->get_real_attrib();
873 const size_t nof_attribs = real_attribs.size();
875 for (size_t i = 0; i < nof_attribs; i++) {
876 SingleWithAttrib *attrib = real_attribs[i];
877 if (attrib->get_attribKeyword() == SingleWithAttrib::AT_EXTENSION) {
878 Qualifiers *qualifiers = attrib->get_attribQualifiers();
879 if (!qualifiers || qualifiers->get_nof_qualifiers() == 0) {
880 // Only care about extension attributes without qualifiers
881 Error_Context cntxt(attrib, "In `extension' attribute");
882 init_coding_attrib_lex(attrib->get_attribSpec());
883 int result = yyparse(); /* 0=ok, 1=error, 2=out of memory */
885 cleanup_coding_attrib_lex();
886 } // if no qualifiers