From 54d43f3260baaad25f5598ff876799711fe109ea Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 9 Jul 2015 07:15:10 -0700 Subject: Parser cleanup: embed scanner in parser. * parser.c (parser_destroy): New GC finalizer static function. (parser_ops): Register parser_destroy. (parser_common_init): New function, shared by parse and parse_once. Initializes embedded scanner. (parser_cleanup): New function, shared by parse_once and parser_destroy. (parser): Use parser_common_init. * parser.h (parser_t): New member, yyscan. (reset_scanner, parser_common_init): Declared. * parser.l (reset_scanner): New function. * parser.y (parse_once): Use parser_common_init, and thus perform only a few initializations. Do not define scanner as a local variable. (parse): Call reset_scanner instead of yylex_init since the scanner is being reused, and for the same reason do not call yylex_destroy. GC will do that now. --- parser.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'parser.c') diff --git a/parser.c b/parser.c index c0f3c6da..aa85a7f4 100644 --- a/parser.c +++ b/parser.c @@ -64,32 +64,52 @@ static void parser_mark(val obj) gc_mark(p->primer); } +static void parser_destroy(val obj) +{ + parser_t *p = coerce(parser_t *, obj->co.handle); + parser_cleanup(p); +} + static struct cobj_ops parser_ops = { eq, cobj_print_op, - cobj_destroy_free_op, + parser_destroy, parser_mark, cobj_hash_op, }; -val parser(val stream, val lineno, val primer) +void parser_common_init(parser_t *p) { - parser_t *p = coerce(parser_t *, chk_malloc(sizeof *p)); - val parser; p->parser = nil; - p->lineno = 0; + p->lineno = 1; p->errors = 0; p->stream = nil; p->name = nil; p->prepared_msg = nil; p->syntax_tree = nil; p->primer = nil; - p->scanner = 0; + yylex_init(&p->yyscan); + p->scanner = convert(scanner_t *, p->yyscan); + yyset_extra(p, p->scanner); +} + +void parser_cleanup(parser_t *p) +{ + if (p->scanner != 0) + yylex_destroy(p->scanner); +} + +val parser(val stream, val lineno, val primer) +{ + parser_t *p = coerce(parser_t *, chk_malloc(sizeof *p)); + val parser; + parser_common_init(p); parser = cobj(coerce(mem_t *, p), parser_s, &parser_ops); p->parser = parser; p->lineno = c_num(default_arg(lineno, one)); p->stream = stream; p->primer = primer; + return parser; } -- cgit v1.2.3