tests: handle locations in a more generic way.

* tests/local.at (AT_YYERROR_PROTOTYPE): New.
Use it.
* tests/cxx-type.at: Extensive revamp to use a more traditional
quotation scheme, and to use the generic yyerror implementation.
Prefer Autotest macros to CPP macros.
* tests/java.at: .
This commit is contained in:
Akim Demaille
2012-06-22 11:34:37 +02:00
parent 7490994123
commit 6d55954743
3 changed files with 77 additions and 89 deletions

View File

@@ -23,15 +23,15 @@ AT_BANNER([[C++ Type Syntax (GLR).]])
# and with RESOLVE1 and RESOLVE2 as annotations on the conflicted rule for # and with RESOLVE1 and RESOLVE2 as annotations on the conflicted rule for
# stmt. Then compile the result. # stmt. Then compile the result.
m4_define([_AT_TEST_GLR_CXXTYPES], m4_define([_AT_TEST_GLR_CXXTYPES],
[ [AT_BISON_OPTION_PUSHDEFS([%glr-parser $1])
AT_BISON_OPTION_PUSHDEFS([$1])
AT_DATA_GRAMMAR([types.y], AT_DATA_GRAMMAR([types.y],
[[/* Simplified C++ Type and Expression Grammar. */ [[/* Simplified C++ Type and Expression Grammar. */
$1 $1
%{ %code requires
{
#include <stdio.h> #include <stdio.h>
union Node { union Node {
struct { struct {
@@ -51,33 +51,22 @@ $1
} term; } term;
}; };
typedef union Node Node; typedef union Node Node;
#define YYSTYPE Node *
}
%code
{
static Node *new_nterm (char const *, Node *, Node *, Node *); static Node *new_nterm (char const *, Node *, Node *, Node *);
static Node *new_term (char *); static Node *new_term (char *);
static void free_node (Node *); static void free_node (Node *);
static char *node_to_string (Node *); static char *node_to_string (Node *);
#define YYSTYPE Node *
]m4_bmatch([$2], [stmtMerge], ]m4_bmatch([$2], [stmtMerge],
[ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[ [ static YYSTYPE stmtMerge (YYSTYPE x0, YYSTYPE x1);])[
#define YYINITDEPTH 10 #define YYINITDEPTH 10
#define YYSTACKEXPANDABLE 1 #define YYSTACKEXPANDABLE 1
struct YYLTYPE; ]AT_YYERROR_DECLARE[
#if YYPURE ]AT_YYLEX_DECLARE[
# if YYLSP_NEEDED }
# define LEX_PARAMETERS YYSTYPE *lvalp, struct YYLTYPE *llocp
# define ERROR_PARAMETERS struct YYLTYPE *llocp, char const *s
# else
# define LEX_PARAMETERS YYSTYPE *lvalp
# endif
#endif
#ifndef LEX_PARAMETERS
# define LEX_PARAMETERS void
#endif
#ifndef ERROR_PARAMETERS
# define ERROR_PARAMETERS char const *s
#endif
int yylex (LEX_PARAMETERS);
void yyerror (ERROR_PARAMETERS);
%}
%token TYPENAME ID %token TYPENAME ID
@@ -144,8 +133,10 @@ main (int argc, char **argv)
return yyparse (); return yyparse ();
} }
]AT_YYERROR_DEFINE[
int int
yylex (LEX_PARAMETERS) yylex (]AT_LEX_FORMALS[)
{ {
char buffer[256]; char buffer[256];
int c; int c;
@@ -181,11 +172,9 @@ yylex (LEX_PARAMETERS)
break; break;
default: default:
{ {
int tok; int tok;]AT_LOCATION_IF([[
#if YYLSP_NEEDED
yylloc.first_line = yylloc.last_line = lineNum; yylloc.first_line = yylloc.last_line = lineNum;
yylloc.first_column = colNum; yylloc.first_column = colNum;]])[
#endif
if (isalpha (c)) if (isalpha (c))
{ {
i = 0; i = 0;
@@ -210,27 +199,14 @@ yylex (LEX_PARAMETERS)
colNum += 1; colNum += 1;
tok = c; tok = c;
yylval = YY_NULL; yylval = YY_NULL;
} }]AT_LOCATION_IF([[
#if YYLSP_NEEDED yylloc.last_column = colNum-1;]])[
yylloc.last_column = colNum-1;
#endif
return tok; return tok;
} }
} }
} }
} }
void
yyerror (ERROR_PARAMETERS)
{
#if YYPURE && YYLSP_NEEDED
/* Pacify GCC by using llocp. */
if (! llocp)
abort ();
#endif
fprintf (stderr, "%s\n", s);
}
static Node * static Node *
new_nterm (char const *form, Node *child0, Node *child1, Node *child2) new_nterm (char const *form, Node *child0, Node *child1, Node *child2)
{ {
@@ -351,7 +327,7 @@ AT_BISON_OPTION_POPDEFS
]) ])
m4_define([_AT_RESOLVED_GLR_OUTPUT], m4_define([_AT_RESOLVED_GLR_OUTPUT],
[[[+(z,q) [[+(z,q)
<declare>(T,x) <declare>(T,x)
<init-declare>(T,x,y) <init-declare>(T,x,y)
=(x,y) =(x,y)
@@ -360,10 +336,10 @@ m4_define([_AT_RESOLVED_GLR_OUTPUT],
<init-declare>(T,y,+(z,q)) <init-declare>(T,y,+(z,q))
<error> <error>
+(z,q) +(z,q)
]]]) ]])
m4_define([_AT_RESOLVED_GLR_OUTPUT_WITH_LOC], m4_define([_AT_RESOLVED_GLR_OUTPUT_WITH_LOC],
[[[3.0-3.5: +(z,q) [[3.0-3.5: +(z,q)
5.0-5.3: <declare>(T,x) 5.0-5.3: <declare>(T,x)
7.0-7.7: <init-declare>(T,x,y) 7.0-7.7: <init-declare>(T,x,y)
9.0-9.5: =(x,y) 9.0-9.5: =(x,y)
@@ -372,10 +348,10 @@ m4_define([_AT_RESOLVED_GLR_OUTPUT_WITH_LOC],
15.0-15.13: <init-declare>(T,y,+(z,q)) 15.0-15.13: <init-declare>(T,y,+(z,q))
17.0-17.15: <error> 17.0-17.15: <error>
19.0-19.5: +(z,q) 19.0-19.5: +(z,q)
]]]) ]])
m4_define([_AT_AMBIG_GLR_OUTPUT], m4_define([_AT_AMBIG_GLR_OUTPUT],
[[[+(z,q) [[+(z,q)
<declare>(T,x) <declare>(T,x)
<init-declare>(T,x,y) <init-declare>(T,x,y)
=(x,y) =(x,y)
@@ -384,10 +360,10 @@ m4_define([_AT_AMBIG_GLR_OUTPUT],
<OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q))) <OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q)))
<error> <error>
+(z,q) +(z,q)
]]]) ]])
m4_define([_AT_AMBIG_GLR_OUTPUT_WITH_LOC], m4_define([_AT_AMBIG_GLR_OUTPUT_WITH_LOC],
[[[3.0-3.5: +(z,q) [[3.0-3.5: +(z,q)
5.0-5.3: <declare>(T,x) 5.0-5.3: <declare>(T,x)
7.0-7.7: <init-declare>(T,x,y) 7.0-7.7: <init-declare>(T,x,y)
9.0-9.5: =(x,y) 9.0-9.5: =(x,y)
@@ -396,15 +372,23 @@ m4_define([_AT_AMBIG_GLR_OUTPUT_WITH_LOC],
15.0-15.13: <OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q))) 15.0-15.13: <OR>(<init-declare>(T,y,+(z,q)),=(<cast>(y,T),+(z,q)))
17.0-17.15: <error> 17.0-17.15: <error>
19.0-19.5: +(z,q) 19.0-19.5: +(z,q)
]]]) ]])
m4_define([_AT_GLR_STDERR], m4_define([_AT_GLR_STDERR],
[[[syntax error [[syntax error
]]]) ]])
m4_define([_AT_GLR_STDERR_WITH_LOC],
[[17.5-4: syntax error
]])
m4_define([_AT_VERBOSE_GLR_STDERR], m4_define([_AT_VERBOSE_GLR_STDERR],
[[[syntax error, unexpected ID, expecting '=' or '+' or ')' [[syntax error, unexpected ID, expecting '=' or '+' or ')'
]]]) ]])
m4_define([_AT_VERBOSE_GLR_STDERR_WITH_LOC],
[[17.5-4: syntax error, unexpected ID, expecting '=' or '+' or ')'
]])
## ---------------------------------------------------- ## ## ---------------------------------------------------- ##
## Compile the grammar described in the documentation. ## ## Compile the grammar described in the documentation. ##
@@ -414,59 +398,59 @@ AT_SETUP([GLR: Resolve ambiguity, impure, no locations])
_AT_TEST_GLR_CXXTYPES([], _AT_TEST_GLR_CXXTYPES([],
[%dprec 1], [%dprec 2]) [%dprec 1], [%dprec 2])
AT_PARSER_CHECK([[./types test-input]], 0, AT_PARSER_CHECK([[./types test-input]], 0,
_AT_RESOLVED_GLR_OUTPUT, _AT_GLR_STDERR) [_AT_RESOLVED_GLR_OUTPUT], [_AT_GLR_STDERR])
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Resolve ambiguity, impure, locations]) AT_SETUP([GLR: Resolve ambiguity, impure, locations])
_AT_TEST_GLR_CXXTYPES([%locations],[%dprec 1],[%dprec 2]) _AT_TEST_GLR_CXXTYPES([%locations],[%dprec 1],[%dprec 2])
AT_PARSER_CHECK([[./types test-input]], 0, AT_PARSER_CHECK([[./types test-input]], 0,
_AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) [_AT_RESOLVED_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC])
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Resolve ambiguity, pure, no locations]) AT_SETUP([GLR: Resolve ambiguity, pure, no locations])
_AT_TEST_GLR_CXXTYPES([%define api.pure], _AT_TEST_GLR_CXXTYPES([%define api.pure],
[%dprec 1], [%dprec 2]) [%dprec 1], [%dprec 2])
AT_PARSER_CHECK([[./types test-input]], 0, AT_PARSER_CHECK([[./types test-input]], 0,
_AT_RESOLVED_GLR_OUTPUT, _AT_GLR_STDERR) [_AT_RESOLVED_GLR_OUTPUT], [_AT_GLR_STDERR])
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Resolve ambiguity, pure, locations]) AT_SETUP([GLR: Resolve ambiguity, pure, locations])
_AT_TEST_GLR_CXXTYPES([%define api.pure %locations], _AT_TEST_GLR_CXXTYPES([%define api.pure %locations],
[%dprec 1], [%dprec 2]) [%dprec 1], [%dprec 2])
AT_PARSER_CHECK([[./types test-input]], 0, AT_PARSER_CHECK([[./types test-input]], 0,
_AT_RESOLVED_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) [_AT_RESOLVED_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC])
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Merge conflicting parses, impure, no locations]) AT_SETUP([GLR: Merge conflicting parses, impure, no locations])
_AT_TEST_GLR_CXXTYPES([], _AT_TEST_GLR_CXXTYPES([],
[%merge <stmtMerge>], [%merge <stmtMerge>]) [%merge <stmtMerge>], [%merge <stmtMerge>])
AT_PARSER_CHECK([[./types test-input]], 0, AT_PARSER_CHECK([[./types test-input]], 0,
_AT_AMBIG_GLR_OUTPUT, _AT_GLR_STDERR) [_AT_AMBIG_GLR_OUTPUT], [_AT_GLR_STDERR])
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Merge conflicting parses, impure, locations]) AT_SETUP([GLR: Merge conflicting parses, impure, locations])
_AT_TEST_GLR_CXXTYPES([%locations], _AT_TEST_GLR_CXXTYPES([%locations],
[%merge <stmtMerge>], [%merge <stmtMerge>]) [%merge <stmtMerge>], [%merge <stmtMerge>])
AT_PARSER_CHECK([[./types test-input]], 0, AT_PARSER_CHECK([[./types test-input]], 0,
_AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) [_AT_AMBIG_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC])
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Merge conflicting parses, pure, no locations]) AT_SETUP([GLR: Merge conflicting parses, pure, no locations])
_AT_TEST_GLR_CXXTYPES([%define api.pure], _AT_TEST_GLR_CXXTYPES([%define api.pure],
[%merge <stmtMerge>], [%merge <stmtMerge>]) [%merge <stmtMerge>], [%merge <stmtMerge>])
AT_PARSER_CHECK([[./types test-input]], 0, AT_PARSER_CHECK([[./types test-input]], 0,
_AT_AMBIG_GLR_OUTPUT, _AT_GLR_STDERR) [_AT_AMBIG_GLR_OUTPUT], [_AT_GLR_STDERR])
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Merge conflicting parses, pure, locations]) AT_SETUP([GLR: Merge conflicting parses, pure, locations])
_AT_TEST_GLR_CXXTYPES([%define api.pure %locations], _AT_TEST_GLR_CXXTYPES([%define api.pure %locations],
[%merge <stmtMerge>],[%merge <stmtMerge>]) [%merge <stmtMerge>],[%merge <stmtMerge>])
AT_PARSER_CHECK([[./types test-input]], 0, AT_PARSER_CHECK([[./types test-input]], 0,
_AT_AMBIG_GLR_OUTPUT_WITH_LOC, _AT_GLR_STDERR) [_AT_AMBIG_GLR_OUTPUT_WITH_LOC], [_AT_GLR_STDERR_WITH_LOC])
AT_CLEANUP AT_CLEANUP
AT_SETUP([GLR: Verbose messages, resolve ambiguity, impure, no locations]) AT_SETUP([GLR: Verbose messages, resolve ambiguity, impure, no locations])
_AT_TEST_GLR_CXXTYPES([%error-verbose], _AT_TEST_GLR_CXXTYPES([%error-verbose],
[%merge <stmtMerge>], [%merge <stmtMerge>]) [%merge <stmtMerge>], [%merge <stmtMerge>])
AT_PARSER_CHECK([[./types test-input]], 0, AT_PARSER_CHECK([[./types test-input]], 0,
_AT_AMBIG_GLR_OUTPUT, _AT_VERBOSE_GLR_STDERR) [_AT_AMBIG_GLR_OUTPUT], [_AT_VERBOSE_GLR_STDERR])
AT_CLEANUP AT_CLEANUP

