them to the parser in order to improve error messages.
* src/scan-gram.l (SC_ESCAPED_STRING, SC_ESCAPED_CHARACTER,
SC_BRACED_CODE, SC_PROLOGUE): Implement.
* tests/input.at (Unclosed constructs): New test case.
* tests/regression.at (Invalid inputs): Update now that unclosed %{ is
seen.
* src/scan-gram.h, src/scan-gram.l (gram_last_braced_code_loc): Remove
unused global.
+2006-08-14 Joel E. Denny <jdenny@ces.clemson.edu>
+
+ In the grammar scanner, STRING_FINISH unclosed constructs and return
+ them to the parser in order to improve error messages.
+ * src/scan-gram.l (SC_ESCAPED_STRING, SC_ESCAPED_CHARACTER,
+ SC_BRACED_CODE, SC_PROLOGUE): Implement.
+ * tests/input.at (Unclosed constructs): New test case.
+ * tests/regression.at (Invalid inputs): Update now that unclosed %{ is
+ seen.
+
+ * src/scan-gram.h, src/scan-gram.l (gram_last_braced_code_loc): Remove
+ unused global.
+
2006-08-13 Joel E. Denny <jdenny@ces.clemson.edu>
Handle string aliases for character tokens correctly.
extern FILE *gram_in;
extern int gram__flex_debug;
extern char *gram_last_string;
-extern location gram_last_braced_code_loc;
void gram_scanner_initialize (void);
void gram_scanner_free (void);
void gram_scanner_last_string_free (void);
STRING_FREE;
}
-/* The location of the most recently saved token, if it was a
- BRACED_CODE token; otherwise, this has an unspecified value. */
-location gram_last_braced_code_loc;
-
static void handle_syncline (char *, location);
static unsigned long int scan_integer (char const *p, int base, location loc);
static int convert_ucn_to_byte (char const *hex_text);
<SC_ESCAPED_STRING>
{
- "\"" {
+ "\""|"\n" {
+ if (yytext[0] == '\n')
+ unexpected_newline (token_start, "\"");
+ STRING_FINISH;
+ loc->start = token_start;
+ val->chars = last_string;
+ BEGIN INITIAL;
+ return STRING;
+ }
+ <<EOF>> {
+ unexpected_eof (token_start, "\"");
STRING_FINISH;
loc->start = token_start;
val->chars = last_string;
BEGIN INITIAL;
return STRING;
}
- \n unexpected_newline (token_start, "\""); BEGIN INITIAL;
- <<EOF>> unexpected_eof (token_start, "\""); BEGIN INITIAL;
}
/*----------------------------------------------------------.
<SC_ESCAPED_CHARACTER>
{
- "'" {
+ "'"|"\n" {
+ if (yytext[0] == '\n')
+ unexpected_newline (token_start, "'");
STRING_GROW;
STRING_FINISH;
loc->start = token_start;
BEGIN INITIAL;
return CHAR;
}
- \n unexpected_newline (token_start, "'"); BEGIN INITIAL;
- <<EOF>> unexpected_eof (token_start, "'"); BEGIN INITIAL;
+ <<EOF>> {
+ unexpected_eof (token_start, "'");
+ STRING_FINISH;
+ loc->start = token_start;
+ if (strlen(last_string) > 1)
+ val->character = last_string[1];
+ else
+ val->character = last_string[0];
+ STRING_FREE;
+ BEGIN INITIAL;
+ return CHAR;
+ }
}
<SC_ESCAPED_CHARACTER,SC_ESCAPED_STRING>
STRING_FINISH;
loc->start = code_start;
val->chars = last_string;
- gram_last_braced_code_loc = *loc;
BEGIN INITIAL;
return BRACED_CODE;
}
(as `<' `<%'). */
"<"{splice}"<" STRING_GROW;
- <<EOF>> unexpected_eof (code_start, "}"); BEGIN INITIAL;
+ <<EOF>> {
+ unexpected_eof (code_start, "}");
+ STRING_FINISH;
+ loc->start = code_start;
+ val->chars = last_string;
+ BEGIN INITIAL;
+ return BRACED_CODE;
+ }
}
return PROLOGUE;
}
- <<EOF>> unexpected_eof (code_start, "%}"); BEGIN INITIAL;
+ <<EOF>> {
+ unexpected_eof (code_start, "%}");
+ STRING_FINISH;
+ loc->start = code_start;
+ val->chars = last_string;
+ BEGIN INITIAL;
+ return PROLOGUE;
+ }
}
AT_CHECK([bison -o input.c input.y])
AT_CLEANUP
+
+
+## --------------------- ##
+## Unclosed constructs. ##
+## --------------------- ##
+
+AT_SETUP([Unclosed constructs])
+
+# Bison's scan-gram.l once forgot to STRING_FINISH some unclosed constructs, so
+# they were prepended to whatever it STRING_GROW'ed next. It also threw them
+# away rather than returning them to the parser. The effect was confusing
+# subsequent error messages.
+
+AT_DATA([input.y],
+[[%token A "a
+%token B "b"
+%token AB "ab" // Used to complain that "ab" was already used.
+%token C '1
+%token TWO "2"
+%token TICK_TWELVE "'12" // Used to complain that "'12" was already used.
+
+%%
+
+start: ;
+
+// Used to report a syntax error because it didn't see any kind of symbol
+// identifier.
+%type <f> 'a
+;
+%type <f> "a
+;
+// Used to report a syntax error because it didn't see braced code.
+%destructor { free ($$)
+]])
+
+AT_CHECK([bison -o input.c input.y], 1, [],
+[[input.y:1.10-2.0: missing `"' at end of line
+input.y:4.10-5.0: missing `'' at end of line
+input.y:14.11-15.0: missing `'' at end of line
+input.y:16.11-17.0: missing `"' at end of line
+input.y:19.13-20.0: missing `}' at end of file
+input.y:20.1: syntax error, unexpected end of file, expecting ;
+]])
+
+AT_CLEANUP
input.y:6.1: invalid character: `%'
input.y:6.2: invalid character: `-'
input.y:7.1-8.0: missing `%}' at end of file
+input.y:7.1-8.0: syntax error, unexpected %{...%}
]])
AT_CLEANUP