lex を試す。複数の状態を指定

「t_foo_INITIAL_PLUS = r'\+'」のように複数の状態「foo」「INITIAL」(初期状態)を指定できるようだ。
('exclusive' でも全条件だったら ANY を使えば良いだけだけど)

#!/usr/bin/env python

import ply.lex as lex

states = (
 ('foo', 'exclusive'),
)

tokens = (
  'A',
  'PLUS',
)

t_A                = r'a'
t_foo_INITIAL_PLUS = r'\+'
t_ANY_ignore       = ' \t\n'

t_foo_A            = r'b'

def t_begin_foo(t):
    r'start_foo'
    t.lexer.begin('foo')

def t_foo_end(t):
    r'end_foo'
    t.lexer.begin('INITIAL')

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

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

lexer = lex.lex()
lexer.input("""
a+a
start_foo
b+b
end_foo
a+a
""")

while 1:
    tok = lexer.token()
    if not tok: break      # No more input
    print tok

で、

LexToken(A,'a',1,1)
LexToken(PLUS,'+',1,2)
LexToken(A,'a',1,3)
LexToken(A,'b',1,15)
LexToken(PLUS,'+',1,16)
LexToken(A,'b',1,17)
LexToken(A,'a',1,27)
LexToken(PLUS,'+',1,28)
LexToken(A,'a',1,29)