mirror of
https://git.savannah.gnu.org/git/bison.git
synced 2026-03-11 05:13:04 +00:00
See http://www.gnu.org/prep/maintain/maintain.html#Copyright-Notices * HACKING, Makefile.am, NEWS, PACKAGING, README, README-alpha: * TODO, bootstrap, bootstrap.conf: * build-aux/update-b4-copyright, cfg.mk, configure.ac: * data/README, data/bison.m4, data/c++-skel.m4, data/c++.m4: * data/c-skel.m4, data/c.m4, data/glr.c, data/glr.cc: * data/java-skel.m4, data/java.m4, data/lalr1.cc: * data/lalr1.java, data/local.mk, data/location.cc: * data/stack.hh, data/variant.hh, data/xslt/bison.xsl: * data/xslt/xml2dot.xsl, data/xslt/xml2text.xsl: * data/xslt/xml2xhtml.xsl, data/yacc.c, djgpp/Makefile.maint: * djgpp/README.in, djgpp/config.bat, djgpp/config.sed: * djgpp/config.site, djgpp/config_h.sed, djgpp/djunpack.bat: * djgpp/local.mk, djgpp/subpipe.c, djgpp/subpipe.h: * djgpp/testsuite.sed, doc/bison.texinfo, doc/local.mk: * doc/refcard.tex, etc/README, etc/bench.pl.in, etc/local.mk: * examples/calc++/Makefile.am, examples/extexi: * examples/local.mk, lib/abitset.c, lib/abitset.h: * lib/bbitset.h, lib/bitset.c, lib/bitset.h: * lib/bitset_stats.c, lib/bitset_stats.h, lib/bitsetv-print.c: * lib/bitsetv-print.h, lib/bitsetv.c, lib/bitsetv.h: * lib/ebitset.c, lib/ebitset.h, lib/get-errno.c: * lib/get-errno.h, lib/lbitset.c, lib/lbitset.h: * lib/libiberty.h, lib/local.mk, lib/main.c, lib/timevar.c: * lib/timevar.def, lib/timevar.h, lib/vbitset.c: * lib/vbitset.h, lib/yyerror.c, m4/bison-i18n.m4: * m4/c-working.m4, m4/cxx.m4, m4/subpipe.m4, m4/timevar.m4: * src/AnnotationList.c, src/AnnotationList.h: * src/InadequacyList.c, src/InadequacyList.h, src/LR0.c: * src/LR0.h, src/Sbitset.c, src/Sbitset.h, src/assoc.c: * src/assoc.h, src/closure.c, src/closure.h, src/complain.c: * src/complain.h, src/conflicts.c, src/conflicts.h: * src/derives.c, src/derives.h, src/files.c, src/files.h: * src/flex-scanner.h, src/getargs.c, src/getargs.h: * src/gram.c, src/gram.h, src/graphviz.c, src/ielr.c: * src/ielr.h, src/lalr.c, src/lalr.h, src/local.mk: * src/location.c, src/location.h, src/main.c: * src/muscle-tab.c, src/muscle-tab.h, src/named-ref.c: * src/named-ref.h, src/nullable.c, src/nullable.h: * src/output.c, src/output.h, src/parse-gram.y: * src/print-xml.c, src/print-xml.h, src/print.c, src/print.h: * src/print_graph.c, src/print_graph.h, src/reader.c: * src/reader.h, src/reduce.c, src/reduce.h, src/relation.c: * src/relation.h, src/scan-code.h, src/scan-code.l: * src/scan-gram.h, src/scan-gram.l, src/scan-skel.h: * src/scan-skel.l, src/state.c, src/state.h, src/symlist.c: * src/symlist.h, src/symtab.c, src/symtab.h, src/system.h: * src/tables.c, src/tables.h, src/uniqstr.c, src/uniqstr.h: * tests/actions.at, tests/atlocal.in, tests/c++.at: * tests/calc.at, tests/conflicts.at, tests/cxx-type.at: * tests/existing.at, tests/glr-regression.at: * tests/headers.at, tests/input.at, tests/java.at: * tests/local.at, tests/local.mk, tests/named-refs.at: * tests/output.at, tests/push.at, tests/reduce.at: * tests/regression.at, tests/sets.at, tests/skeletons.at: * tests/synclines.at, tests/testsuite.at, tests/torture.at: Don't use date ranges in copyright notices. Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
307 lines
8.9 KiB
C
307 lines
8.9 KiB
C
/* Scan Bison Skeletons. -*- C -*-
|
|
|
|
Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
|
|
2010 Free Software Foundation, Inc.
|
|
|
|
This file is part of Bison, the GNU Compiler Compiler.
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
%option nodefault noyywrap noinput nounput never-interactive debug
|
|
%option prefix="skel_" outfile="lex.yy.c"
|
|
|
|
%{
|
|
/* Work around a bug in flex 2.5.31. See Debian bug 333231
|
|
<http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>. */
|
|
#undef skel_wrap
|
|
#define skel_wrap() 1
|
|
|
|
#define FLEX_PREFIX(Id) skel_ ## Id
|
|
#include <src/flex-scanner.h>
|
|
|
|
#include <dirname.h>
|
|
#include <error.h>
|
|
#include <quotearg.h>
|
|
|
|
#include <src/complain.h>
|
|
#include <src/getargs.h>
|
|
#include <src/files.h>
|
|
#include <src/scan-skel.h>
|
|
|
|
#define YY_DECL static int skel_lex (void)
|
|
YY_DECL;
|
|
|
|
#define QPUTS(String) \
|
|
fputs (quotearg_style (c_quoting_style, String), yyout)
|
|
|
|
static void at_directive_perform (int at_directive_argc,
|
|
char *at_directive_argv[],
|
|
char **outnamep, int *out_linenop);
|
|
static void fail_for_at_directive_too_many_args (char const *at_directive_name);
|
|
static void fail_for_at_directive_too_few_args (char const *at_directive_name);
|
|
static void fail_for_invalid_at (char const *at);
|
|
%}
|
|
|
|
%x SC_AT_DIRECTIVE_ARGS
|
|
%x SC_AT_DIRECTIVE_SKIP_WS
|
|
|
|
%%
|
|
|
|
%{
|
|
int out_lineno IF_LINT (= 0);
|
|
char *outname = NULL;
|
|
|
|
/* Currently, only the @warn, @complain, @fatal, @warn_at, @complain_at, and
|
|
@fatal_at directives take multiple arguments, and the last three already
|
|
can't take more than 7. at_directive_argv[0] is the directive name. */
|
|
#define AT_DIRECTIVE_ARGC_MAX 8
|
|
int at_directive_argc = 0;
|
|
char *at_directive_argv[AT_DIRECTIVE_ARGC_MAX];
|
|
%}
|
|
|
|
"@@" fputc ('@', yyout);
|
|
"@{" fputc ('[', yyout);
|
|
"@}" fputc (']', yyout);
|
|
"@`" /* Emtpy. Used by b4_cat in ../data/bison.m4. */
|
|
@\n /* Likewise. */
|
|
|
|
"@oline@" fprintf (yyout, "%d", out_lineno + 1);
|
|
"@ofile@" QPUTS (outname);
|
|
"@dir_prefix@" QPUTS (dir_prefix);
|
|
|
|
@[a-z_]+"(" {
|
|
yytext[yyleng-1] = '\0';
|
|
obstack_grow (&obstack_for_string, yytext, yyleng);
|
|
at_directive_argv[at_directive_argc++] =
|
|
obstack_finish (&obstack_for_string);
|
|
BEGIN SC_AT_DIRECTIVE_ARGS;
|
|
}
|
|
|
|
/* This pattern must not match more than the previous @ patterns. */
|
|
@[^@{}`(\n]* fail_for_invalid_at (yytext);
|
|
\n out_lineno++; ECHO;
|
|
[^@\n]+ ECHO;
|
|
|
|
<INITIAL><<EOF>> {
|
|
if (outname)
|
|
{
|
|
free (outname);
|
|
xfclose (yyout);
|
|
}
|
|
return EOF;
|
|
}
|
|
|
|
<SC_AT_DIRECTIVE_ARGS>{
|
|
[^@]+ { STRING_GROW; }
|
|
|
|
"@@" { obstack_1grow (&obstack_for_string, '@'); }
|
|
"@{" { obstack_1grow (&obstack_for_string, '['); }
|
|
"@}" { obstack_1grow (&obstack_for_string, ']'); }
|
|
"@`" /* Empty. Useful for starting an argument
|
|
that begins with whitespace. */
|
|
@\n /* Empty. */
|
|
|
|
@[,)] {
|
|
if (at_directive_argc >= AT_DIRECTIVE_ARGC_MAX)
|
|
fail_for_at_directive_too_many_args (at_directive_argv[0]);
|
|
|
|
obstack_1grow (&obstack_for_string, '\0');
|
|
at_directive_argv[at_directive_argc++] =
|
|
obstack_finish (&obstack_for_string);
|
|
|
|
/* Like M4, skip whitespace after a comma. */
|
|
if (yytext[1] == ',')
|
|
BEGIN SC_AT_DIRECTIVE_SKIP_WS;
|
|
else
|
|
{
|
|
at_directive_perform (at_directive_argc, at_directive_argv,
|
|
&outname, &out_lineno);
|
|
obstack_free (&obstack_for_string, at_directive_argv[0]);
|
|
at_directive_argc = 0;
|
|
BEGIN INITIAL;
|
|
}
|
|
}
|
|
|
|
@.? { fail_for_invalid_at (yytext); }
|
|
}
|
|
|
|
<SC_AT_DIRECTIVE_SKIP_WS>{
|
|
[ \t\r\n]
|
|
. { yyless (0); BEGIN SC_AT_DIRECTIVE_ARGS; }
|
|
}
|
|
|
|
<SC_AT_DIRECTIVE_ARGS,SC_AT_DIRECTIVE_SKIP_WS>{
|
|
<<EOF>> {
|
|
fatal (_("unclosed %s directive in skeleton"), at_directive_argv[0]);
|
|
}
|
|
}
|
|
|
|
%%
|
|
|
|
/*------------------------.
|
|
| Scan a Bison skeleton. |
|
|
`------------------------*/
|
|
|
|
void
|
|
scan_skel (FILE *in)
|
|
{
|
|
static bool initialized = false;
|
|
if (!initialized)
|
|
{
|
|
initialized = true;
|
|
obstack_init (&obstack_for_string);
|
|
}
|
|
skel_in = in;
|
|
skel__flex_debug = trace_flag & trace_skeleton;
|
|
skel_lex ();
|
|
}
|
|
|
|
void
|
|
skel_scanner_free (void)
|
|
{
|
|
obstack_free (&obstack_for_string, 0);
|
|
/* Reclaim Flex's buffers. */
|
|
yylex_destroy ();
|
|
}
|
|
|
|
static void
|
|
at_directive_perform (int at_directive_argc,
|
|
char *at_directive_argv[],
|
|
char **outnamep, int *out_linenop)
|
|
{
|
|
if (0 == strcmp (at_directive_argv[0], "@basename"))
|
|
{
|
|
if (at_directive_argc > 2)
|
|
fail_for_at_directive_too_many_args (at_directive_argv[0]);
|
|
fputs (last_component (at_directive_argv[1]), yyout);
|
|
}
|
|
else if (0 == strcmp (at_directive_argv[0], "@warn")
|
|
|| 0 == strcmp (at_directive_argv[0], "@complain")
|
|
|| 0 == strcmp (at_directive_argv[0], "@fatal"))
|
|
{
|
|
void (*func)(char const *, ...);
|
|
switch (at_directive_argv[0][1])
|
|
{
|
|
case 'w': func = warn; break;
|
|
case 'c': func = complain; break;
|
|
case 'f': func = fatal; break;
|
|
default: aver (false); break;
|
|
}
|
|
switch (at_directive_argc)
|
|
{
|
|
case 2:
|
|
func (_(at_directive_argv[1]));
|
|
break;
|
|
case 3:
|
|
func (_(at_directive_argv[1]), at_directive_argv[2]);
|
|
break;
|
|
case 4:
|
|
func (_(at_directive_argv[1]), at_directive_argv[2],
|
|
at_directive_argv[3]);
|
|
break;
|
|
case 5:
|
|
func (_(at_directive_argv[1]), at_directive_argv[2],
|
|
at_directive_argv[3], at_directive_argv[4]);
|
|
break;
|
|
case 6:
|
|
func (_(at_directive_argv[1]), at_directive_argv[2],
|
|
at_directive_argv[3], at_directive_argv[4],
|
|
at_directive_argv[5]);
|
|
break;
|
|
default:
|
|
fail_for_at_directive_too_many_args (at_directive_argv[0]);
|
|
break;
|
|
}
|
|
}
|
|
else if (0 == strcmp (at_directive_argv[0], "@warn_at")
|
|
|| 0 == strcmp (at_directive_argv[0], "@complain_at")
|
|
|| 0 == strcmp (at_directive_argv[0], "@fatal_at"))
|
|
{
|
|
void (*func)(location, char const *, ...);
|
|
location loc;
|
|
if (at_directive_argc < 4)
|
|
fail_for_at_directive_too_few_args (at_directive_argv[0]);
|
|
switch (at_directive_argv[0][1])
|
|
{
|
|
case 'w': func = warn_at; break;
|
|
case 'c': func = complain_at; break;
|
|
case 'f': func = fatal_at; break;
|
|
default: aver (false); break;
|
|
}
|
|
boundary_set_from_string (&loc.start, at_directive_argv[1]);
|
|
boundary_set_from_string (&loc.end, at_directive_argv[2]);
|
|
switch (at_directive_argc)
|
|
{
|
|
case 4:
|
|
func (loc, _(at_directive_argv[3]));
|
|
break;
|
|
case 5:
|
|
func (loc, _(at_directive_argv[3]), at_directive_argv[4]);
|
|
break;
|
|
case 6:
|
|
func (loc, _(at_directive_argv[3]), at_directive_argv[4],
|
|
at_directive_argv[5]);
|
|
break;
|
|
case 7:
|
|
func (loc, _(at_directive_argv[3]), at_directive_argv[4],
|
|
at_directive_argv[5], at_directive_argv[6]);
|
|
break;
|
|
case 8:
|
|
func (loc, _(at_directive_argv[3]), at_directive_argv[4],
|
|
at_directive_argv[5], at_directive_argv[6],
|
|
at_directive_argv[7]);
|
|
break;
|
|
default:
|
|
fail_for_at_directive_too_many_args (at_directive_argv[0]);
|
|
break;
|
|
}
|
|
}
|
|
else if (0 == strcmp (at_directive_argv[0], "@output"))
|
|
{
|
|
if (at_directive_argc > 2)
|
|
fail_for_at_directive_too_many_args (at_directive_argv[0]);
|
|
if (*outnamep)
|
|
{
|
|
free (*outnamep);
|
|
xfclose (yyout);
|
|
}
|
|
*outnamep = xstrdup (at_directive_argv[1]);
|
|
output_file_name_check (outnamep);
|
|
yyout = xfopen (*outnamep, "w");
|
|
*out_linenop = 1;
|
|
}
|
|
else
|
|
fail_for_invalid_at (at_directive_argv[0]);
|
|
}
|
|
|
|
static void
|
|
fail_for_at_directive_too_few_args (char const *at_directive_name)
|
|
{
|
|
fatal (_("too few arguments for %s directive in skeleton"),
|
|
at_directive_name);
|
|
}
|
|
|
|
static void
|
|
fail_for_at_directive_too_many_args (char const *at_directive_name)
|
|
{
|
|
fatal (_("too many arguments for %s directive in skeleton"),
|
|
at_directive_name);
|
|
}
|
|
|
|
static void
|
|
fail_for_invalid_at (char const *at)
|
|
{
|
|
fatal ("invalid @ in skeleton: %s", at);
|
|
}
|