3030#include <assert.h>
3131#include <string.h>
3232
33+ #include "py/nlr.h"
3334#include "py/lexer.h"
3435#include "py/parse.h"
3536#include "py/parsenum.h"
@@ -382,7 +383,7 @@ STATIC void push_result_rule(parser_t *parser, mp_uint_t src_line, const rule_t
382383 push_result_node (parser , (mp_parse_node_t )pn );
383384}
384385
385- mp_parse_node_t mp_parse (mp_lexer_t * lex , mp_parse_input_kind_t input_kind , mp_parse_error_kind_t * parse_error_kind_out ) {
386+ mp_parse_node_t mp_parse (mp_lexer_t * lex , mp_parse_input_kind_t input_kind ) {
386387
387388 // initialise parser and allocate memory for its stacks
388389
@@ -717,15 +718,15 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p
717718 }
718719 }
719720
720- mp_parse_node_t result ;
721+ mp_obj_t exc = MP_OBJ_NULL ;
722+ mp_parse_node_t result = MP_PARSE_NODE_NULL ;
721723
722724 // check if we had a memory error
723725 if (parser .had_memory_error ) {
724726memory_error :
725- * parse_error_kind_out = MP_PARSE_ERROR_MEMORY ;
726- result = MP_PARSE_NODE_NULL ;
727+ exc = mp_obj_new_exception_msg ( & mp_type_MemoryError ,
728+ "parser could not allocate enough memory" ) ;
727729 goto finished ;
728-
729730 }
730731
731732 // check we are at the end of the token stream
@@ -747,17 +748,30 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p
747748 // free the memory that we don't need anymore
748749 m_del (rule_stack_t , parser .rule_stack , parser .rule_stack_alloc );
749750 m_del (mp_parse_node_t , parser .result_stack , parser .result_stack_alloc );
750-
751- // return the result
752- return result ;
751+ // we also free the lexer on behalf of the caller (see below)
752+
753+ if (exc != MP_OBJ_NULL ) {
754+ // had an error so raise the exception
755+ // add traceback to give info about file name and location
756+ // we don't have a 'block' name, so just pass the NULL qstr to indicate this
757+ mp_obj_exception_add_traceback (exc , lex -> source_name , lex -> tok_line , MP_QSTR_NULL );
758+ mp_lexer_free (lex );
759+ nlr_raise (exc );
760+ } else {
761+ mp_lexer_free (lex );
762+ return result ;
763+ }
753764
754765syntax_error :
755766 if (lex -> tok_kind == MP_TOKEN_INDENT ) {
756- * parse_error_kind_out = MP_PARSE_ERROR_UNEXPECTED_INDENT ;
767+ exc = mp_obj_new_exception_msg (& mp_type_IndentationError ,
768+ "unexpected indent" );
757769 } else if (lex -> tok_kind == MP_TOKEN_DEDENT_MISMATCH ) {
758- * parse_error_kind_out = MP_PARSE_ERROR_UNMATCHED_UNINDENT ;
770+ exc = mp_obj_new_exception_msg (& mp_type_IndentationError ,
771+ "unindent does not match any outer indentation level" );
759772 } else {
760- * parse_error_kind_out = MP_PARSE_ERROR_INVALID_SYNTAX ;
773+ exc = mp_obj_new_exception_msg (& mp_type_SyntaxError ,
774+ "invalid syntax" );
761775#ifdef USE_RULE_NAME
762776 // debugging: print the rule name that failed and the token
763777 printf ("rule: %s\n" , rule -> rule_name );
@@ -766,6 +780,5 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p
766780#endif
767781#endif
768782 }
769- result = MP_PARSE_NODE_NULL ;
770783 goto finished ;
771784}
0 commit comments