X-Git-Url: https://git.saurik.com/bison.git/blobdiff_plain/561f9a30af99cfbd4dbb51bcc82506c987cb92a9..fbbf9b3bb99ef505b55d5d1ba8b98f98226dc358:/tests/regression.at diff --git a/tests/regression.at b/tests/regression.at index 89818745..d8788f88 100644 --- a/tests/regression.at +++ b/tests/regression.at @@ -40,7 +40,434 @@ exp: '(' exp ')' | NUM ; AT_CHECK([bison -v duplicate.y -o duplicate.c], 0, ignore, ignore) -AT_CLEANUP([duplicate.*]) +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 @@ -63,7 +490,7 @@ exp: {}; AT_CHECK([bison --defines union.y]) -AT_CLEANUP([union.*]) +AT_CLEANUP ## --------------------------------------- ## @@ -86,15 +513,15 @@ exp: {}; AT_CHECK([bison union-comment.y]) AT_CHECK([fgrep '//*' union-comment.tab.c], [1], []) -AT_CLEANUP([union-comment.*]) +AT_CLEANUP -## --------------- ## -## invalid input. ## -## --------------- ## +## ----------------- ## +## Invalid input 1. ## +## ----------------- ## -AT_SETUP([Invalid input]) +AT_SETUP([Invalid input: 1]) AT_DATA([input.y], [[%% @@ -102,69 +529,154 @@ AT_DATA([input.y], ]]) AT_CHECK([bison input.y], [1], [], -[input.y:2: invalid input: `?' +[[input.y:2: invalid input: `?' input.y:3: fatal error: no rules in the input grammar -]) +]]) AT_CLEANUP ## ----------------- ## -## Invalid input 1. ## +## Invalid input 2. ## ## ----------------- ## -AT_SETUP([Invalid input: 1]) +AT_SETUP([Invalid input: 2]) AT_DATA([input.y], [[%% -? +default: 'a' } ]]) AT_CHECK([bison input.y], [1], [], -[input.y:2: invalid input: `?' -input.y:3: fatal error: no rules in the input grammar -]) +[[input.y:2: invalid input: `}' +]]) AT_CLEANUP -## ----------------- ## -## Invalid input 2. ## -## ----------------- ## +## -------------------- ## +## Invalid %directive. ## +## -------------------- ## -AT_SETUP([Invalid input: 2]) + +AT_SETUP([Invalid %directive]) AT_DATA([input.y], -[[%% -default: 'a' } +[[%invalid ]]) AT_CHECK([bison input.y], [1], [], -[input.y:2: invalid input: `}' -]) +[[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_SETUP([Invalid CPP headers]) +# AT_TEST_CPP_GUARD_H([INPUT-FILE-BASE) +# ------------------------------------- +m4_define([AT_TEST_CPP_GUARD_H], +[AT_SETUP([Invalid CPP guards: $1]) -mkdir input +# Possibly create inner directories. +dirname=`AS_DIRNAME([$1])` +AS_MKDIR_P([$dirname]) -AT_DATA([input/input.y], +AT_DATA([$1.y], [%% dummy: ]) -AT_CHECK([bison --defines input/input.y]) +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_CHECK([sed 1q input/input.tab.h], 0, -[[#ifndef INPUT_INPUT_TAB_H +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(input) +AT_CLEANUP