2 /******************************************************************************
4 * Copyright (C) 2012-2017 Icinga Development Team (https://www.icinga.com/) *
6 * This program is free software; you can redistribute it and/or *
7 * modify it under the terms of the GNU General Public License *
8 * as published by the Free Software Foundation; either version 2 *
9 * of the License, or (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software Foundation *
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ******************************************************************************/
21 #include "classcompiler.hpp"
30 using namespace icinga;
32 #define YYLTYPE icinga::ClassDebugInfo
42 %parse-param { ClassCompiler *context }
43 %lex-param { void *scanner }
50 std::vector<Field> *fields;
52 FieldAccessor *fieldaccessor;
53 std::vector<FieldAccessor> *fieldaccessors;
55 std::vector<Rule> *rules;
59 %token T_INCLUDE "#include (T_INCLUDE)"
60 %token T_IMPL_INCLUDE "#impl_include (T_IMPL_INCLUDE)"
61 %token T_CLASS "class (T_CLASS)"
62 %token T_CODE "code (T_CODE)"
63 %token T_LOAD_AFTER "load_after (T_LOAD_AFTER)"
64 %token T_LIBRARY "library (T_LIBRARY)"
65 %token T_NAMESPACE "namespace (T_NAMESPACE)"
66 %token T_VALIDATOR "validator (T_VALIDATOR)"
67 %token T_REQUIRED "required (T_REQUIRED)"
68 %token T_NAVIGATION "navigation (T_NAVIGATION)"
69 %token T_NAME "name (T_NAME)"
70 %token T_ARRAY "array (T_ARRAY)"
71 %token T_STRING "string (T_STRING)"
72 %token T_ANGLE_STRING "angle_string (T_ANGLE_STRING)"
73 %token T_FIELD_ATTRIBUTE "field_attribute (T_FIELD_ATTRIBUTE)"
74 %token T_CLASS_ATTRIBUTE "class_attribute (T_CLASS_ATTRIBUTE)"
75 %token T_IDENTIFIER "identifier (T_IDENTIFIER)"
76 %token T_GET "get (T_GET)"
77 %token T_SET "set (T_SET)"
78 %token T_DEFAULT "default (T_DEFAULT)"
79 %token T_FIELD_ACCESSOR_TYPE "field_accessor_type (T_FIELD_ACCESSOR_TYPE)"
80 %type <text> T_IDENTIFIER
82 %type <text> T_ANGLE_STRING
83 %type <text> identifier
84 %type <text> alternative_name_specifier
85 %type <text> inherits_specifier
86 %type <text> type_base_specifier
88 %type <text> angle_include
89 %type <text> impl_include
90 %type <text> angle_impl_include
92 %type <num> T_FIELD_ATTRIBUTE
93 %type <field> field_attribute
94 %type <field> field_attributes
95 %type <field> field_attribute_list
96 %type <num> T_FIELD_ACCESSOR_TYPE
97 %type <num> T_CLASS_ATTRIBUTE
98 %type <num> class_attribute_list
99 %type <type> field_type
100 %type <field> class_field
101 %type <fields> class_fields
103 %type <fieldaccessors> field_accessor_list
104 %type <fieldaccessors> field_accessors
105 %type <fieldaccessor> field_accessor
106 %type <rule> validator_rule
107 %type <rules> validator_rules
108 %type <validator> validator
112 int yylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
114 void yyerror(YYLTYPE *locp, ClassCompiler *, const char *err)
116 std::cerr << "in " << locp->path << " at " << locp->first_line << ":" << locp->first_column << "-" << locp->last_line << ":" << locp->last_column << ": "
122 int yyparse(ClassCompiler *context);
124 void ClassCompiler::Compile(void)
128 } catch (const std::exception& ex) {
129 std::cerr << "Exception: " << ex.what();
132 HandleMissingValidators();
135 #define scanner (context->GetScanner())
141 statements: /* empty */
142 | statements statement
147 context->HandleInclude($1, yylloc);
152 context->HandleAngleInclude($1, yylloc);
157 context->HandleImplInclude($1, yylloc);
162 context->HandleAngleImplInclude($1, yylloc);
167 context->HandleClass(*$1, yylloc);
172 context->HandleValidator(*$1, yylloc);
178 context->HandleCode($1, yylloc);
184 include: T_INCLUDE T_STRING
190 angle_include: T_INCLUDE T_ANGLE_STRING
196 impl_include: T_IMPL_INCLUDE T_STRING
202 angle_impl_include: T_IMPL_INCLUDE T_ANGLE_STRING
208 namespace: T_NAMESPACE identifier '{'
210 context->HandleNamespaceBegin($2, yylloc);
215 context->HandleNamespaceEnd(yylloc);
219 code: T_CODE T_STRING
225 library: T_LIBRARY T_IDENTIFIER ';'
227 context->HandleLibrary($2, yylloc);
232 class: class_attribute_list T_CLASS T_IDENTIFIER inherits_specifier type_base_specifier '{' class_fields '}' ';'
251 for (const Field& field : *$7) {
252 if (field.Attributes & FALoadDependency) {
253 $$->LoadDependencies.push_back(field.Name);
255 $$->Fields.push_back(field);
260 ClassCompiler::OptimizeStructLayout($$->Fields);
264 class_attribute_list: /* empty */
272 | class_attribute_list T_CLASS_ATTRIBUTE
277 inherits_specifier: /* empty */
287 type_base_specifier: /* empty */
297 class_fields: /* empty */
299 $$ = new std::vector<Field>();
301 | class_fields class_field
308 field_type: identifier
310 $$ = new FieldType();
315 | T_NAME '(' identifier ')'
317 $$ = new FieldType();
323 | T_ARRAY '(' field_type ')'
330 class_field: field_attribute_list field_type identifier alternative_name_specifier field_accessor_list ';'
334 if ((field->Attributes & (FAConfig | FAState)) == 0)
335 field->Attributes |= FAEphemeral;
344 field->AlternativeName = $4;
348 std::vector<FieldAccessor>::const_iterator it;
349 for (it = $5->begin(); it != $5->end(); it++) {
352 field->GetAccessor = it->Accessor;
353 field->PureGetAccessor = it->Pure;
356 field->SetAccessor = it->Accessor;
357 field->PureSetAccessor = it->Pure;
360 field->DefaultAccessor = it->Accessor;
363 field->TrackAccessor = it->Accessor;
366 field->NavigateAccessor = it->Accessor;
367 field->PureNavigateAccessor = it->Pure;
376 | T_LOAD_AFTER identifier ';'
378 Field *field = new Field();
379 field->Attributes = FALoadDependency;
386 alternative_name_specifier: /* empty */
396 field_attribute_list: /* empty */
400 | '[' field_attributes ']'
406 field_attribute: T_FIELD_ATTRIBUTE
414 $$->Attributes = FARequired;
416 | T_NAVIGATION '(' identifier ')'
419 $$->Attributes = FANavigation;
420 $$->NavigationName = $3;
426 $$->Attributes = FANavigation;
430 field_attributes: /* empty */
434 | field_attributes ',' field_attribute
437 $$->Attributes |= $3->Attributes;
438 if (!$3->NavigationName.empty())
439 $$->NavigationName = $3->NavigationName;
448 field_accessor_list: /* empty */
450 $$ = new std::vector<FieldAccessor>();
452 | '{' field_accessors '}'
458 field_accessors: /* empty */
460 $$ = new std::vector<FieldAccessor>();
462 | field_accessors field_accessor
470 field_accessor: T_FIELD_ACCESSOR_TYPE T_STRING
472 $$ = new FieldAccessor(static_cast<FieldAccessorType>($1), $2, false);
475 | T_FIELD_ACCESSOR_TYPE ';'
477 $$ = new FieldAccessor(static_cast<FieldAccessorType>($1), "", true);
481 validator_rules: /* empty */
483 $$ = new std::vector<Rule>();
485 | validator_rules validator_rule
492 validator_rule: T_NAME '(' T_IDENTIFIER ')' identifier ';'
502 | T_IDENTIFIER identifier ';'
512 | T_NAME '(' T_IDENTIFIER ')' identifier '{' validator_rules '}' ';'
524 | T_IDENTIFIER identifier '{' validator_rules '}' ';'
536 | T_REQUIRED identifier ';'
539 $$->Attributes = RARequired;
547 validator: T_VALIDATOR T_IDENTIFIER '{' validator_rules '}' ';'
549 $$ = new Validator();
559 identifier: T_IDENTIFIER