summaryrefslogtreecommitdiffstats
path: root/parser.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-07-09 07:15:10 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-07-09 07:15:10 -0700
commit54d43f3260baaad25f5598ff876799711fe109ea (patch)
tree2a11d79234c7f2767094129fe44ba9b118039c1e /parser.c
parent64f9da2d4335178f7ffa0008a33ed1ee375e807d (diff)
downloadtxr-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.c32
1 files changed, 26 insertions, 6 deletions
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;
}