From fd090e057b9af15b69c346b26b90e2cb58d06adc Mon Sep 17 00:00:00 2001 From: Gunnar Beutner Date: Thu, 26 Feb 2015 13:50:25 +0100 Subject: [PATCH] Implement 'else if' fixes #8548 --- doc/16-language-reference.md | 10 +++++---- lib/config/config_parser.yy | 41 +++++++++++++++++++++++++++++++++--- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/doc/16-language-reference.md b/doc/16-language-reference.md index 393a004a8..0a5be4a2f 100644 --- a/doc/16-language-reference.md +++ b/doc/16-language-reference.md @@ -668,11 +668,13 @@ Example: a = 3 - if (a < 5) { + if (a < 5) { a *= 7 - } else { - a *= 2 - } + } else if (a > 10) { + a *= 5 + } else { + a *= 2 + } An if/else construct can also be used in place of any other value. The value of an if/else statement is the value of the last statement which was evaluated for the branch which was taken: diff --git a/lib/config/config_parser.yy b/lib/config/config_parser.yy index 23a1803dc..9d52912e1 100644 --- a/lib/config/config_parser.yy +++ b/lib/config/config_parser.yy @@ -97,6 +97,8 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig std::vector *slist; std::vector > *llist; std::vector *elist; + std::vector > *ebranchlist; + std::pair *ebranch; std::pair *cvitem; std::map *cvlist; icinga::ScopeSpecifier scope; @@ -197,6 +199,8 @@ static void MakeRBinaryOp(Expression** result, Expression *left, Expression *rig %type rterm_array %type rterm_scope_require_side_effect %type rterm_scope +%type else_if_branches +%type else_if_branch %type rterm_side_effect %type rterm_no_side_effect %type lterm @@ -757,6 +761,27 @@ rterm_scope: '{' } ; +else_if_branch: T_ELSE T_IF '(' rterm ')' rterm_scope + { + DictExpression *atrue = dynamic_cast($6); + atrue->MakeInline(); + + $$ = new std::pair($4, atrue); + } + ; + +else_if_branches: /* empty */ + { + $$ = new std::vector >(); + } + | else_if_branches else_if_branch + { + $$ = $1; + $$->push_back(*$2); + delete $2; + } + ; + rterm_side_effect: rterm '(' rterm_items ')' { $$ = new FunctionCallExpression($1, *$3, @$); @@ -790,13 +815,23 @@ rterm_side_effect: rterm '(' rterm_items ')' $$ = new ConditionalExpression($3, atrue, NULL, @$); } - | T_IF '(' rterm ')' rterm_scope T_ELSE rterm_scope + | T_IF '(' rterm ')' rterm_scope else_if_branches T_ELSE rterm_scope { DictExpression *atrue = dynamic_cast($5); atrue->MakeInline(); - DictExpression *afalse = dynamic_cast($7); - afalse->MakeInline(); + std::vector > ebranches = *$6; + delete $6; + + DictExpression *afalsedict = dynamic_cast($8); + afalsedict->MakeInline(); + + Expression *afalse = afalsedict; + + for (int i = ebranches.size() - 1; i >= 0; i--) { + const std::pair& ebranch = ebranches[i]; + afalse = new ConditionalExpression(ebranch.first, ebranch.second, afalse, @6); + } $$ = new ConditionalExpression($3, atrue, afalse, @$); }