* src/muscle_tab.h (MUSCLE_INSERT_INT, MUSCLE_INSERT_STRING)

(MUSCLE_INSERT_PREFIX): ...to there.
* src/output.c (MUSCLE_INSERT_INT, MUSCLE_INSERT_STRING)
(MUSCLE_INSERT_PREFIX): Move from here...
* src/bison.hairy: Add a section directive.  Put braces around muscle
names.  This parser skeleton is still broken, but Bison should not
choke on a bad muscle 'syntax'.
* src/bison.simple: Add a section directive.  Put braces around muscle
names.
* src/files.h (strsuffix, stringappend): Add declarations.
(tab_extension): Add declaration.
(short_base_name): Add declaration.
* src/files.c (strsuffix, stringappend): No longer static.  These
functions are used in the skeleton parser.
(tab_extension): New.
(compute_base_names): Use the computations done in this function
to guess if the generated parsers should have '.tab' in their
names.
(short_base_name): No longer static.
* src/output.c (output_skeleton): New.
(output): Disable call to output_master_parser, and give a try to
a new skeleton handling system.
(guards_output, actions_output): No longer static.
(token_definitions_output, get_lines_number): No longer static.
* configure.in: Use AM_PROG_LEX and AC_PROG_YACC.
* src/Makefile.am (bison_SOURCES): Add scan-skel.l and
parse-skel.y.
* src/parse-skel.y: New file.
* src/scan-skel.l: New file.
This commit is contained in:
Robert Anisko
2001-12-30 15:01:06 +00:00
parent 3cd5bcdd19
commit 9b3add5beb
11 changed files with 411 additions and 80 deletions

View File

@@ -1,3 +1,42 @@
2001-12-30 Robert Anisko <robert.anisko@epita.fr>
* src/muscle_tab.h (MUSCLE_INSERT_INT, MUSCLE_INSERT_STRING)
(MUSCLE_INSERT_PREFIX): ...to there.
* src/output.c (MUSCLE_INSERT_INT, MUSCLE_INSERT_STRING)
(MUSCLE_INSERT_PREFIX): Move from here...
* src/bison.hairy: Add a section directive. Put braces around muscle
names. This parser skeleton is still broken, but Bison should not
choke on a bad muscle 'syntax'.
* src/bison.simple: Add a section directive. Put braces around muscle
names.
* src/files.h (strsuffix, stringappend): Add declarations.
(tab_extension): Add declaration.
(short_base_name): Add declaration.
* src/files.c (strsuffix, stringappend): No longer static. These
functions are used in the skeleton parser.
(tab_extension): New.
(compute_base_names): Use the computations done in this function
to guess if the generated parsers should have '.tab' in their
names.
(short_base_name): No longer static.
* src/output.c (output_skeleton): New.
(output): Disable call to output_master_parser, and give a try to
a new skeleton handling system.
(guards_output, actions_output): No longer static.
(token_definitions_output, get_lines_number): No longer static.
* configure.in: Use AM_PROG_LEX and AC_PROG_YACC.
* src/Makefile.am (bison_SOURCES): Add scan-skel.l and
parse-skel.y.
* src/parse-skel.y: New file.
* src/scan-skel.l: New file.
2001-12-29 Akim Demaille <akim@epita.fr>
%name-prefix is broken.

View File

@@ -35,6 +35,8 @@ AC_SUBST([GCC])
# Checks for programs.
AC_PROG_CC
AM_PROG_LEX
AC_PROG_YACC
AC_MINIX
AC_ISC_POSIX
AM_PROG_CC_STDC

View File

@@ -23,6 +23,7 @@ DEFS = @DEFS@ \
-DLOCALEDIR=\"$(datadir)/locale\"
CFLAGS = @CFLAGS@ $(WARNING_CFLAGS)
YFLAGS = "-dv"
# libintl.h in is build/intl, intl/libgettext.h in src/,
# config.h in build/.
@@ -43,7 +44,8 @@ bison_SOURCES = LR0.c closure.c complain.c conflicts.c \
print_graph.h print_graph.c \
muscle_tab.h muscle_tab.c \
options.h options.c \
print.c reader.c reduce.c symtab.c warshall.c vcg.c
print.c reader.c reduce.c symtab.c warshall.c vcg.c \
parse-skel.y scan-skel.l
EXTRA_bison_SOURCES = vmsgetargs.c

View File

