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>
* src/parse-skel.y: Get rid of the shift/reduce conflict:

View File

@@ -23,17 +23,25 @@
%defines
%verbose
%error-verbose
%locations
%name-prefix="skel_"
%pure-parser
%{
#include "system.h"
#include "obstack.h"
#include "quotearg.h"
#include "files.h"
#include "getargs.h"
#include "output.h"
#include "skeleton.h"
#include "muscle_tab.h"
extern FILE* yyin;
extern int yylineno;
/* Pass the control structure to YYPARSE but not YYLEX (yet?). */
#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;
FILE* parser = NULL;
@@ -41,28 +49,37 @@ FILE* parser = NULL;
size_t output_line;
size_t skeleton_line;
static int merror PARAMS ((const char* error));
static int yyerror PARAMS ((const char* error));
static void merror 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
{
char *muscle;
char *string;
char *literal;
char character;
int yacc;
int boolean;
}
/* Name of a muscle. */
%token <muscle> MUSCLE
%token <string> MUSCLE
/* A string dedicated to Bison (%%"foo"). */
%token <string> STRING
/* Raw data, to output directly. */
%token <literal> RAW
%token <string> RAW
/* Spaces. */
%token <literal> BLANKS
%token <string> BLANKS
/* Raw data, but char by char. */
%token <character> CHARACTER
@@ -76,11 +93,14 @@ static int yyerror PARAMS ((const char* error));
%token TOKENS
%token ACTIONS
%type <yacc> section.yacc
%type <boolean> section.yacc
%start skeleton
%start input
%%
input:
{ LOCATION_RESET (yylloc) } skeleton
;
skeleton : /* Empty. */ { }
| 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)
{
printf ("line %d: %%{%s} undeclared.\n", skeleton_line, error);
return 0;
}
static int
yyerror (const char* error)
void
skel_error (skel_control_t *control,
const yyltype *loc, const char *msg)
{
fprintf (stderr, "%s\n", error);
return 0;
/* Neutralize GCC warnings for unused parameters. */
skel_control_t *c = control;
c++;
LOCATION_PRINT (stderr, *loc);
fprintf (stderr, "%s\n", msg);
}
void
@@ -192,9 +246,10 @@ process_skeleton (const char* skel)
skeleton_line = 1;
/* Output. */
yyin = fopen (skel, "r");
yydebug = 0;
yyparse ();
skel_in = fopen (skel, "r");
skel__flex_debug = 0;
skel_debug = trace_flag ? 1 : 0;
skel_parse (NULL);
/* Close the last parser. */
if (parser)

View File

@@ -19,14 +19,9 @@
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
%{
#include "system.h"
#include "skeleton.h"
#include "parse-skel.h"
%}
%option debug nodefault noyywrap nounput
%option prefix="skel_" outfile="lex.yy.c"
%option nounput
%option noyywrap
/* If we enable
%option yylineno
@@ -35,7 +30,22 @@
Seems like a Flex bug to me: Why the heck yylineno would trigger
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; }
"%%{skeleton-line}" { return SLINE; }
@@ -49,30 +59,37 @@
/* Muscle. */
"%%{"[a-zA-Z][0-9a-zA-Z_-]+"}" {
yylval.muscle = xstrndup (yytext + 3, yyleng - 4);
yylval->string = xstrndup (yytext + 3, yyleng - 4);
return MUSCLE;
}
/* String. */
"%%\"".*"\"" {
yylval.string = xstrndup (yytext + 3, yyleng - 4);
yylval->string = xstrndup (yytext + 3, yyleng - 4);
return STRING;
}
/* End of line. */
"\n" {
LOCATION_LINES (*yylloc, yyleng);
return '\n';
}
/* White spaces. */
[\t ]+ {
yylval.literal = yytext;
yylval->string = yytext;
return BLANKS;
}
/* Plain Characters. */
[^%\n]+ {
yylval->string = yytext;
return RAW;
}
/* Plain Character. */
. {
yylval.character = *yytext;
yylval->character = *yytext;
return CHARACTER;
}

View File

@@ -21,12 +21,56 @@
#ifndef 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));
/* From scan-skel.l. */
extern int skel__flex_debug;
/* Renamed yyin. */
extern FILE* skel_in;
# define YY_DECL \
int yylex PARAMS ((void))
int skel_lex PARAMS ((yystype *yylval, yyltype *yylloc))
YY_DECL;
#endif SKELETON_H_