From 2e36e0feae8d1dd75c8410b365d7dc33b30ce66b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 21 Apr 2019 04:06:20 -0700 Subject: parser: always use stream-associated parser for parse_once. This refactoring is needed for fixing the off-by-one line number bug when the hash bang line is processed. * eval.c (load): Don't define parser locally; ensure there is one in the stream and use it. * match.c (v_load): Likewise. * parser.c (get_parser_impl): Renamed to parser_get_impl and changed from internal to external linkage. (ensure_parser): Changed to external linkage. (lisp_parser_impl, read_file_common): Follow rename of get_parser_impl. * parser.h (parse_once): Declaration updated. (parser_get_impl, ensure_parser): Declared. * parser.y (parse_once): Take self parameter; drop parser parameter. Ensure a parser to the stream, rather than declaring one locally. Don't clean up the parser when done, just let the stream clean it up. * txr.c (parse_once_noerr): Parser argument is dropped and not passed to parse_once. Program name is passed as self argument to parse_once. (txr_main): When parsing the TXR pattern query, don't define a parser locally; ensure there is one in the stream and use it, like in load and v_load. --- eval.c | 9 +++++---- match.c | 11 ++++++----- parser.c | 8 ++++---- parser.h | 4 +++- parser.y | 9 +++------ txr.c | 14 ++++++++------ 6 files changed, 29 insertions(+), 26 deletions(-) diff --git a/eval.c b/eval.c index a91d7bc8..ee9ac973 100644 --- a/eval.c +++ b/eval.c @@ -4364,21 +4364,22 @@ val load(val target) } } else { int gc = gc_state(0); - parser_t parser; - parse_once(stream, name, &parser); + val parser_obj = ensure_parser(stream); + parser_t *parser = parser_get_impl(self, parser_obj); + parse_once(self, stream, name); gc_state(gc); close_stream(stream, nil); uw_release_deferred_warnings(); - if (parser.errors) + if (parser->errors) uw_throwf(query_error_s, lit("~a: parser errors in ~a"), self, path, nao); { val match_ctx = uw_get_match_context(); val bindings = cdr(match_ctx); - val result = extract(parser.syntax_tree, nil, bindings); + val result = extract(parser->syntax_tree, nil, bindings); cons_bind (new_bindings, success, result); if (success) uw_set_match_context(cons(car(match_ctx), new_bindings)); diff --git a/match.c b/match.c index 26f26a01..230b7be3 100644 --- a/match.c +++ b/match.c @@ -4331,18 +4331,19 @@ static val v_load(match_files_ctx *c) if (!txr_lisp_p) { int gc = gc_state(0); - parser_t parser; + val parser_obj = ensure_parser(stream); + parser_t *parser = parser_get_impl(self, parser_obj); - parse_once(stream, name, &parser); + parse_once(self, stream, name); gc_state(gc); - if (parser.errors) + if (parser->errors) sem_error(specline, lit("~s: errors encountered in ~a"), sym, path, nao); if (sym == include_s) { - ret = parser.syntax_tree; + ret = parser->syntax_tree; } else { - val spec = parser.syntax_tree; + val spec = parser->syntax_tree; val result = match_files(mf_spec(*c, spec)); if (!result) { diff --git a/parser.c b/parser.c index 4ac341b7..fbc2e2ca 100644 --- a/parser.c +++ b/parser.c @@ -173,12 +173,12 @@ val parser(val stream, val lineno) return parser; } -static parser_t *get_parser_impl(val self, val parser) +parser_t *parser_get_impl(val self, val parser) { return coerce(parser_t *, cobj_handle(self, parser, parser_s)); } -static val ensure_parser(val stream) +val ensure_parser(val stream) { loc pcdr = gethash_l(lit("internal error"), stream_parser_hash, stream, nulloc); val pars = deref(pcdr); @@ -541,7 +541,7 @@ static val lisp_parse_impl(val self, val interactive, val rlcp_p, val source_in, stream_get_prop(input_stream, name_k))); val parser = ensure_parser(input_stream); val saved_dyn = dyn_env; - parser_t *pi = get_parser_impl(self, parser); + parser_t *pi = parser_get_impl(self, parser); volatile val parsed = nil; if (rlcp_p) @@ -628,7 +628,7 @@ static val read_file_common(val self, val stream, val error_stream, val compiled val parser = ensure_parser(stream); if (compiled) { - parser_t *pi = get_parser_impl(self, parser); + parser_t *pi = parser_get_impl(self, parser); pi->rec_source_loc = 0; } diff --git a/parser.h b/parser.h index 246832ab..ec694bbb 100644 --- a/parser.h +++ b/parser.h @@ -102,7 +102,7 @@ void parser_resolve_circ(parser_t *); void parser_circ_def(parser_t *, val num, val expr); val parser_circ_ref(parser_t *, val num); void scrub_scanner(scanner_t *, int yy_char, wchar_t *lexeme); -int parse_once(val stream, val name, parser_t *parser); +int parse_once(val self, val stream, val name); int parse(parser_t *parser, val name, enum prime_parser); val source_loc(val form); val source_loc_str(val form, val alt); @@ -129,7 +129,9 @@ val repl(val bindings, val in_stream, val out_stream, val env); void parser_common_init(parser_t *); void parser_cleanup(parser_t *); val parser(val stream, val lineno); +parser_t *parser_get_impl(val self, val parser); val get_parser(val stream); +val ensure_parser(val stream); val parser_errors(val parser); val parser_eof(val parser); void parse_init(void); diff --git a/parser.y b/parser.y index f70693c5..e878d636 100644 --- a/parser.y +++ b/parser.y @@ -1847,16 +1847,14 @@ void yybadtoken(parser_t *parser, int tok, val context) yyerrorf(scnr, lit("unexpected character ~a"), chr(tok), nao); } -int parse_once(val stream, val name, parser_t *parser) +int parse_once(val self, val stream, val name) { int res = 0; #if CONFIG_DEBUG_SUPPORT unsigned dbg_state = debug_clear(opt_dbg_expansion ? 0 : DBG_ENABLE); #endif - parser_common_init(parser); - - parser->stream = stream; - parser->name = name; + val parser_obj = ensure_parser(stream); + parser_t *parser = parser_get_impl(self, parser_obj); parser->rec_source_loc = 1; uw_catch_begin(cons(error_s, nil), esym, eobj); @@ -1872,7 +1870,6 @@ int parse_once(val stream, val name, parser_t *parser) } uw_unwind { - parser_cleanup(parser); #if CONFIG_DEBUG_SUPPORT debug_set(dbg_state); #endif diff --git a/txr.c b/txr.c index 4de8c3f7..5c9ce0c6 100644 --- a/txr.c +++ b/txr.c @@ -470,10 +470,11 @@ static void no_dbg_support(val arg) } #endif -static int parse_once_noerr(val stream, val name, parser_t *parser) +static int parse_once_noerr(val stream, val name) { val pfx = format(nil, lit("~a:"), name, nao); - ignerr_func_body(int, 0, parse_once(stream, name, parser), std_error, pfx); + ignerr_func_body(int, 0, parse_once(prog_string, stream, name), + std_error, pfx); } static val read_compiled_file_noerr(val self, val stream, val name, val error_stream) @@ -1052,22 +1053,23 @@ int txr_main(int argc, char **argv) if (!txr_lisp_p) { int gc = gc_state(0); - parser_t parser; - parse_once_noerr(parse_stream, spec_file_str, &parser); + val parser_obj = ensure_parser(parse_stream); + parser_t *parser = parser_get_impl(prog_string, parser_obj); + parse_once_noerr(parse_stream, spec_file_str); gc_state(gc); close_stream(parse_stream, nil); uw_release_deferred_warnings(); - spec = parser.syntax_tree; + spec = parser->syntax_tree; opt_loglevel = match_loglevel; if (opt_compat && opt_compat <= 199) reg_var(intern(lit("*self-path*"), user_package), spec_file_str); - if (parser.errors) { + if (parser->errors) { if (enter_repl) goto repl; return EXIT_FAILURE; -- cgit v1.2.3