規則の途中のアクションで shift/reduce conflicts が発生してしまう

まんま

#!/usr/bin/env python

import ply.lex as lex

tokens = (
  'A',
  'B',
  'C',
  'D',
  'X',
)

t_A = r'A'
t_B = r'B'
t_C = r'C'
t_D = r'D'
t_X = r'X'
t_ignore = " \t"

def t_error(t):
    print "Illegal character '%s'" % t.value[0]
    t.lexer.skip(1)

lex.lex()


import ply.yacc as yacc

def p_foo(p):
    """foo : abcd
           | abcx"""

def p_abcd(p):
    "abcd : A B C D"

def p_abcx(p):
    "abcx : A B C X"

def p_error(p):
    print "Syntax error at '%s'" % p.value

yacc.yacc()


while 1:
    try:
        s = raw_input('input > ')
    except EOFError:
        break
    if not s: continue
    yacc.parse(s)

で、

input > A B C D
input > A B C X


規則の途中のアクションを使った場合

#!/usr/bin/env python

import ply.lex as lex

tokens = (
  'A',
  'B',
  'C',
  'D',
  'X',
)

t_A = r'A'
t_B = r'B'
t_C = r'C'
t_D = r'D'
t_X = r'X'
t_ignore = " \t"

def t_error(t):
    print "Illegal character '%s'" % t.value[0]
    t.lexer.skip(1)

lex.lex()


import ply.yacc as yacc

def p_foo(p):
    """foo : abcd
           | abcx"""

def p_abcd(p):
    "abcd : A B C D"

def p_abcx(p):
    "abcx : A B seen_AB C X"

def p_seen_AB(p):
    "seen_AB :"

def p_error(p):
    print "Syntax error at '%s'" % p.value

yacc.yacc()


while 1:
    try:
        s = raw_input('input > ')
    except EOFError:
        break
    if not s: continue
    yacc.parse(s)

で、

yacc: Generating LALR parsing table...
yacc: 1 shift/reduce conflict
input > A B C D
input > A B C X
Syntax error at 'X'

解決策は?