X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/a737b2163c275761f32589bf7c249016452bb730..0ced3098fd97e1483b4ac938bdce99bfc7942539:/src/scan-gram.l diff --git a/src/scan-gram.l b/src/scan-gram.l index 5f7ac60e..742d54e8 100644 --- a/src/scan-gram.l +++ b/src/scan-gram.l @@ -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); %} @@ -179,6 +182,7 @@ splice (\\[ \f\t\v]*\n)* { "%binary" return PERCENT_NONASSOC; "%debug" return PERCENT_DEBUG; + "%default"[-_]"prec" return PERCENT_DEFAULT_PREC; "%define" return PERCENT_DEFINE; "%defines" return PERCENT_DEFINES; "%destructor" token_type = PERCENT_DESTRUCTOR; BEGIN SC_PRE_CODE; @@ -187,14 +191,17 @@ splice (\\[ \f\t\v]*\n)* "%expect" return PERCENT_EXPECT; "%file-prefix" return PERCENT_FILE_PREFIX; "%fixed"[-_]"output"[-_]"files" return PERCENT_YACC; + "%initial-action" token_type = PERCENT_INITIAL_ACTION; BEGIN SC_PRE_CODE; "%glr-parser" return PERCENT_GLR_PARSER; "%left" return PERCENT_LEFT; "%lex-param" token_type = PERCENT_LEX_PARAM; BEGIN SC_PRE_CODE; "%locations" return PERCENT_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; "%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; @@ -270,16 +277,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 (); + } } @@ -318,7 +327,7 @@ splice (\\[ \f\t\v]*\n)* { "*/" BEGIN context_state; .|\n ; - <> unexpected_end_of_file (token_start, "*/"); + <> unexpected_eof (token_start, "*/"); BEGIN context_state; } @@ -329,7 +338,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,8 +371,9 @@ splice (\\[ \f\t\v]*\n)* return STRING; } + \0 complain_at (*loc, _("invalid null character")); .|\n STRING_GROW; - <> unexpected_end_of_file (token_start, "\""); + <> unexpected_eof (token_start, "\""); BEGIN INITIAL; } /*---------------------------------------------------------------. @@ -388,8 +398,9 @@ splice (\\[ \f\t\v]*\n)* return ID; } + \0 complain_at (*loc, _("invalid null character")); .|\n STRING_GROW; - <> unexpected_end_of_file (token_start, "'"); + <> unexpected_eof (token_start, "'"); BEGIN INITIAL; } @@ -403,6 +414,8 @@ splice (\\[ \f\t\v]*\n)* unsigned long c = strtoul (yytext + 1, 0, 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)); else obstack_1grow (&obstack_for_string, c); } @@ -413,6 +426,8 @@ splice (\\[ \f\t\v]*\n)* c = strtoul (yytext + 2, 0, 16); if (UCHAR_MAX < c || get_errno ()) complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext)); + else if (! c) + complain_at (*loc, _("invalid null character: %s"), quote (yytext)); else obstack_1grow (&obstack_for_string, c); } @@ -432,6 +447,8 @@ splice (\\[ \f\t\v]*\n)* 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)); else obstack_1grow (&obstack_for_string, c); } @@ -451,7 +468,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; } @@ -464,7 +481,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; + } } @@ -530,6 +550,8 @@ splice (\\[ \f\t\v]*\n)* return token_type; } } + + <> unexpected_eof (scanner_cursor, "{}"); BEGIN INITIAL; } @@ -582,7 +604,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; } @@ -600,7 +622,7 @@ splice (\\[ \f\t\v]*\n)* return PROLOGUE; } - <> unexpected_end_of_file (code_start, "%}"); + <> unexpected_eof (code_start, "%}"); BEGIN INITIAL; } @@ -638,6 +660,11 @@ splice (\\[ \f\t\v]*\n)* %% +/* Keeps track of the maximum number of semantic values to the left of + a handle (those referenced by $0, $-1, etc.) are required by the + semantic actions of this grammar. */ +int max_left_semantic_context = 0; + /* Set *LOC and adjust scanner cursor to account for token TOKEN of size SIZE. */ @@ -770,6 +797,8 @@ handle_action_dollar (char *text, location loc) if (INT_MIN <= num && num <= rule_length && ! get_errno ()) { int n = num; + if (1-n > max_left_semantic_context) + max_left_semantic_context = 1-n; if (!type_name && n > 0) type_name = symbol_list_n_type_name_get (current_rule, loc, n); if (!type_name && typed) @@ -789,10 +818,10 @@ handle_action_dollar (char *text, location loc) } -/*-----------------------------------------------------------------. -| Dispatch onto handle_action_dollar, or handle_destructor_dollar, | -| depending upon TOKEN_TYPE. | -`-----------------------------------------------------------------*/ +/*----------------------------------------------------------------. +| Map `$?' onto the proper M4 symbol, depending on its TOKEN_TYPE | +| (are we in an action?). | +`----------------------------------------------------------------*/ static void handle_dollar (int token_type, char *text, location loc) @@ -805,6 +834,7 @@ handle_dollar (int token_type, char *text, location loc) break; case PERCENT_DESTRUCTOR: + case PERCENT_INITIAL_ACTION: case PERCENT_PRINTER: if (text[1] == '$') { @@ -830,7 +860,7 @@ static inline bool handle_action_at (char *text, location loc) { char *cp = text + 1; - locations_flag = 1; + locations_flag = true; if (! current_rule) return false; @@ -857,10 +887,10 @@ handle_action_at (char *text, location loc) } -/*-------------------------------------------------------------------. -| Dispatch onto handle_action_at, or handle_destructor_at, depending | -| upon CODE_KIND. | -`-------------------------------------------------------------------*/ +/*----------------------------------------------------------------. +| Map `@?' onto the proper M4 symbol, depending on its TOKEN_TYPE | +| (are we in an action?). | +`----------------------------------------------------------------*/ static void handle_at (int token_type, char *text, location loc) @@ -871,6 +901,7 @@ handle_at (int token_type, char *text, location loc) handle_action_at (text, loc); return; + case PERCENT_INITIAL_ACTION: case PERCENT_DESTRUCTOR: case PERCENT_PRINTER: if (text[1] == '$') @@ -964,25 +995,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]); }