# Bison Regressions. -*- Autotest -*- # Copyright 2001 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 # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # 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. AT_BANNER([[Regression tests.]]) ## ------------------ ## ## Duplicate string. ## ## ------------------ ## AT_SETUP([Duplicate string]) AT_DATA([duplicate.y], [[/* `Bison -v' used to dump core when two tokens are defined with the same string, as LE and GE below. */ %token NUM %token LE "<=" %token GE "<=" %% exp: '(' exp ')' | NUM ; %% ]]) AT_CHECK([bison -v duplicate.y -o duplicate.c], 0, ignore, ignore) AT_CLEANUP ## ------------------------- ## ## Unresolved SR Conflicts. ## ## ------------------------- ## AT_SETUP([Unresolved SR Conflicts]) AT_DATA([input.y], [[%token NUM OP %% exp: exp OP exp | NUM; ]]) AT_CHECK([bison input.y -o input.c -v], 0, [], [input.y contains 1 shift/reduce conflict. ]) # Check the contents of the report. AT_CHECK([cat input.output], [], [[State 4 contains 1 shift/reduce conflict. Grammar Number, Line, Rule 1 3 exp -> exp OP exp 2 3 exp -> NUM Terminals, with rules where they appear $ (-1) error (256) NUM (257) 2 OP (258) 1 Nonterminals, with rules where they appear exp (5) on left: 1 2, on right: 1 state 0 NUM shift, and go to state 1 exp go to state 2 state 1 exp -> NUM . (rule 2) $default reduce using rule 2 (exp) state 2 exp -> exp . OP exp (rule 1) $ go to state 5 OP shift, and go to state 3 state 3 exp -> exp OP . exp (rule 1) NUM shift, and go to state 1 exp go to state 4 state 4 exp -> exp . OP exp (rule 1) exp -> exp OP exp . (rule 1) OP shift, and go to state 3 OP [reduce using rule 1 (exp)] $default reduce using rule 1 (exp) state 5 $ go to state 6 state 6 $default accept ]]) AT_CLEANUP ## --------------------- ## ## Solved SR Conflicts. ## ## --------------------- ## AT_SETUP([Solved SR Conflicts]) AT_DATA([input.y], [[%token NUM OP %right OP %% exp: exp OP exp | NUM; ]]) AT_CHECK([bison input.y -o input.c -v], 0, [], []) # Check the contents of the report. AT_CHECK([cat input.output], [], [[Conflict in state 4 between rule 1 and token OP resolved as shift. Grammar Number, Line, Rule 1 4 exp -> exp OP exp 2 4 exp -> NUM Terminals, with rules where they appear $ (-1) error (256) NUM (257) 2 OP (258) 1 Nonterminals, with rules where they appear exp (5) on left: 1 2, on right: 1 state 0 NUM shift, and go to state 1 exp go to state 2 state 1 exp -> NUM . (rule 2) $default reduce using rule 2 (exp) state 2 exp -> exp . OP exp (rule 1) $ go to state 5 OP shift, and go to state 3 state 3 exp -> exp OP . exp (rule 1) NUM shift, and go to state 1 exp go to state 4 state 4 exp -> exp . OP exp (rule 1) exp -> exp OP exp . (rule 1) OP shift, and go to state 3 $default reduce using rule 1 (exp) state 5 $ go to state 6 state 6 $default accept ]]) AT_CLEANUP ## ------------------- ## ## Rule Line Numbers. ## ## ------------------- ## AT_SETUP([Rule Line Numbers]) AT_DATA([input.y], [[%% expr: 'a' { } 'b' { } | { } 'c' { } ]]) AT_CHECK([bison input.y -o input.c -v], 0, [], []) # Check the contents of the report. AT_CHECK([cat input.output], [], [[Grammar Number, Line, Rule 1 2 @1 -> /* empty */ 2 2 expr -> 'a' @1 'b' 3 15 @2 -> /* empty */ 4 15 expr -> @2 'c' Terminals, with rules where they appear $ (-1) 'a' (97) 2 'b' (98) 2 'c' (99) 4 error (256) Nonterminals, with rules where they appear expr (6) on left: 2 4 @1 (7) on left: 1, on right: 2 @2 (8) on left: 3, on right: 4 state 0 'a' shift, and go to state 1 $default reduce using rule 3 (@2) expr go to state 6 @2 go to state 2 state 1 expr -> 'a' . @1 'b' (rule 2) $default reduce using rule 1 (@1) @1 go to state 3 state 2 expr -> @2 . 'c' (rule 4) 'c' shift, and go to state 4 state 3 expr -> 'a' @1 . 'b' (rule 2) 'b' shift, and go to state 5 state 4 expr -> @2 'c' . (rule 4) $default reduce using rule 4 (expr) state 5 expr -> 'a' @1 'b' . (rule 2) $default reduce using rule 2 (expr) state 6 $ go to state 7 state 7 $default accept ]]) AT_CLEANUP ## -------------------- ## ## %expect not enough. ## ## -------------------- ## AT_SETUP([%expect not enough]) AT_DATA([input.y], [[%token NUM OP %expect 0 %% exp: exp OP exp | NUM; ]]) AT_CHECK([bison input.y -o input.c], 1, [], [input.y contains 1 shift/reduce conflict. expected 0 shift/reduce conflicts ]) AT_CLEANUP ## --------------- ## ## %expect right. ## ## --------------- ## AT_SETUP([%expect right]) AT_DATA([input.y], [[%token NUM OP %expect 1 %% exp: exp OP exp | NUM; ]]) AT_CHECK([bison input.y -o input.c], 0) AT_CLEANUP ## ------------------ ## ## %expect too much. ## ## ------------------ ## AT_SETUP([%expect too much]) AT_DATA([input.y], [[%token NUM OP %expect 2 %% exp: exp OP exp | NUM; ]]) AT_CHECK([bison input.y -o input.c], 1, [], [input.y contains 1 shift/reduce conflict. expected 2 shift/reduce conflicts ]) AT_CLEANUP ## ---------------------- ## ## Mixing %token styles. ## ## ---------------------- ## AT_SETUP([Mixing %token styles]) # Taken from the documentation. AT_DATA([input.y], [[%token OR "||" %token LE 134 "<=" %left OR "<=" %% exp: ; %% ]]) AT_CHECK([bison -v input.y -o input.c], 0, ignore, ignore) AT_CLEANUP ## ---------------------- ## ## %union and --defines. ## ## ---------------------- ## AT_SETUP([%union and --defines]) AT_DATA([union.y], [%union { int integer; char *string ; } %% exp: {}; ]) AT_CHECK([bison --defines union.y]) AT_CLEANUP ## --------------------------------------- ## ## Duplicate '/' in C comments in %union ## ## --------------------------------------- ## AT_SETUP([%union and C comments]) AT_DATA([union-comment.y], [%union { /* The int. */ int integer; /* The string. */ char *string ; } %% exp: {}; ]) AT_CHECK([bison union-comment.y]) AT_CHECK([fgrep '//*' union-comment.tab.c], [1], []) AT_CLEANUP ## ----------------- ## ## Invalid input 1. ## ## ----------------- ## AT_SETUP([Invalid input: 1]) AT_DATA([input.y], [[%% ? ]]) AT_CHECK([bison input.y], [1], [], [[input.y:2: invalid input: `?' input.y:3: fatal error: no rules in the input grammar ]]) AT_CLEANUP ## ----------------- ## ## Invalid input 2. ## ## ----------------- ## AT_SETUP([Invalid input: 2]) AT_DATA([input.y], [[%% default: 'a' } ]]) AT_CHECK([bison input.y], [1], [], [[input.y:2: invalid input: `}' ]]) AT_CLEANUP ## -------------------- ## ## Invalid %directive. ## ## -------------------- ## AT_SETUP([Invalid %directive]) AT_DATA([input.y], [[%invalid ]]) AT_CHECK([bison input.y], [1], [], [[input.y:1: unrecognized: %invalid input.y:1: Skipping to next % input.y:2: fatal error: no input grammar ]]) AT_CLEANUP ## --------------------- ## ## Invalid CPP headers. ## ## --------------------- ## # AT_TEST_CPP_GUARD_H([INPUT-FILE-BASE) # ------------------------------------- m4_define([AT_TEST_CPP_GUARD_H], [AT_SETUP([Invalid CPP guards: $1]) # Possibly create inner directories. dirname=`AS_DIRNAME([$1])` AS_MKDIR_P([$dirname]) AT_DATA([$1.y], [%% dummy: ]) AT_CHECK([bison --defines=$1.h $1.y]) # CPP should be happy with it. AT_CHECK([$CC -E $1.h], 0, [ignore]) AT_CLEANUP ]) AT_TEST_CPP_GUARD_H([input/input]) AT_TEST_CPP_GUARD_H([9foo]) ## ---------------- ## ## Broken Closure. ## ## ---------------- ## # TC was once broken during a massive `simplification' of the code. # It resulted in bison dumping core on the following grammar (the # computation of FIRSTS uses TC). It managed to produce a pretty # exotic closure: # # TC: Input # # 01234567 # +--------+ # 0| 1 | # 1| 1 | # 2| 1 | # 3| 1 | # 4| 1 | # 5| 1 | # 6| 1| # 7| | # +--------+ # # TC: Output # # 01234567 # +--------+ # 0| 1 | # 1| 111 | # 2| 111 | # 3| 1111 | # 4| 111 1 | # 5| 111 1 | # 6| 111 1| # 7| 111 | # +--------+ # # instead of that below. AT_SETUP([Broken Closure]) AT_DATA([input.y], [[%% a: b b: c c: d d: e e: f f: g g: h h: 'h' ]]) AT_CHECK([bison --trace input.y 2>&1 | sed -n '/^TC: Output BEGIN/,/^TC: Output END/p'], [0], [[TC: Output BEGIN @&t@ 01234567 +--------+ 0| 1111111| 1| 111111| 2| 11111| 3| 1111| 4| 111| 5| 11| 6| 1| 7| | +--------+ TC: Output END ]]) AT_CLEANUP