diff options
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | gc.c | 5 | ||||
-rw-r--r-- | gc.h | 1 | ||||
-rw-r--r-- | match.c | 1 | ||||
-rw-r--r-- | parser.c | 49 | ||||
-rw-r--r-- | parser.h | 25 | ||||
-rw-r--r-- | parser.l | 50 | ||||
-rw-r--r-- | parser.y | 3 | ||||
-rw-r--r-- | txr.c | 1 |
9 files changed, 97 insertions, 41 deletions
@@ -184,7 +184,8 @@ endef $(call DEP,$(OBJS) $(EXTRA_OBJS-y),\ $(conf_dir)/config.make $(conf_dir)/config.h) -$(call DEP,opt/lex.yy.o dbg/lex.yy.o,y.tab.h) +$(eval $(foreach item,lex.yy.o txr.o match.o parser.o,\ + $(call DEP,opt/$(item) dbg/$(item),y.tab.h))) lex.yy.c: $(top_srcdir)parser.l $(call ABBREV,LEX) @@ -395,6 +395,11 @@ static int in_heap(val ptr) return 0; } +int gc_is_heap_obj(union obj *ptr) +{ + return in_heap(ptr); +} + static void mark_mem_region(val *low, val *high) { if (low > high) { @@ -34,6 +34,7 @@ void gc(void); int gc_state(int); void gc_mark(val); int gc_is_reachable(val); +int gc_is_heap_obj(union obj *ptr); #if CONFIG_GEN_GC val gc_set(loc, val); @@ -40,6 +40,7 @@ #include "unwind.h" #include "regex.h" #include "stream.h" +#include "y.tab.h" #include "parser.h" #include "txr.h" #include "utf8.h" @@ -45,14 +45,24 @@ #include "hash.h" #include "eval.h" #include "stream.h" +#include "y.tab.h" #include "parser.h" val parser_s, unique_s; static val stream_parser_hash; +static void yy_tok_mark(struct yy_token *tok) +{ + obj_t *ptr = tok->yy_lval.val; + + if (gc_is_heap_obj(ptr)) + gc_mark(ptr); +} + static void parser_mark(val obj) { + int i; parser_t *p = coerce(parser_t *, obj->co.handle); assert (p->parser == nil || p->parser == obj); @@ -61,6 +71,9 @@ static void parser_mark(val obj) gc_mark(p->prepared_msg); if (p->syntax_tree != nao) gc_mark(p->syntax_tree); + yy_tok_mark(&p->recent_tok); + for (i = 0; i < 4; i++) + yy_tok_mark(&p->tok_pushback[i]); } static void parser_destroy(val obj) @@ -79,6 +92,8 @@ static struct cobj_ops parser_ops = { void parser_common_init(parser_t *p) { + int i; + p->parser = nil; p->lineno = 1; p->errors = 0; @@ -89,6 +104,13 @@ void parser_common_init(parser_t *p) yylex_init(&p->yyscan); p->scanner = convert(scanner_t *, p->yyscan); yyset_extra(p, p->scanner); + p->recent_tok.yy_char = 0; + p->recent_tok.yy_lval.val = 0; + for (i = 0; i < 4; i++) { + p->tok_pushback[i].yy_char = 0; + p->tok_pushback[i].yy_lval.val = 0; + } + p->tok_idx = 0; } void parser_cleanup(parser_t *p) @@ -124,25 +146,20 @@ static val ensure_parser(val stream) return set(cdr_l(cell), parser(stream, one)); } -void prime_parser(parser_t *p, int hold_byte, val name) +static void pushback_token(parser_t *p, struct yy_token *tok) { - val secret_token_stream; - - if (hold_byte) { - val secret_token_string = format(nil, lit("@\x01" "E~a"), - chr(hold_byte + 0xDC00), nao); - secret_token_stream = make_string_byte_input_stream(secret_token_string); - } else { - secret_token_stream = make_string_byte_input_stream(lit("@\x01" "E")); - } + assert (p->tok_idx < 4); + p->tok_pushback[p->tok_idx++] = *tok; +} - if (catenated_stream_p(p->stream)) { - catenated_stream_push(secret_token_stream, p->stream); - } else { - set(mkloc(p->stream, p->parser), - make_catenated_stream(list(secret_token_stream, p->stream, nao))); - } +void prime_parser(parser_t *p, val name) +{ + struct yy_token secret_escape_e = { SECRET_ESCAPE_E }; + if (p->recent_tok.yy_char) + pushback_token(p, &p->recent_tok); + pushback_token(p, &secret_escape_e); + prime_scanner(p->scanner); set(mkloc(p->name, p->parser), name); } @@ -31,7 +31,16 @@ typedef struct yyguts_t scanner_t; typedef void *yyscan_t; #endif -typedef struct { +typedef struct parser parser_t; + +#ifdef SPACE + +struct yy_token { + int yy_char; + YYSTYPE yy_lval; +}; + +struct parser { val parser; cnum lineno; int errors; @@ -41,7 +50,11 @@ typedef struct { val syntax_tree; yyscan_t yyscan; scanner_t *scanner; -} parser_t; + struct yy_token recent_tok; + struct yy_token tok_pushback[4]; + int tok_idx; +}; +#endif extern const wchar_t *spec_file; extern val form_to_ln_hash; @@ -53,14 +66,18 @@ 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); -int reset_scanner(scanner_t *scanner); +#ifdef SPACE +int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner); +#endif int yylex_init(yyscan_t *pscanner); int yylex_destroy(yyscan_t scanner); parser_t *yyget_extra(yyscan_t scanner); void yyset_extra(parser_t *, yyscan_t); +void yyset_hold_char(yyscan_t, int); void parser_l_init(void); void open_txr_file(val spec_file, val *txr_lisp_p, val *name, val *stream); -void prime_parser(parser_t *, int hold_byte, val name); +void prime_parser(parser_t *, val name); +void prime_scanner(scanner_t *); int parse_once(val stream, val name, parser_t *parser); int parse(parser_t *parser, val name); val source_loc(val form); @@ -47,10 +47,10 @@ #include "signal.h" #include "unwind.h" #include "hash.h" +#include "y.tab.h" #include "parser.h" #include "eval.h" #include "txr.h" -#include "y.tab.h" #define YY_INPUT(buf, result, max_size) \ do { \ @@ -61,6 +61,9 @@ result = n; \ } while (0) +#define YY_DECL \ + static int yylex_impl(YYSTYPE *yylval_param, yyscan_t yyscanner) + int opt_loglevel = 1; /* 0 - quiet; 1 - normal; 2 - verbose */ val form_to_ln_hash; @@ -860,12 +863,6 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} return SECRET_ESCAPE_R; } -<INITIAL>@\x01E { - yy_push_state(SPECIAL, yyscanner); - yy_push_state(NESTED, yyscanner); - return SECRET_ESCAPE_E; -} - <INITIAL>^@[#;].*\n { /* eat whole line comment */ yyextra->lineno++; @@ -1015,18 +1012,6 @@ void end_of_char(scanner_t *yyg) yy_pop_state(yyg); } -int reset_scanner(scanner_t *yyg) -{ - int hold_byte = yyg->yy_hold_char; - - while (YYSTATE != INITIAL) - yy_pop_state(yyg); - - yy_flush_buffer(YY_CURRENT_BUFFER, yyg); - - return hold_byte; -} - val source_loc(val form) { return gethash(form_to_ln_hash, form); @@ -1040,6 +1025,33 @@ val source_loc_str(val form, val alt) return if3(line, format(nil, lit("~a:~a"), file, line, nao), alt); } +int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner) +{ + struct yyguts_t * yyg = convert(struct yyguts_t *, yyscanner); + int yy_char; + + if (yyextra->tok_idx > 0) { + struct yy_token *tok = &yyextra->tok_pushback[--yyextra->tok_idx]; + yyextra->recent_tok = *tok; + *yylval_param = tok->yy_lval; + return tok->yy_char; + } + + yy_char = yyextra->recent_tok.yy_char = yylex_impl(yylval_param, yyscanner); + yyextra->recent_tok.yy_lval = *yylval_param; + + return yy_char; +} + +void prime_scanner(scanner_t *yyg) +{ + if (YYSTATE == INITIAL) { + yy_push_state(SPECIAL, yyg); + yy_push_state(NESTED, yyg); + yy_push_state(NESTED, yyg); + } +} + void parser_l_init(void) { prot1(&form_to_ln_hash); @@ -45,6 +45,7 @@ #include "hash.h" #include "eval.h" #include "stream.h" +#include "y.tab.h" #include "parser.h" static val sym_helper(parser_t *parser, wchar_t *lexeme, val meta_allowed); @@ -1491,7 +1492,7 @@ int parse(parser_t *parser, val name) parser->errors = 0; parser->prepared_msg = nil; parser->syntax_tree = nil; - prime_parser(parser, reset_scanner(parser->scanner), name); + prime_parser(parser, name); res = yyparse(parser->scanner, parser); @@ -45,6 +45,7 @@ #include "gc.h" #include "signal.h" #include "unwind.h" +#include "y.tab.h" #include "parser.h" #include "match.h" #include "utf8.h" |