diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-07-09 07:15:10 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-07-09 07:15:10 -0700 |
commit | 54d43f3260baaad25f5598ff876799711fe109ea (patch) | |
tree | 2a11d79234c7f2767094129fe44ba9b118039c1e /parser.c | |
parent | 64f9da2d4335178f7ffa0008a33ed1ee375e807d (diff) | |
download | txr-54d43f3260baaad25f5598ff876799711fe109ea.tar.gz txr-54d43f3260baaad25f5598ff876799711fe109ea.tar.bz2 txr-54d43f3260baaad25f5598ff876799711fe109ea.zip |
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.
Diffstat (limited to 'parser.c')
-rw-r--r-- | parser.c | 32 |
1 files changed, 26 insertions, 6 deletions
@@ -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; } |