@@ -1,3 +1,4 @@
%%{section} %%{body} %%".c" %%{yacc}
/* -*- C -*- */
/* YYERROR and YYCOST are set by guards. If yyerror is set to a
@@ -332,4 +333,4 @@ yyerrlab:
goto yyresume;
}
%%actions
%%{actions}

View File

@@ -1,7 +1,8 @@
%%{section} %%{body} %%".c" %%{yacc}
/* -*- C -*- */
/* A Bison parser, made from %%filename
by GNU bison %%version. */
/* A Bison parser, made from %%{filename}
by GNU bison %%{version}. */
/* Skeleton output parser for bison,
Copyright 1984, 1989, 1990, 2000, 2001 Free Software Foundation, Inc.
@@ -35,31 +36,31 @@
#define YYBISON 1
/* Pure parsers. */
#define YYPURE %%pure
#define YYPURE %%{pure}
/* Using locations. */
#define YYLSP_NEEDED %%locations-flag
#define YYLSP_NEEDED %%{locations-flag}
/* If NAME_PREFIX is specified substitute the variables and functions
names. */
#define yyparse %%prefix##parse
#define yylex %%prefix##lex
#define yyerror %%prefix##error
#define yylval %%prefix##lval
#define yychar %%prefix##char
#define yydebug %%prefix##debug
#define yynerrs %%prefix##nerrs
#define yyparse %%{prefix}parse
#define yylex %%{prefix}lex
#define yyerror %%{prefix}error
#define yylval %%{prefix}lval
#define yychar %%{prefix}char
#define yydebug %%{prefix}debug
#define yynerrs %%{prefix}nerrs
#if YYLSP_NEEDED
# define yylloc %%prefix##lloc
# define yylloc %%{prefix}lloc
#endif
/* Copy the user declarations. */
%%prologue
%%{prologue}
/* Enabling traces. */
#ifndef YYDEBUG
# define YYDEBUG %%debug
# define YYDEBUG %%{debug}
#endif
/* Enabling verbose error messages. */
@@ -67,11 +68,11 @@
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
# define YYERROR_VERBOSE %%error-verbose
# define YYERROR_VERBOSE %%{error-verbose}
#endif
#ifndef YYSTYPE
typedef %%stype yystype;
typedef %%{stype} yystype;
# define YYSTYPE yystype
#endif
@@ -83,11 +84,11 @@ typedef struct yyltype
int last_line;
int last_column;
} yyltype;
# define YYLTYPE %%ltype
# define YYLTYPE %%{ltype}
#endif
/* Line %%skeleton-line of %%skeleton. */
#line %%line "%%parser-file-name"
/* Line %%{skeleton-line} of %%{skeleton}. */
#line %%{line} "%%{parser-file-name}"
/* All symbols defined below should begin with yy or YY, to avoid
infringing on user name space. This should be done even for local
@@ -184,30 +185,30 @@ union yyalloc
#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
/* Tokens. */
%%tokendef
%%{tokendef}
/* YYFINAL -- State number of the termination state. */
#define YYFINAL %%final
#define YYFLAG %%flag
#define YYLAST %%last
#define YYFINAL %%{final}
#define YYFLAG %%{flag}
#define YYLAST %%{last}
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS %%ntokens
#define YYNTOKENS %%{ntokens}
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS %%nnts
#define YYNNTS %%{nnts}
/* YYNRULES -- Number of rules. */
#define YYNRULES %%nrules
#define YYNRULES %%{nrules}
/* YYNRULES -- Number of states. */
#define YYNSTATES %%nstates
#define YYMAXUTOK %%maxtok
#define YYNSTATES %%{nstates}
#define YYMAXUTOK %%{maxtok}
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
#define YYTRANSLATE(x) ((unsigned)(x) <= %%maxtok ? yytranslate[x] : %%nsym)
#define YYTRANSLATE(x) ((unsigned)(x) <= %%{maxtok} ? yytranslate[x] : %%{nsym})
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
static const char yytranslate[] =
{
%%translate
%%{translate}
};
#if YYDEBUG
@@ -215,19 +216,19 @@ static const char yytranslate[] =
YYRHS. */
static const short yyprhs[] =
{
%%prhs
%%{prhs}
};
/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const short yyrhs[] =
{
%%rhs
%%{rhs}
};
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
static const short yyrline[] =
{
%%rline
%%{rline}
};
#endif
@@ -236,26 +237,26 @@ static const short yyrline[] =
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
%%tname
%%{tname}
};
#endif
/* YYTOKNUM[YYN] -- Index in YYTNAME corresponding to YYLEX. */
static const short yytoknum[] =
{
%%toknum
%%{toknum}
};
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
static const short yyr1[] =
{
%%r1
%%{r1}
};
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
static const short yyr2[] =
{
%%r2
%%{r2}
};
/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
@@ -263,26 +264,26 @@ static const short yyr2[] =
error. */
static const short yydefact[] =
{
%%defact
%%{defact}
};
/* YYPGOTO[NTERM-NUM]. */
static const short yydefgoto[] =
{
%%defgoto
%%{defgoto}
};
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
STATE-NUM. */
static const short yypact[] =
{
%%pact
%%{pact}
};
/* YYPGOTO[NTERM-NUM]. */
static const short yypgoto[] =
{
%%pgoto
%%{pgoto}
};
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
@@ -290,12 +291,12 @@ static const short yypgoto[] =
number is the opposite. If zero, do what YYDEFACT says. */
static const short yytable[] =
{
%%table
%%{table}
};
static const short yycheck[] =
{
%%check
%%{check}
};
@@ -419,7 +420,7 @@ int yydebug;
/* YYINITDEPTH -- initial size of the parser's stacks. */
#ifndef YYINITDEPTH
# define YYINITDEPTH %%initdepth
# define YYINITDEPTH %%{initdepth}
#endif
/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
@@ -434,7 +435,7 @@ int yydebug;
#endif
#ifndef YYMAXDEPTH
# define YYMAXDEPTH %%maxdepth
# define YYMAXDEPTH %%{maxdepth}
#endif
@@ -903,11 +904,11 @@ yyreduce:
#endif
switch (yyn)
{
%%actions
%%{actions}
}
/* Line %%skeleton-line of %%skeleton. */
#line %%line "%%parser-file-name"
/* Line %%{skeleton-line} of %%{skeleton}. */
#line %%{line} "%%{parser-file-name}"
yyvsp -= yylen;
yyssp -= yylen;
@@ -1138,4 +1139,4 @@ yyreturn:
return yyresult;
}
%%epilogue
%%{epilogue}

