X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/31b850d2d433aff80a6cc31fef79ada95dab0153..4413bbd3d1689a23f441cbdca898b99d802bb6d6:/src/scan-gram.l
diff --git a/src/scan-gram.l b/src/scan-gram.l
index 279bba97..bcb7209b 100644
--- a/src/scan-gram.l
+++ b/src/scan-gram.l
@@ -18,7 +18,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
-%option debug nodefault nounput noyywrap never-interactive
+%option debug nodefault noinput nounput noyywrap never-interactive
%option prefix="gram_" outfile="lex.yy.c"
%{
@@ -37,6 +37,7 @@
#include
#include
+#include
#include
#include
@@ -70,7 +71,7 @@ static size_t no_cr_read (FILE *, char *, size_t);
/* A string representing the most recently saved token. */
static char *last_string;
-/* Bracketed identifier */
+/* Bracketed identifier. */
static uniqstr bracketed_id_str = 0;
static location bracketed_id_loc;
static boundary bracketed_id_start;
@@ -108,7 +109,7 @@ static void unexpected_newline (boundary, char const *);
%x SC_COMMENT SC_LINE_COMMENT
/* Strings and characters in code. */
%x SC_STRING SC_CHARACTER
- /* Bracketed identifiers support */
+ /* Bracketed identifiers support. */
%x SC_BRACKETED_ID SC_RETURN_BRACKETED_ID
letter [-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
@@ -260,8 +261,8 @@ splice (\\[ \f\t\v]*\n)*
complain_at (*loc, _("invalid identifier: %s"), quote (yytext));
}
- /* Characters. We don't check there is only one. */
- "'" STRING_GROW; token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
+ /* Characters. */
+ "'" token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
/* Strings. */
"\"" token_start = loc->start; BEGIN SC_ESCAPED_STRING;
@@ -336,19 +337,19 @@ splice (\\[ \f\t\v]*\n)*
{
"[" {
- if (!bracketed_id_str)
- {
- bracketed_id_start = loc->start;
- bracketed_id_context_state = YY_START;
- BEGIN SC_BRACKETED_ID;
- }
- else
+ if (bracketed_id_str)
{
ROLLBACK_CURRENT_TOKEN;
BEGIN SC_RETURN_BRACKETED_ID;
*loc = id_loc;
return ID;
}
+ else
+ {
+ bracketed_id_start = loc->start;
+ bracketed_id_context_state = YY_START;
+ BEGIN SC_BRACKETED_ID;
+ }
}
":" {
BEGIN (bracketed_id_str ? SC_RETURN_BRACKETED_ID : INITIAL);
@@ -375,15 +376,15 @@ splice (\\[ \f\t\v]*\n)*
{
{id} {
- if (!bracketed_id_str)
+ if (bracketed_id_str)
{
- bracketed_id_str = uniqstr_new (yytext);
- bracketed_id_loc = *loc;
+ complain_at (*loc, _("unexpected identifier in bracketed name: %s"),
+ quote (yytext));
}
else
{
- complain_at (*loc, _("redundant identifier in bracketed name: %s"),
- quote (yytext));
+ bracketed_id_str = uniqstr_new (yytext);
+ bracketed_id_loc = *loc;
}
}
"]" {
@@ -399,7 +400,7 @@ splice (\\[ \f\t\v]*\n)*
}
}
else
- complain_at (*loc, _("a non empty identifier expected"));
+ complain_at (*loc, _("an identifier expected"));
}
. {
complain_at (*loc, _("invalid character in bracketed name: %s"),
@@ -493,24 +494,42 @@ splice (\\[ \f\t\v]*\n)*
{
"'"|"\n" {
- if (yytext[0] == '\n')
- unexpected_newline (token_start, "'");
- STRING_GROW;
STRING_FINISH;
loc->start = token_start;
- val->character = last_string[1];
+ val->character = last_string[0];
+ {
+ /* FIXME: Eventually, make these errors. */
+ if (last_string[0] == '\0')
+ {
+ warn_at (*loc, _("empty character literal"));
+ /* '\0' seems dangerous even if we are about to complain. */
+ val->character = '\'';
+ }
+ else if (last_string[1] != '\0')
+ warn_at (*loc, _("extra characters in character literal"));
+ }
+ if (yytext[0] == '\n')
+ unexpected_newline (token_start, "'");
STRING_FREE;
BEGIN INITIAL;
return CHAR;
}
<> {
- 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];
+ val->character = last_string[0];
+ {
+ /* FIXME: Eventually, make these errors. */
+ if (last_string[0] == '\0')
+ {
+ warn_at (*loc, _("empty character literal"));
+ /* '\0' seems dangerous even if we are about to complain. */
+ val->character = '\'';
+ }
+ else if (last_string[1] != '\0')
+ warn_at (*loc, _("extra characters in character literal"));
+ }
+ unexpected_eof (token_start, "'");
STRING_FREE;
BEGIN INITIAL;
return CHAR;
@@ -560,10 +579,9 @@ splice (\\[ \f\t\v]*\n)*
{
\\[0-7]{1,3} {
unsigned long int c = strtoul (yytext + 1, NULL, 8);
- if (UCHAR_MAX < c)
- complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
- else if (! c)
- complain_at (*loc, _("invalid null character: %s"), quote (yytext));
+ if (!c || UCHAR_MAX < c)
+ complain_at (*loc, _("invalid number after \\-escape: %s"),
+ yytext+1);
else
obstack_1grow (&obstack_for_string, c);
}
@@ -571,10 +589,9 @@ splice (\\[ \f\t\v]*\n)*
\\x[0-9abcdefABCDEF]+ {
verify (UCHAR_MAX < ULONG_MAX);
unsigned long int c = strtoul (yytext + 2, NULL, 16);
- if (UCHAR_MAX < c)
- complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
- else if (! c)
- complain_at (*loc, _("invalid null character: %s"), quote (yytext));
+ if (!c || UCHAR_MAX < c)
+ complain_at (*loc, _("invalid number after \\-escape: %s"),
+ yytext+1);
else
obstack_1grow (&obstack_for_string, c);
}
@@ -592,16 +609,20 @@ splice (\\[ \f\t\v]*\n)*
\\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
int c = convert_ucn_to_byte (yytext);
- if (c < 0)
- complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
- else if (! c)
- complain_at (*loc, _("invalid null character: %s"), quote (yytext));
+ if (c <= 0)
+ complain_at (*loc, _("invalid number after \\-escape: %s"),
+ yytext+1);
else
obstack_1grow (&obstack_for_string, c);
}
\\(.|\n) {
- complain_at (*loc, _("unrecognized escape sequence: %s"), quote (yytext));
- STRING_GROW;
+ char const *p = yytext + 1;
+ /* Quote only if escaping won't make the character visible. */
+ if (isspace ((unsigned char) *p) && isprint ((unsigned char) *p))
+ p = quote (p);
+ else
+ p = quotearg_style_mem (escape_quoting_style, p, 1);
+ complain_at (*loc, _("invalid character after \\-escape: %s"), p);
}
}