Fix unexpanded macros in GLR defines file.

Reported by Csaba Raduly at
<http://lists.gnu.org/archive/html/bug-bison/2008-11/msg00048.html>.
* THANKS (Csaba Raduly): Add.
* data/glr.c: Fix overquoting on b4_prefix for yylval and yylloc.
* tests/calc.at (_AT_DATA_CALC_Y): If %defines is specified, generate
lexer in a separate module that includes the defines file.
(AT_CHECK_CALC): Use AT_FULL_COMPILE and request compilation of lexer
source.
* tests/local.at (_AT_BISON_OPTION_PUSHDEFS): Push AT_DEFINES_IF.
Adjust AT_LOC and AT_VAL to use AT_NAME_PREFIX.
(AT_BISON_OPTION_POPDEFS): Pop AT_DEFINES_IF.
(AT_DATA_SOURCE_PROLOGUE): New.
(AT_DATA_GRAMMAR_PROLOGUE): Use AT_DATA_SOURCE_PROLOGUE.
(AT_DATA_SOURCE): New.
(AT_FULL_COMPILE): New, copied from master branch and extended to
support an additional output file.
This commit is contained in:
Joel E. Denny
2008-11-18 22:34:26 -05:00
parent bf151b75ff
commit 462503f825
5 changed files with 232 additions and 169 deletions

View File

@@ -1,3 +1,23 @@
2008-11-18 Joel E. Denny <jdenny@ces.clemson.edu>
Fix unexpanded macros in GLR defines file.
Reported by Csaba Raduly at
<http://lists.gnu.org/archive/html/bug-bison/2008-11/msg00048.html>.
* THANKS (Csaba Raduly): Add.
* data/glr.c: Fix overquoting on b4_prefix for yylval and yylloc.
* tests/calc.at (_AT_DATA_CALC_Y): If %defines is specified, generate
lexer in a separate module that includes the defines file.
(AT_CHECK_CALC): Use AT_FULL_COMPILE and request compilation of lexer
source.
* tests/local.at (_AT_BISON_OPTION_PUSHDEFS): Push AT_DEFINES_IF.
Adjust AT_LOC and AT_VAL to use AT_NAME_PREFIX.
(AT_BISON_OPTION_POPDEFS): Pop AT_DEFINES_IF.
(AT_DATA_SOURCE_PROLOGUE): New.
(AT_DATA_GRAMMAR_PROLOGUE): Use AT_DATA_SOURCE_PROLOGUE.
(AT_DATA_SOURCE): New.
(AT_FULL_COMPILE): New, copied from master branch and extended to
support an additional source file.
2008-11-17 Joel E. Denny <jdenny@ces.clemson.edu> 2008-11-17 Joel E. Denny <jdenny@ces.clemson.edu>
Don't let maintainer-*-check targets force a version update. Don't let maintainer-*-check targets force a version update.

1
THANKS
View File

@@ -22,6 +22,7 @@ Charles-Henri de Boysson de-boy_c@epita.fr
Christian Burger cburger@sunysb.edu Christian Burger cburger@sunysb.edu
Cris Bailiff c.bailiff+bison@awayweb.com Cris Bailiff c.bailiff+bison@awayweb.com
Cris van Pelt cris@amf03054.office.wxs.nl Cris van Pelt cris@amf03054.office.wxs.nl
Csaba Raduly csaba_22@yahoo.co.uk
Daniel Hagerty hag@gnu.org Daniel Hagerty hag@gnu.org
David J. MacKenzie djm@gnu.org David J. MacKenzie djm@gnu.org
Derek M. Jones derek@knosof.co.uk Derek M. Jones derek@knosof.co.uk

View File

@@ -1,8 +1,8 @@
-*- C -*- -*- C -*-
# GLR skeleton for Bison # GLR skeleton for Bison
# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, # Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software
# Inc. # Foundation, Inc.
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -2644,10 +2644,10 @@ b4_copyright([Skeleton interface for Bison GLR parsers in C],
b4_shared_declarations b4_shared_declarations
b4_pure_if([], b4_pure_if([],
[[extern YYSTYPE b4_prefix][lval;]]) [[extern YYSTYPE ]b4_prefix[lval;]])
b4_locations_if([b4_pure_if([], b4_locations_if([b4_pure_if([],
[extern YYLTYPE b4_prefix[]lloc;]) [extern YYLTYPE ]b4_prefix[lloc;])
]) ])
])]) ])])
m4_divert_pop(0) m4_divert_pop(0)

