X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/f56f6d78b0a7f672b70211d0abfd33e643601bce..f9315de5a470cb492502c8fbcadafca3a47abd33:/tests/glr-regression.at diff --git a/tests/glr-regression.at b/tests/glr-regression.at index b7d24ab7..91768a19 100644 --- a/tests/glr-regression.at +++ b/tests/glr-regression.at @@ -1,5 +1,5 @@ # Checking GLR Parsing: Regression Tests -*- Autotest -*- -# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. # 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 @@ -13,8 +13,8 @@ # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. AT_BANNER([[GLR Regression Tests]]) @@ -34,7 +34,7 @@ AT_DATA_GRAMMAR([glr-regr1.y], #define YYSTYPE int static YYSTYPE exprMerge (YYSTYPE x0, YYSTYPE x1); int yylex (void); -int yyerror (char const *msg); +void yyerror (char const *msg); %} @@ -70,11 +70,10 @@ main (void) return yyparse (); } -int +void yyerror (char const *msg) { fprintf (stderr, "%s\n", msg); - exit (4); } @@ -114,7 +113,7 @@ AT_CLEANUP ## Improper handling of embedded actions and $-N in GLR parsers ## ## ------------------------------------------------------------ ## -AT_SETUP([Improper handling of embedded actions and $-N in GLR parsers]) +AT_SETUP([Improper handling of embedded actions and dollar(-N) in GLR parsers]) AT_DATA_GRAMMAR([glr-regr2a.y], [[/* Regression Test: Improper handling of embedded actions and $-N */ @@ -127,6 +126,7 @@ AT_DATA_GRAMMAR([glr-regr2a.y], #include #include + #include #include int yylex (void); void yyerror (char const *); @@ -138,7 +138,7 @@ AT_DATA_GRAMMAR([glr-regr2a.y], command: 's' var 't' - { printf ("Variable: '%s'\n", $2); } + { printf ("Variable: '%s'\n", $2); } 'v' 'x' 'q' | 's' var_list 't' 'e' { printf ("Varlist: '%s'\n", $2); } @@ -155,12 +155,12 @@ var_list: { $$ = $1; } | var ',' var_list { - char buffer[50]; - strcpy (buffer, $1); - strcat (buffer, ","); - strcat (buffer, $3); - $$ = strdup (buffer); - } + char *s = (char *) malloc (strlen ($1) + 1 + strlen ($3) + 1); + strcpy (s, $1); + strcat (s, ","); + strcat (s, $3); + $$ = s; + } ; var_printer: 'v' @@ -172,8 +172,9 @@ FILE *yyin = NULL; int yylex (void) -{ +{ char buf[50]; + char *s; switch (fscanf (yyin, " %1[a-z,]", buf)) { case 1: return buf[0]; @@ -182,8 +183,13 @@ yylex (void) default: break; } - fscanf (yyin, "%s", buf); - yylval = strdup (buf); + if (fscanf (yyin, "%49s", buf) != 1) + return 0; + if (sizeof buf - 1 <= strlen (buf)) + abort (); + s = (char *) malloc (strlen (buf) + 1); + strcpy (s, buf); + yylval = s; return 'V'; } @@ -194,9 +200,9 @@ yyerror (char const *s) int main (int argc, char **argv) -{ +{ yyin = stdin; - if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 1; + if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 3; return yyparse (); } ]]) @@ -217,4 +223,200 @@ AT_CHECK([[echo s VARIABLE_3 t v x | ./glr-regr2a]], 0, ]], []) +AT_CLEANUP + +## ------------------------------------------------------------ ## +## Improper merging of GLR delayed action sets ## +## ------------------------------------------------------------ ## + +AT_SETUP([Improper merging of GLR delayed action sets]) + +AT_DATA_GRAMMAR([glr-regr3.y], +[[/* Regression Test: Improper merging of GLR delayed action sets. */ +/* Reported by M. Rosien */ + +%{ +#include +#include + +static int MergeRule (int x0, int x1); +static void yyerror(char const * s); +int yylex (void); + +#define RULE(x) (1 << (x)) + +%} + +%glr-parser + +%token BAD_CHAR +%token P1 P2 T1 T2 T3 T4 O1 O2 + +%% + +S : P1 T4 O2 NT6 P2 { printf ("Result: %x\n", $4); } +; + +NT1 : P1 T1 O1 T2 P2 { $$ = RULE(2); } %merge +; + +NT2 : NT1 { $$ = RULE(3); } %merge + | P1 NT1 O1 T3 P2 { $$ = RULE(4); } %merge +; + +NT3 : T3 { $$ = RULE(5); } %merge + | P1 NT1 O1 T3 P2 { $$ = RULE(6); } %merge +; + +NT4 : NT3 { $$ = RULE(7); } %merge + | NT2 { $$ = RULE(8); } %merge + | P1 NT2 O1 NT3 P2 { $$ = RULE(9); } %merge +; + +NT5 : NT4 { $$ = RULE(10); } %merge +; + +NT6 : P1 NT1 O1 T3 P2 { $$ = RULE(11) | $2; } %merge + | NT5 { $$ = RULE(12) | $1; } %merge +; + +%% + +static int MergeRule (int x0, int x1) { + return x0 | x1; +} + +static void yyerror(char const * s) { + fprintf(stderr,"error: %s\n",s); +} + +FILE *yyin = NULL; + +int P[] = { P1, P2 }; +int O[] = { O1, O2 }; +int T[] = { T1, T2, T3, T4 }; + +int yylex (void) +{ + char inp[3]; + if (fscanf (yyin, "%2s", inp) == EOF) + return 0; + switch (inp[0]) + { + case 'p': return P[inp[1] - '1']; + case 't': return T[inp[1] - '1']; + case 'o': return O[inp[1] - '1']; + } + return BAD_CHAR; +} + +int main(int argc, char* argv[]) { + yyin = stdin; + if (argc == 2 && !(yyin = fopen (argv[1], "r"))) return 3; + return yyparse (); +} +]]) + +AT_CHECK([[bison -o glr-regr3.c glr-regr3.y]], 0, [], +[glr-regr3.y: conflicts: 1 shift/reduce, 1 reduce/reduce +]) +AT_COMPILE([glr-regr3]) + +AT_CHECK([[echo p1 t4 o2 p1 p1 t1 o1 t2 p2 o1 t3 p2 p2 | ./glr-regr3]], 0, +[[Result: 1c04 +]], []) + +AT_CLEANUP + + +## ---------------------------------------------------------------------- ## +## Duplicate representation of merged trees ## +## Thanks to Joel E. Denny for this test; see ## +## . ## +## ---------------------------------------------------------------------- ## + +AT_SETUP([Duplicate representation of merged trees]) + +AT_DATA_GRAMMAR([glr-regr4.y], +[[%union { char *ptr; } +%type S A A1 A2 B +%glr-parser + +%{ + #include + #include + #include + static char *merge (YYSTYPE, YYSTYPE); + static char *make_value (char *, char *); + static void yyerror (char const *); + static int yylex (void); +%} + +%% + +tree: S { printf ("%s\n", $1); } ; + +S: + A %merge { $$ = make_value ("S", $1); } + | B %merge { $$ = make_value ("S", $1); } + ; + +A: + A1 %merge { $$ = make_value ("A", $1); } + | A2 %merge { $$ = make_value ("A", $1); } + ; + +A1: 'a' { $$ = make_value ("A1", "'a'"); } ; +A2: 'a' { $$ = make_value ("A2", "'a'"); } ; +B: 'a' { $$ = make_value ("B", "'a'"); } ; + +%% + +static int +yylex (void) +{ + static char const *input = "a"; + return *input++; +} + +int +main (void) +{ + return yyparse (); +} + +static char * +make_value (char *parent, char *child) +{ + char const format[] = "%s <- %s"; + char *value = malloc (strlen (parent) + strlen (child) + sizeof format); + sprintf (value, format, parent, child); + return value; +} + +static char * +merge (YYSTYPE s1, YYSTYPE s2) +{ + char const format[] = "merge{ %s and %s }"; + char *value = malloc (strlen (s1.ptr) + strlen (s2.ptr) + sizeof format); + sprintf (value, format, s1.ptr, s2.ptr); + return value; +} + +static void +yyerror (char const *msg) +{ + printf ("%s\n", msg); +} +]]) + +AT_CHECK([[bison -o glr-regr4.c glr-regr4.y]], 0, [], +[glr-regr4.y: conflicts: 1 reduce/reduce +]) +AT_COMPILE([glr-regr4]) + +AT_CHECK([[./glr-regr4]], 0, +[[merge{ S <- merge{ A <- A1 <- 'a' and A <- A2 <- 'a' } and S <- B <- 'a' } +]], []) + AT_CLEANUP