summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-06-10 06:31:00 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-06-10 06:31:00 -0700
commit421b7c3aec0b60d126cdec79f2647c901323389f (patch)
tree42821cc8e857c2dc0bfb978f4f06aaf98a9b0a1d
parentb6057e0f7e7ef3f40b0877f8da48ec98d89045c7 (diff)
downloadtxr-421b7c3aec0b60d126cdec79f2647c901323389f.tar.gz
txr-421b7c3aec0b60d126cdec79f2647c901323389f.tar.bz2
txr-421b7c3aec0b60d126cdec79f2647c901323389f.zip
Error handling improvement in read.
* parser.y (spec): New grammar production to handle the cases that SECRET_ESCAPE_E is not followed by anything (the input ends before any object is scanned, or there is no input token which starts an object). * parser.c (lisp_parse): Deal with EOF indication from parser (the syntax_tree member of parser_t set to nao).
-rw-r--r--ChangeLog12
-rw-r--r--parser.c10
-rw-r--r--parser.y7
3 files changed, 25 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 40aaea74..846a2fab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2015-06-10 Kaz Kylheku <kaz@kylheku.com>
+ Error handling improvement in read.
+
+ * parser.y (spec): New grammar production to handle the cases
+ that SECRET_ESCAPE_E is not followed by anything (the input
+ ends before any object is scanned, or there is no input
+ token which starts an object).
+
+ * parser.c (lisp_parse): Deal with EOF indication from parser
+ (the syntax_tree member of parser_t set to nao).
+
+2015-06-10 Kaz Kylheku <kaz@kylheku.com>
+
* parser.y (yybadtoken): Print unexpected character
literally rather than as a Lisp character literal.
diff --git a/parser.c b/parser.c
index 6081c538..34903ce9 100644
--- a/parser.c
+++ b/parser.c
@@ -181,17 +181,19 @@ val lisp_parse(val source_in, val error_stream, val error_return_val, val name_i
{
int gc = gc_state(0);
- name = if3(std_error != std_null, name, lit(""));
- set(mkloc(pi->name, parser), name);
+ set(mkloc(pi->name, parser), if3(std_error != std_null, name, lit("")));
parse(pi);
gc_state(gc);
}
dyn_env = saved_dyn;
- if (pi->errors) {
+ if (pi->errors || pi->syntax_tree == nao) {
if (missingp(error_return_val))
- uw_throwf(syntax_error_s, lit("read: syntax error"), nao);
+ uw_throwf(syntax_error_s, lit("read: ~a: ~a"), name,
+ if3(pi->syntax_tree == nao,
+ lit("end of input reached without seeing object"),
+ lit("errors encountered")), nao);
return error_return_val;
}
diff --git a/parser.y b/parser.y
index 343981f0..01e7295e 100644
--- a/parser.y
+++ b/parser.y
@@ -137,6 +137,13 @@ spec : clauses { parser->syntax_tree = $1; }
| /* empty */ { parser->syntax_tree = nil; }
| SECRET_ESCAPE_R regexpr { parser->syntax_tree = $2; end_of_regex(scnr); }
| SECRET_ESCAPE_E n_expr { parser->syntax_tree = $2; YYACCEPT; }
+ | SECRET_ESCAPE_E { if (yychar == YYEOF) {
+ parser->syntax_tree = nao;
+ YYACCEPT;
+ } else {
+ yybadtok(yychar, nil);
+ parser->syntax_tree = nil;
+ } }
| error '\n' { parser->syntax_tree = nil;
if (parser->errors >= 8)
YYABORT;