単純なものを試す。ルールの書きかた、まとめ方

#!/usr/bin/env python

import ply.lex as lex

tokens = (
  'A', 'B', 'C',
  'D', 'E', 'F',
  'a', 'b', 'c',
)

t_A = r'A'
t_B = r'B'
t_C = r'C'
t_D = r'D'
t_E = r'E'
t_F = r'F'
t_a = r'a'
t_b = r'b'
t_c = r'c'
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_input(p):
    '''input : lower
             | upper'''

def p_lower(p):
    '''lower : a b c'''
    print "*abc*"

def p_upper(p):
    '''upper : A B C
             | D E F'''
    if p[1] == 'A':
        print "*ABC*"
    else:
        print "*DEF*"

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
*abc*
input > A B C
*ABC*
input > D E F
*DEF*


複数のルールをまとめて書くこともできる。

#!/usr/bin/env python

import ply.lex as lex

tokens = (
  'A', 'B', 'C',
  'D', 'E', 'F',
  'a', 'b', 'c',
)

t_A = r'A'
t_B = r'B'
t_C = r'C'
t_D = r'D'
t_E = r'E'
t_F = r'F'
t_a = r'a'
t_b = r'b'
t_c = r'c'
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_input(p):
    '''input : lower
             | upper
       lower : a b c
       upper : A B C
             | D E F'''
    if p[1] == 'A':
        print "*ABC*"
    elif p[1] == 'D':
        print "*DEF*"
    elif p[1] == 'a':
        print "*abc*"

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
*abc*
input > A B C
*ABC*
input > D E F
*DEF*

「elif p[1] == 'a':」を「else:」にしたら「*abc*」が2つ目の出力として常に出るようになった。変だなと思ったが、input の規則のところでマッチしているのかな???