py/parse: Refactor code to remove assert(0)'s.

This helps to improve code coverage.  Note that most of the changes in
this patch are just de-denting the cases of the switch statements.
This commit is contained in:
Damien George 2017-01-17 17:00:55 +11:00
parent 5314219f18
commit 86e942309a
1 changed files with 47 additions and 60 deletions

View File

@ -295,8 +295,9 @@ void mp_parse_node_print(mp_parse_node_t pn, size_t indent) {
case MP_PARSE_NODE_ID: printf("id(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_ID: printf("id(%s)\n", qstr_str(arg)); break;
case MP_PARSE_NODE_STRING: printf("str(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_STRING: printf("str(%s)\n", qstr_str(arg)); break;
case MP_PARSE_NODE_BYTES: printf("bytes(%s)\n", qstr_str(arg)); break; case MP_PARSE_NODE_BYTES: printf("bytes(%s)\n", qstr_str(arg)); break;
case MP_PARSE_NODE_TOKEN: printf("tok(%u)\n", (uint)arg); break; default:
default: assert(0); assert(MP_PARSE_NODE_LEAF_KIND(pn) == MP_PARSE_NODE_TOKEN);
printf("tok(%u)\n", (uint)arg); break;
} }
} else { } else {
// node must be a mp_parse_node_struct_t // node must be a mp_parse_node_struct_t
@ -870,38 +871,30 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
// progress through the rule // progress through the rule
for (; i < n; ++i) { for (; i < n; ++i) {
switch (rule->arg[i] & RULE_ARG_KIND_MASK) { if ((rule->arg[i] & RULE_ARG_KIND_MASK) == RULE_ARG_TOK) {
case RULE_ARG_TOK: { // need to match a token
// need to match a token mp_token_kind_t tok_kind = rule->arg[i] & RULE_ARG_ARG_MASK;
mp_token_kind_t tok_kind = rule->arg[i] & RULE_ARG_ARG_MASK; if (lex->tok_kind == tok_kind) {
if (lex->tok_kind == tok_kind) { // matched token
// matched token if (tok_kind == MP_TOKEN_NAME) {
if (tok_kind == MP_TOKEN_NAME) { push_result_token(&parser, rule);
push_result_token(&parser, rule); }
} mp_lexer_to_next(lex);
mp_lexer_to_next(lex); } else {
} else { // failed to match token
// failed to match token if (i > 0) {
if (i > 0) { // already eaten tokens so can't backtrack
// already eaten tokens so can't backtrack goto syntax_error;
goto syntax_error; } else {
} else { // this rule failed, so backtrack
// this rule failed, so backtrack backtrack = true;
backtrack = true; goto next_rule;
goto next_rule;
}
} }
break;
} }
case RULE_ARG_RULE: } else {
case RULE_ARG_OPT_RULE: push_rule(&parser, rule_src_line, rule, i + 1); // save this and-rule
rule_and_no_other_choice: push_rule_from_arg(&parser, rule->arg[i]); // push child of and-rule
push_rule(&parser, rule_src_line, rule, i + 1); // save this and-rule goto next_rule;
push_rule_from_arg(&parser, rule->arg[i]); // push child of and-rule
goto next_rule;
default:
assert(0);
goto rule_and_no_other_choice; // to help flow control analysis
} }
} }
@ -973,7 +966,9 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
break; break;
} }
case RULE_ACT_LIST: { default: {
assert((rule->act & RULE_ACT_KIND_MASK) == RULE_ACT_LIST);
// n=2 is: item item* // n=2 is: item item*
// n=1 is: item (sep item)* // n=1 is: item (sep item)*
// n=3 is: item (sep item)* [sep] // n=3 is: item (sep item)* [sep]
@ -1011,32 +1006,27 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
} else { } else {
for (;;) { for (;;) {
size_t arg = rule->arg[i & 1 & n]; size_t arg = rule->arg[i & 1 & n];
switch (arg & RULE_ARG_KIND_MASK) { if ((arg & RULE_ARG_KIND_MASK) == RULE_ARG_TOK) {
case RULE_ARG_TOK: if (lex->tok_kind == (arg & RULE_ARG_ARG_MASK)) {
if (lex->tok_kind == (arg & RULE_ARG_ARG_MASK)) { if (i & 1 & n) {
if (i & 1 & n) { // separators which are tokens are not pushed to result stack
// separators which are tokens are not pushed to result stack
} else {
push_result_token(&parser, rule);
}
mp_lexer_to_next(lex);
// got element of list, so continue parsing list
i += 1;
} else { } else {
// couldn't get element of list push_result_token(&parser, rule);
i += 1;
backtrack = true;
goto list_backtrack;
} }
break; mp_lexer_to_next(lex);
case RULE_ARG_RULE: // got element of list, so continue parsing list
rule_list_no_other_choice: i += 1;
push_rule(&parser, rule_src_line, rule, i + 1); // save this list-rule } else {
push_rule_from_arg(&parser, arg); // push child of list-rule // couldn't get element of list
goto next_rule; i += 1;
default: backtrack = true;
assert(0); goto list_backtrack;
goto rule_list_no_other_choice; // to help flow control analysis }
} else {
assert((arg & RULE_ARG_KIND_MASK) == RULE_ARG_RULE);
push_rule(&parser, rule_src_line, rule, i + 1); // save this list-rule
push_rule_from_arg(&parser, arg); // push child of list-rule
goto next_rule;
} }
} }
} }
@ -1062,9 +1052,6 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) {
} }
break; break;
} }
default:
assert(0);
} }
} }