I'm attempting to write a grammar to parse templating language say jinja2 (or twig at your choose), and I can't successfully parse switch-case statement.
Let me show desired syntax:
{% switch username %}
    {% case "Jim" %}
        I want to say: 
    {% case "Nik" %}
        Hello man!
    {% endcase %}
    {% case "Bob" %}
        Hi
    {% default %}
        Who are you?
{% endswitch %}
Here endcase just works as break.
Worked portion of my grammar file:
program ::= template_language(Q) . {
    status->ret = Q;
}
template_language(R) ::= statement_list(L) . {
    R = L;
}
statement_list(R) ::= statement_list(L) statement(S) . {
    R = my_list(L, S);
}
statement_list(R) ::= statement(S) . {
    R = my_list(NULL, S);
}
statement(R) ::= switch_statement(E) . {
    R = E;
}
// empty {% switch expr %} {% endswitch %}
switch_statement(R) ::= OPEN_DELIMITER SWITCH expr(E) CLOSE_DELIMITER OPEN_DELIMITER ENDSWITCH CLOSE_DELIMITER . {
    R = my_switch_statement(E, NULL, status->scanner_state);
}
switch_statement(R) ::= OPEN_DELIMITER SWITCH expr(E) CLOSE_DELIMITER case_clauses(C) OPEN_DELIMITER ENDSWITCH CLOSE_DELIMITER . {
    R = my_switch_statement(E, C, status->scanner_state);
}
case_clauses(R) ::= case_clauses(C) case_clause(K) . {
    R = my_list(C, K);
}
case_clauses(R) ::= case_clause(K) . {
    R = my_list(NULL, K);
}
// empty {% case expr %} {% endcase %}
case_clause(R) ::= OPEN_DELIMITER CASE expr(E) CLOSE_DELIMITER OPEN_DELIMITER ENDCASE CLOSE_DELIMITER . {
    R = case_clause(E, NULL, status->scanner_state);
}
case_clause(R) ::= OPEN_DELIMITER CASE expr(E) CLOSE_DELIMITER statement_list(T) OPEN_DELIMITER ENDCASE CLOSE_DELIMITER . {
    R = case_clause(E, T, status->scanner_state);
}
This is just part of my grammar and I have worked grammar for for, if, while, do, loop, etc.
But I have no idea about:
{% case expr %} statement_list(T)without{% endcase %}{% default %} statement_list(T)
For example I tried to use:
case_clause(R) ::= OPEN_DELIMITER CASE expr(E) CLOSE_DELIMITER statement_list(T) . {
    R = case_clause(E, T, status->scanner_state);
}
for #1 but no luck, got
This rule can not be reduced.
The same for #2
Frankly speaking I'm understand the root of problem - the lack of case/default-bound, but actually I have no idea how to address this issue.
Any help would be greatly appreciated!