View File

@@ -51,19 +51,22 @@ char *infile = NULL;
char *attrsfile = NULL;
static char *base_name = NULL;
static char *short_base_name = NULL;
char *short_base_name = NULL;
/* C source file extension (the parser source). */
const char *src_extension = NULL;
/* Header file extension (if option ``-d'' is specified). */
const char *header_extension = NULL;
/* Should we insert '.tab' in yacc-compatible parsers? */
int tab_extension = 0;
/*--------------------------.
| Is SUFFIX ending STRING? |
`--------------------------*/
static int
int
strsuffix (const char *string, const char *suffix)
{
size_t string_len = strlen (string);
@@ -80,7 +83,7 @@ strsuffix (const char *string, const char *suffix)
| STRING1, and STRING2. |
`-----------------------------------------------------------------*/
static char *
char*
stringappend (const char *string1, const char *string2)
{
size_t len = strlen (string1) + strlen (string2);
@@ -334,6 +337,11 @@ compute_base_names (void)
short_base_length -= 4;
short_base_name = strndup (spec_outfile, short_base_length);
/* FIXME: This is a quick and dirty way for me to find out if we
should .tab or not, using the computations above. */
if (strcmp (base_name, short_base_name))
tab_extension = 1;
return;
}
@@ -360,6 +368,10 @@ compute_base_names (void)
if (ext_index)
compute_exts_from_gf (infile + ext_index);
/* It seems that when only a prefix is given, '.tab' should always be
used. */
tab_extension = 1;
return;
}
@@ -393,6 +405,9 @@ compute_base_names (void)
strlen (short_base_name) + strlen (EXT_TAB) + 1);
stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);
/* By default, Bison should insert '.tab' were needed. */
tab_extension = 1;
return;
}
}

View File

@@ -68,4 +68,18 @@ char *compute_header_macro PARAMS ((void));
const char *skeleton_find PARAMS ((const char *envvar,
const char *skeleton_name));
/* Is SUFFIX ending STRING? */
int strsuffix (const char* string, const char* suffix);
/* Return a newly allocated string composed of the concatenation of
STRING1, and STRING2. */
char* stringappend (const char* string1, const char* string2);
/* Should we insert '.tab' in yacc-compatible parsers? */
extern int tab_extension;
/* Prefix used to generate output files names. */
extern char* short_base_name;
#endif /* !FILES_H_ */

View File

@@ -33,4 +33,26 @@ void muscle_init PARAMS ((void));
void muscle_insert PARAMS ((const char *key, const char *value));
const char *muscle_find PARAMS ((const char *key));
#define MUSCLE_INSERT_INT(Key, Value) \
{ \
obstack_fgrow1 (&muscle_obstack, "%d", Value); \
obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
}
#define MUSCLE_INSERT_STRING(Key, Value) \
{ \
obstack_sgrow (&muscle_obstack, Value); \
obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
}
#define MUSCLE_INSERT_PREFIX(Key, Value) \
{ \
obstack_fgrow2 (&muscle_obstack, "%s%s", \
spec_name_prefix ? spec_name_prefix : "yy", Value); \
obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
}
#endif /* not MUSCLE_TAB_H_ */

View File

@@ -125,7 +125,7 @@ static struct obstack format_obstack;
int error_verbose = 0;
/* Returns the number of lines of S. */
static size_t
size_t
get_lines_number (const char *s)
{
size_t lines = 0;
@@ -503,7 +503,7 @@ token_actions (void)
| Output the actions to OOUT. |
`-----------------------------*/
static void
void
actions_output (FILE *out, size_t *line)
{
int rule;
@@ -539,7 +539,7 @@ actions_output (FILE *out, size_t *line)
| Output the guards to OOUT. |
`----------------------------*/
static void
void
guards_output (FILE *out, size_t *line)
{
int rule;
@@ -571,7 +571,7 @@ guards_output (FILE *out, size_t *line)
| Output the tokens definition to OOUT. |
`---------------------------------------*/
static void
void
token_definitions_output (FILE *out, size_t *line)
{
int i;
@@ -1042,6 +1042,11 @@ static void
output_master_parser (void)
{
FILE *parser = xfopen (parser_file_name, "w");
/* FIXME: Remove the two following lines. */
printf ("Test: %s\n", infile);
printf ("Test: %s\n", parser_file_name);
if (!skeleton)
{
if (semantic_parser)
@@ -1056,29 +1061,24 @@ output_master_parser (void)
xfclose (parser);
}
/* Call the skeleton parser. */
/* FIXME. */
static
void
output_skeleton ()
{
/* Find the right skeleton file. */
if (!skeleton)
{
if (semantic_parser)
skeleton = skeleton_find ("BISON_HAIRY", BISON_HAIRY);
else
skeleton = skeleton_find ("BISON_SIMPLE", BISON_SIMPLE);
}
#define MUSCLE_INSERT_INT(Key, Value) \
{ \
obstack_fgrow1 (&muscle_obstack, "%d", Value); \
obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
}
#define MUSCLE_INSERT_STRING(Key, Value) \
{ \
obstack_sgrow (&muscle_obstack, Value); \
obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
}
#define MUSCLE_INSERT_PREFIX(Key, Value) \
{ \
obstack_fgrow2 (&muscle_obstack, "%s%s", \
spec_name_prefix ? spec_name_prefix : "yy", Value); \
obstack_1grow (&muscle_obstack, 0); \
muscle_insert (Key, obstack_finish (&muscle_obstack)); \
/* Parse the skeleton file and output the needed parsers. */
muscle_insert ("skeleton", skeleton);
process_skeleton (infile, skeleton);
}
static void
@@ -1102,7 +1102,6 @@ prepare (void)
MUSCLE_INSERT_INT ("locations-flag", locations_flag);
}
/*-------------------------.
| Output the header file. |
`-------------------------*/
@@ -1188,8 +1187,13 @@ output (void)
obstack_1grow (&attrs_obstack, 0);
muscle_insert ("prologue", obstack_finish (&attrs_obstack));
/* Process the selected skeleton file. */
output_skeleton ();
/* Output the parser. */
#if 0
output_master_parser ();
#endif
/* Output the header if needed. */
if (defines_flag)
header_output ();

176
src/parse-skel.y Normal file
View File

@@ -0,0 +1,176 @@
%{
#include "system.h"
#include "obstack.h"
#include "files.h"
#include "muscle_tab.h"
#define YYDEBUG 1
#define YYERROR_VERBOSE 1
extern FILE* yyin;
extern int yylineno;
char* prefix = NULL;
FILE* parser = NULL;
size_t output_line;
size_t skeleton_line;
extern struct obstack muscle_obstack;
%}
%union
{
char* muscle;
char* string;
char character;
int yacc;
}
%token< muscle > MUSCLE
%token< string > STRING
%token< character > CHARACTER
%token LINE
%token SLINE
%token YACC
%token SECTION
%token GUARDS
%token TOKENS
%token ACTIONS
%type< yacc > section.yacc
%start skeleton
%%
skeleton : /* Empty. */ { }
| section skeleton { }
;
section : section.header section.body { }
;
section.header : SECTION gb MUSCLE gb STRING gb section.yacc gb '\n'
{
char* name = 0;
char* limit = 0;
char* suffix = $5;
/* Close the previous parser. */
if (parser)
parser = (xfclose (parser), NULL);
/* If the following section should be named with the yacc-style, and it's
suffix is of the form 'something.h' or 'something.c', then add '.tab' in
the middle of the suffix. */
if (tab_extension && $7 && (strsuffix (suffix, ".h") ||
strsuffix (suffix, ".c")))
{
size_t prefix_len = strlen (prefix);
size_t suffix_len = strlen (suffix);
/* Allocate enough space to insert '.tab'. */
name = XMALLOC (char, prefix_len + suffix_len + 5);
limit = strrchr (suffix, '.');
if (!limit)
limit = suffix;
/* Prefix is 'X', suffix is 'Y.Z'. Name will be 'XY.tab.Z'. */
{
char* cp = 0;
cp = stpcpy (name, prefix);
cp = stpncpy (cp, suffix, limit - suffix);
cp = stpcpy (cp, ".tab");
cp = stpcpy (cp, limit);
}
}
else
name = stringappend (prefix, suffix);
/* Prepare the next parser to be output. */
parser = xfopen (name, "w");
MUSCLE_INSERT_STRING ("parser-file-name", name);
XFREE (name);
++skeleton_line;
}
;
section.yacc : /* Empty. */ { $$ = 0; }
| YACC { $$ = 1; }
;
section.body
: /* Empty. */ { }
| section.body '\n' { fputc ('\n', parser); ++output_line; ++skeleton_line; }
| section.body LINE { fprintf (parser, "%d", output_line); }
| section.body SLINE { fprintf (parser, "%d", skeleton_line); }
| section.body GUARDS { guards_output (parser, &output_line); }
| section.body TOKENS { token_definitions_output (parser, &output_line); }
| section.body ACTIONS { actions_output (parser, &output_line); }
| section.body CHARACTER { fputc ($2, parser); }
| section.body MUSCLE {
const char* value = muscle_find ($2);
if (value)
{
fputs (value, parser);
output_line += get_lines_number (value);
}
else
{
fprintf (parser, "%%{%s}", $2);
merror ($2);
}
}
;
gb : /* Empty. */ { }
| gb CHARACTER { /* Do not echo garbage characters. */ }
;
%%
int
merror (const char* error)
{
printf ("line %d: %%{%s} undeclared.\n", skeleton_line, error);
return 0;
}
int
yyerror (const char* error)
{
printf ("line %d: %s.\n", yylineno, error);
return 0;
}
int
process_skeleton (const char* grammar,
const char* skeleton)
{
const char* limit = 0;
/* Compute prefix. Actually, it seems that the processing I need here is
done in compute_base_names, and the result stored in short_base_name. */
prefix = short_base_name;
/* Prepare a few things. */
output_line = 1;
skeleton_line = 1;
/* Output. */
yyin = fopen (skeleton, "r");
yydebug = 0;
yyparse ();
/* Close the last parser. */
if (parser)
parser = (xfclose (parser), NULL);
}

55
src/scan-skel.l Normal file
View File

@@ -0,0 +1,55 @@
%{
#include <stdlib.h>
#include <string.h>
#include "parse-skel.h"
%}
%option nounput
%option noyywrap
%option yylineno
%%
"%%{line}" { return LINE; }
"%%{skeleton-line}" { return SLINE; }
"%%{yacc}" { return YACC; }
"%%{section}" { return SECTION; }
"%%{guards}" { return GUARDS; }
"%%{actions}" { return ACTIONS; }
"%%{tokendef}" { return TOKENS; }
"%%{"[a-zA-Z][0-9a-zA-Z_-]+"}" { /* Muscle. */
size_t len = strlen (yytext);
yylval.string = (char*) malloc (len - 3);
strncpy (yylval.string, yytext + 3, len - 4);
yylval.string[len - 4] = 0;
return MUSCLE;
}
"%%\"".*"\"" { /* String. */
size_t len = strlen (yytext);
yylval.string = (char*) malloc (len - 3);
strncpy (yylval.string, yytext + 3, len - 4);
yylval.string[len - 4] = 0;
return STRING;
}
<<EOF>> { /* End of file. */
return 0;
}
"\n" { /* End of line. */
return '\n';
}
. { /* Character. */
yylval.character = *yytext;
return CHARACTER;
}
%%