Equip the skeleton chain with location tracking, runtime trace,

pure parser and scanner.
* src/parse-skel.y: Request a pure parser, locations, and prefix
renaming.
(%union): Having several members with the same type does not help
type mismatches, simplify.
(YYPRINT, yyprint): New.
(yyerror): ``Rename'' (there is a #define yyerror skel_error) as...
(skel_error): this.
Handle locations.
* src/scan-skel.l: Adjust to these changes.
* src/skeleton.h (LOCATION_RESET, LOCATION_LINES, LOCATION_STEP)
(LOCATION_PRINT, skel_control_t): New.
This commit is contained in:
Akim Demaille
2002-01-02 14:56:12 +00:00
parent 24fad99e2b
commit aed7fd9b97
4 changed files with 167 additions and 34 deletions

View File

@@ -1,3 +1,20 @@
2002-01-02 Akim Demaille <akim@epita.fr>
Equip the skeleton chain with location tracking, runtime trace,
pure parser and scanner.
* src/parse-skel.y: Request a pure parser, locations, and prefix
renaming.
(%union): Having several members with the same type does not help
type mismatches, simplify.
(YYPRINT, yyprint): New.
(yyerror): ``Rename'' (there is a #define yyerror skel_error) as...
(skel_error): this.
Handle locations.
* src/scan-skel.l: Adjust to these changes.
* src/skeleton.h (LOCATION_RESET, LOCATION_LINES, LOCATION_STEP)
(LOCATION_PRINT, skel_control_t): New.
2001-12-30 Akim Demaille <akim@epita.fr> 2001-12-30 Akim Demaille <akim@epita.fr>
* src/parse-skel.y: Get rid of the shift/reduce conflict: * src/parse-skel.y: Get rid of the shift/reduce conflict:

View File

@@ -23,17 +23,25 @@
%defines %defines
%verbose %verbose
%error-verbose %error-verbose
%locations
%name-prefix="skel_"
%pure-parser
%{ %{
#include "system.h" #include "system.h"
#include "obstack.h" #include "obstack.h"
#include "quotearg.h"
#include "files.h" #include "files.h"
#include "getargs.h"
#include "output.h" #include "output.h"
#include "skeleton.h" #include "skeleton.h"
#include "muscle_tab.h" #include "muscle_tab.h"
extern FILE* yyin; /* Pass the control structure to YYPARSE but not YYLEX (yet?). */
extern int yylineno; #define YYPARSE_PARAM skel_control
/* YYPARSE receives SKEL_CONTROL as a void *. Provide a correctly
typed access to it. */
#define yycontrol ((skel_control_t *) skel_control)
char* prefix = NULL; char* prefix = NULL;
FILE* parser = NULL; FILE* parser = NULL;
@@ -41,28 +49,37 @@ FILE* parser = NULL;
size_t output_line; size_t output_line;
size_t skeleton_line; size_t skeleton_line;
static int merror PARAMS ((const char* error)); static void merror PARAMS ((const char* error));
static int yyerror PARAMS ((const char* error));
/* Request detailed parse error messages, and pass them to
YLEVAL_ERROR. */
#undef yyerror
#define yyerror(Msg) \
skel_error (yycontrol, &yylloc, Msg)
/* When debugging our pure parser, we want to see values and locations
of the tokens. */
#define YYPRINT(File, Type, Value) \
yyprint (File, &yylloc, Type, &Value)
static void yyprint (FILE *file, const yyltype *loc,
int type, const yystype *value);
%} %}
%union %union
{ {
char *muscle;
char *string; char *string;
char *literal;
char character; char character;
int yacc; int boolean;
} }
/* Name of a muscle. */ /* Name of a muscle. */
%token <muscle> MUSCLE %token <string> MUSCLE
/* A string dedicated to Bison (%%"foo"). */ /* A string dedicated to Bison (%%"foo"). */
%token <string> STRING %token <string> STRING
/* Raw data, to output directly. */ /* Raw data, to output directly. */
%token <literal> RAW %token <string> RAW
/* Spaces. */ /* Spaces. */
%token <literal> BLANKS %token <string> BLANKS
/* Raw data, but char by char. */ /* Raw data, but char by char. */
%token <character> CHARACTER %token <character> CHARACTER
@@ -76,11 +93,14 @@ static int yyerror PARAMS ((const char* error));
%token TOKENS %token TOKENS
%token ACTIONS %token ACTIONS
%type <yacc> section.yacc %type <boolean> section.yacc
%start skeleton %start input
%% %%
input:
{ LOCATION_RESET (yylloc) } skeleton
;
skeleton : /* Empty. */ { } skeleton : /* Empty. */ { }
| section skeleton { } | section skeleton { }
@@ -165,19 +185,53 @@ section.body
} }
; ;
%% %%
/*------------------------------------------------------------------.
| When debugging the parser, display tokens' locations and values. |
`------------------------------------------------------------------*/
static int static void
yyprint (FILE *file,
const yyltype *loc, int type, const yystype *value)
{
fputs (" (", file);
LOCATION_PRINT (file, *loc);
fputs (")", file);
switch (type)
{
case MUSCLE:
case STRING:
case RAW:
case BLANKS:
fprintf (file, " = %s", quotearg_style (c_quoting_style,
value->string));
break;
case CHARACTER:
fprintf (file, " = '%c'", value->character);
break;
case YACC:
fprintf (file, " = %s", value->boolean ? "true" : "false");
break;
}
}
static void
merror (const char* error) merror (const char* error)
{ {
printf ("line %d: %%{%s} undeclared.\n", skeleton_line, error); printf ("line %d: %%{%s} undeclared.\n", skeleton_line, error);
return 0;
} }
static int void
yyerror (const char* error) skel_error (skel_control_t *control,
const yyltype *loc, const char *msg)
{ {
fprintf (stderr, "%s\n", error); /* Neutralize GCC warnings for unused parameters. */
return 0; skel_control_t *c = control;
c++;
LOCATION_PRINT (stderr, *loc);
fprintf (stderr, "%s\n", msg);
} }
void void
@@ -192,9 +246,10 @@ process_skeleton (const char* skel)
skeleton_line = 1; skeleton_line = 1;
/* Output. */ /* Output. */
yyin = fopen (skel, "r"); skel_in = fopen (skel, "r");
yydebug = 0; skel__flex_debug = 0;
yyparse (); skel_debug = trace_flag ? 1 : 0;
skel_parse (NULL);
/* Close the last parser. */ /* Close the last parser. */
if (parser) if (parser)

