Removing an exception from the otherwise quite systematic syntax.
Closes #111.
<m/expr/ { else: | <m/num_or_prefix [ .. num_or_prefix]/: <m/statement/ ; [
... ] }</cf>. The expression after <cf>case</cf> can be of any type which can be
on the left side of the ˜ operator and anything that could be a member of
-a set is allowed before <cf/:/. Multiple commands are allowed without <cf/{}/
-grouping. If <cf><m/expr/</cf> matches one of the <cf/:/ clauses, statements
+a set is allowed before <cf/:/. Multiple commands must be grouped by <cf/{}/.
+If <cf><m/expr/</cf> matches one of the <cf/:/ clauses, statements
between it and next <cf/:/ statement are executed. If <cf><m/expr/</cf> matches
neither of the <cf/:/ clauses, the statements after <cf/else:/ are executed.
}
case arg1 {
- 2: print "two"; print "I can do more commands without {}";
+ 2: { print "two"; print "Multiple commands must brace themselves."; }
3 .. 5: print "three to five";
else: print "something else";
}
Reload of filters is now done by `reload filters` command, contrary to just `reload` in BIRD 2.
+## Filters
+
+We have removed the exception for `case` where multiple commands could be written
+after the case label without braces. This caused unneeded complexity in the parser.
+
## Route attributes
All protocol attributes have been renamed in CLI to align with the filter language tokens.
%nonassoc ELSE
%type <xp> cmds_int cmd_prep
-%type <x> term term_bs cmd cmd_var cmds cmds_scoped constant constructor var var_list var_list_r function_call bgp_path_expr bgp_path bgp_path_tail term_dot_method method_name_cont
+%type <x> term term_bs cmd cmd_var cmds constant constructor var var_list var_list_r function_call bgp_path_expr bgp_path bgp_path_tail term_dot_method method_name_cont
%type <fsa> static_attr
%type <f> filter where_filter
%type <fl> filter_body function_body
| cmds_int { $$ = $1.begin; }
;
-cmds_scoped: { cf_push_soft_scope(new_config); } cmds { cf_pop_soft_scope(new_config); $$ = $2; } ;
-
cmd_var: var | cmd ;
cmd_prep: cmd_var {
;
switch_body: /* EMPTY */ { $$ = NULL; }
- | switch_body switch_items ':' cmds_scoped {
+ | switch_body switch_items ':' cmd {
/* Fill data fields */
struct f_tree *t;
for (t = $2; t; t = t->left)
t->data = $4;
$$ = f_merge_items($1, $2);
}
- | switch_body ELSECOL cmds_scoped {
+ | switch_body ELSECOL cmd {
struct f_tree *t = f_new_tree();
t->from.type = t->to.type = T_VOID;
t->right = t;
;
cmd:
- '{' cmds_scoped '}' {
- $$ = $2;
- }
+ '{' { cf_push_soft_scope(new_config); } cmds { cf_pop_soft_scope(new_config); } '}' { $$ = $3; }
| IF term THEN cmd {
$$ = f_new_inst(FI_CONDITION, $2, $4, NULL);
}
function aux_t_int(int t; int u)
{
+ int v;
case t {
1: {}
+ 2: { int u; u = 1; v = 42; }
+ 3: if true then v = t + u + 53; else v = 35 + u + t;
else: {}
}
}