1 /* Bison Grammar Scanner                             -*- C -*-
 
   3    Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 
   5    This file is part of Bison, the GNU Compiler Compiler.
 
   7    This program is free software; you can redistribute it and/or modify
 
   8    it under the terms of the GNU General Public License as published by
 
   9    the Free Software Foundation; either version 2 of the License, or
 
  10    (at your option) any later version.
 
  12    This program is distributed in the hope that it will be useful,
 
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
  15    GNU General Public License for more details.
 
  17    You should have received a copy of the GNU General Public License
 
  18    along with this program; if not, write to the Free Software
 
  19    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
  23 %option debug nodefault nounput noyywrap never-interactive
 
  24 %option prefix="gram_" outfile="lex.yy.c"
 
  27 /* Work around a bug in flex 2.5.31.  See Debian bug 333231
 
  28    <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.  */
 
  46 #define YY_USER_INIT                                    \
 
  49       scanner_cursor.file = current_file;               \
 
  50       scanner_cursor.line = 1;                          \
 
  51       scanner_cursor.column = 1;                        \
 
  52       code_start = scanner_cursor;                      \
 
  56 /* Pacify "gcc -Wmissing-prototypes" when flex 2.5.31 is used.  */
 
  57 int gram_get_lineno (void);
 
  58 FILE *gram_get_in (void);
 
  59 FILE *gram_get_out (void);
 
  60 int gram_get_leng (void);
 
  61 char *gram_get_text (void);
 
  62 void gram_set_lineno (int);
 
  63 void gram_set_in (FILE *);
 
  64 void gram_set_out (FILE *);
 
  65 int gram_get_debug (void);
 
  66 void gram_set_debug (int);
 
  67 int gram_lex_destroy (void);
 
  69 /* Location of scanner cursor.  */
 
  70 boundary scanner_cursor;
 
  72 static void adjust_location (location *, char const *, size_t);
 
  73 #define YY_USER_ACTION  adjust_location (loc, yytext, yyleng);
 
  75 static size_t no_cr_read (FILE *, char *, size_t);
 
  76 #define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
 
  79 /* OBSTACK_FOR_STRING -- Used to store all the characters that we need to
 
  80    keep (to construct ID, STRINGS etc.).  Use the following macros to
 
  83    Use STRING_GROW to append what has just been matched, and
 
  84    STRING_FINISH to end the string (it puts the ending 0).
 
  85    STRING_FINISH also stores this string in LAST_STRING, which can be
 
  86    used, and which is used by STRING_FREE to free the last string.  */
 
  88 static struct obstack obstack_for_string;
 
  90 /* A string representing the most recently saved token.  */
 
  91 static char *last_string;
 
  95   obstack_grow (&obstack_for_string, yytext, yyleng)
 
  97 #define STRING_FINISH                                   \
 
  99     obstack_1grow (&obstack_for_string, '\0');          \
 
 100     last_string = obstack_finish (&obstack_for_string); \
 
 103 #define STRING_FREE \
 
 104   obstack_free (&obstack_for_string, last_string)
 
 107 scanner_last_string_free (void)
 
 112 /* Within well-formed rules, RULE_LENGTH is the number of values in
 
 113    the current rule so far, which says where to find `$0' with respect
 
 114    to the top of the stack.  It is not the same as the rule->length in
 
 115    the case of mid rule actions.
 
 117    Outside of well-formed rules, RULE_LENGTH has an undefined value.  */
 
 118 static int rule_length;
 
 120 static void rule_length_overflow (location) __attribute__ ((__noreturn__));
 
 122 /* Increment the rule length by one, checking for overflow.  */
 
 124 increment_rule_length (location loc)
 
 128   /* Don't allow rule_length == INT_MAX, since that might cause
 
 129      confusion with strtol if INT_MAX == LONG_MAX.  */
 
 130   if (rule_length == INT_MAX)
 
 131     rule_length_overflow (loc);
 
 134 static void handle_dollar (int token_type, char *cp, location loc);
 
 135 static void handle_at (int token_type, char *cp, location loc);
 
 136 static void handle_syncline (char *, location);
 
 137 static unsigned long int scan_integer (char const *p, int base, location loc);
 
 138 static int convert_ucn_to_byte (char const *hex_text);
 
 139 static void unexpected_eof (boundary, char const *);
 
 140 static void unexpected_newline (boundary, char const *);
 
 143 %x SC_COMMENT SC_LINE_COMMENT SC_YACC_COMMENT
 
 144 %x SC_STRING SC_CHARACTER
 
 145 %x SC_AFTER_IDENTIFIER
 
 146 %x SC_ESCAPED_STRING SC_ESCAPED_CHARACTER
 
 147 %x SC_PRE_CODE SC_BRACED_CODE SC_PROLOGUE SC_EPILOGUE
 
 149 letter    [.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_]
 
 150 id        {letter}({letter}|[0-9])*
 
 151 directive %{letter}({letter}|[0-9]|-)*
 
 154 /* POSIX says that a tag must be both an id and a C union member, but
 
 155    historically almost any character is allowed in a tag.  We disallow
 
 156    NUL and newline, as this simplifies our implementation.  */
 
 159 /* Zero or more instances of backslash-newline.  Following GCC, allow
 
 160    white space between the backslash and the newline.  */
 
 161 splice   (\\[ \f\t\v]*\n)*
 
 165   /* Nesting level of the current code in braces.  */
 
 166   int braces_level IF_LINT (= 0);
 
 168   /* Parent context state, when applicable.  */
 
 169   int context_state IF_LINT (= 0);
 
 171   /* Token type to return, when applicable.  */
 
 172   int token_type IF_LINT (= 0);
 
 174   /* Location of most recent identifier, when applicable.  */
 
 175   location id_loc IF_LINT (= empty_location);
 
 177   /* Where containing code started, when applicable.  Its initial
 
 178      value is relevant only when yylex is invoked in the SC_EPILOGUE
 
 180   boundary code_start = scanner_cursor;
 
 182   /* Where containing comment or string or character literal started,
 
 184   boundary token_start IF_LINT (= scanner_cursor);
 
 188   /*-----------------------.
 
 189   | Scanning white space.  |
 
 190   `-----------------------*/
 
 192 <INITIAL,SC_AFTER_IDENTIFIER,SC_PRE_CODE>
 
 194   /* Comments and white space.  */
 
 195   ","          warn_at (*loc, _("stray `,' treated as white space"));
 
 199     token_start = loc->start;
 
 200     context_state = YY_START;
 
 201     BEGIN SC_YACC_COMMENT;
 
 204   /* #line directives are not documented, and may be withdrawn or
 
 205      modified in future versions of Bison.  */
 
 206   ^"#line "{int}" \"".*"\"\n" {
 
 207     handle_syncline (yytext + sizeof "#line " - 1, *loc);
 
 212   /*----------------------------.
 
 213   | Scanning Bison directives.  |
 
 214   `----------------------------*/
 
 217   "%binary"               return PERCENT_NONASSOC;
 
 218   "%debug"                return PERCENT_DEBUG;
 
 219   "%default"[-_]"prec"    return PERCENT_DEFAULT_PREC;
 
 220   "%define"               return PERCENT_DEFINE;
 
 221   "%defines"              return PERCENT_DEFINES;
 
 222   "%destructor"           token_type = PERCENT_DESTRUCTOR; BEGIN SC_PRE_CODE;
 
 223   "%dprec"                return PERCENT_DPREC;
 
 224   "%error"[-_]"verbose"   return PERCENT_ERROR_VERBOSE;
 
 225   "%expect"               return PERCENT_EXPECT;
 
 226   "%expect"[-_]"rr"       return PERCENT_EXPECT_RR;
 
 227   "%file-prefix"          return PERCENT_FILE_PREFIX;
 
 228   "%fixed"[-_]"output"[-_]"files"   return PERCENT_YACC;
 
 229   "%initial-action"       token_type = PERCENT_INITIAL_ACTION; BEGIN SC_PRE_CODE;
 
 230   "%glr-parser"           return PERCENT_GLR_PARSER;
 
 231   "%left"                 return PERCENT_LEFT;
 
 232   "%lex-param"            token_type = PERCENT_LEX_PARAM; BEGIN SC_PRE_CODE;
 
 233   "%locations"            return PERCENT_LOCATIONS;
 
 234   "%merge"                return PERCENT_MERGE;
 
 235   "%name"[-_]"prefix"     return PERCENT_NAME_PREFIX;
 
 236   "%no"[-_]"default"[-_]"prec"  return PERCENT_NO_DEFAULT_PREC;
 
 237   "%no"[-_]"lines"        return PERCENT_NO_LINES;
 
 238   "%nonassoc"             return PERCENT_NONASSOC;
 
 239   "%nondeterministic-parser"   return PERCENT_NONDETERMINISTIC_PARSER;
 
 240   "%nterm"                return PERCENT_NTERM;
 
 241   "%output"               return PERCENT_OUTPUT;
 
 242   "%parse-param"          token_type = PERCENT_PARSE_PARAM; BEGIN SC_PRE_CODE;
 
 243   "%prec"                 rule_length--; return PERCENT_PREC;
 
 244   "%printer"              token_type = PERCENT_PRINTER; BEGIN SC_PRE_CODE;
 
 245   "%pure"[-_]"parser"     return PERCENT_PURE_PARSER;
 
 246   "%require"              return PERCENT_REQUIRE;
 
 247   "%right"                return PERCENT_RIGHT;
 
 248   "%skeleton"             return PERCENT_SKELETON;
 
 249   "%start"                return PERCENT_START;
 
 250   "%term"                 return PERCENT_TOKEN;
 
 251   "%token"                return PERCENT_TOKEN;
 
 252   "%token"[-_]"table"     return PERCENT_TOKEN_TABLE;
 
 253   "%type"                 return PERCENT_TYPE;
 
 254   "%union"                token_type = PERCENT_UNION; BEGIN SC_PRE_CODE;
 
 255   "%verbose"              return PERCENT_VERBOSE;
 
 256   "%yacc"                 return PERCENT_YACC;
 
 259     complain_at (*loc, _("invalid directive: %s"), quote (yytext));
 
 263   "|"                     rule_length = 0; return PIPE;
 
 264   ";"                     return SEMICOLON;
 
 267     val->symbol = symbol_get (yytext, *loc);
 
 269     increment_rule_length (*loc);
 
 270     BEGIN SC_AFTER_IDENTIFIER;
 
 274     val->integer = scan_integer (yytext, 10, *loc);
 
 277   0[xX][0-9abcdefABCDEF]+ {
 
 278     val->integer = scan_integer (yytext, 16, *loc);
 
 282   /* Characters.  We don't check there is only one.  */
 
 283   "'"         STRING_GROW; token_start = loc->start; BEGIN SC_ESCAPED_CHARACTER;
 
 286   "\""        token_start = loc->start; BEGIN SC_ESCAPED_STRING;
 
 289   "%{"        code_start = loc->start; BEGIN SC_PROLOGUE;
 
 291   /* Code in between braces.  */
 
 294     token_type = BRACED_CODE;
 
 296     code_start = loc->start;
 
 297     BEGIN SC_BRACED_CODE;
 
 302     obstack_grow (&obstack_for_string, yytext + 1, yyleng - 2);
 
 304     val->uniqstr = uniqstr_new (last_string);
 
 310     static int percent_percent_count;
 
 311     if (++percent_percent_count == 2)
 
 313     return PERCENT_PERCENT;
 
 317     complain_at (*loc, _("invalid character: %s"), quote (yytext));
 
 321     loc->start = loc->end = scanner_cursor;
 
 327   /*-----------------------------------------------------------------.
 
 328   | Scanning after an identifier, checking whether a colon is next.  |
 
 329   `-----------------------------------------------------------------*/
 
 331 <SC_AFTER_IDENTIFIER>
 
 340     scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);
 
 354   /*---------------------------------------------------------------.
 
 355   | Scanning a Yacc comment.  The initial `/ *' is already eaten.  |
 
 356   `---------------------------------------------------------------*/
 
 360   "*/"     BEGIN context_state;
 
 362   <<EOF>>  unexpected_eof (token_start, "*/"); BEGIN context_state;
 
 366   /*------------------------------------------------------------.
 
 367   | Scanning a C comment.  The initial `/ *' is already eaten.  |
 
 368   `------------------------------------------------------------*/
 
 372   "*"{splice}"/"  STRING_GROW; BEGIN context_state;
 
 373   <<EOF>>         unexpected_eof (token_start, "*/"); BEGIN context_state;
 
 377   /*--------------------------------------------------------------.
 
 378   | Scanning a line comment.  The initial `//' is already eaten.  |
 
 379   `--------------------------------------------------------------*/
 
 383   "\n"           STRING_GROW; BEGIN context_state;
 
 384   {splice}       STRING_GROW;
 
 385   <<EOF>>        BEGIN context_state;
 
 389   /*------------------------------------------------.
 
 390   | Scanning a Bison string, including its escapes. |
 
 391   | The initial quote is already eaten.             |
 
 392   `------------------------------------------------*/
 
 398     loc->start = token_start;
 
 399     val->chars = last_string;
 
 400     increment_rule_length (*loc);
 
 404   \n            unexpected_newline (token_start, "\""); BEGIN INITIAL;
 
 405   <<EOF>>       unexpected_eof (token_start, "\"");     BEGIN INITIAL;
 
 408   /*----------------------------------------------------------.
 
 409   | Scanning a Bison character literal, decoding its escapes. |
 
 410   | The initial quote is already eaten.                       |
 
 411   `----------------------------------------------------------*/
 
 413 <SC_ESCAPED_CHARACTER>
 
 416     unsigned char last_string_1;
 
 419     loc->start = token_start;
 
 420     val->symbol = symbol_get (quotearg_style (escape_quoting_style,
 
 423     symbol_class_set (val->symbol, token_sym, *loc, false);
 
 424     last_string_1 = last_string[1];
 
 425     symbol_user_token_number_set (val->symbol, last_string_1, *loc);
 
 427     increment_rule_length (*loc);
 
 431   \n            unexpected_newline (token_start, "'");  BEGIN INITIAL;
 
 432   <<EOF>>       unexpected_eof (token_start, "'");      BEGIN INITIAL;
 
 435 <SC_ESCAPED_CHARACTER,SC_ESCAPED_STRING>
 
 437   \0        complain_at (*loc, _("invalid null character"));
 
 441   /*----------------------------.
 
 442   | Decode escaped characters.  |
 
 443   `----------------------------*/
 
 445 <SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>
 
 448     unsigned long int c = strtoul (yytext + 1, NULL, 8);
 
 450       complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
 
 452       complain_at (*loc, _("invalid null character: %s"), quote (yytext));
 
 454       obstack_1grow (&obstack_for_string, c);
 
 457   \\x[0-9abcdefABCDEF]+ {
 
 458     verify (UCHAR_MAX < ULONG_MAX);
 
 459     unsigned long int c = strtoul (yytext + 2, NULL, 16);
 
 461       complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
 
 463       complain_at (*loc, _("invalid null character: %s"), quote (yytext));
 
 465       obstack_1grow (&obstack_for_string, c);
 
 468   \\a   obstack_1grow (&obstack_for_string, '\a');
 
 469   \\b   obstack_1grow (&obstack_for_string, '\b');
 
 470   \\f   obstack_1grow (&obstack_for_string, '\f');
 
 471   \\n   obstack_1grow (&obstack_for_string, '\n');
 
 472   \\r   obstack_1grow (&obstack_for_string, '\r');
 
 473   \\t   obstack_1grow (&obstack_for_string, '\t');
 
 474   \\v   obstack_1grow (&obstack_for_string, '\v');
 
 476   /* \\[\"\'?\\] would be shorter, but it confuses xgettext.  */
 
 477   \\("\""|"'"|"?"|"\\")  obstack_1grow (&obstack_for_string, yytext[1]);
 
 479   \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
 
 480     int c = convert_ucn_to_byte (yytext);
 
 482       complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
 
 484       complain_at (*loc, _("invalid null character: %s"), quote (yytext));
 
 486       obstack_1grow (&obstack_for_string, c);
 
 489     complain_at (*loc, _("unrecognized escape sequence: %s"), quote (yytext));
 
 494   /*--------------------------------------------.
 
 495   | Scanning user-code characters and strings.  |
 
 496   `--------------------------------------------*/
 
 498 <SC_CHARACTER,SC_STRING>
 
 500   {splice}|\\{splice}[^\n$@\[\]]        STRING_GROW;
 
 505   "'"           STRING_GROW; BEGIN context_state;
 
 506   \n            unexpected_newline (token_start, "'"); BEGIN context_state;
 
 507   <<EOF>>       unexpected_eof (token_start, "'"); BEGIN context_state;
 
 512   "\""          STRING_GROW; BEGIN context_state;
 
 513   \n            unexpected_newline (token_start, "\""); BEGIN context_state;
 
 514   <<EOF>>       unexpected_eof (token_start, "\""); BEGIN context_state;
 
 518   /*---------------------------------------------------.
 
 519   | Strings, comments etc. can be found in user code.  |
 
 520   `---------------------------------------------------*/
 
 522 <SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
 
 526     context_state = YY_START;
 
 527     token_start = loc->start;
 
 532     context_state = YY_START;
 
 533     token_start = loc->start;
 
 538     context_state = YY_START;
 
 539     token_start = loc->start;
 
 544     context_state = YY_START;
 
 545     BEGIN SC_LINE_COMMENT;
 
 550   /*---------------------------------------------------------------.
 
 551   | Scanning after %union etc., possibly followed by white space.  |
 
 552   | For %union only, allow arbitrary C code to appear before the   |
 
 553   | following brace, as an extension to POSIX.                     |
 
 554   `---------------------------------------------------------------*/
 
 559     bool valid = yytext[0] == '{' || token_type == PERCENT_UNION;
 
 560     scanner_cursor.column -= mbsnwidth (yytext, yyleng, 0);
 
 566         code_start = loc->start;
 
 567         BEGIN SC_BRACED_CODE;
 
 571         complain_at (*loc, _("missing `{' in %s"),
 
 572                      token_name (token_type));
 
 573         obstack_sgrow (&obstack_for_string, "{}");
 
 575         val->chars = last_string;
 
 581   <<EOF>>  unexpected_eof (scanner_cursor, "{}"); BEGIN INITIAL;
 
 585   /*---------------------------------------------------------------.
 
 586   | Scanning some code in braces (%union and actions). The initial |
 
 587   | "{" is already eaten.                                          |
 
 588   `---------------------------------------------------------------*/
 
 592   "{"|"<"{splice}"%"  STRING_GROW; braces_level++;
 
 593   "%"{splice}">"      STRING_GROW; braces_level--;
 
 595     bool outer_brace = --braces_level < 0;
 
 597     /* As an undocumented Bison extension, append `;' before the last
 
 598        brace in braced code, so that the user code can omit trailing
 
 599        `;'.  But do not append `;' if emulating Yacc, since Yacc does
 
 602        FIXME: Bison should warn if a semicolon seems to be necessary
 
 603        here, and should omit the semicolon if it seems unnecessary
 
 604        (e.g., after ';', '{', or '}', each followed by comments or
 
 605        white space).  Such a warning shouldn't depend on --yacc; it
 
 606        should depend on a new --pedantic option, which would cause
 
 607        Bison to warn if it detects an extension to POSIX.  --pedantic
 
 608        should also diagnose other Bison extensions like %yacc.
 
 609        Perhaps there should also be a GCC-style --pedantic-errors
 
 610        option, so that such warnings are diagnosed as errors.  */
 
 611     if (outer_brace && token_type == BRACED_CODE && ! yacc_flag)
 
 612       obstack_1grow (&obstack_for_string, ';');
 
 614     obstack_1grow (&obstack_for_string, '}');
 
 619         loc->start = code_start;
 
 620         val->chars = last_string;
 
 621         increment_rule_length (*loc);
 
 627   /* Tokenize `<<%' correctly (as `<<' `%') rather than incorrrectly
 
 629   "<"{splice}"<"  STRING_GROW;
 
 631   "$"("<"{tag}">")?(-?[0-9]+|"$")  handle_dollar (token_type, yytext, *loc);
 
 632   "@"(-?[0-9]+|"$")                handle_at (token_type, yytext, *loc);
 
 635     warn_at (*loc, _("stray `$'"));
 
 636     obstack_sgrow (&obstack_for_string, "$][");
 
 639     warn_at (*loc, _("stray `@'"));
 
 640     obstack_sgrow (&obstack_for_string, "@@");
 
 643   <<EOF>>  unexpected_eof (code_start, "}"); BEGIN INITIAL;
 
 647   /*--------------------------------------------------------------.
 
 648   | Scanning some prologue: from "%{" (already scanned) to "%}".  |
 
 649   `--------------------------------------------------------------*/
 
 655     loc->start = code_start;
 
 656     val->chars = last_string;
 
 661   <<EOF>>  unexpected_eof (code_start, "%}"); BEGIN INITIAL;
 
 665   /*---------------------------------------------------------------.
 
 666   | Scanning the epilogue (everything after the second "%%", which |
 
 667   | has already been eaten).                                       |
 
 668   `---------------------------------------------------------------*/
 
 674     loc->start = code_start;
 
 675     val->chars = last_string;
 
 682   /*-----------------------------------------.
 
 683   | Escape M4 quoting characters in C code.  |
 
 684   `-----------------------------------------*/
 
 686 <SC_COMMENT,SC_LINE_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
 
 688   \$    obstack_sgrow (&obstack_for_string, "$][");
 
 689   \@    obstack_sgrow (&obstack_for_string, "@@");
 
 690   \[    obstack_sgrow (&obstack_for_string, "@{");
 
 691   \]    obstack_sgrow (&obstack_for_string, "@}");
 
 695   /*-----------------------------------------------------.
 
 696   | By default, grow the string obstack with the input.  |
 
 697   `-----------------------------------------------------*/
 
 699 <SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE,SC_STRING,SC_CHARACTER,SC_ESCAPED_STRING,SC_ESCAPED_CHARACTER>.      |
 
 700 <SC_COMMENT,SC_LINE_COMMENT,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>\n   STRING_GROW;
 
 704 /* Keeps track of the maximum number of semantic values to the left of
 
 705    a handle (those referenced by $0, $-1, etc.) are required by the
 
 706    semantic actions of this grammar. */
 
 707 int max_left_semantic_context = 0;
 
 709 /* If BUF is null, add BUFSIZE (which in this case must be less than
 
 710    INT_MAX) to COLUMN; otherwise, add mbsnwidth (BUF, BUFSIZE, 0) to
 
 711    COLUMN.  If an overflow occurs, or might occur but is undetectable,
 
 712    return INT_MAX.  Assume COLUMN is nonnegative.  */
 
 715 add_column_width (int column, char const *buf, size_t bufsize)
 
 718   unsigned int remaining_columns = INT_MAX - column;
 
 722       if (INT_MAX / 2 <= bufsize)
 
 724       width = mbsnwidth (buf, bufsize, 0);
 
 729   return width <= remaining_columns ? column + width : INT_MAX;
 
 732 /* Set *LOC and adjust scanner cursor to account for token TOKEN of
 
 736 adjust_location (location *loc, char const *token, size_t size)
 
 738   int line = scanner_cursor.line;
 
 739   int column = scanner_cursor.column;
 
 740   char const *p0 = token;
 
 741   char const *p = token;
 
 742   char const *lim = token + size;
 
 744   loc->start = scanner_cursor;
 
 746   for (p = token; p < lim; p++)
 
 750         line += line < INT_MAX;
 
 757           column = add_column_width (column, p0, p - p0);
 
 758           column = add_column_width (column, NULL, 8 - ((column - 1) & 7));
 
 764   scanner_cursor.line = line;
 
 765   scanner_cursor.column = column = add_column_width (column, p0, p - p0);
 
 767   loc->end = scanner_cursor;
 
 769   if (line == INT_MAX && loc->start.line != INT_MAX)
 
 770     warn_at (*loc, _("line number overflow"));
 
 771   if (column == INT_MAX && loc->start.column != INT_MAX)
 
 772     warn_at (*loc, _("column number overflow"));
 
 776 /* Read bytes from FP into buffer BUF of size SIZE.  Return the
 
 777    number of bytes read.  Remove '\r' from input, treating \r\n
 
 778    and isolated \r as \n.  */
 
 781 no_cr_read (FILE *fp, char *buf, size_t size)
 
 783   size_t bytes_read = fread (buf, 1, size, fp);
 
 786       char *w = memchr (buf, '\r', bytes_read);
 
 790           char const *lim = buf + bytes_read;
 
 794               /* Found an '\r'.  Treat it like '\n', but ignore any
 
 795                  '\n' that immediately follows.  */
 
 800                   if (ch != '\n' && ungetc (ch, fp) != ch)
 
 806               /* Copy until the next '\r'.  */
 
 812               while ((*w++ = *r++) != '\r');
 
 823 /*------------------------------------------------------------------.
 
 824 | TEXT is pointing to a wannabee semantic value (i.e., a `$').      |
 
 826 | Possible inputs: $[<TYPENAME>]($|integer)                         |
 
 828 | Output to OBSTACK_FOR_STRING a reference to this semantic value.  |
 
 829 `------------------------------------------------------------------*/
 
 832 handle_action_dollar (char *text, location loc)
 
 834   const char *type_name = NULL;
 
 840   /* Get the type name if explicit. */
 
 853         type_name = symbol_list_n_type_name_get (current_rule, loc, 0);
 
 854       if (!type_name && typed)
 
 855         complain_at (loc, _("$$ of `%s' has no declared type"),
 
 856                      current_rule->sym->tag);
 
 859       obstack_fgrow1 (&obstack_for_string,
 
 860                       "]b4_lhs_value([%s])[", type_name);
 
 861       current_rule->used = true;
 
 865       long int num = strtol (cp, NULL, 10);
 
 867       if (1 - INT_MAX + rule_length <= num && num <= rule_length)
 
 870           if (max_left_semantic_context < 1 - n)
 
 871             max_left_semantic_context = 1 - n;
 
 872           if (!type_name && 0 < n)
 
 873             type_name = symbol_list_n_type_name_get (current_rule, loc, n);
 
 874           if (!type_name && typed)
 
 875             complain_at (loc, _("$%d of `%s' has no declared type"),
 
 876                          n, current_rule->sym->tag);
 
 879           obstack_fgrow3 (&obstack_for_string,
 
 880                           "]b4_rhs_value(%d, %d, [%s])[",
 
 881                           rule_length, n, type_name);
 
 882           symbol_list_n_used_set (current_rule, n, true);
 
 885         complain_at (loc, _("integer out of range: %s"), quote (text));
 
 892 /*----------------------------------------------------------------.
 
 893 | Map `$?' onto the proper M4 symbol, depending on its TOKEN_TYPE |
 
 894 | (are we in an action?).                                         |
 
 895 `----------------------------------------------------------------*/
 
 898 handle_dollar (int token_type, char *text, location loc)
 
 903       if (handle_action_dollar (text, loc))
 
 907     case PERCENT_DESTRUCTOR:
 
 908     case PERCENT_INITIAL_ACTION:
 
 909     case PERCENT_PRINTER:
 
 912           obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
 
 921   complain_at (loc, _("invalid value: %s"), quote (text));
 
 925 /*------------------------------------------------------.
 
 926 | TEXT is a location token (i.e., a `@...').  Output to |
 
 927 | OBSTACK_FOR_STRING a reference to this location.      |
 
 928 `------------------------------------------------------*/
 
 931 handle_action_at (char *text, location loc)
 
 934   locations_flag = true;
 
 940     obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
 
 943       long int num = strtol (cp, NULL, 10);
 
 945       if (1 - INT_MAX + rule_length <= num && num <= rule_length)
 
 948           obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location(%d, %d)[",
 
 952         complain_at (loc, _("integer out of range: %s"), quote (text));
 
 959 /*----------------------------------------------------------------.
 
 960 | Map `@?' onto the proper M4 symbol, depending on its TOKEN_TYPE |
 
 961 | (are we in an action?).                                         |
 
 962 `----------------------------------------------------------------*/
 
 965 handle_at (int token_type, char *text, location loc)
 
 970       handle_action_at (text, loc);
 
 973     case PERCENT_INITIAL_ACTION:
 
 974     case PERCENT_DESTRUCTOR:
 
 975     case PERCENT_PRINTER:
 
 978           obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
 
 987   complain_at (loc, _("invalid value: %s"), quote (text));
 
 991 /*------------------------------------------------------.
 
 992 | Scan NUMBER for a base-BASE integer at location LOC.  |
 
 993 `------------------------------------------------------*/
 
 995 static unsigned long int
 
 996 scan_integer (char const *number, int base, location loc)
 
 998   verify (INT_MAX < ULONG_MAX);
 
 999   unsigned long int num = strtoul (number, NULL, base);
 
1003       complain_at (loc, _("integer out of range: %s"), quote (number));
 
1011 /*------------------------------------------------------------------.
 
1012 | Convert universal character name UCN to a single-byte character,  |
 
1013 | and return that character.  Return -1 if UCN does not correspond  |
 
1014 | to a single-byte character.                                       |
 
1015 `------------------------------------------------------------------*/
 
1018 convert_ucn_to_byte (char const *ucn)
 
1020   verify (UCHAR_MAX <= INT_MAX);
 
1021   unsigned long int code = strtoul (ucn + 2, NULL, 16);
 
1023   /* FIXME: Currently we assume Unicode-compatible unibyte characters
 
1024      on ASCII hosts (i.e., Latin-1 on hosts with 8-bit bytes).  On
 
1025      non-ASCII hosts we support only the portable C character set.
 
1026      These limitations should be removed once we add support for
 
1027      multibyte characters.  */
 
1029   if (UCHAR_MAX < code)
 
1032 #if ! ('$' == 0x24 && '@' == 0x40 && '`' == 0x60 && '~' == 0x7e)
 
1034     /* A non-ASCII host.  Use CODE to index into a table of the C
 
1035        basic execution character set, which is guaranteed to exist on
 
1036        all Standard C platforms.  This table also includes '$', '@',
 
1037        and '`', which are not in the basic execution character set but
 
1038        which are unibyte characters on all the platforms that we know
 
1040     static signed char const table[] =
 
1042         '\0',   -1,   -1,   -1,   -1,   -1,   -1, '\a',
 
1043         '\b', '\t', '\n', '\v', '\f', '\r',   -1,   -1,
 
1044           -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
 
1045           -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
 
1046          ' ',  '!',  '"',  '#',  '$',  '%',  '&', '\'',
 
1047          '(',  ')',  '*',  '+',  ',',  '-',  '.',  '/',
 
1048          '0',  '1',  '2',  '3',  '4',  '5',  '6',  '7',
 
1049          '8',  '9',  ':',  ';',  '<',  '=',  '>',  '?',
 
1050          '@',  'A',  'B',  'C',  'D',  'E',  'F',  'G',
 
1051          'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',
 
1052          'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',
 
1053          'X',  'Y',  'Z',  '[', '\\',  ']',  '^',  '_',
 
1054          '`',  'a',  'b',  'c',  'd',  'e',  'f',  'g',
 
1055          'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
 
1056          'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
 
1057          'x',  'y',  'z',  '{',  '|',  '}',  '~'
 
1060     code = code < sizeof table ? table[code] : -1;
 
1068 /*----------------------------------------------------------------.
 
1069 | Handle `#line INT "FILE"'.  ARGS has already skipped `#line '.  |
 
1070 `----------------------------------------------------------------*/
 
1073 handle_syncline (char *args, location loc)
 
1076   unsigned long int lineno = strtoul (args, &after_num, 10);
 
1077   char *file = strchr (after_num, '"') + 1;
 
1078   *strchr (file, '"') = '\0';
 
1079   if (INT_MAX <= lineno)
 
1081       warn_at (loc, _("line number overflow"));
 
1084   scanner_cursor.file = current_file = uniqstr_new (file);
 
1085   scanner_cursor.line = lineno;
 
1086   scanner_cursor.column = 1;
 
1090 /*---------------------------------.
 
1091 | Report a rule that is too long.  |
 
1092 `---------------------------------*/
 
1095 rule_length_overflow (location loc)
 
1097   fatal_at (loc, _("rule is too long"));
 
1101 /*----------------------------------------------------------------.
 
1102 | For a token or comment starting at START, report message MSGID, |
 
1103 | which should say that an end marker was found before            |
 
1104 | the expected TOKEN_END.                                         |
 
1105 `----------------------------------------------------------------*/
 
1108 unexpected_end (boundary start, char const *msgid, char const *token_end)
 
1112   loc.end = scanner_cursor;
 
1113   complain_at (loc, _(msgid), token_end);
 
1117 /*------------------------------------------------------------------------.
 
1118 | Report an unexpected EOF in a token or comment starting at START.       |
 
1119 | An end of file was encountered and the expected TOKEN_END was missing.  |
 
1120 `------------------------------------------------------------------------*/
 
1123 unexpected_eof (boundary start, char const *token_end)
 
1125   unexpected_end (start, N_("missing `%s' at end of file"), token_end);
 
1129 /*----------------------------------------.
 
1130 | Likewise, but for unexpected newlines.  |
 
1131 `----------------------------------------*/
 
1134 unexpected_newline (boundary start, char const *token_end)
 
1136   unexpected_end (start, N_("missing `%s' at end of line"), token_end);
 
1140 /*-------------------------.
 
1141 | Initialize the scanner.  |
 
1142 `-------------------------*/
 
1145 scanner_initialize (void)
 
1147   obstack_init (&obstack_for_string);
 
1151 /*-----------------------------------------------.
 
1152 | Free all the memory allocated to the scanner.  |
 
1153 `-----------------------------------------------*/
 
1158   obstack_free (&obstack_for_string, 0);
 
1159   /* Reclaim Flex's buffers.  */
 
1160   yy_delete_buffer (YY_CURRENT_BUFFER);