View File

@@ -19,14 +19,9 @@
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */ 02111-1307, USA. */
%{ %option debug nodefault noyywrap nounput
#include "system.h" %option prefix="skel_" outfile="lex.yy.c"
#include "skeleton.h"
#include "parse-skel.h"
%}
%option nounput
%option noyywrap
/* If we enable /* If we enable
%option yylineno %option yylineno
@@ -35,7 +30,22 @@
Seems like a Flex bug to me: Why the heck yylineno would trigger Seems like a Flex bug to me: Why the heck yylineno would trigger
the REJECT exception??? */ the REJECT exception??? */
%{
#include "system.h"
#include "skeleton.h"
#include "parse-skel.h"
%}
%{
/* Each time we match a string, move the end cursor to its end. */
#define YY_USER_ACTION yylloc->last_column += yyleng;
%}
%% %%
%{
/* At each yylex invocation, mark the current position as the
start of the next token. */
LOCATION_STEP (*yylloc);
%}
"%%{line}" { return LINE; } "%%{line}" { return LINE; }
"%%{skeleton-line}" { return SLINE; } "%%{skeleton-line}" { return SLINE; }
@@ -49,30 +59,37 @@
/* Muscle. */ /* Muscle. */
"%%{"[a-zA-Z][0-9a-zA-Z_-]+"}" { "%%{"[a-zA-Z][0-9a-zA-Z_-]+"}" {
yylval.muscle = xstrndup (yytext + 3, yyleng - 4); yylval->string = xstrndup (yytext + 3, yyleng - 4);
return MUSCLE; return MUSCLE;
} }
/* String. */ /* String. */
"%%\"".*"\"" { "%%\"".*"\"" {
yylval.string = xstrndup (yytext + 3, yyleng - 4); yylval->string = xstrndup (yytext + 3, yyleng - 4);
return STRING; return STRING;
} }
/* End of line. */ /* End of line. */
"\n" { "\n" {
LOCATION_LINES (*yylloc, yyleng);
return '\n'; return '\n';
} }
/* White spaces. */ /* White spaces. */
[\t ]+ { [\t ]+ {
yylval.literal = yytext; yylval->string = yytext;
return BLANKS; return BLANKS;
} }
/* Plain Characters. */
[^%\n]+ {
yylval->string = yytext;
return RAW;
}
/* Plain Character. */ /* Plain Character. */
. { . {
yylval.character = *yytext; yylval->character = *yytext;
return CHARACTER; return CHARACTER;
} }

View File

@@ -21,12 +21,56 @@
#ifndef SKELETON_H_ #ifndef SKELETON_H_
# define SKELETON_H_ # define SKELETON_H_
/* From parse-skel.y. */ # include "parse-skel.h"
/* Initialize LOC. */
# define LOCATION_RESET(Loc) \
(Loc).first_column = (Loc).first_line = 1; \
(Loc).last_column = (Loc).last_line = 1;
/* Advance of NUM lines. */
# define LOCATION_LINES(Loc, Num) \
(Loc).last_column = 1; \
(Loc).last_line += Num;
/* Restart: move the first cursor to the last position. */
# define LOCATION_STEP(Loc) \
(Loc).first_column = (Loc).last_column; \
(Loc).first_line = (Loc).last_line;
/* Output LOC on the stream OUT. */
# define LOCATION_PRINT(Out, Loc) \
if ((Loc).first_line != (Loc).last_line) \
fprintf (Out, "%d.%d-%d.%d", \
(Loc).first_line, (Loc).first_column, \
(Loc).last_line, (Loc).last_column - 1); \
else if ((Loc).first_column < (Loc).last_column - 1) \
fprintf (Out, "%d.%d-%d", (Loc).first_line, \
(Loc).first_column, (Loc).last_column - 1); \
else \
fprintf (Out, "%d.%d", (Loc).first_line, (Loc).first_column)
/* Pure parsers need to pass arguments to yyparse. */
typedef struct skel_control_s
{
/* For the time being, nothing. */
} skel_control_t;
/* From parse-skel.y. */
extern int skel_debug;
void skel_error PARAMS ((skel_control_t *control,
const yyltype *loc, const char *msg));
void process_skeleton PARAMS ((const char* skel)); void process_skeleton PARAMS ((const char* skel));
/* From scan-skel.l. */ /* From scan-skel.l. */
extern int skel__flex_debug;
/* Renamed yyin. */
extern FILE* skel_in;
# define YY_DECL \ # define YY_DECL \
int yylex PARAMS ((void)) int skel_lex PARAMS ((yystype *yylval, yyltype *yylloc))
YY_DECL; YY_DECL;
#endif SKELETON_H_ #endif SKELETON_H_