* 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> 2001-12-29 Akim Demaille <akim@epita.fr>
%name-prefix is broken. %name-prefix is broken.

View File

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

View File

@@ -23,6 +23,7 @@ DEFS = @DEFS@ \
-DLOCALEDIR=\"$(datadir)/locale\" -DLOCALEDIR=\"$(datadir)/locale\"
CFLAGS = @CFLAGS@ $(WARNING_CFLAGS) CFLAGS = @CFLAGS@ $(WARNING_CFLAGS)
YFLAGS = "-dv"
# libintl.h in is build/intl, intl/libgettext.h in src/, # libintl.h in is build/intl, intl/libgettext.h in src/,
# config.h in build/. # config.h in build/.
@@ -43,7 +44,8 @@ bison_SOURCES = LR0.c closure.c complain.c conflicts.c \
print_graph.h print_graph.c \ print_graph.h print_graph.c \
muscle_tab.h muscle_tab.c \ muscle_tab.h muscle_tab.c \
options.h options.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 EXTRA_bison_SOURCES = vmsgetargs.c

View File

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

View File

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

View File

@@ -51,19 +51,22 @@ char *infile = NULL;
char *attrsfile = NULL; char *attrsfile = NULL;
static char *base_name = NULL; static char *base_name = NULL;
static char *short_base_name = NULL; char *short_base_name = NULL;
/* C source file extension (the parser source). */ /* C source file extension (the parser source). */
const char *src_extension = NULL; const char *src_extension = NULL;
/* Header file extension (if option ``-d'' is specified). */ /* Header file extension (if option ``-d'' is specified). */
const char *header_extension = NULL; const char *header_extension = NULL;
/* Should we insert '.tab' in yacc-compatible parsers? */
int tab_extension = 0;
/*--------------------------. /*--------------------------.
| Is SUFFIX ending STRING? | | Is SUFFIX ending STRING? |
`--------------------------*/ `--------------------------*/
static int int
strsuffix (const char *string, const char *suffix) strsuffix (const char *string, const char *suffix)
{ {
size_t string_len = strlen (string); size_t string_len = strlen (string);
@@ -80,7 +83,7 @@ strsuffix (const char *string, const char *suffix)
| STRING1, and STRING2. | | STRING1, and STRING2. |
`-----------------------------------------------------------------*/ `-----------------------------------------------------------------*/
static char * char*
stringappend (const char *string1, const char *string2) stringappend (const char *string1, const char *string2)
{ {
size_t len = strlen (string1) + strlen (string2); size_t len = strlen (string1) + strlen (string2);
@@ -334,6 +337,11 @@ compute_base_names (void)
short_base_length -= 4; short_base_length -= 4;
short_base_name = strndup (spec_outfile, short_base_length); 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; return;
} }
@@ -360,6 +368,10 @@ compute_base_names (void)
if (ext_index) if (ext_index)
compute_exts_from_gf (infile + 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; return;
} }
@@ -393,6 +405,9 @@ compute_base_names (void)
strlen (short_base_name) + strlen (EXT_TAB) + 1); strlen (short_base_name) + strlen (EXT_TAB) + 1);
stpcpy (stpcpy (base_name, short_base_name), EXT_TAB); stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);
/* By default, Bison should insert '.tab' were needed. */
tab_extension = 1;
return; return;
} }
} }

View File

@@ -68,4 +68,18 @@ char *compute_header_macro PARAMS ((void));
const char *skeleton_find PARAMS ((const char *envvar, const char *skeleton_find PARAMS ((const char *envvar,
const char *skeleton_name)); 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_ */ #endif /* !FILES_H_ */

View File

@@ -33,4 +33,26 @@ void muscle_init PARAMS ((void));
void muscle_insert PARAMS ((const char *key, const char *value)); void muscle_insert PARAMS ((const char *key, const char *value));
const char *muscle_find PARAMS ((const char *key)); 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_ */ #endif /* not MUSCLE_TAB_H_ */

View File

@@ -125,7 +125,7 @@ static struct obstack format_obstack;
int error_verbose = 0; int error_verbose = 0;
/* Returns the number of lines of S. */ /* Returns the number of lines of S. */
static size_t size_t
get_lines_number (const char *s) get_lines_number (const char *s)
{ {
size_t lines = 0; size_t lines = 0;
@@ -503,7 +503,7 @@ token_actions (void)
| Output the actions to OOUT. | | Output the actions to OOUT. |
`-----------------------------*/ `-----------------------------*/
static void void
actions_output (FILE *out, size_t *line) actions_output (FILE *out, size_t *line)
{ {
int rule; int rule;
@@ -539,7 +539,7 @@ actions_output (FILE *out, size_t *line)
| Output the guards to OOUT. | | Output the guards to OOUT. |
`----------------------------*/ `----------------------------*/
static void void
guards_output (FILE *out, size_t *line) guards_output (FILE *out, size_t *line)
{ {
int rule; int rule;
@@ -571,7 +571,7 @@ guards_output (FILE *out, size_t *line)
| Output the tokens definition to OOUT. | | Output the tokens definition to OOUT. |
`---------------------------------------*/ `---------------------------------------*/
static void void
token_definitions_output (FILE *out, size_t *line) token_definitions_output (FILE *out, size_t *line)
{ {
int i; int i;
@@ -1042,6 +1042,11 @@ static void
output_master_parser (void) output_master_parser (void)
{ {
FILE *parser = xfopen (parser_file_name, "w"); 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 (!skeleton)
{ {
if (semantic_parser) if (semantic_parser)
@@ -1056,29 +1061,24 @@ output_master_parser (void)
xfclose (parser); 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) \ /* Parse the skeleton file and output the needed parsers. */
{ \ muscle_insert ("skeleton", skeleton);
obstack_fgrow1 (&muscle_obstack, "%d", Value); \ process_skeleton (infile, skeleton);
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)); \
} }
static void static void
@@ -1102,7 +1102,6 @@ prepare (void)
MUSCLE_INSERT_INT ("locations-flag", locations_flag); MUSCLE_INSERT_INT ("locations-flag", locations_flag);
} }
/*-------------------------. /*-------------------------.
| Output the header file. | | Output the header file. |
`-------------------------*/ `-------------------------*/
@@ -1188,8 +1187,13 @@ output (void)
obstack_1grow (&attrs_obstack, 0); obstack_1grow (&attrs_obstack, 0);
muscle_insert ("prologue", obstack_finish (&attrs_obstack)); muscle_insert ("prologue", obstack_finish (&attrs_obstack));
/* Process the selected skeleton file. */
output_skeleton ();
/* Output the parser. */ /* Output the parser. */
#if 0
output_master_parser (); output_master_parser ();
#endif
/* Output the header if needed. */ /* Output the header if needed. */
if (defines_flag) if (defines_flag)
header_output (); 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;
}
%%