X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/931394cbc10909854852366d589f1d25527922fc..93b68a0e09d1f4964c47ac8cf180220b22372372:/tests/actions.at diff --git a/tests/actions.at b/tests/actions.at index 79dee6fb..990b72bd 100644 --- a/tests/actions.at +++ b/tests/actions.at @@ -31,10 +31,12 @@ AT_SETUP([Mid-rule actions]) AT_DATA([[input.y]], [[%{ -#include -#include -static void yyerror (const char *msg); -static int yylex (void); +# include +# include + static void yyerror (const char *msg); + static int yylex (void); +# define YYDEBUG 1 +# define YYERROR_VERBOSE 1 %} %% exp: { putchar ('0'); } @@ -72,8 +74,263 @@ main (void) AT_CHECK([bison input.y -d -v -o input.c]) AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore]) -AT_CHECK([input], 0, +AT_CHECK([./input], 0, [[0123456789 ]]) AT_CLEANUP + + + +## ---------------- ## +## Exotic Dollars. ## +## ---------------- ## + +AT_SETUP([Exotic Dollars]) + +AT_DATA([[input.y]], +[[%{ +# include +# include + static void yyerror (const char *msg); + static int yylex (void); +# define YYDEBUG 1 +# define YYERROR_VERBOSE 1 +%} + +%union +{ + int val; +}; + +%type a_1 a_2 a_4 a_5 + sum_of_the_five_previous_values + +%% +exp: a_1 a_2 { $$ = 3; } a_4 a_5 sum_of_the_five_previous_values + { + printf ("%d\n", $6); + } +; +a_1: { $$ = 1; }; +a_2: { $$ = 2; }; +a_4: { $$ = 4; }; +a_5: { $$ = 5; }; + +sum_of_the_five_previous_values: + { + $$ = $0 + $-1 + $-2 + $-3 + $-4; + } +; + +%% +static int +yylex (void) +{ + return EOF; +} + +static void +yyerror (const char *msg) +{ + fprintf (stderr, "%s\n", msg); +} + +int +main (void) +{ + return yyparse (); +} +]]) + +AT_CHECK([bison input.y -d -v -o input.c]) +AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore]) +AT_CHECK([./input], 0, +[[15 +]]) + +AT_CLEANUP + + + +## ------------- ## +## Destructors. ## +## ------------- ## + +AT_SETUP([Destructors]) + +# Make sure complex $n work. + +AT_DATA([[input.y]], +[[%{ +#include +#include +#include + +#define YYERROR_VERBOSE 1 +#define YYDEBUG 1 +#define YYPRINT yyprint +%} +%verbose +%union +{ + int ival; +} +%type 'x' thing line input +%destructor { printf ("Freeing input %d from %d\n", $$, @$.first_line); } input +%destructor { printf ("Freeing line %d from %d\n", $$, @$.first_line); } line +%destructor { printf ("Freeing thing %d from %d\n", $$, @$.first_line); } thing +%destructor { printf ("Freeing 'x' %d from %d\n", $$, @$.first_line); } 'x' + +%{ +static int yylex (void); +static void yyerror (const char *msg); +static void yyprint (FILE *out, int num, YYSTYPE val); +%} + + +%% +input: + /* Nothing. */ + { + $$ = 0; + printf ("input(%d): /* Nothing */';'\n", $$); + } +| line input /* Right recursive to load the stack so that popping at + EOF can be exercised. */ + { + $$ = 2; + printf ("input(%d): line(%d) input(%d)';'\n", $$, $1, $2); + } +; + +line: + thing thing thing ';' + { + $$ = $1; + printf ("line(%d): thing(%d) thing(%d) thing(%d) ';'\n", $$, $1, $2, $3); + } +| thing thing ';' + { + $$ = $1; + printf ("line(%d): thing(%d) thing(%d) ';'\n", $$, $1, $2); + } +| thing ';' + { + $$ = $1; + printf ("line(%d): thing(%d) ';'\n", $$, $1); + } +| error ';' + { + $$ = -1; + printf ("line(%d): error ';'\n", $$); + } +; + +thing: + 'x' + { + $$ = $1; + printf ("thing(%d): 'x'(%d)\n", $$, $1); + } +; +%% +static int +yylex (void) +{ + static const unsigned int input[] = + { + /* Exericise the discarding of stack top and input until `error' + can be reduced. */ + 'x', 'x', 'x', 'x', 'x', 'x', ';', + + /* Load the stack and provoke an error that cannot be caught be + the grammar, and check that the stack is cleared. */ + 'x', 'x', ';', + 'x', ';', + 'y' + }; + static int counter = 0; + + if (counter < (sizeof(input) / sizeof (input[0]))) + { + yylval.ival = counter; + printf ("sending: '%c'(%d)\n", input[counter], counter); + /* As in BASIC, line numbers go from 10 to 10. */ + yylloc.first_line = 10 * counter; + return input[counter++]; + } + else + { + printf ("sending: EOF\n"); + return EOF; + } +} + +static void +yyerror (const char *msg) +{ + fprintf (stdout, "%d: %s\n", yylloc.first_line, msg); +} + +static void +yyprint (FILE *out, int num, YYSTYPE val) +{ + fprintf (out, " = %d", val.ival); +} + +int +main (void) +{ + yydebug = !!getenv ("YYDEBUG"); + if (yyparse ()) + { + fprintf (stdout, "Parsing FAILED.\n"); + exit (1); + } + fprintf (stdout, "Successful parse.\n"); + return 0; +} +]]) + +AT_CHECK([bison input.y --location -d -v -o input.c]) +AT_CHECK([$CC $CFLAGS $CPPFLAGS input.c -o input], 0, [], [ignore]) +AT_CHECK([./input], 1, +[[sending: 'x'(0) +thing(0): 'x'(0) +sending: 'x'(1) +thing(1): 'x'(1) +sending: 'x'(2) +thing(2): 'x'(2) +sending: 'x'(3) +30: parse error, unexpected 'x', expecting ';' +Freeing thing 2 from 20 +Freeing thing 1 from 10 +Freeing thing 0 from 0 +Freeing 'x' 3 from 30 +sending: 'x'(4) +Freeing 'x' 4 from 40 +sending: 'x'(5) +Freeing 'x' 5 from 50 +sending: ';'(6) +line(-1): error ';' +sending: 'x'(7) +thing(7): 'x'(7) +sending: 'x'(8) +thing(8): 'x'(8) +sending: ';'(9) +line(7): thing(7) thing(8) ';' +sending: 'x'(10) +thing(10): 'x'(10) +sending: ';'(11) +line(10): thing(10) ';' +sending: 'y'(12) +120: parse error, unexpected $undefined., expecting $ or error or 'x' +sending: EOF +Freeing line 10 from 100 +Freeing line 7 from 70 +Freeing line -1 from 50 +Parsing FAILED. +]]) + +AT_CLEANUP