X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/11b192127cac086338bfaa43f3bab3acda8e3a20..246ff8c1d38b041a080a7aa98711bf2728698b6f:/src/scan-gram.l diff --git a/src/scan-gram.l b/src/scan-gram.l index 2275d022..2ed6d2fd 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -1,6 +1,6 @@ /* Bison Grammar Scanner -*- C -*- - Copyright (C) 2002-2012 Free Software Foundation, Inc. + Copyright (C) 2002-2013 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -%option debug nodefault noinput nounput noyywrap never-interactive +%option debug nodefault noinput noyywrap never-interactive %option prefix="gram_" outfile="lex.yy.c" %{ @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -73,6 +74,15 @@ static size_t no_cr_read (FILE *, char *, size_t); yyless (0); \ } while (0) +#define DEPRECATED(Msg) \ + do { \ + size_t i; \ + deprecated_directive (loc, yytext, Msg); \ + scanner_cursor.column -= mbsnwidth (Msg, strlen (Msg), 0); \ + for (i = strlen (Msg); i != 0; --i) \ + unput (Msg[i - 1]); \ + } while (0) + /* A string representing the most recently saved token. */ static char *last_string; @@ -119,8 +129,8 @@ static void unexpected_newline (boundary, char const *); %x SC_BRACKETED_ID SC_RETURN_BRACKETED_ID letter [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_] +notletter [^.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]{-}[%\{] id {letter}({letter}|[-0-9])* -directive %{id} int [0-9]+ /* POSIX says that a tag must be both an id and a C union member, but @@ -134,6 +144,10 @@ tag [^\0<>]+ white space between the backslash and the newline. */ splice (\\[ \f\t\v]*\n)* +/* An equal sign, with optional leading whitespaces. This is used in some + deprecated constructs. */ +eqopt ([[:space:]]*=)? + %% %{ /* Nesting level. Either for nested braces, or nested angle brackets @@ -165,10 +179,10 @@ splice (\\[ \f\t\v]*\n)* { /* Comments and white space. */ "," { - complain_at (*loc, Wother, _("stray ',' treated as white space")); + complain (loc, Wother, _("stray ',' treated as white space")); } [ \f\n\t\v] | - "//".* ; + "//".* continue; "/*" { token_start = loc->start; context_state = YY_START; @@ -177,7 +191,7 @@ splice (\\[ \f\t\v]*\n)* /* #line directives are not documented, and may be withdrawn or modified in future versions of Bison. */ - ^"#line "{int}" \"".*"\"\n" { + ^"#line "{int}(" \"".*"\"")?"\n" { handle_syncline (yytext + sizeof "#line " - 1, *loc); } } @@ -198,16 +212,16 @@ splice (\\[ \f\t\v]*\n)* "%binary" return PERCENT_NONASSOC; "%code" return PERCENT_CODE; "%debug" RETURN_PERCENT_FLAG("parse.trace"); - "%default"[-_]"prec" return PERCENT_DEFAULT_PREC; + "%default-prec" return PERCENT_DEFAULT_PREC; "%define" return PERCENT_DEFINE; "%defines" return PERCENT_DEFINES; "%destructor" return PERCENT_DESTRUCTOR; "%dprec" return PERCENT_DPREC; - "%error"[-_]"verbose" return PERCENT_ERROR_VERBOSE; + "%error-verbose" return PERCENT_ERROR_VERBOSE; "%expect" return PERCENT_EXPECT; - "%expect"[-_]"rr" return PERCENT_EXPECT_RR; + "%expect-rr" return PERCENT_EXPECT_RR; "%file-prefix" return PERCENT_FILE_PREFIX; - "%fixed"[-_]"output"[-_]"files" return PERCENT_YACC; + "%fixed-output-files" return PERCENT_YACC; "%initial-action" return PERCENT_INITIAL_ACTION; "%glr-parser" return PERCENT_GLR_PARSER; "%language" return PERCENT_LANGUAGE; @@ -215,9 +229,9 @@ splice (\\[ \f\t\v]*\n)* "%lex-param" RETURN_PERCENT_PARAM(lex); "%locations" RETURN_PERCENT_FLAG("locations"); "%merge" return PERCENT_MERGE; - "%name"[-_]"prefix" return PERCENT_NAME_PREFIX; - "%no"[-_]"default"[-_]"prec" return PERCENT_NO_DEFAULT_PREC; - "%no"[-_]"lines" return PERCENT_NO_LINES; + "%name-prefix" return PERCENT_NAME_PREFIX; + "%no-default-prec" return PERCENT_NO_DEFAULT_PREC; + "%no-lines" return PERCENT_NO_LINES; "%nonassoc" return PERCENT_NONASSOC; "%nondeterministic-parser" return PERCENT_NONDETERMINISTIC_PARSER; "%nterm" return PERCENT_NTERM; @@ -227,21 +241,34 @@ splice (\\[ \f\t\v]*\n)* "%prec" return PERCENT_PREC; "%precedence" return PERCENT_PRECEDENCE; "%printer" return PERCENT_PRINTER; - "%pure"[-_]"parser" RETURN_PERCENT_FLAG("api.pure"); + "%pure-parser" RETURN_PERCENT_FLAG("api.pure"); "%require" return PERCENT_REQUIRE; "%right" return PERCENT_RIGHT; "%skeleton" return PERCENT_SKELETON; "%start" return PERCENT_START; "%term" return PERCENT_TOKEN; "%token" return PERCENT_TOKEN; - "%token"[-_]"table" return PERCENT_TOKEN_TABLE; + "%token-table" return PERCENT_TOKEN_TABLE; "%type" return PERCENT_TYPE; "%union" return PERCENT_UNION; "%verbose" return PERCENT_VERBOSE; "%yacc" return PERCENT_YACC; - {directive} { - complain_at (*loc, complaint, _("invalid directive: %s"), quote (yytext)); + /* deprecated */ + "%default"[-_]"prec" DEPRECATED("%default-prec"); + "%error"[-_]"verbose" DEPRECATED("%define parse.error verbose"); + "%expect"[-_]"rr" DEPRECATED("%expect-rr"); + "%file-prefix"{eqopt} DEPRECATED("%file-prefix"); + "%fixed"[-_]"output"[-_]"files" DEPRECATED("%fixed-output-files"); + "%name"[-_]"prefix"{eqopt} DEPRECATED("%name-prefix"); + "%no"[-_]"default"[-_]"prec" DEPRECATED("%no-default-prec"); + "%no"[-_]"lines" DEPRECATED("%no-lines"); + "%output"{eqopt} DEPRECATED("%output"); + "%pure"[-_]"parser" DEPRECATED("%pure-parser"); + "%token"[-_]"table" DEPRECATED("%token-table"); + + "%"{id}|"%"{notletter}([[:graph:]])+ { + complain (loc, complaint, _("invalid directive: %s"), quote (yytext)); } "=" return EQUAL; @@ -267,7 +294,7 @@ splice (\\[ \f\t\v]*\n)* /* Identifiers may not start with a digit. Yet, don't silently accept "1FOO" as "1 FOO". */ {int}{id} { - complain_at (*loc, complaint, _("invalid identifier: %s"), quote (yytext)); + complain (loc, complaint, _("invalid identifier: %s"), quote (yytext)); } /* Characters. */ @@ -324,8 +351,10 @@ splice (\\[ \f\t\v]*\n)* BEGIN SC_BRACKETED_ID; } - . { - complain_at (*loc, complaint, _("invalid character: %s"), quote (yytext)); + [^\[%A-Za-z0-9_<>{}\"\'*;|=/, \f\n\t\v]+|. { + complain (loc, complaint, "%s: %s", + ngettext ("invalid character", "invalid characters", yyleng), + quote_mem (yytext, yyleng)); } <> { @@ -342,7 +371,7 @@ splice (\\[ \f\t\v]*\n)* { - \0 complain_at (*loc, complaint, _("invalid null character")); + \0 complain (loc, complaint, _("invalid null character")); } @@ -394,9 +423,9 @@ splice (\\[ \f\t\v]*\n)* {id} { if (bracketed_id_str) { - complain_at (*loc, complaint, - _("unexpected identifier in bracketed name: %s"), - quote (yytext)); + complain (loc, complaint, + _("unexpected identifier in bracketed name: %s"), + quote (yytext)); } else { @@ -417,12 +446,16 @@ splice (\\[ \f\t\v]*\n)* } } else - complain_at (*loc, complaint, _("an identifier expected")); + complain (loc, complaint, _("an identifier expected")); } - . { - complain_at (*loc, complaint, _("invalid character in bracketed name: %s"), - quote (yytext)); + + [^\].A-Za-z0-9_/ \f\n\t\v]+|. { + complain (loc, complaint, "%s: %s", + ngettext ("invalid character in bracketed name", + "invalid characters in bracketed name", yyleng), + quote_mem (yytext, yyleng)); } + <> { BEGIN bracketed_id_context_state; unexpected_eof (bracketed_id_start, "]"); @@ -449,7 +482,7 @@ splice (\\[ \f\t\v]*\n)* { "*/" BEGIN context_state; - .|\n ; + .|\n continue; <> unexpected_eof (token_start, "*/"); BEGIN context_state; } @@ -484,23 +517,15 @@ splice (\\[ \f\t\v]*\n)* { - "\""|"\n" { - if (yytext[0] == '\n') - unexpected_newline (token_start, "\""); - STRING_FINISH; - loc->start = token_start; - val->chars = last_string; - BEGIN INITIAL; - return STRING; - } - <> { - unexpected_eof (token_start, "\""); + "\"" { STRING_FINISH; loc->start = token_start; val->chars = last_string; BEGIN INITIAL; return STRING; } + <> unexpected_eof (token_start, "\""); + "\n" unexpected_newline (token_start, "\""); } /*----------------------------------------------------------. @@ -510,49 +535,27 @@ splice (\\[ \f\t\v]*\n)* { - "'"|"\n" { + "'" { STRING_FINISH; loc->start = token_start; val->character = last_string[0]; + + /* FIXME: Eventually, make these errors. */ + if (last_string[0] == '\0') { - /* FIXME: Eventually, make these errors. */ - if (last_string[0] == '\0') - { - complain_at (*loc, Wother, _("empty character literal")); - /* '\0' seems dangerous even if we are about to complain. */ - val->character = '\''; - } - else if (last_string[1] != '\0') - complain_at (*loc, Wother, - _("extra characters in character literal")); + complain (loc, Wother, _("empty character literal")); + /* '\0' seems dangerous even if we are about to complain. */ + val->character = '\''; } - if (yytext[0] == '\n') - unexpected_newline (token_start, "'"); - STRING_FREE; - BEGIN INITIAL; - return CHAR; - } - <> { - STRING_FINISH; - loc->start = token_start; - val->character = last_string[0]; - { - /* FIXME: Eventually, make these errors. */ - if (last_string[0] == '\0') - { - complain_at (*loc, Wother, _("empty character literal")); - /* '\0' seems dangerous even if we are about to complain. */ - val->character = '\''; - } - else if (last_string[1] != '\0') - complain_at (*loc, Wother, - _("extra characters in character literal")); - } - unexpected_eof (token_start, "'"); + else if (last_string[1] != '\0') + complain (loc, Wother, + _("extra characters in character literal")); STRING_FREE; BEGIN INITIAL; return CHAR; } + "\n" unexpected_newline (token_start, "'"); + <> unexpected_eof (token_start, "'"); } /*-----------------------------------------------------------. @@ -579,15 +582,7 @@ splice (\\[ \f\t\v]*\n)* [^<>]+ STRING_GROW; "<"+ STRING_GROW; nesting += yyleng; - <> { - unexpected_eof (token_start, ">"); - STRING_FINISH; - loc->start = token_start; - val->uniqstr = uniqstr_new (last_string); - STRING_FREE; - BEGIN INITIAL; - return TAG; - } + <> unexpected_eof (token_start, ">"); } /*----------------------------. @@ -599,7 +594,7 @@ splice (\\[ \f\t\v]*\n)* \\[0-7]{1,3} { unsigned long int c = strtoul (yytext + 1, NULL, 8); if (!c || UCHAR_MAX < c) - complain_at (*loc, complaint, _("invalid number after \\-escape: %s"), + complain (loc, complaint, _("invalid number after \\-escape: %s"), yytext+1); else obstack_1grow (&obstack_for_string, c); @@ -609,7 +604,7 @@ splice (\\[ \f\t\v]*\n)* verify (UCHAR_MAX < ULONG_MAX); unsigned long int c = strtoul (yytext + 2, NULL, 16); if (!c || UCHAR_MAX < c) - complain_at (*loc, complaint, _("invalid number after \\-escape: %s"), + complain (loc, complaint, _("invalid number after \\-escape: %s"), yytext+1); else obstack_1grow (&obstack_for_string, c); @@ -629,7 +624,7 @@ 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, complaint, _("invalid number after \\-escape: %s"), + complain (loc, complaint, _("invalid number after \\-escape: %s"), yytext+1); else obstack_1grow (&obstack_for_string, c); @@ -641,7 +636,7 @@ splice (\\[ \f\t\v]*\n)* p = quote (p); else p = quotearg_style_mem (escape_quoting_style, p, 1); - complain_at (*loc, complaint, _("invalid character after \\-escape: %s"), + complain (loc, complaint, _("invalid character after \\-escape: %s"), p); } } @@ -658,15 +653,15 @@ splice (\\[ \f\t\v]*\n)* { "'" STRING_GROW; BEGIN context_state; - \n unexpected_newline (token_start, "'"); BEGIN context_state; - <> unexpected_eof (token_start, "'"); BEGIN context_state; + \n unexpected_newline (token_start, "'"); + <> unexpected_eof (token_start, "'"); } { "\"" STRING_GROW; BEGIN context_state; - \n unexpected_newline (token_start, "\""); BEGIN context_state; - <> unexpected_eof (token_start, "\""); BEGIN context_state; + \n unexpected_newline (token_start, "\""); + <> unexpected_eof (token_start, "\""); } @@ -717,15 +712,7 @@ splice (\\[ \f\t\v]*\n)* (as '<' '<%'). */ "<"{splice}"<" STRING_GROW; - <> { - int token = (YY_START == SC_BRACED_CODE) ? BRACED_CODE : BRACED_PREDICATE; - unexpected_eof (code_start, "}"); - STRING_FINISH; - loc->start = code_start; - val->code = last_string; - BEGIN INITIAL; - return token; - } + <> unexpected_eof (code_start, "}"); } @@ -776,14 +763,7 @@ splice (\\[ \f\t\v]*\n)* return PROLOGUE; } - <> { - unexpected_eof (code_start, "%}"); - STRING_FINISH; - loc->start = code_start; - val->chars = last_string; - BEGIN INITIAL; - return PROLOGUE; - } + <> unexpected_eof (code_start, "%}"); } @@ -873,7 +853,7 @@ scan_integer (char const *number, int base, location loc) if (INT_MAX < num) { - complain_at (loc, complaint, _("integer out of range: %s"), + complain (&loc, complaint, _("integer out of range: %s"), quote (number)); num = INT_MAX; } @@ -939,31 +919,35 @@ convert_ucn_to_byte (char const *ucn) } -/*----------------------------------------------------------------. -| Handle '#line INT "FILE"'. ARGS has already skipped '#line '. | -`----------------------------------------------------------------*/ +/*---------------------------------------------------------------------. +| Handle '#line INT( "FILE")?\n'. ARGS has already skipped '#line '. | +`---------------------------------------------------------------------*/ static void handle_syncline (char *args, location loc) { - char *after_num; - unsigned long int lineno = strtoul (args, &after_num, 10); - char *file = strchr (after_num, '"') + 1; - *strchr (file, '"') = '\0'; + char *file; + unsigned long int lineno = strtoul (args, &file, 10); if (INT_MAX <= lineno) { - complain_at (loc, Wother, _("line number overflow")); + complain (&loc, Wother, _("line number overflow")); lineno = INT_MAX; } - current_file = uniqstr_new (file); + + file = strchr (file, '"'); + if (file) + { + *strchr (file + 1, '"') = '\0'; + current_file = uniqstr_new (file + 1); + } boundary_set (&scanner_cursor, current_file, lineno, 1); } /*----------------------------------------------------------------. | For a token or comment starting at START, report message MSGID, | -| which should say that an end marker was found before | -| the expected TOKEN_END. | +| which should say that an end marker was found before the | +| expected TOKEN_END. Then, pretend that TOKEN_END was found. | `----------------------------------------------------------------*/ static void @@ -972,17 +956,27 @@ unexpected_end (boundary start, char const *msgid, char const *token_end) location loc; loc.start = start; loc.end = scanner_cursor; + size_t i = strlen (token_end); + +/* Adjust scanner cursor so that any later message does not count + the characters about to be inserted. */ + scanner_cursor.column -= i; + + while (i != 0) + unput (token_end[--i]); + token_end = quote (token_end); - // Instead of '\'', display "'". + /* Instead of '\'', display "'". */ if (STREQ (token_end, "'\\''")) token_end = "\"'\""; - complain_at (loc, complaint, _(msgid), token_end); + complain (&loc, complaint, _(msgid), token_end); } /*------------------------------------------------------------------------. | Report an unexpected EOF in a token or comment starting at START. | | An end of file was encountered and the expected TOKEN_END was missing. | +| After reporting the problem, pretend that TOKEN_END was found. | `------------------------------------------------------------------------*/ static void