View File

@@ -1,7 +1,7 @@
# Simple calculator. -*- Autotest -*- # Simple calculator. -*- Autotest -*-
# Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software # Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free
# Foundation, Inc. # Software Foundation, Inc.
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -28,21 +28,162 @@
# _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES]) # _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
# ----------------------------------------------- # -----------------------------------------------
# Produce `calc.y'. Don't call this macro directly, because it contains # Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
# some occurrences of `$1' etc. which will be interpreted by m4. So # `calc-lex.cc'.
# you should call it with $1, $2, and $3 as arguments, which is what #
# AT_DATA_CALC_Y does. # Don't call this macro directly, because it contains some occurrences
# of `$1' etc. which will be interpreted by m4. So you should call it
# with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does.
m4_define([_AT_DATA_CALC_Y], m4_define([_AT_DATA_CALC_Y],
[m4_if([$1$2$3], $[1]$[2]$[3], [], [m4_if([$1$2$3], $[1]$[2]$[3], [],
[m4_fatal([$0: Invalid arguments: $@])])dnl [m4_fatal([$0: Invalid arguments: $@])])dnl
m4_pushdef([AT_CALC_LEX],
[[#include <ctype.h>
int ]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[);
static int get_char (]AT_LEX_FORMALS[);
static void unget_char (]AT_LEX_PRE_FORMALS[ int c);
]AT_LOCATION_IF([
static YYLTYPE last_yylloc;
])[
static int
get_char (]AT_LEX_FORMALS[)
{
int res = getc (input);
]AT_USE_LEX_ARGS[;
]AT_LOCATION_IF([
last_yylloc = AT_LOC;
if (res == '\n')
{
AT_LOC.last_line++;
AT_LOC.last_column = 1;
}
else
AT_LOC.last_column++;
])[
return res;
}
static void
unget_char (]AT_LEX_PRE_FORMALS[ int c)
{
]AT_USE_LEX_ARGS[;
]AT_LOCATION_IF([
/* Wrong when C == `\n'. */
AT_LOC = last_yylloc;
])[
ungetc (c, input);
}
static int
read_signed_integer (]AT_LEX_FORMALS[)
{
int c = get_char (]AT_LEX_ARGS[);
int sign = 1;
int n = 0;
]AT_USE_LEX_ARGS[;
if (c == '-')
{
c = get_char (]AT_LEX_ARGS[);
sign = -1;
}
while (isdigit (c))
{
n = 10 * n + (c - '0');
c = get_char (]AT_LEX_ARGS[);
}
unget_char (]AT_LEX_PRE_ARGS[ c);
return sign * n;
}
/*---------------------------------------------------------------.
| Lexical analyzer returns an integer on the stack and the token |
| NUM, or the ASCII character read if not a number. Skips all |
| blanks and tabs, returns 0 for EOF. |
`---------------------------------------------------------------*/
int
]AT_NAME_PREFIX[lex (]AT_LEX_FORMALS[)
{
static int init = 1;
int c;
if (init)
{
init = 0;
]AT_LOCATION_IF([
AT_LOC.last_column = 1;
AT_LOC.last_line = 1;
])[
}
]AT_LOCATION_IF([
AT_LOC.first_column = AT_LOC.last_column;
AT_LOC.first_line = AT_LOC.last_line;
])[
/* Skip white space. */
while ((c = get_char (]AT_LEX_ARGS[)) == ' ' || c == '\t')
{
]AT_LOCATION_IF(
[ AT_LOC.first_column = AT_LOC.last_column;
AT_LOC.first_line = AT_LOC.last_line;
])[
}
/* process numbers */
if (c == '.' || isdigit (c))
{
unget_char (]AT_LEX_PRE_ARGS[ c);
]AT_VAL[.ival = read_signed_integer (]AT_LEX_ARGS[);
return NUM;
}
/* Return end-of-file. */
if (c == EOF)
return CALC_EOF;
/* Return single chars. */
return c;
}
]])
AT_DATA_GRAMMAR([calc.y], AT_DATA_GRAMMAR([calc.y],
[[/* Infix notation calculator--calc */ [[/* Infix notation calculator--calc */
]$4 ]$4
AT_SKEL_CC_IF( AT_SKEL_CC_IF(
[%define global_tokens_and_yystype])[ [%define global_tokens_and_yystype])[
%{ %code requires {
#include <stdio.h> /* Exercise pre-prologue dependency to %union. */
typedef int semantic_value;
}
/* Exercise %union. */
%union
{
semantic_value ival;
};
%code provides {
#include <stdio.h>
/* The input. */
extern FILE *input;]AT_SKEL_CC_IF([[
#ifndef YYLTYPE
# define YYLTYPE ]AT_NAME_PREFIX[::location
#endif
#define first_line begin.line
#define first_column begin.column
#define last_line end.line
#define last_column end.column]])[
}
%code {
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#if HAVE_UNISTD_H #if HAVE_UNISTD_H
@@ -51,33 +192,13 @@ AT_SKEL_CC_IF(
# undef alarm # undef alarm
# define alarm(seconds) /* empty */ # define alarm(seconds) /* empty */
#endif #endif
#include <ctype.h>
#define USE(Var) #define USE(Var)
/* Exercise pre-prologue dependency to %union. */ FILE *input;
typedef int semantic_value;
static semantic_value global_result = 0; static semantic_value global_result = 0;
static int global_count = 0; static int global_count = 0;
%}
/* Exercise %union. */
%union
{
semantic_value ival;
};
%{
static int power (int base, int exponent); static int power (int base, int exponent);
]AT_SKEL_CC_IF( ]AT_SKEL_CC_IF(,
[#ifndef YYLTYPE
[#] define YYLTYPE AT_NAME_PREFIX::location
#endif
#define first_line begin.line
#define first_column begin.column
#define last_line end.line
#define last_column end.column
],
[/* yyerror receives the location if: [/* yyerror receives the location if:
- %location & %pure & %glr - %location & %pure & %glr
- %location & %pure & %yacc & %parse-param. */ - %location & %pure & %yacc & %parse-param. */
@@ -85,10 +206,8 @@ static void yyerror (AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])
AT_PARAM_IF([semantic_value *result, int *count, ]) AT_PARAM_IF([semantic_value *result, int *count, ])
const char *s const char *s
);])[ );])[
static int yylex (]AT_LEX_FORMALS[); int yylex (]AT_LEX_FORMALS[);
static int get_char (]AT_LEX_FORMALS[); }
static void unget_char (]AT_LEX_PRE_FORMALS[ int c);
%}
]AT_SKEL_CC_IF( ]AT_SKEL_CC_IF(
[/* The lalr1.cc skeleton, for backward compatibility, defines [/* The lalr1.cc skeleton, for backward compatibility, defines
@@ -144,8 +263,6 @@ exp:
| '-' error { $$ = 0; YYERROR; } | '-' error { $$ = 0; YYERROR; }
; ;
%% %%
/* The input. */
static FILE *input;
]AT_SKEL_CC_IF( ]AT_SKEL_CC_IF(
[/* A C++ error reporting function. */ [/* A C++ error reporting function. */
@@ -185,117 +302,7 @@ AT_YYERROR_SEES_LOC_IF([
fprintf (stderr, "%s\n", s); fprintf (stderr, "%s\n", s);
}])[ }])[
]AT_DEFINES_IF(, [AT_CALC_LEX])[
]AT_LOCATION_IF([
static YYLTYPE last_yylloc;
])[
static int
get_char (]AT_LEX_FORMALS[)
{
int res = getc (input);
]AT_USE_LEX_ARGS[;
]AT_LOCATION_IF([
last_yylloc = AT_LOC;
if (res == '\n')
{
AT_LOC.last_line++;
AT_LOC.last_column = 1;
}
else
AT_LOC.last_column++;
])[
return res;
}
static void
unget_char (]AT_LEX_PRE_FORMALS[ int c)
{
]AT_USE_LEX_ARGS[;
]AT_LOCATION_IF([
/* Wrong when C == `\n'. */
AT_LOC = last_yylloc;
])[
ungetc (c, input);
}
static int
read_signed_integer (]AT_LEX_FORMALS[)
{
int c = get_char (]AT_LEX_ARGS[);
int sign = 1;
int n = 0;
]AT_USE_LEX_ARGS[;
if (c == '-')
{
c = get_char (]AT_LEX_ARGS[);
sign = -1;
}
while (isdigit (c))
{
n = 10 * n + (c - '0');
c = get_char (]AT_LEX_ARGS[);
}
unget_char (]AT_LEX_PRE_ARGS[ c);
return sign * n;
}
/*---------------------------------------------------------------.
| Lexical analyzer returns an integer on the stack and the token |
| NUM, or the ASCII character read if not a number. Skips all |
| blanks and tabs, returns 0 for EOF. |
`---------------------------------------------------------------*/
static int
yylex (]AT_LEX_FORMALS[)
{
static int init = 1;
int c;
if (init)
{
init = 0;
]AT_LOCATION_IF([
AT_LOC.last_column = 1;
AT_LOC.last_line = 1;
])[
}
]AT_LOCATION_IF([
AT_LOC.first_column = AT_LOC.last_column;
AT_LOC.first_line = AT_LOC.last_line;
])[
/* Skip white space. */
while ((c = get_char (]AT_LEX_ARGS[)) == ' ' || c == '\t')
{
]AT_LOCATION_IF(
[ AT_LOC.first_column = AT_LOC.last_column;
AT_LOC.first_line = AT_LOC.last_line;
])[
}
/* process numbers */
if (c == '.' || isdigit (c))
{
unget_char (]AT_LEX_PRE_ARGS[ c);
]AT_VAL[.ival = read_signed_integer (]AT_LEX_ARGS[);
return NUM;
}
/* Return end-of-file. */
if (c == EOF)
return CALC_EOF;
/* Return single chars. */
return c;
}
static int static int
power (int base, int exponent) power (int base, int exponent)
@@ -343,12 +350,18 @@ main (int argc, const char **argv)
return status; return status;
} }
]]) ]])
AT_DEFINES_IF([AT_DATA_SOURCE([[calc-lex.c]AT_SKEL_CC_IF([[c]])],
[[#include "calc.h]AT_SKEL_CC_IF([[h]])["
]AT_CALC_LEX])])
m4_popdef([AT_CALC_LEX])
])# _AT_DATA_CALC_Y ])# _AT_DATA_CALC_Y
# AT_DATA_CALC_Y([BISON-OPTIONS]) # AT_DATA_CALC_Y([BISON-OPTIONS])
# ------------------------------- # -------------------------------
# Produce `calc.y'. # Produce `calc.y' and, if %defines was specified, `calc-lex.c' or
# `calc-lex.cc'.
m4_define([AT_DATA_CALC_Y], m4_define([AT_DATA_CALC_Y],
[_AT_DATA_CALC_Y($[1], $[2], $[3], [$1]) [_AT_DATA_CALC_Y($[1], $[2], $[3], [$1])
]) ])
@@ -453,12 +466,7 @@ m4_ifval([$2], [AT_CHECK([exit 77])])
AT_BISON_OPTION_PUSHDEFS([$1]) AT_BISON_OPTION_PUSHDEFS([$1])
AT_DATA_CALC_Y([$1]) AT_DATA_CALC_Y([$1])
AT_FULL_COMPILE([calc], [AT_DEFINES_IF([[lex]])])
AT_SKEL_CC_IF(
[AT_BISON_CHECK([-o calc.cc calc.y])
AT_COMPILE_CXX([calc])],
[AT_BISON_CHECK([-o calc.c calc.y])
AT_COMPILE([calc])])
# Test the priorities. # Test the priorities.
_AT_CHECK_CALC([$1], _AT_CHECK_CALC([$1],

View File

@@ -1,7 +1,8 @@
# Process this -*- Autotest -*- file with autom4te. # Process this -*- Autotest -*- file with autom4te.
# Macros for the GNU Bison Test suite. # Macros for the GNU Bison Test suite.
# Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. # Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation,
# Inc.
# This program is free software: you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
@@ -39,6 +40,8 @@ m4_define([AT_BISON_OPTION_PUSHDEFS],
m4_define([_AT_BISON_OPTION_PUSHDEFS], m4_define([_AT_BISON_OPTION_PUSHDEFS],
[m4_if([$1$2], $[1]$[2], [], [m4_if([$1$2], $[1]$[2], [],
[m4_fatal([$0: Invalid arguments: $@])])dnl [m4_fatal([$0: Invalid arguments: $@])])dnl
m4_pushdef([AT_DEFINES_IF],
[m4_bmatch([$3], [%defines], [$1], [$2])])
m4_pushdef([AT_SKEL_CC_IF], m4_pushdef([AT_SKEL_CC_IF],
[m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])]) [m4_bmatch([$3], [%language "[Cc]\+\+"\|%skeleton "[a-z0-9]+\.cc"], [$1], [$2])])
m4_pushdef([AT_GLR_IF], m4_pushdef([AT_GLR_IF],
@@ -100,8 +103,8 @@ AT_PURE_LEX_IF(
m4_pushdef([AT_LEX_PRE_ARGS], m4_pushdef([AT_LEX_PRE_ARGS],
[AT_LEX_ARGS, ]) [AT_LEX_ARGS, ])
], ],
[m4_pushdef([AT_LOC], [(yylloc)]) [m4_pushdef([AT_LOC], [[(]AT_NAME_PREFIX[lloc)]])
m4_pushdef([AT_VAL], [(yylval)]) m4_pushdef([AT_VAL], [[(]AT_NAME_PREFIX[lval)]])
m4_pushdef([AT_LEX_FORMALS], [void]) m4_pushdef([AT_LEX_FORMALS], [void])
m4_pushdef([AT_LEX_ARGS], []) m4_pushdef([AT_LEX_ARGS], [])
m4_pushdef([AT_USE_LEX_ARGS], []) m4_pushdef([AT_USE_LEX_ARGS], [])
@@ -135,6 +138,7 @@ m4_popdef([AT_GLR_IF])
m4_popdef([AT_SKEL_CC_IF]) m4_popdef([AT_SKEL_CC_IF])
m4_popdef([AT_GLR_CC_IF]) m4_popdef([AT_GLR_CC_IF])
m4_popdef([AT_LALR1_CC_IF]) m4_popdef([AT_LALR1_CC_IF])
m4_popdef([AT_DEFINES_IF])
])# AT_BISON_OPTION_POPDEFS ])# AT_BISON_OPTION_POPDEFS
@@ -143,21 +147,37 @@ m4_popdef([AT_LALR1_CC_IF])
## Generating Grammar Files. ## ## Generating Grammar Files. ##
## -------------------------- ## ## -------------------------- ##
# AT_DATA_SOURCE_PROLOGUE
# ------------------------
# The prologue that should be included in any source code that is
# meant to be compiled.
m4_define([AT_DATA_SOURCE_PROLOGUE],
[[#include <config.h>
/* We don't need perfect functions for these tests. */
#undef malloc
#undef memcmp
#undef realloc
]])
# AT_DATA_GRAMMAR_PROLOGUE # AT_DATA_GRAMMAR_PROLOGUE
# ------------------------ # ------------------------
# The prologue that should be included in any grammar which parser is # The prologue that should be included in any grammar which parser is
# meant to be compiled. # meant to be compiled.
m4_define([AT_DATA_GRAMMAR_PROLOGUE], m4_define([AT_DATA_GRAMMAR_PROLOGUE],
[[%{ [[%code top {
#include <config.h> ]AT_DATA_SOURCE_PROLOGUE[]dnl
/* We don't need perfect functions for these tests. */ [}
#undef malloc ]])
#undef memcmp
#undef realloc
%}]
])
# AT_DATA_SOURCE(NAME, CONTENT)
# -----------------------------
# Generate the file NAME, which CONTENT is preceded by
# AT_DATA_SOURCE_PROLOGUE.
m4_define([AT_DATA_SOURCE],
[AT_DATA([$1],
[AT_DATA_SOURCE_PROLOGUE
$2])
])
# AT_DATA_GRAMMAR(NAME, CONTENT) # AT_DATA_GRAMMAR(NAME, CONTENT)
# ------------------------------ # ------------------------------
@@ -268,6 +288,20 @@ AT_CHECK([$CXX $CXXFLAGS $CPPFLAGS m4_bmatch([$1], [[.]], [], [$LDFLAGS ])-o $1
0, [ignore], [ignore])]) 0, [ignore], [ignore])])
# AT_FULL_COMPILE(OUTPUT, [OTHER])
# --------------------------------
# Compile OUTPUT.y to OUTPUT.c or OUTPUT.cc, and compile it to OUTPUT.
# If OTHER is specified, compile OUTPUT-OTHER.c or OUTPUT-OTHER.cc to OUTPUT
# along with it.
# Relies on AT_SKEL_CC_IF.
m4_define([AT_FULL_COMPILE],
[AT_SKEL_CC_IF(
[AT_BISON_CHECK([-o $1.cc $1.y])
AT_COMPILE_CXX([$1]m4_ifval($2, [, [$1.cc $1-$2.cc]]))],
[AT_BISON_CHECK([-o $1.c $1.y])
AT_COMPILE([$1]m4_ifval($2, [, [$1.c $1-$2.c]]))])
])
## ---------------------------- ## ## ---------------------------- ##
## Running a generated parser. ## ## Running a generated parser. ##