diff options
-rw-r--r-- | ChangeLog | 25 | ||||
-rw-r--r-- | parser.c | 32 | ||||
-rw-r--r-- | parser.h | 14 | ||||
-rw-r--r-- | parser.l | 8 | ||||
-rw-r--r-- | parser.y | 21 |
5 files changed, 72 insertions, 28 deletions
@@ -1,3 +1,28 @@ +2015-07-09 Kaz Kylheku <kaz@kylheku.com> + + 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. + 2015-07-08 Kaz Kylheku <kaz@kylheku.com> Bugfix: define-modify-macro not registered for auto-loading. @@ -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; } @@ -26,6 +26,11 @@ typedef struct yyguts_t scanner_t; +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void *yyscan_t; +#endif + typedef struct { val parser; cnum lineno; @@ -35,14 +40,10 @@ typedef struct { val prepared_msg; val syntax_tree; val primer; + yyscan_t yyscan; scanner_t *scanner; } parser_t; -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void *yyscan_t; -#endif - extern const wchar_t *spec_file; extern val form_to_ln_hash; extern val parser_s; @@ -52,6 +53,7 @@ void yyerrorf(scanner_t *scanner, val s, ...); void yybadtoken(parser_t *, int tok, val context); void end_of_regex(scanner_t *scanner); void end_of_char(scanner_t *scanner); +void reset_scanner(scanner_t *scanner); int yylex_init(yyscan_t *pscanner); int yylex_destroy(yyscan_t scanner); parser_t *yyget_extra(yyscan_t scanner); @@ -72,6 +74,8 @@ val rlcp_tree(val to, val from); val regex_parse(val string, val error_stream); val lisp_parse(val source, val error_stream, val error_return_val, val name); val read_eval_stream(val stream, val error_stream, val hash_bang_support); +void parser_common_init(parser_t *); +void parser_cleanup(parser_t *); val parser(val stream, val lineno, val primer); val get_parser(val stream); val parser_errors(val parser); @@ -960,6 +960,14 @@ void end_of_char(scanner_t *yyg) yy_pop_state(yyg); } +void reset_scanner(scanner_t *yyg) +{ + while (YYSTATE != INITIAL) + yy_pop_state(yyg); + + yy_flush_buffer(YY_CURRENT_BUFFER, yyg); +} + val source_loc(val form) { return gethash(form_to_ln_hash, form); @@ -1443,22 +1443,15 @@ void yybadtoken(parser_t *parser, int tok, val context) int parse_once(val stream, val name, parser_t *parser) { int res; - yyscan_t scanner; - parser->lineno = 1; - parser->errors = 0; + parser_common_init(parser); + parser->stream = stream; parser->name = name; - parser->prepared_msg = nil; - parser->syntax_tree = nil; - yylex_init(&scanner); - parser->scanner = convert(scanner_t *, scanner); - - yyset_extra(parser, parser->scanner); res = yyparse(parser->scanner, parser); - yylex_destroy(parser->scanner); + parser_cleanup(parser); return res; } @@ -1466,20 +1459,14 @@ int parse_once(val stream, val name, parser_t *parser) int parse(parser_t *parser) { int res; - yyscan_t scanner; parser->errors = 0; parser->prepared_msg = nil; parser->syntax_tree = nil; prime_parser(parser->parser); - yylex_init(&scanner); - parser->scanner = convert(scanner_t *, scanner); - - yyset_extra(parser, parser->scanner); + reset_scanner(parser->scanner); res = yyparse(parser->scanner, parser); - yylex_destroy(parser->scanner); - return res; } |