summaryrefslogtreecommitdiffstats
path: root/txr.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2014-08-02 18:31:31 -0700
committerKaz Kylheku <kaz@kylheku.com>2014-08-02 18:31:31 -0700
commit894c655f0214531ad7eff3d68d72792ae18d40cd (patch)
treec7da31229ce40626fa937de8e688ac645ace2309 /txr.c
parent73a7ae605d364be49dc5bd1cc15c1116fe47a446 (diff)
downloadtxr-894c655f0214531ad7eff3d68d72792ae18d40cd.tar.gz
txr-894c655f0214531ad7eff3d68d72792ae18d40cd.tar.bz2
txr-894c655f0214531ad7eff3d68d72792ae18d40cd.zip
Big switch to reentrant lexing and parsing.
* parser.l (YY_INPUT): Stop relying on removed yyin_stream; refer to stream via yyextra. (yyin_stream, lineno, errors, spec_file_str, prepared_error_message): Global variables removed. (yyget_column, yyset_column): Missing prototypes not generated by flex in bison bridge mode have to be added by us to avoid warning. (yyerror): Takes parser and scanner as parameters. Prepared error message is now in the parser context. Calls to other error handling functions receive scanner context. (yyerr): New function. (yyerrorf, yyerrprepf): Takes scanner argument, chases extra data to get to parser, and refers to parser variables instead of globals. (num_esc): Scanner argument added. (%option reentrant, %option bison-bridge, %option extra-type): New flex options. (grammar): yyscanner added everywhere. (end_of_char): Takes scanner argument. (parse_init): Removed references to yyin_stream and prepared_error_message. (parse_reset): Function renamed to open_txr_file. Returns results via pointers instead of setting global variables. (regex_parse, lisp_parse): Use reentrant parser interface. * parser.y (yyerror): Prototype removed. (yylex): Prototype moved after grammar, with new arguments. (sym_helper, define_transform): Take scanner argument. (make_expr): Takes parser argument. (rlrec): New static function. (rl): Function turned into macro. (mkexp, symhlpr): New macros. (%purse-parser, %parse-param, %lex-param): New Yacc options. (grammar): Actions re-worked for reentrance. Parser and scanner contexts are passed down to helper functions, in some cases via the three new macros. The result of the parse is stored in the syntax_tree member of the parser_t structure instead of a global. The yylex function receives the scanner instance. (get_spec): Function removed. (parse): New function. * parser.h (lineno, errors, yyin_stream, spec_file_str): Declarations removed. (parser_t): New struct. (yyerr): New function declared. (yyparse, yyerror, yyerrorf, end_of_regex, end_of_char, yylex, yylex_destroy): Declarations updated.
Diffstat (limited to 'txr.c')
-rw-r--r--txr.c23
1 files changed, 10 insertions, 13 deletions
diff --git a/txr.c b/txr.c
index 02d42048..d637ddbb 100644
--- a/txr.c
+++ b/txr.c
@@ -301,17 +301,14 @@ int txr_main(int argc, char **argv)
val spec_file = nil;
val bindings = nil;
val evaled = nil;
+ val spec_file_str;
int match_loglevel = opt_loglevel;
val arg_undo = nil, arg;
+ val parse_stream = std_input;
list_collect_decl(arg_list, arg_tail);
- prot1(&spec_file_str);
-
setvbuf(stderr, 0, _IOLBF, 0);
-
- yyin_stream = std_input;
-
if (argc <= 1) {
hint();
return EXIT_FAILURE;
@@ -519,7 +516,7 @@ int txr_main(int argc, char **argv)
if (gt(length_str(specstring), zero) &&
chr_str(specstring, minus(length_str(specstring), one)) != chr('\n'))
specstring = cat_str(list(specstring, string(L"\n"), nao), nil);
- yyin_stream = make_string_byte_input_stream(specstring);
+ parse_stream = make_string_byte_input_stream(specstring);
if (arg)
arg_list = arg_undo;
} else if (spec_file) {
@@ -527,7 +524,7 @@ int txr_main(int argc, char **argv)
FILE *in = w_fopen(c_str(spec_file), L"r");
if (in == 0)
uw_throwf(file_error_s, lit("unable to open ~a"), spec_file, nao);
- yyin_stream = make_stdio_stream(in, spec_file);
+ parse_stream = make_stdio_stream(in, spec_file);
spec_file_str = spec_file;
} else {
spec_file_str = lit("stdin");
@@ -546,7 +543,7 @@ int txr_main(int argc, char **argv)
FILE *in = w_fopen(c_str(arg), L"r");
if (in == 0)
uw_throwf(file_error_s, lit("unable to open ~a"), arg, nao);
- yyin_stream = make_stdio_stream(in, arg);
+ parse_stream = make_stdio_stream(in, arg);
spec_file_str = arg;
} else {
spec_file_str = lit("stdin");
@@ -557,14 +554,14 @@ int txr_main(int argc, char **argv)
{
int gc = gc_state(0);
- yyparse();
- yylex_destroy();
+ parser_t parser;
+ parse(parse_stream, spec_file_str, &parser);
gc_state(gc);
- if (errors)
+ if (parser.errors)
return EXIT_FAILURE;
- spec = remove_hash_bang_line(get_spec());
+ spec = remove_hash_bang_line(parser.syntax_tree);
opt_loglevel = match_loglevel;
@@ -577,7 +574,7 @@ int txr_main(int argc, char **argv)
{
int retval = extract(spec, arg_list, bindings);
- return errors ? EXIT_FAILURE : retval;
+ return parser.errors ? EXIT_FAILURE : retval;
}
}
}