Remove stack option. We no longer use the stack, since the stack was

never deeper than 1; instead, use the new auto var c_context to record
the stacked value.

Remove nounput option.  At an unexpected end of file, we now unput
the minimal input necessary to end cleanly; this simplifies the
code.

Avoid unbounded token sizes where this is easy.

(unexpected_end_of_file): New function.
Use it to systematize the error message on unexpected EOF.
(last-string): Now auto, not static.
(YY_OBS_FREE): Remove unnecessary do while (0) wrapper.
(scanner_last_string_free): Remove; not used.
(percent_percent_count): Move decl to just before use.
(SC_ESCAPED_CHARACTER): Return ID at unexpected end of file,
not the (never otherwised-used) CHARACTER.
This commit is contained in:
Paul Eggert
2002-11-08 05:20:20 +00:00
parent 87fbb0bffc
commit a706a1cc03

View File

@@ -19,7 +19,7 @@
02111-1307 USA
*/
%option debug nodefault noyywrap nounput never-interactive stack
%option debug nodefault noyywrap never-interactive
%option prefix="gram_" outfile="lex.yy.c"
%{
@@ -129,19 +129,6 @@ extend_location (location_t *loc, char const *token, int size)
}
/* Report an unexpected end of file at LOC. A token or comment began
with TOKEN_START, but an end of file was encountered and the
expected TOKEN_END was missing. */
static void
unexpected_end_of_file (location_t loc,
char const *token_start, char const *token_end)
{
complain_at (loc, _("unexpected end of file in `%s ... %s'"),
token_start, token_end);
}
/* STRING_OBSTACK -- Used to store all the characters that we need to
keep (to construct ID, STRINGS etc.). Use the following macros to
@@ -153,7 +140,6 @@ unexpected_end_of_file (location_t loc,
used, and which is used by YY_OBS_FREE to free the last string. */
static struct obstack string_obstack;
char *last_string;
#define YY_OBS_GROW \
obstack_grow (&string_obstack, yytext, yyleng)
@@ -164,19 +150,9 @@ char *last_string;
last_string = obstack_finish (&string_obstack); \
} while (0)
#define YY_OBS_FREE \
do { \
obstack_free (&string_obstack, last_string); \
} while (0)
#define YY_OBS_FREE \
obstack_free (&string_obstack, last_string)
void
scanner_last_string_free (void)
{
YY_OBS_FREE;
}
static int percent_percent_count = 0;
/* Within well-formed rules, RULE_LENGTH is the number of values in
the current rule so far, which says where to find `$0' with respect
@@ -192,6 +168,7 @@ static void handle_at (braced_code_t code_kind,
char *cp, location_t location);
static void handle_syncline (char *args, location_t *location);
static int convert_ucn_to_byte (char const *hex_text);
static void unexpected_end_of_file (location_t, char const *);
%}
%x SC_COMMENT SC_LINE_COMMENT SC_YACC_COMMENT
@@ -215,8 +192,15 @@ splice (\\[ \f\t\v]*\n)*
%%
%{
/* Nesting level of the current code in braces. */
int braces_level IF_LINT (= 0);
/* Scanner context when scanning C code. */
int c_context IF_LINT (= 0);
/* A string representing the most recently saved token. */
char *last_string;
/* At each yylex invocation, mark the current position as the
start of the next token. */
YY_STEP;
@@ -276,7 +260,7 @@ splice (\\[ \f\t\v]*\n)*
"," return COMMA;
";" return SEMICOLON;
[ \f\n\t\v]+ YY_STEP;
[ \f\n\t\v] YY_STEP;
{id} {
yylval->symbol = symbol_get (yytext, *yylloc);
@@ -298,20 +282,20 @@ splice (\\[ \f\t\v]*\n)*
}
/* Characters. We don't check there is only one. */
"'" YY_OBS_GROW; yy_push_state (SC_ESCAPED_CHARACTER);
"'" YY_OBS_GROW; BEGIN SC_ESCAPED_CHARACTER;
/* Strings. */
"\"" YY_OBS_GROW; yy_push_state (SC_ESCAPED_STRING);
"\"" YY_OBS_GROW; BEGIN SC_ESCAPED_STRING;
/* Comments. */
"/*" BEGIN SC_YACC_COMMENT;
"//".* YY_STEP;
/* Prologue. */
"%{" yy_push_state (SC_PROLOGUE);
"%{" BEGIN SC_PROLOGUE;
/* Code in between braces. */
"{" YY_OBS_GROW; braces_level = 0; yy_push_state (SC_BRACED_CODE);
"{" YY_OBS_GROW; braces_level = 0; BEGIN SC_BRACED_CODE;
/* A type. */
"<"{tag}">" {
@@ -321,33 +305,20 @@ splice (\\[ \f\t\v]*\n)*
return TYPE;
}
"%%" {
"%%" {
static int percent_percent_count;
if (++percent_percent_count == 2)
yy_push_state (SC_EPILOGUE);
BEGIN SC_EPILOGUE;
return PERCENT_PERCENT;
}
. {
. {
complain_at (*yylloc, _("invalid character: %s"), quote (yytext));
YY_STEP;
}
}
/*-------------------------------------------------------------------.
| Whatever the start condition (but those which correspond to |
| entities `swallowed' by Bison: SC_YACC_COMMENT, SC_ESCAPED_STRING, |
| and SC_ESCAPED_CHARACTER), no M4 character must escape as is. |
`-------------------------------------------------------------------*/
<SC_COMMENT,SC_LINE_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
{
\[ obstack_sgrow (&string_obstack, "@<:@");
\] obstack_sgrow (&string_obstack, "@:>@");
}
/*---------------------------------------------------------------.
| Scanning a Yacc comment. The initial `/ *' is already eaten. |
`---------------------------------------------------------------*/
@@ -359,12 +330,8 @@ splice (\\[ \f\t\v]*\n)*
BEGIN INITIAL;
}
[^*]+|"*" ;
<<EOF>> {
unexpected_end_of_file (*yylloc, "/*", "*/");
BEGIN INITIAL;
}
.|\n ;
<<EOF>> unexpected_end_of_file (*yylloc, "*/");
}
@@ -374,13 +341,8 @@ splice (\\[ \f\t\v]*\n)*
<SC_COMMENT>
{
"*"{splice}"/" YY_OBS_GROW; yy_pop_state ();
[^*\[\]]+|"*" YY_OBS_GROW;
<<EOF>> {
unexpected_end_of_file (*yylloc, "/*", "*/");
yy_pop_state ();
}
"*"{splice}"/" YY_OBS_GROW; BEGIN c_context;
<<EOF>> unexpected_end_of_file (*yylloc, "*/");
}
@@ -390,9 +352,9 @@ splice (\\[ \f\t\v]*\n)*
<SC_LINE_COMMENT>
{
"\n" YY_OBS_GROW; yy_pop_state ();
([^\n\[\]]|{splice})+ YY_OBS_GROW;
<<EOF>> yy_pop_state ();
"\n" YY_OBS_GROW; BEGIN c_context;
{splice} YY_OBS_GROW;
<<EOF>> BEGIN c_context;
}
@@ -404,25 +366,16 @@ splice (\\[ \f\t\v]*\n)*
<SC_ESCAPED_STRING>
{
"\"" {
assert (yy_top_state () == INITIAL);
YY_OBS_GROW;
YY_OBS_FINISH;
yylval->string = last_string;
yy_pop_state ();
rule_length++;
BEGIN INITIAL;
return STRING;
}
[^\"\\]+ YY_OBS_GROW;
<<EOF>> {
unexpected_end_of_file (*yylloc, "\"", "\"");
assert (yy_top_state () == INITIAL);
YY_OBS_FINISH;
yylval->string = last_string;
yy_pop_state ();
return STRING;
}
.|\n YY_OBS_GROW;
<<EOF>> unexpected_end_of_file (*yylloc, "\"");
}
/*---------------------------------------------------------------.
@@ -434,30 +387,19 @@ splice (\\[ \f\t\v]*\n)*
{
"'" {
YY_OBS_GROW;
assert (yy_top_state () == INITIAL);
{
YY_OBS_FINISH;
yylval->symbol = symbol_get (last_string, *yylloc);
symbol_class_set (yylval->symbol, token_sym, *yylloc);
symbol_user_token_number_set (yylval->symbol,
(unsigned char) last_string[1], *yylloc);
YY_OBS_FREE;
yy_pop_state ();
rule_length++;
return ID;
}
}
[^\'\\]+ YY_OBS_GROW;
<<EOF>> {
unexpected_end_of_file (*yylloc, "'", "'");
assert (yy_top_state () == INITIAL);
YY_OBS_FINISH;
yylval->string = last_string;
yy_pop_state ();
return CHARACTER;
yylval->symbol = symbol_get (last_string, *yylloc);
symbol_class_set (yylval->symbol, token_sym, *yylloc);
symbol_user_token_number_set (yylval->symbol,
(unsigned char) last_string[1], *yylloc);
YY_OBS_FREE;
rule_length++;
BEGIN INITIAL;
return ID;
}
.|\n YY_OBS_GROW;
<<EOF>> unexpected_end_of_file (*yylloc, "'");
}
@@ -517,8 +459,6 @@ splice (\\[ \f\t\v]*\n)*
quote (yytext));
YY_OBS_GROW;
}
/* FLex wants this rule, in case of a `\<<EOF>>'. */
\\ YY_OBS_GROW;
}
@@ -529,23 +469,10 @@ splice (\\[ \f\t\v]*\n)*
<SC_CHARACTER>
{
"'" {
YY_OBS_GROW;
assert (yy_top_state () != INITIAL);
yy_pop_state ();
}
[^'\[\]\\]+ YY_OBS_GROW;
"'" YY_OBS_GROW; BEGIN c_context;
\\{splice}[^\[\]] YY_OBS_GROW;
{splice} YY_OBS_GROW;
/* Needed for `\<<EOF>>', `\\<<newline>>[', and `\\<<newline>>]'. */
\\ YY_OBS_GROW;
<<EOF>> {
unexpected_end_of_file (*yylloc, "'", "'");
assert (yy_top_state () != INITIAL);
yy_pop_state ();
}
<<EOF>> unexpected_end_of_file (*yylloc, "'");
}
@@ -556,23 +483,10 @@ splice (\\[ \f\t\v]*\n)*
<SC_STRING>
{
"\"" {
assert (yy_top_state () != INITIAL);
YY_OBS_GROW;
yy_pop_state ();
}
[^\"\[\]\\]+ YY_OBS_GROW;
"\"" YY_OBS_GROW; BEGIN c_context;
\\{splice}[^\[\]] YY_OBS_GROW;
{splice} YY_OBS_GROW;
/* Needed for `\<<EOF>>', `\\<<newline>>[', and `\\<<newline>>]'. */
\\ YY_OBS_GROW;
<<EOF>> {
unexpected_end_of_file (*yylloc, "\"", "\"");
assert (yy_top_state () != INITIAL);
yy_pop_state ();
}
<<EOF>> unexpected_end_of_file (*yylloc, "\"");
}
@@ -582,18 +496,10 @@ splice (\\[ \f\t\v]*\n)*
<SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
{
/* Characters. We don't check there is only one. */
"'" YY_OBS_GROW; yy_push_state (SC_CHARACTER);
/* Strings. */
"\"" YY_OBS_GROW; yy_push_state (SC_STRING);
/* Comments. */
"/"{splice}"*" YY_OBS_GROW; yy_push_state (SC_COMMENT);
"/"{splice}"/" YY_OBS_GROW; yy_push_state (SC_LINE_COMMENT);
/* Not comments. */
"/" YY_OBS_GROW;
"'" YY_OBS_GROW; c_context = YY_START; BEGIN SC_CHARACTER;
"\"" YY_OBS_GROW; c_context = YY_START; BEGIN SC_STRING;
"/"{splice}"*" YY_OBS_GROW; c_context = YY_START; BEGIN SC_COMMENT;
"/"{splice}"/" YY_OBS_GROW; c_context = YY_START; BEGIN SC_LINE_COMMENT;
}
@@ -611,31 +517,24 @@ splice (\\[ \f\t\v]*\n)*
braces_level--;
if (braces_level < 0)
{
yy_pop_state ();
YY_OBS_FINISH;
yylval->string = last_string;
rule_length++;
BEGIN INITIAL;
return BRACED_CODE;
}
}
/* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly
(as `<' `<%'). */
"<"{splice}"<" YY_OBS_GROW;
"$"("<"{tag}">")?(-?[0-9]+|"$") { handle_dollar (current_braced_code,
yytext, *yylloc); }
"@"(-?[0-9]+|"$") { handle_at (current_braced_code,
yytext, *yylloc); }
/* `"<"{splice}"<"' tokenizes `<<%' correctly (as `<<' `%') rather
than incorrrectly (as `<' `<%'). */
[^\"$%\'/<@\[\]\{\}]+|[$%/<@]|"<"{splice}"<" YY_OBS_GROW;
<<EOF>> {
unexpected_end_of_file (*yylloc, "{", "}");
yy_pop_state ();
YY_OBS_FINISH;
yylval->string = last_string;
return BRACED_CODE;
}
<<EOF>> unexpected_end_of_file (*yylloc, "}");
}
@@ -646,22 +545,13 @@ splice (\\[ \f\t\v]*\n)*
<SC_PROLOGUE>
{
"%}" {
yy_pop_state ();
YY_OBS_FINISH;
yylval->string = last_string;
BEGIN INITIAL;
return PROLOGUE;
}
[^%\[\]/\'\"]+ YY_OBS_GROW;
"%" YY_OBS_GROW;
<<EOF>> {
unexpected_end_of_file (*yylloc, "%{", "%}");
yy_pop_state ();
YY_OBS_FINISH;
yylval->string = last_string;
return PROLOGUE;
}
<<EOF>> unexpected_end_of_file (*yylloc, "%}");
}
@@ -672,17 +562,28 @@ splice (\\[ \f\t\v]*\n)*
<SC_EPILOGUE>
{
[^\[\]]+ YY_OBS_GROW;
<<EOF>> {
yy_pop_state ();
YY_OBS_FINISH;
yylval->string = last_string;
BEGIN INITIAL;
return EPILOGUE;
}
}
/*----------------------------------------------------------------.
| By default, grow the string obstack with the input, escaping M4 |
| quoting characters. |
`----------------------------------------------------------------*/
<SC_COMMENT,SC_LINE_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
{
\[ obstack_sgrow (&string_obstack, "@<:@");
\] obstack_sgrow (&string_obstack, "@:>@");
.|\n YY_OBS_GROW;
}
%%
/*------------------------------------------------------------------.
@@ -933,6 +834,24 @@ handle_syncline (char *args, location_t *location)
location->last_line = lineno;
}
/*-------------------------------------------------------------.
| Report an unexpected end of file at LOC. 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 (location_t loc, char const *token_end)
{
size_t i;
complain_at (loc, _("missing `%s' at end of file"), token_end);
for (i = strlen (token_end); i != 0; i--)
unput (token_end[i - 1]);
}
/*-------------------------.
| Initialize the scanner. |
`-------------------------*/