-#include "system.h"
-#include "mbswidth.h"
-#include "complain.h"
-#include "quote.h"
-#include "getargs.h"
-#include "gram.h"
-#include "reader.h"
-
-/* Each time we match a string, move the end cursor to its end. */
-#define YY_USER_INIT \
-do { \
- LOCATION_RESET (*yylloc); \
- yylloc->file = infile; \
- /* This is only to avoid GCC warnings. */ \
- if (yycontrol) {;}; \
-} while (0)
-
-#define YY_USER_ACTION extend_location (yylloc, yytext, yyleng);
-#define YY_STEP LOCATION_STEP (*yylloc)
-
-#define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
-
-
-/* Read bytes from FP into buffer BUF of size SIZE. Return the
- number of bytes read. Remove '\r' from input, treating \r\n
- and isolated \r as \n. */
-
-static size_t
-no_cr_read (FILE *fp, char *buf, size_t size)
-{
- size_t s = fread (buf, 1, size, fp);
- if (s)
- {
- char *w = memchr (buf, '\r', s);
- if (w)
- {
- char const *r = ++w;
- char const *lim = buf + s;
-
- for (;;)
- {
- /* Found an '\r'. Treat it like '\n', but ignore any
- '\n' that immediately follows. */
- w[-1] = '\n';
- if (r == lim)
- {
- int ch = getc (fp);
- if (ch != '\n' && ungetc (ch, fp) != ch)
- break;
- }
- else if (*r == '\n')
- r++;
-
- /* Copy until the next '\r'. */
- do
- {
- if (r == lim)
- return w - buf;
- }
- while ((*w++ = *r++) != '\r');
- }
-
- return w - buf;
- }
- }
-
- return s;
-}
+/* Work around a bug in flex 2.5.31. See Debian bug 333231
+ <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>. */
+#undef gram_wrap
+#define gram_wrap() 1
- "%glr-parser" return PERCENT_GLR_PARSER;
- "%left" return PERCENT_LEFT;
- "%locations" return PERCENT_LOCATIONS;
- "%merge" return PERCENT_MERGE;
- "%name"[-_]"prefix" return PERCENT_NAME_PREFIX;
- "%no"[-_]"lines" return PERCENT_NO_LINES;
- "%nonassoc" return PERCENT_NONASSOC;
- "%nterm" return PERCENT_NTERM;
- "%output" return PERCENT_OUTPUT;
- "%parse-param" return PERCENT_PARSE_PARAM;
- "%prec" rule_length--; return PERCENT_PREC;
- "%printer" return PERCENT_PRINTER;
- "%pure"[-_]"parser" return PERCENT_PURE_PARSER;
- "%right" return PERCENT_RIGHT;
- "%lex-param" return PERCENT_LEX_PARAM;
- "%skeleton" return PERCENT_SKELETON;
- "%start" return PERCENT_START;
- "%term" return PERCENT_TOKEN;
- "%token" return PERCENT_TOKEN;
- "%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 (*yylloc, _("invalid directive: %s"), quote (yytext));
- YY_STEP;
+ "%initial-action" return PERCENT_INITIAL_ACTION;
+ "%glr-parser" return PERCENT_GLR_PARSER;
+ "%language" return PERCENT_LANGUAGE;
+ "%left" return PERCENT_LEFT;
+ "%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;
+ "%nonassoc" return PERCENT_NONASSOC;
+ "%nondeterministic-parser" return PERCENT_NONDETERMINISTIC_PARSER;
+ "%nterm" return PERCENT_NTERM;
+ "%output" return PERCENT_OUTPUT;
+ "%param" RETURN_PERCENT_PARAM(both);
+ "%parse-param" RETURN_PERCENT_PARAM(parse);
+ "%prec" return PERCENT_PREC;
+ "%precedence" return PERCENT_PRECEDENCE;
+ "%printer" return PERCENT_PRINTER;
+ "%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;
+ "%type" return PERCENT_TYPE;
+ "%union" return PERCENT_UNION;
+ "%verbose" return PERCENT_VERBOSE;
+ "%yacc" return PERCENT_YACC;
+
+ {directive} {
+ complain (loc, complaint, _("invalid directive: %s"), quote (yytext));
- obstack_1grow (&string_obstack, c);
- }
-
- \\a obstack_1grow (&string_obstack, '\a');
- \\b obstack_1grow (&string_obstack, '\b');
- \\f obstack_1grow (&string_obstack, '\f');
- \\n obstack_1grow (&string_obstack, '\n');
- \\r obstack_1grow (&string_obstack, '\r');
- \\t obstack_1grow (&string_obstack, '\t');
- \\v obstack_1grow (&string_obstack, '\v');
- \\[\"\'?\\] obstack_1grow (&string_obstack, yytext[1]);
- \\(u|U[0-9a-fA-F]{4})[0-9a-fA-F]{4} {
+ obstack_1grow (&obstack_for_string, c);
+ }
+
+ \\a obstack_1grow (&obstack_for_string, '\a');
+ \\b obstack_1grow (&obstack_for_string, '\b');
+ \\f obstack_1grow (&obstack_for_string, '\f');
+ \\n obstack_1grow (&obstack_for_string, '\n');
+ \\r obstack_1grow (&obstack_for_string, '\r');
+ \\t obstack_1grow (&obstack_for_string, '\t');
+ \\v obstack_1grow (&obstack_for_string, '\v');
+
+ /* \\[\"\'?\\] would be shorter, but it confuses xgettext. */
+ \\("\""|"'"|"?"|"\\") obstack_1grow (&obstack_for_string, yytext[1]);
+
+ \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
- long num;
- errno = 0;
- num = strtol (cp, 0, 10);
-
- if (INT_MIN <= num && num <= rule_length && ! errno)
- {
- int n = num;
- if (!type_name && n > 0)
- type_name = symbol_list_n_type_name_get (current_rule, location,
- n);
- if (!type_name && typed)
- complain_at (location, _("$%d of `%s' has no declared type"),
- n, current_rule->sym->tag);
- if (!type_name)
- type_name = "";
- obstack_fgrow3 (&string_obstack,
- "]b4_rhs_value([%d], [%d], [%s])[",
- rule_length, n, type_name);
- }
- else
- complain_at (location, _("invalid value: %s"), quote (text));
+ char *w = memchr (buf, '\r', bytes_read);
+ if (w)
+ {
+ char const *r = ++w;
+ char const *lim = buf + bytes_read;
+
+ for (;;)
+ {
+ /* Found an '\r'. Treat it like '\n', but ignore any
+ '\n' that immediately follows. */
+ w[-1] = '\n';
+ if (r == lim)
+ {
+ int ch = getc (fp);
+ if (ch != '\n' && ungetc (ch, fp) != ch)
+ break;
+ }
+ else if (*r == '\n')
+ r++;
+
+ /* Copy until the next '\r'. */
+ do
+ {
+ if (r == lim)
+ return w - buf;
+ }
+ while ((*w++ = *r++) != '\r');
+ }
+
+ return w - buf;
+ }
- '\0', -1, -1, -1, -1, -1, -1, '\a',
- '\b', '\t', '\n', '\v', '\f', '\r', -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1,
- ' ', '!', '"', '#', '$', '%', '&', '\'',
- '(', ')', '*', '+', ',', '-', '.', '/',
- '0', '1', '2', '3', '4', '5', '6', '7',
- '8', '9', ':', ';', '<', '=', '>', '?',
- '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
- 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
- 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
- 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
- '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
- 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
- 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
- 'x', 'y', 'z', '{', '|', '}', '~'
+ '\0', -1, -1, -1, -1, -1, -1, '\a',
+ '\b', '\t', '\n', '\v', '\f', '\r', -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ ' ', '!', '"', '#', '$', '%', '&', '\'',
+ '(', ')', '*', '+', ',', '-', '.', '/',
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', ':', ';', '<', '=', '>', '?',
+ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
+ 'x', 'y', 'z', '{', '|', '}', '~'
+/*----------------------------------------------------------------.
+| Handle '#line INT "FILE"'. 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';
+ if (INT_MAX <= lineno)
+ {
+ complain (&loc, Wother, _("line number overflow"));
+ lineno = INT_MAX;
+ }
+ current_file = uniqstr_new (file);
+ 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. |
+`----------------------------------------------------------------*/
+
+static void
+unexpected_end (boundary start, char const *msgid, char const *token_end)
+{
+ location loc;
+ loc.start = start;
+ loc.end = scanner_cursor;
+ token_end = quote (token_end);
+ // Instead of '\'', display "'".
+ if (STREQ (token_end, "'\\''"))
+ 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. |
+`------------------------------------------------------------------------*/
+
+static void
+unexpected_eof (boundary start, char const *token_end)
+{
+ unexpected_end (start, N_("missing %s at end of file"), token_end);
+}
+
+
+/*----------------------------------------.
+| Likewise, but for unexpected newlines. |
+`----------------------------------------*/
+
+static void
+unexpected_newline (boundary start, char const *token_end)
+{
+ unexpected_end (start, N_("missing %s at end of line"), token_end);
+}
+
+