View File

@@ -32,6 +32,7 @@ AT_BANNER([[Java Calculator.]])
m4_define([_AT_DATA_JAVA_CALC_Y], m4_define([_AT_DATA_JAVA_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
AT_BISON_OPTION_PUSHDEFS([%language "Java" $4])
AT_DATA([Calc.y], AT_DATA([Calc.y],
[[/* Infix notation calculator--calc */ [[/* Infix notation calculator--calc */
%language "Java" %language "Java"
@@ -122,20 +123,8 @@ AT_LOCATION_IF([[
public Position getEndPos() { public Position getEndPos() {
return yypos; return yypos;
} }
public void yyerror (Calc.Location l, String s)
{
if (l == null)
System.err.println (s);
else
System.err.println (l + ": " + s);
}
]], [[
public void yyerror (String s)
{
System.err.println (s);
}
]])[ ]])[
]AT_YYERROR_DEFINE[
Integer yylval; Integer yylval;
@@ -211,11 +200,12 @@ class Position {
} }
]]) ]])
AT_BISON_OPTION_POPDEFS
])# _AT_DATA_JAVA_CALC_Y ])# _AT_DATA_JAVA_CALC_Y
# AT_DATA_CALC_Y([BISON-OPTIONS]) # AT_DATA_CALC_Y([BISON-OPTIONS])
# ------------------------------------------------- # -------------------------------
# Produce `calc.y'. # Produce `calc.y'.
m4_define([AT_DATA_JAVA_CALC_Y], m4_define([AT_DATA_JAVA_CALC_Y],
[_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1]) [_AT_DATA_JAVA_CALC_Y($[1], $[2], $[3], [$1])
@@ -224,7 +214,7 @@ m4_define([AT_DATA_JAVA_CALC_Y],
# _AT_CHECK_JAVA_CALC_ERROR(BISON-OPTIONS, INPUT, # _AT_CHECK_JAVA_CALC_ERROR(BISON-OPTIONS, INPUT,
# [VERBOSE-AND-LOCATED-ERROR-MESSAGE]) # [VERBOSE-AND-LOCATED-ERROR-MESSAGE])
# --------------------------------------------------------- # --------------------------------------------------------------
# Run `calc' on INPUT, and expect a `syntax error' message. # Run `calc' on INPUT, and expect a `syntax error' message.
# #
# If INPUT starts with a slash, it is used as absolute input file name, # If INPUT starts with a slash, it is used as absolute input file name,

View File

@@ -281,7 +281,7 @@ $2])
# AT_YYLEX_DEFINE(INPUT-STRING, [ACTION]) # AT_YYLEX_DEFINE(INPUT-STRING, [ACTION])
# --------------------------------------- # ---------------------------------------
m4_define([AT_YYLEX_DECLARE_EXTERN], m4_define([AT_YYLEX_DECLARE_EXTERN],
[int AT_API_PREFIX[]lex (void);dnl [int AT_API_PREFIX[]lex (]AT_LEX_FORMALS[);dnl
]) ])
m4_define([AT_YYLEX_DECLARE], m4_define([AT_YYLEX_DECLARE],
@@ -291,7 +291,7 @@ m4_define([AT_YYLEX_DECLARE],
m4_define([AT_YYLEX_DEFINE], m4_define([AT_YYLEX_DEFINE],
[[#include <stdlib.h> /* abort */ [[#include <stdlib.h> /* abort */
static int static int
]AT_API_PREFIX[lex (void) ]AT_API_PREFIX[lex (]AT_LEX_FORMALS[)
{ {
static char const input[] = "$1"; static char const input[] = "$1";
static size_t toknum = 0; static size_t toknum = 0;
@@ -306,15 +306,20 @@ static int
}]dnl }]dnl
]) ])
# AT_YYERROR_PROTOTYPE
# AT_YYERROR_DECLARE_EXTERN # AT_YYERROR_DECLARE_EXTERN
# AT_YYERROR_DECLARE # AT_YYERROR_DECLARE
# AT_YYERROR_DEFINE # AT_YYERROR_DEFINE
# ------------------------- # -------------------------
# Beware that must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS # Must be called inside a AT_BISON_OPTION_PUSHDEFS/POPDEFS pair.
# pair. m4_define([AT_YYERROR_PROTOTYPE],
[m4_case(AT_LANG,
[c], [[void ]AT_API_PREFIX[error (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg)]])[]dnl
])
m4_define([AT_YYERROR_DECLARE_EXTERN], m4_define([AT_YYERROR_DECLARE_EXTERN],
[m4_case(AT_LANG, [m4_case(AT_LANG,
[c], [void AT_API_PREFIX[]error (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg);])[]dnl [c], [AT_YYERROR_PROTOTYPE;])[]dnl
]) ])
m4_define([AT_YYERROR_DECLARE], m4_define([AT_YYERROR_DECLARE],
@@ -326,8 +331,8 @@ m4_define([AT_YYERROR_DEFINE],
[m4_case(AT_LANG, [m4_case(AT_LANG,
[c], [[#include <stdio.h> [c], [[#include <stdio.h>
/* A C error reporting function. */ /* A C error reporting function. */
static void static
yyerror (]AT_YYERROR_ARG_LOC_IF([YYLTYPE *llocp, ])[const char *msg) ]AT_YYERROR_PROTOTYPE[
{ {
]AT_YYERROR_SEES_LOC_IF([[ ]AT_YYERROR_SEES_LOC_IF([[
fprintf (stderr, "%d.%d", fprintf (stderr, "%d.%d",
@@ -348,10 +353,19 @@ void
(void) l; (void) l;
std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl; std::cerr << ]AT_LOCATION_IF([l << ": " << ])[m << std::endl;
}]], }]],
[java], [[public void yyerror (String msg) [java], [AT_LOCATION_IF([[public void yyerror (Calc.Location l, String s)
{ {
System.err.println (msg); if (l == null)
}]])]) System.err.println (s);
else
System.err.println (l + ": " + s);
}
]], [[
public void yyerror (String s)
{
System.err.println (s);
}]])])dnl
])
## --------------- ## ## --------------- ##