This is some software I have written to assist in debugging shift/reduce and reduce/reduce conflicts from grammars input to Bison. The tool reads the output produced with Bison's '-v' switch, and helps you identify where the conflicts arise in your grammar.

Here is the source kit. You need to compile with GCC.

To give an example of what it does, with the following Bison input file


%token A B X Y
%%

start : a ;

a : b x | x ;

c : X | Y | c X | c Y ;

b : d | b d ;

d : A | B ;

x : d c | c ;

Bison gives the following output file :


State 8 contains 2 shift/reduce conflicts.
State 12 contains 2 shift/reduce conflicts.

Grammar
rule 1    start -> a
rule 2    a -> b x
rule 3    a -> x
rule 4    c -> X
rule 5    c -> Y
rule 6    c -> c X
rule 7    c -> c Y
rule 8    b -> d
rule 9    b -> b d
rule 10   d -> A
rule 11   d -> B
rule 12   x -> d c
rule 13   x -> c

Terminals, with rules where they appear

$ (-1)
error (256)
A (257) 10
B (258) 11
X (259) 4 6
Y (260) 5 7

Nonterminals, with rules where they appear

start (7)
    on left: 1
a (8)
    on left: 2 3, on right: 1
c (9)
    on left: 4 5 6 7, on right: 6 7 12 13
b (10)
    on left: 8 9, on right: 2 9
d (11)
    on left: 10 11, on right: 8 9 12
x (12)
    on left: 12 13, on right: 2 3


state 0

    A   	shift, and go to state 1
    B   	shift, and go to state 2
    X   	shift, and go to state 3
    Y   	shift, and go to state 4

    start	go to state 15
    a   	go to state 5
    c   	go to state 6
    b   	go to state 7
    d   	go to state 8
    x   	go to state 9



state 1

    d  ->  A .   (rule 10)

    $default	reduce using rule 10 (d)



state 2

    d  ->  B .   (rule 11)

    $default	reduce using rule 11 (d)



state 3

    c  ->  X .   (rule 4)

    $default	reduce using rule 4 (c)



state 4

    c  ->  Y .   (rule 5)

    $default	reduce using rule 5 (c)



state 5

    start  ->  a .   (rule 1)

    $default	reduce using rule 1 (start)



state 6

    c  ->  c . X   (rule 6)
    c  ->  c . Y   (rule 7)
    x  ->  c .   (rule 13)

    X   	shift, and go to state 10
    Y   	shift, and go to state 11

    $default	reduce using rule 13 (x)



state 7

    a  ->  b . x   (rule 2)
    b  ->  b . d   (rule 9)

    A   	shift, and go to state 1
    B   	shift, and go to state 2
    X   	shift, and go to state 3
    Y   	shift, and go to state 4

    c   	go to state 6
    d   	go to state 12
    x   	go to state 13



state 8

    b  ->  d .   (rule 8)
    x  ->  d . c   (rule 12)

    X   	shift, and go to state 3
    Y   	shift, and go to state 4

    X   	[reduce using rule 8 (b)]
    Y   	[reduce using rule 8 (b)]
    $default	reduce using rule 8 (b)

    c   	go to state 14



state 9

    a  ->  x .   (rule 3)

    $default	reduce using rule 3 (a)



state 10

    c  ->  c X .   (rule 6)

    $default	reduce using rule 6 (c)



state 11

    c  ->  c Y .   (rule 7)

    $default	reduce using rule 7 (c)



state 12

    b  ->  b d .   (rule 9)
    x  ->  d . c   (rule 12)

    X   	shift, and go to state 3
    Y   	shift, and go to state 4

    X   	[reduce using rule 9 (b)]
    Y   	[reduce using rule 9 (b)]
    $default	reduce using rule 9 (b)

    c   	go to state 14



state 13

    a  ->  b x .   (rule 2)

    $default	reduce using rule 2 (a)



state 14

    c  ->  c . X   (rule 6)
    c  ->  c . Y   (rule 7)
    x  ->  d c .   (rule 12)

    X   	shift, and go to state 10
    Y   	shift, and go to state 11

    $default	reduce using rule 12 (x)



state 15

    $   	go to state 16



state 16

    $   	go to state 17



state 17

    $default	accept

and the gramdiag software gives the following output


**********************************************************************
Shift/reduce conflict in state 8 when [X] follows [b] :

Option to reduce [b] using rule 8 (b -> [0:] d)
with token [X] occurring afterwards :

[x] follows [b] at positions (0,1) in rule 1 : a -> [0:] b [1:] x

  [c] occurs at the start of [x] (rule 13 : x -> [0:] c)
  [X] occurs at the start of [c] (rule 4 : c -> [0:] X)

Options to shift token [X] :

[X] can be shifted next in rule 12 (x -> [0:] d . [1:] c)
    [X] occurs at the start of [c] (rule 4 : c -> [0:] X)

**********************************************************************
Shift/reduce conflict in state 8 when [Y] follows [b] :

Option to reduce [b] using rule 8 (b -> [0:] d)
with token [Y] occurring afterwards :

[x] follows [b] at positions (0,1) in rule 1 : a -> [0:] b [1:] x

  [c] occurs at the start of [x] (rule 13 : x -> [0:] c)
  [Y] occurs at the start of [c] (rule 5 : c -> [0:] Y)

Options to shift token [Y] :

[Y] can be shifted next in rule 12 (x -> [0:] d . [1:] c)
    [Y] occurs at the start of [c] (rule 5 : c -> [0:] Y)

**********************************************************************
Shift/reduce conflict in state 12 when [X] follows [b] :

Option to reduce [b] using rule 9 (b -> [0:] b [1:] d)
with token [X] occurring afterwards :

[x] follows [b] at positions (0,1) in rule 1 : a -> [0:] b [1:] x

  [c] occurs at the start of [x] (rule 13 : x -> [0:] c)
  [X] occurs at the start of [c] (rule 4 : c -> [0:] X)

Options to shift token [X] :

[X] can be shifted next in rule 12 (x -> [0:] d . [1:] c)
    [X] occurs at the start of [c] (rule 4 : c -> [0:] X)

**********************************************************************
Shift/reduce conflict in state 12 when [Y] follows [b] :

Option to reduce [b] using rule 9 (b -> [0:] b [1:] d)
with token [Y] occurring afterwards :

[x] follows [b] at positions (0,1) in rule 1 : a -> [0:] b [1:] x

  [c] occurs at the start of [x] (rule 13 : x -> [0:] c)
  [Y] occurs at the start of [c] (rule 5 : c -> [0:] Y)

Options to shift token [Y] :

[Y] can be shifted next in rule 12 (x -> [0:] d . [1:] c)
    [Y] occurs at the start of [c] (rule 5 : c -> [0:] Y)