エラーまわり

#!/usr/bin/env python

import ply.lex as lex

tokens = (
  'A',
  'B',
)

t_A = r'A'
t_B = r'B'
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 : A'
    print "*a*"

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: Warning. Token 'B' defined, but not used.
yacc: Warning. There is 1 unused token.
yacc: Generating LALR parsing table...
input > A
*a*
input > B
Syntax error at 'B'
input > A B
Syntax error at 'B'
*a*
Traceback (most recent call last):
  File "./20080413_ply00.py", line 39, in ?
    yacc.parse(s)
  File "/usr/lib/python2.3/site-packages/ply/yacc.py", line 314, in parse
    state = goto[statestack[-1]][pname]
IndexError: list index out of range

入力「B」だと「Syntax error」がちゃんと出力され大丈夫な(落ちない)のは、なぜ?


ルールの中に明示的に error を入れてみる

#!/usr/bin/env python

import ply.lex as lex

tokens = (
  'A',
  'B',
)

t_A = r'A'
t_B = r'B'
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 : A'
    print "*a*"

def p_input_error(p):
    'input : A error'
    print "Syntax error after 'A'"

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: Warning. Token 'B' defined, but not used.
yacc: Warning. There is 1 unused token.
yacc: Generating LALR parsing table...
input > A
*a*
input > B
Syntax error at 'B'
input > A B
Syntax error at 'B'
Syntax error after 'A'
input > A B
Syntax error at 'B'
Syntax error after 'A'
input > B A
Syntax error at 'B'
*a*