diff options
Diffstat (limited to 'py/parse.c')
-rw-r--r-- | py/parse.c | 119 |
1 files changed, 25 insertions, 94 deletions
diff --git a/py/parse.c b/py/parse.c index 5a5adc6093..2f16748a6c 100644 --- a/py/parse.c +++ b/py/parse.c @@ -147,15 +147,7 @@ typedef struct _mp_parse_chunk_t { byte data[]; } mp_parse_chunk_t; -typedef enum { - PARSE_ERROR_NONE = 0, - PARSE_ERROR_MEMORY, - PARSE_ERROR_CONST, -} parse_error_t; - typedef struct _parser_t { - parse_error_t parse_error; - size_t rule_stack_alloc; size_t rule_stack_top; rule_stack_t *rule_stack; @@ -216,15 +208,8 @@ STATIC void *parser_alloc(parser_t *parser, size_t num_bytes) { } STATIC void push_rule(parser_t *parser, size_t src_line, const rule_t *rule, size_t arg_i) { - if (parser->parse_error) { - return; - } if (parser->rule_stack_top >= parser->rule_stack_alloc) { - rule_stack_t *rs = m_renew_maybe(rule_stack_t, parser->rule_stack, parser->rule_stack_alloc, parser->rule_stack_alloc + MICROPY_ALLOC_PARSE_RULE_INC, true); - if (rs == NULL) { - parser->parse_error = PARSE_ERROR_MEMORY; - return; - } + rule_stack_t *rs = m_renew(rule_stack_t, parser->rule_stack, parser->rule_stack_alloc, parser->rule_stack_alloc + MICROPY_ALLOC_PARSE_RULE_INC); parser->rule_stack = rs; parser->rule_stack_alloc += MICROPY_ALLOC_PARSE_RULE_INC; } @@ -241,7 +226,6 @@ STATIC void push_rule_from_arg(parser_t *parser, size_t arg) { } STATIC void pop_rule(parser_t *parser, const rule_t **rule, size_t *arg_i, size_t *src_line) { - assert(!parser->parse_error); parser->rule_stack_top -= 1; *rule = rules[parser->rule_stack[parser->rule_stack_top].rule_id]; *arg_i = parser->rule_stack[parser->rule_stack_top].arg_i; @@ -354,31 +338,18 @@ STATIC void result_stack_show(parser_t *parser) { */ STATIC mp_parse_node_t pop_result(parser_t *parser) { - if (parser->parse_error) { - return MP_PARSE_NODE_NULL; - } assert(parser->result_stack_top > 0); return parser->result_stack[--parser->result_stack_top]; } STATIC mp_parse_node_t peek_result(parser_t *parser, size_t pos) { - if (parser->parse_error) { - return MP_PARSE_NODE_NULL; - } assert(parser->result_stack_top > pos); return parser->result_stack[parser->result_stack_top - 1 - pos]; } STATIC void push_result_node(parser_t *parser, mp_parse_node_t pn) { - if (parser->parse_error) { - return; - } if (parser->result_stack_top >= parser->result_stack_alloc) { - mp_parse_node_t *stack = m_renew_maybe(mp_parse_node_t, parser->result_stack, parser->result_stack_alloc, parser->result_stack_alloc + MICROPY_ALLOC_PARSE_RESULT_INC, true); - if (stack == NULL) { - parser->parse_error = PARSE_ERROR_MEMORY; - return; - } + mp_parse_node_t *stack = m_renew(mp_parse_node_t, parser->result_stack, parser->result_stack_alloc, parser->result_stack_alloc + MICROPY_ALLOC_PARSE_RESULT_INC); parser->result_stack = stack; parser->result_stack_alloc += MICROPY_ALLOC_PARSE_RESULT_INC; } @@ -387,10 +358,6 @@ STATIC void push_result_node(parser_t *parser, mp_parse_node_t pn) { STATIC mp_parse_node_t make_node_const_object(parser_t *parser, size_t src_line, mp_obj_t obj) { mp_parse_node_struct_t *pn = parser_alloc(parser, sizeof(mp_parse_node_struct_t) + sizeof(mp_obj_t)); - if (pn == NULL) { - parser->parse_error = PARSE_ERROR_MEMORY; - return MP_PARSE_NODE_NULL; - } pn->source_line = src_line; #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D // nodes are 32-bit pointers, but need to store 64-bit object @@ -653,8 +620,11 @@ STATIC bool fold_constants(parser_t *parser, const rule_t *rule, size_t num_args mp_parse_node_t pn_value = ((mp_parse_node_struct_t*)((mp_parse_node_struct_t*)pn1)->nodes[1])->nodes[0]; mp_obj_t value; if (!mp_parse_node_get_int_maybe(pn_value, &value)) { - parser->parse_error = PARSE_ERROR_CONST; - return false; + mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, + "constant must be an integer"); + mp_obj_exception_add_traceback(exc, parser->lexer->source_name, + ((mp_parse_node_struct_t*)pn1)->source_line, MP_QSTR_NULL); + nlr_raise(exc); } // store the value in the table of dynamic constants @@ -755,10 +725,6 @@ STATIC void push_result_rule(parser_t *parser, size_t src_line, const rule_t *ru #endif mp_parse_node_struct_t *pn = parser_alloc(parser, sizeof(mp_parse_node_struct_t) + sizeof(mp_parse_node_t) * num_args); - if (pn == NULL) { - parser->parse_error = PARSE_ERROR_MEMORY; - return; - } pn->source_line = src_line; pn->kind_num_nodes = (rule->rule_id & 0xff) | (num_args << 8); for (size_t i = num_args; i > 0; i--) { @@ -773,15 +739,13 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { parser_t parser; - parser.parse_error = PARSE_ERROR_NONE; - parser.rule_stack_alloc = MICROPY_ALLOC_PARSE_RULE_INIT; parser.rule_stack_top = 0; - parser.rule_stack = m_new_maybe(rule_stack_t, parser.rule_stack_alloc); + parser.rule_stack = m_new(rule_stack_t, parser.rule_stack_alloc); parser.result_stack_alloc = MICROPY_ALLOC_PARSE_RESULT_INIT; parser.result_stack_top = 0; - parser.result_stack = m_new_maybe(mp_parse_node_t, parser.result_stack_alloc); + parser.result_stack = m_new(mp_parse_node_t, parser.result_stack_alloc); parser.lexer = lex; @@ -792,11 +756,6 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { mp_map_init(&parser.consts, 0); #endif - // check if we could allocate the stacks - if (parser.rule_stack == NULL || parser.result_stack == NULL) { - goto memory_error; - } - // work out the top-level rule to use, and push it on the stack size_t top_level_rule; switch (input_kind) { @@ -815,7 +774,7 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { for (;;) { next_rule: - if (parser.rule_stack_top == 0 || parser.parse_error) { + if (parser.rule_stack_top == 0) { break; } @@ -1077,27 +1036,12 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { parser.tree.chunk = parser.cur_chunk; } - mp_obj_t exc; - - if (parser.parse_error) { - #if MICROPY_COMP_CONST - if (parser.parse_error == PARSE_ERROR_CONST) { - exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, - "constant must be an integer"); - } else - #endif - { - assert(parser.parse_error == PARSE_ERROR_MEMORY); - memory_error: - exc = mp_obj_new_exception_msg(&mp_type_MemoryError, - "parser could not allocate enough memory"); - } - parser.tree.root = MP_PARSE_NODE_NULL; - } else if ( + if ( lex->tok_kind != MP_TOKEN_END // check we are at the end of the token stream || parser.result_stack_top == 0 // check that we got a node (can fail on empty input) ) { - syntax_error: + syntax_error:; + mp_obj_t exc; if (lex->tok_kind == MP_TOKEN_INDENT) { exc = mp_obj_new_exception_msg(&mp_type_IndentationError, "unexpected indent"); @@ -1108,37 +1052,24 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, "invalid syntax"); } - parser.tree.root = MP_PARSE_NODE_NULL; - } else { - // no errors - - //result_stack_show(parser); - //printf("rule stack alloc: %d\n", parser.rule_stack_alloc); - //printf("result stack alloc: %d\n", parser.result_stack_alloc); - //printf("number of parse nodes allocated: %d\n", num_parse_nodes_allocated); - - // get the root parse node that we created - assert(parser.result_stack_top == 1); - exc = MP_OBJ_NULL; - parser.tree.root = parser.result_stack[0]; + // add traceback to give info about file name and location + // we don't have a 'block' name, so just pass the NULL qstr to indicate this + mp_obj_exception_add_traceback(exc, lex->source_name, lex->tok_line, MP_QSTR_NULL); + nlr_raise(exc); } + // get the root parse node that we created + assert(parser.result_stack_top == 1); + parser.tree.root = parser.result_stack[0]; + // free the memory that we don't need anymore m_del(rule_stack_t, parser.rule_stack, parser.rule_stack_alloc); m_del(mp_parse_node_t, parser.result_stack, parser.result_stack_alloc); - // we also free the lexer on behalf of the caller (see below) - if (exc != MP_OBJ_NULL) { - // had an error so raise the exception - // add traceback to give info about file name and location - // we don't have a 'block' name, so just pass the NULL qstr to indicate this - mp_obj_exception_add_traceback(exc, lex->source_name, lex->tok_line, MP_QSTR_NULL); - mp_lexer_free(lex); - nlr_raise(exc); - } else { - mp_lexer_free(lex); - return parser.tree; - } + // we also free the lexer on behalf of the caller + mp_lexer_free(lex); + + return parser.tree; } void mp_parse_tree_clear(mp_parse_tree_t *tree) { |