From 80023f287c52876b82af43027dd4605ab939d006 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 12 Aug 2015 20:35:04 -0700 Subject: Use new pushback token priming for single regex parse. * parser.h (enum prime_parser): New enum. (prime_parser, prime_scanner, parse): Declarations updated with new argument. * parser.c (prime_parser): New argument of enum prime_parser type Select appropriate secret token for regex and Lisp case. Pass prime selector down to prime_scanner. (regex_parse): Do not prepend secret escape to string. Do not use parse_once function; instead do the parser init and cleanup here and use the parse function. (lisp_parse): Pass new argument to parse, configuring the parser to be primed for Lisp parsing. * parser.l (grammar): Rule producing SECRET_ESCAPE_R removed. (prime_scanner): New argument. Pop the scanner state down to INITIAL. Then unconditionally switch to appopriate state based on priming configuration. * parser.y (parse): New argument for priming selection, passed down to prime parser. --- parser.c | 30 +++++++++++++++++++++--------- parser.h | 8 +++++--- parser.l | 17 ++++++++++------- parser.y | 4 ++-- 4 files changed, 38 insertions(+), 21 deletions(-) diff --git a/parser.c b/parser.c index 03677164..86dc9a4d 100644 --- a/parser.c +++ b/parser.c @@ -152,14 +152,23 @@ static void pushback_token(parser_t *p, struct yy_token *tok) p->tok_pushback[p->tok_idx++] = *tok; } -void prime_parser(parser_t *p, val name) +void prime_parser(parser_t *p, val name, enum prime_parser prim) { - struct yy_token secret_escape_e = { SECRET_ESCAPE_E }; + struct yy_token sec_tok = { 0 }; + + switch (prim) { + case prime_lisp: + sec_tok.yy_char = SECRET_ESCAPE_E; + break; + case prime_regex: + sec_tok.yy_char = SECRET_ESCAPE_R; + break; + } if (p->recent_tok.yy_char) pushback_token(p, &p->recent_tok); - pushback_token(p, &secret_escape_e); - prime_scanner(p->scanner); + pushback_token(p, &sec_tok); + prime_scanner(p->scanner, prim); set(mkloc(p->name, p->parser), name); } @@ -231,20 +240,23 @@ except: val regex_parse(val string, val error_stream) { uses_or2; - val parse_string = cat_str(list(lit("@\x01R"), string, nao), nil); val save_stream = std_error; - val stream = make_string_byte_input_stream(parse_string); + val stream = make_string_byte_input_stream(string); parser_t parser; error_stream = default_bool_arg(error_stream); std_error = if3(error_stream == t, std_output, or2(error_stream, std_null)); + parser_common_init(&parser); + parser.stream = stream; + { int gc = gc_state(0); - val name = if3(std_error != std_null, lit("regex"), lit("")); - parse_once(stream, name, &parser); + parse(&parser, if3(std_error != std_null, lit("regex"), lit("")), prime_regex); gc_state(gc); } + + parser_cleanup(&parser); std_error = save_stream; return parser.errors ? nil : parser.syntax_tree; } @@ -274,7 +286,7 @@ val lisp_parse(val source_in, val error_stream, val error_return_val, val name_i { int gc = gc_state(0); - parse(pi, if3(std_error != std_null, name, lit(""))); + parse(pi, if3(std_error != std_null, name, lit("")), prime_lisp); gc_state(gc); } diff --git a/parser.h b/parser.h index bedebfbe..fe8e4413 100644 --- a/parser.h +++ b/parser.h @@ -56,6 +56,8 @@ struct parser { }; #endif +enum prime_parser { prime_lisp, prime_regex }; + extern const wchar_t *spec_file; extern val form_to_ln_hash; extern val parser_s; @@ -76,10 +78,10 @@ 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 *, val name); -void prime_scanner(scanner_t *); +void prime_parser(parser_t *, val name, enum prime_parser); +void prime_scanner(scanner_t *, enum prime_parser); int parse_once(val stream, val name, parser_t *parser); -int parse(parser_t *parser, val name); +int parse(parser_t *parser, val name, enum prime_parser); val source_loc(val form); val source_loc_str(val form, val alt); val rlset(val form, val info); diff --git a/parser.l b/parser.l index 92bad198..2610a921 100644 --- a/parser.l +++ b/parser.l @@ -858,11 +858,6 @@ UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U} yy_push_state(SPECIAL, yyscanner); } -@\x01R { - yy_push_state(REGEX, yyscanner); - return SECRET_ESCAPE_R; -} - ^@[#;].*\n { /* eat whole line comment */ yyextra->lineno++; @@ -1043,12 +1038,20 @@ int yylex(YYSTYPE *yylval_param, yyscan_t yyscanner) return yy_char; } -void prime_scanner(scanner_t *yyg) +void prime_scanner(scanner_t *yyg, enum prime_parser prim) { - if (YYSTATE == INITIAL) { + while (YYSTATE != INITIAL) + yy_pop_state(yyg); + + switch (prim) { + case prime_lisp: yy_push_state(SPECIAL, yyg); yy_push_state(NESTED, yyg); yy_push_state(NESTED, yyg); + break; + case prime_regex: + yy_push_state(REGEX, yyg); + break; } } diff --git a/parser.y b/parser.y index 641422f3..a88293f6 100644 --- a/parser.y +++ b/parser.y @@ -1478,14 +1478,14 @@ int parse_once(val stream, val name, parser_t *parser) return res; } -int parse(parser_t *parser, val name) +int parse(parser_t *parser, val name, enum prime_parser prim) { int res; parser->errors = 0; parser->prepared_msg = nil; parser->syntax_tree = nil; - prime_parser(parser, name); + prime_parser(parser, name, prim); res = yyparse(parser->scanner, parser); -- cgit v1.2.3