diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-07-10 07:31:55 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-07-10 07:31:55 -0700 |
commit | 5c4e844c2c9c25324c3c1cb6d47b2967f65c633d (patch) | |
tree | fa96ee3aedbc243b16c011268bd5d99df9759b2e | |
parent | 4fa8bbcb93d76caa7e599c60952ee06c45f55bd2 (diff) | |
download | txr-5c4e844c2c9c25324c3c1cb6d47b2967f65c633d.tar.gz txr-5c4e844c2c9c25324c3c1cb6d47b2967f65c633d.tar.bz2 txr-5c4e844c2c9c25324c3c1cb6d47b2967f65c633d.zip |
Bugfix: lexer loses unmatched "hold char" between top-level forms.
Test case: file containing 4(prinl 3). Scanner consumes 4 and (.
The ( is lost when the scanner is reset for the next call to yyparse,
resulting in jut prinl being read and interpreted as a variable.
* parser.c (prime_parser): If present, append hold byte to priming
string. Takes parser_t * instead of parser, and returns void now.
* parser.l (reset_scanner): Now returns int value, the value
of the scanner's yy_hold_char variable which is nonzero when
the scanner is hanging on to an unmatched byte of input.
* parser.h (reset_scanner, prime_parser): Declarations updated.
* parser.y (parse): Pass hold byte returned by reset_scanner to
prime_parser.
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | parser.c | 17 | ||||
-rw-r--r-- | parser.h | 4 | ||||
-rw-r--r-- | parser.l | 6 | ||||
-rw-r--r-- | parser.y | 3 |
5 files changed, 39 insertions, 11 deletions
@@ -1,5 +1,25 @@ 2015-07-10 Kaz Kylheku <kaz@kylheku.com> + Bugfix: lexer loses unmatched "hold char" between top-level forms. + + Test case: file containing 4(prinl 3). Scanner consumes 4 and (. + The ( is lost when the scanner is reset for the next call to yyparse, + resulting in jut prinl being read and interpreted as a variable. + + * parser.c (prime_parser): If present, append hold byte to priming + string. Takes parser_t * instead of parser, and returns void now. + + * parser.l (reset_scanner): Now returns int value, the value + of the scanner's yy_hold_char variable which is nonzero when + the scanner is hanging on to an unmatched byte of input. + + * parser.h (reset_scanner, prime_parser): Declarations updated. + + * parser.y (parse): Pass hold byte returned by reset_scanner to + prime_parser. + +2015-07-10 Kaz Kylheku <kaz@kylheku.com> + * stream.c (byte_in_unget_byte): Wrong function name in error message. 2015-07-10 Kaz Kylheku <kaz@kylheku.com> @@ -127,19 +127,24 @@ static val ensure_parser(val stream, val primer) return set(cdr_l(cell), parser(stream, one, primer)); } -val prime_parser(val parser) +void prime_parser(parser_t *p, int hold_byte) { - parser_t *p = get_parser_impl(parser); - val secret_token_stream = make_string_byte_input_stream(lit("@\x01" "E")); + 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")); + } if (catenated_stream_p(p->stream)) { catenated_stream_push(secret_token_stream, p->stream); } else { - set(mkloc(p->stream, parser), + set(mkloc(p->stream, p->parser), make_catenated_stream(list(secret_token_stream, p->stream, nao))); } - - return parser; } void open_txr_file(val spec_file, val *txr_lisp_p, val *name, val *stream) @@ -53,14 +53,14 @@ 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 reset_scanner(scanner_t *scanner); 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 parser_l_init(void); void open_txr_file(val spec_file, val *txr_lisp_p, val *name, val *stream); -val prime_parser(val parser); +void prime_parser(parser_t *, int hold_byte); int parse_once(val stream, val name, parser_t *parser); int parse(parser_t *parser); val source_loc(val form); @@ -960,12 +960,16 @@ void end_of_char(scanner_t *yyg) yy_pop_state(yyg); } -void reset_scanner(scanner_t *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) @@ -1463,8 +1463,7 @@ int parse(parser_t *parser) parser->errors = 0; parser->prepared_msg = nil; parser->syntax_tree = nil; - prime_parser(parser->parser); - reset_scanner(parser->scanner); + prime_parser(parser, reset_scanner(parser->scanner)); res = yyparse(parser->scanner, parser); |