X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/624a35e20b675af53c8e23805ce79b3b6e3b11ed..916708d59e02812675ce2d85597b7e1f2d677213:/src/scan-gram.l diff --git a/src/scan-gram.l b/src/scan-gram.l index da041a4f..337f9db1 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -1,6 +1,6 @@ /* Bison Grammar Scanner -*- C -*- - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of Bison, the GNU Compiler Compiler. @@ -20,7 +20,7 @@ 02111-1307 USA */ -%option debug nodefault noyywrap never-interactive +%option debug nodefault nounput noyywrap never-interactive %option prefix="gram_" outfile="lex.yy.c" %{ @@ -43,6 +43,7 @@ scanner_cursor.file = current_file; \ scanner_cursor.line = 1; \ scanner_cursor.column = 1; \ + code_start = scanner_cursor; \ } \ while (0) @@ -101,7 +102,7 @@ static void handle_dollar (int token_type, char *cp, location loc); static void handle_at (int token_type, char *cp, location loc); static void handle_syncline (char *args); static int convert_ucn_to_byte (char const *hex_text); -static void unexpected_end_of_file (boundary, char const *); +static void unexpected_eof (boundary, char const *); %} %x SC_COMMENT SC_LINE_COMMENT SC_YACC_COMMENT @@ -136,14 +137,16 @@ splice (\\[ \f\t\v]*\n)* int token_type IF_LINT (= 0); /* Location of most recent identifier, when applicable. */ - location id_loc IF_LINT (= *loc); + location id_loc IF_LINT (= empty_location); - /* Where containing code started, when applicable. */ - boundary code_start IF_LINT (= loc->start); + /* Where containing code started, when applicable. Its initial + value is relevant only when yylex is invoked in the SC_EPILOGUE + start condition. */ + boundary code_start = scanner_cursor; /* Where containing comment or string or character literal started, when applicable. */ - boundary token_start IF_LINT (= loc->start); + boundary token_start IF_LINT (= scanner_cursor); %} @@ -154,10 +157,15 @@ splice (\\[ \f\t\v]*\n)* { [ \f\n\t\v] ; + "," warn_at (*loc, _("stray `,' treated as white space")); /* Comments. */ - "/*" token_start = loc->start; context_state = YY_START; BEGIN SC_YACC_COMMENT; "//".* ; + "/*" { + token_start = loc->start; + context_state = YY_START; + BEGIN SC_YACC_COMMENT; + } /* #line directives are not documented, and may be withdrawn or modified in future versions of Bison. */ @@ -190,6 +198,7 @@ splice (\\[ \f\t\v]*\n)* "%name"[-_]"prefix" return PERCENT_NAME_PREFIX; "%no"[-_]"lines" return PERCENT_NO_LINES; "%nonassoc" return PERCENT_NONASSOC; + "%nondeterministic-parser" return PERCENT_NONDETERMINISTIC_PARSER; "%nterm" return PERCENT_NTERM; "%output" return PERCENT_OUTPUT; "%parse-param" token_type = PERCENT_PARSE_PARAM; BEGIN SC_PRE_CODE; @@ -215,10 +224,6 @@ splice (\\[ \f\t\v]*\n)* "|" rule_length = 0; return PIPE; ";" return SEMICOLON; - "," { - warn_at (*loc, _("stray `,' treated as white space")); - } - {id} { val->symbol = symbol_get (yytext, *loc); id_loc = *loc; @@ -269,16 +274,18 @@ splice (\\[ \f\t\v]*\n)* "%%" { static int percent_percent_count; if (++percent_percent_count == 2) - { - code_start = loc->start; - BEGIN SC_EPILOGUE; - } + BEGIN SC_EPILOGUE; return PERCENT_PERCENT; } . { complain_at (*loc, _("invalid character: %s"), quote (yytext)); } + + <> { + loc->start = loc->end = scanner_cursor; + yyterminate (); + } } @@ -317,7 +324,7 @@ splice (\\[ \f\t\v]*\n)* { "*/" BEGIN context_state; .|\n ; - <> unexpected_end_of_file (token_start, "*/"); + <> unexpected_eof (token_start, "*/"); BEGIN context_state; } @@ -328,7 +335,7 @@ splice (\\[ \f\t\v]*\n)* { "*"{splice}"/" STRING_GROW; BEGIN context_state; - <> unexpected_end_of_file (token_start, "*/"); + <> unexpected_eof (token_start, "*/"); BEGIN context_state; } @@ -362,7 +369,7 @@ splice (\\[ \f\t\v]*\n)* } .|\n STRING_GROW; - <> unexpected_end_of_file (token_start, "\""); + <> unexpected_eof (token_start, "\""); BEGIN INITIAL; } /*---------------------------------------------------------------. @@ -388,7 +395,7 @@ splice (\\[ \f\t\v]*\n)* } .|\n STRING_GROW; - <> unexpected_end_of_file (token_start, "'"); + <> unexpected_eof (token_start, "'"); BEGIN INITIAL; } @@ -450,7 +457,7 @@ splice (\\[ \f\t\v]*\n)* { "'" STRING_GROW; BEGIN context_state; \\{splice}[^$@\[\]] STRING_GROW; - <> unexpected_end_of_file (token_start, "'"); + <> unexpected_eof (token_start, "'"); BEGIN context_state; } @@ -463,7 +470,10 @@ splice (\\[ \f\t\v]*\n)* { "\"" STRING_GROW; BEGIN context_state; \\{splice}[^$@\[\]] STRING_GROW; - <> unexpected_end_of_file (token_start, "\""); + <> { + unexpected_eof (token_start, "\""); + BEGIN context_state; + } } @@ -529,6 +539,8 @@ splice (\\[ \f\t\v]*\n)* return token_type; } } + + <> unexpected_eof (scanner_cursor, "{}"); BEGIN INITIAL; } @@ -542,9 +554,28 @@ splice (\\[ \f\t\v]*\n)* "{"|"<"{splice}"%" STRING_GROW; braces_level++; "%"{splice}">" STRING_GROW; braces_level--; "}" { - STRING_GROW; - braces_level--; - if (braces_level < 0) + bool outer_brace = --braces_level < 0; + + /* As an undocumented Bison extension, append `;' before the last + brace in braced code, so that the user code can omit trailing + `;'. But do not append `;' if emulating Yacc, since Yacc does + not append one. + + FIXME: Bison should warn if a semicolon seems to be necessary + here, and should omit the semicolon if it seems unnecessary + (e.g., after ';', '{', or '}', each followed by comments or + white space). Such a warning shouldn't depend on --yacc; it + should depend on a new --pedantic option, which would cause + Bison to warn if it detects an extension to POSIX. --pedantic + should also diagnose other Bison extensions like %yacc. + Perhaps there should also be a GCC-style --pedantic-errors + option, so that such warnings are diagnosed as errors. */ + if (outer_brace && token_type == BRACED_CODE && ! yacc_flag) + obstack_1grow (&obstack_for_string, ';'); + + obstack_1grow (&obstack_for_string, '}'); + + if (outer_brace) { STRING_FINISH; rule_length++; @@ -562,7 +593,7 @@ splice (\\[ \f\t\v]*\n)* "$"("<"{tag}">")?(-?[0-9]+|"$") handle_dollar (token_type, yytext, *loc); "@"(-?[0-9]+|"$") handle_at (token_type, yytext, *loc); - <> unexpected_end_of_file (code_start, "}"); + <> unexpected_eof (code_start, "}"); BEGIN INITIAL; } @@ -580,7 +611,7 @@ splice (\\[ \f\t\v]*\n)* return PROLOGUE; } - <> unexpected_end_of_file (code_start, "%}"); + <> unexpected_eof (code_start, "%}"); BEGIN INITIAL; } @@ -662,14 +693,14 @@ adjust_location (location *loc, char const *token, size_t size) static size_t no_cr_read (FILE *fp, char *buf, size_t size) { - size_t s = fread (buf, 1, size, fp); - if (s) + size_t bytes_read = fread (buf, 1, size, fp); + if (bytes_read) { - char *w = memchr (buf, '\r', s); + char *w = memchr (buf, '\r', bytes_read); if (w) { char const *r = ++w; - char const *lim = buf + s; + char const *lim = buf + bytes_read; for (;;) { @@ -698,7 +729,7 @@ no_cr_read (FILE *fp, char *buf, size_t size) } } - return s; + return bytes_read; } @@ -944,25 +975,15 @@ handle_syncline (char *args) /*------------------------------------------------------------------------. | 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 -unexpected_end_of_file (boundary start, char const *token_end) +unexpected_eof (boundary start, char const *token_end) { - size_t i = strlen (token_end); - location loc; loc.start = start; loc.end = scanner_cursor; complain_at (loc, _("missing `%s' at end of file"), 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]); }